FELIX-2211: Simplify the repository parser based on KXml2
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@924667 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundlerepository/pom.xml b/bundlerepository/pom.xml
index 652e0fc..9db3ee8 100644
--- a/bundlerepository/pom.xml
+++ b/bundlerepository/pom.xml
@@ -47,6 +47,12 @@
<artifactId>kxml2</artifactId>
<version>2.2.2</version>
<optional>true</optional>
+ <exclusions>
+ <exclusion>
+ <groupId>xmlpull</groupId>
+ <artifactId>xmlpull</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
@@ -81,7 +87,11 @@
<configuration>
<instructions>
<Export-Package>org.apache.felix.bundlerepository;version="2.0"</Export-Package>
- <Private-Package>org.kxml2.*,org.xmlpull.*;-split-package:=merge-first,org.apache.felix.bundlerepository.impl.*</Private-Package>
+ <Private-Package>
+ org.kxml2.io,
+ org.xmlpull.v1,
+ org.apache.felix.bundlerepository.impl.*
+ </Private-Package>
<Import-Package>!javax.xml.parsers,!org.xml.sax,org.osgi.service.log;resolution:=optional,org.osgi.service.obr;resolution:=optional,javax.xml.stream;resolution:=optional,*</Import-Package>
<DynamicImport-Package>org.apache.felix.shell</DynamicImport-Package>
<Bundle-Activator>${pom.artifactId}.impl.Activator</Bundle-Activator>
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/PullParser.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/PullParser.java
new file mode 100644
index 0000000..1a1b47b
--- /dev/null
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/PullParser.java
@@ -0,0 +1,319 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.bundlerepository.impl;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import org.kxml2.io.KXmlParser;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+/**
+ * Repository XML parser based on StaX
+ */
+public class PullParser implements RepositoryImpl.RepositoryParser
+{
+
+ public PullParser()
+ {
+ }
+
+ public void parse(RepositoryImpl repository, InputStream is) throws Exception
+ {
+ KXmlParser reader = new KXmlParser();
+ reader.setInput(new BufferedReader(new InputStreamReader(is)));
+ int event = reader.nextTag();
+ if (event != XmlPullParser.START_TAG || !REPOSITORY.equals(reader.getName()))
+ {
+ throw new Exception("Expected element 'repository' at the root of the document");
+ }
+ for (int i = 0, nb = reader.getAttributeCount(); i < nb; i++)
+ {
+ String name = reader.getAttributeName(i);
+ String value = reader.getAttributeValue(i);
+ if (NAME.equals(name))
+ {
+ repository.setName(value);
+ }
+ else if (LASTMODIFIED.equals(name))
+ {
+ repository.setLastmodified(value);
+ }
+ }
+ while ((event = reader.nextTag()) == XmlPullParser.START_TAG)
+ {
+ String element = reader.getName();
+ if (REFERRAL.equals(element))
+ {
+ Referral referral = parseReferral(reader);
+ repository.addReferral(referral);
+ }
+ else if (RESOURCE.equals(element))
+ {
+ ResourceImpl resource = parseResource(reader);
+ repository.addResource(resource);
+ }
+ else
+ {
+ ignoreTag(reader);
+ }
+ }
+ // Sanity check
+ sanityCheckEndElement(reader, event, REPOSITORY);
+ }
+
+ private void sanityCheckEndElement(KXmlParser reader, int event, String element)
+ {
+ if (event != XmlPullParser.END_TAG || !element.equals(reader.getName()))
+ {
+ throw new IllegalStateException("Unexpected state while finishing element " + element);
+ }
+ }
+
+ private Referral parseReferral(KXmlParser reader) throws Exception
+ {
+ Referral referral = new Referral();
+ for (int i = 0, nb = reader.getAttributeCount(); i < nb; i++)
+ {
+ String name = reader.getAttributeName(i);
+ String value = reader.getAttributeValue(i);
+ if (DEPTH.equals(name))
+ {
+ referral.setDepth(value);
+ }
+ else if (URL.equals(name))
+ {
+ referral.setUrl(value);
+ }
+ }
+ sanityCheckEndElement(reader, reader.nextTag(), REFERRAL);
+ return referral;
+ }
+
+ private ResourceImpl parseResource(KXmlParser reader) throws Exception
+ {
+ ResourceImpl resource = new ResourceImpl();
+ try
+ {
+ for (int i = 0, nb = reader.getAttributeCount(); i < nb; i++)
+ {
+ resource.put(reader.getAttributeName(i), reader.getAttributeValue(i));
+ }
+ int event;
+ while ((event = reader.nextTag()) == XmlPullParser.START_TAG)
+ {
+ String element = reader.getName();
+ if (CATEGORY.equals(element))
+ {
+ CategoryImpl category = parseCategory(reader);
+ resource.addCategory(category);
+ }
+ else if (CAPABILITY.equals(element))
+ {
+ CapabilityImpl capability = parseCapability(reader);
+ resource.addCapability(capability);
+ }
+ else if (REQUIRE.equals(element))
+ {
+ RequirementImpl requirement = parseRequire(reader);
+ resource.addRequire(requirement);
+ }
+ else
+ {
+ StringBuffer sb = null;
+ String type = reader.getAttributeValue(null, "type");
+ while ((event = reader.next()) != XmlPullParser.END_TAG)
+ {
+ switch (event)
+ {
+ case XmlPullParser.START_TAG:
+ throw new Exception("Unexpected element inside <require/> element");
+ case XmlPullParser.TEXT:
+ if (sb == null)
+ {
+ sb = new StringBuffer();
+ }
+ sb.append(reader.getText());
+ break;
+ }
+ }
+ if (sb != null)
+ {
+ resource.put(element, sb.toString().trim(), type);
+ }
+ }
+ }
+ // Sanity check
+ if (event != XmlPullParser.END_TAG || !RESOURCE.equals(reader.getName()))
+ {
+ throw new Exception("Unexpected state");
+ }
+ return resource;
+ }
+ catch (Exception e)
+ {
+ throw new Exception("Error while parsing resource " + resource.getId() + " at line " + reader.getLineNumber() + " and column " + reader.getColumnNumber(), e);
+ }
+ }
+
+ private CategoryImpl parseCategory(KXmlParser reader) throws IOException, XmlPullParserException
+ {
+ CategoryImpl category = new CategoryImpl();
+ for (int i = 0, nb = reader.getAttributeCount(); i < nb; i++)
+ {
+ if (ID.equals(reader.getAttributeName(i)))
+ {
+ category.setId(reader.getAttributeValue(i));
+ }
+ }
+ sanityCheckEndElement(reader, reader.nextTag(), CATEGORY);
+ return category;
+ }
+
+ private CapabilityImpl parseCapability(KXmlParser reader) throws Exception
+ {
+ CapabilityImpl capability = new CapabilityImpl();
+ for (int i = 0, nb = reader.getAttributeCount(); i < nb; i++)
+ {
+ String name = reader.getAttributeName(i);
+ String value = reader.getAttributeValue(i);
+ if (NAME.equals(name))
+ {
+ capability.setName(value);
+ }
+ }
+ int event;
+ while ((event = reader.nextTag()) == XmlPullParser.START_TAG)
+ {
+ String element = reader.getName();
+ if (P.equals(element))
+ {
+ PropertyImpl prop = parseProperty(reader);
+ capability.addP(prop);
+ }
+ else
+ {
+ ignoreTag(reader);
+ }
+ }
+ // Sanity check
+ sanityCheckEndElement(reader, event, CAPABILITY);
+ return capability;
+ }
+
+ private PropertyImpl parseProperty(KXmlParser reader) throws Exception
+ {
+ String n = null, t = null, v = null;
+ for (int i = 0, nb = reader.getAttributeCount(); i < nb; i++)
+ {
+ String name = reader.getAttributeName(i);
+ String value = reader.getAttributeValue(i);
+ if (N.equals(name))
+ {
+ n = value;
+ }
+ else if (T.equals(name))
+ {
+ t = value;
+ }
+ else if (V.equals(name))
+ {
+ v = value;
+ }
+ }
+ PropertyImpl prop = new PropertyImpl(n, t, v);
+ // Sanity check
+ sanityCheckEndElement(reader, reader.nextTag(), P);
+ return prop;
+ }
+
+ private RequirementImpl parseRequire(KXmlParser reader) throws Exception
+ {
+ RequirementImpl requirement = new RequirementImpl();
+ for (int i = 0, nb = reader.getAttributeCount(); i < nb; i++)
+ {
+ String name = reader.getAttributeName(i);
+ String value = reader.getAttributeValue(i);
+ if (NAME.equals(name))
+ {
+ requirement.setName(value);
+ }
+ else if (FILTER.equals(name))
+ {
+ requirement.setFilter(value);
+ }
+ else if (EXTEND.equals(name))
+ {
+ requirement.setExtend(value);
+ }
+ else if (MULTIPLE.equals(name))
+ {
+ requirement.setMultiple(value);
+ }
+ else if (OPTIONAL.equals(name))
+ {
+ requirement.setOptional(value);
+ }
+ }
+ int event;
+ StringBuffer sb = null;
+ while ((event = reader.next()) != XmlPullParser.END_TAG)
+ {
+ switch (event)
+ {
+ case XmlPullParser.START_TAG:
+ throw new Exception("Unexpected element inside <require/> element");
+ case XmlPullParser.TEXT:
+ if (sb == null)
+ {
+ sb = new StringBuffer();
+ }
+ sb.append(reader.getText());
+ break;
+ }
+ }
+ if (sb != null)
+ {
+ requirement.addText(sb.toString());
+ }
+ // Sanity check
+ sanityCheckEndElement(reader, event, REQUIRE);
+ return requirement;
+ }
+
+ private void ignoreTag(KXmlParser reader) throws IOException, XmlPullParserException {
+ int level = 1;
+ int event = 0;
+ while (level > 0)
+ {
+ event = reader.next();
+ if (event == XmlPullParser.START_TAG)
+ {
+ level++;
+ }
+ else if (event == XmlPullParser.END_TAG)
+ {
+ level--;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/RepositoryImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/RepositoryImpl.java
index db8af53..4518f5a 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/RepositoryImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/RepositoryImpl.java
@@ -39,8 +39,6 @@
import org.apache.felix.bundlerepository.Capability;
import org.apache.felix.bundlerepository.Requirement;
import org.apache.felix.bundlerepository.Resource;
-import org.apache.felix.bundlerepository.impl.metadataparser.XmlCommonHandler;
-import org.apache.felix.bundlerepository.impl.metadataparser.kxmlsax.KXml2SAXParser;
import org.apache.felix.bundlerepository.Repository;
public class RepositoryImpl implements Repository
@@ -287,7 +285,7 @@
}
if (parser == null)
{
- parser = new KXml2Parser();
+ parser = new PullParser();
}
parser.parse(this, is);
@@ -295,45 +293,27 @@
public interface RepositoryParser
{
+ static final String REPOSITORY = "repository";
+ static final String NAME = "name";
+ static final String LASTMODIFIED = "lastmodified";
+ static final String REFERRAL = "referral";
+ static final String RESOURCE = "resource";
+ static final String DEPTH = "depth";
+ static final String URL = "url";
+ static final String CATEGORY = "category";
+ static final String ID = "id";
+ static final String CAPABILITY = "capability";
+ static final String REQUIRE = "require";
+ static final String P = "p";
+ static final String N = "n";
+ static final String T = "t";
+ static final String V = "v";
+ static final String FILTER = "filter";
+ static final String EXTEND = "extend";
+ static final String MULTIPLE = "multiple";
+ static final String OPTIONAL = "optional";
+
void parse(RepositoryImpl repository, InputStream is) throws Exception;
}
- public static class KXml2Parser implements RepositoryParser
- {
- public void parse(final RepositoryImpl repository, final InputStream is) throws Exception
- {
- BufferedReader br;// Create the parser Kxml
- XmlCommonHandler handler = new XmlCommonHandler(repository.m_logger);
- Object factory = new Object()
- {
- public RepositoryImpl newInstance()
- {
- return repository;
- }
- };
-
- // Get default setter method for Repository.
- Method repoSetter = RepositoryImpl.class.getDeclaredMethod(
- "put", new Class[] { Object.class, Object.class });
-
- // Get default setter method for Resource.
- Method resSetter = ResourceImpl.class.getDeclaredMethod(
- "put", new Class[] { Object.class, Object.class });
-
- // Map XML tags to types.
- handler.addType("repository", factory, Repository.class, repoSetter);
- handler.addType("referral", Referral.class, null, null);
- handler.addType("resource", ResourceImpl.class, Resource.class, resSetter);
- handler.addType("category", CategoryImpl.class, null, null);
- handler.addType("require", RequirementImpl.class, Requirement.class, null);
- handler.addType("capability", CapabilityImpl.class, Capability.class, null);
- handler.addType("p", PropertyImpl.class, null, null);
- handler.setDefaultType(String.class, null, null);
-
- br = new BufferedReader(new InputStreamReader(is));
- KXml2SAXParser parser;
- parser = new KXml2SAXParser(br);
- parser.parseXML(handler);
- }
- }
}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/StaxParser.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/StaxParser.java
index e13fe3d..450c9ac 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/StaxParser.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/StaxParser.java
@@ -30,25 +30,6 @@
*/
public class StaxParser implements RepositoryImpl.RepositoryParser
{
- private static final String REPOSITORY = "repository";
- private static final String NAME = "name";
- private static final String LASTMODIFIED = "lastmodified";
- private static final String REFERRAL = "referral";
- private static final String RESOURCE = "resource";
- private static final String DEPTH = "depth";
- private static final String URL = "url";
- private static final String CATEGORY = "category";
- private static final String ID = "id";
- private static final String CAPABILITY = "capability";
- private static final String REQUIRE = "require";
- private static final String P = "p";
- private static final String N = "n";
- private static final String T = "t";
- private static final String V = "v";
- private static final String FILTER = "filter";
- private static final String EXTEND = "extend";
- private static final String MULTIPLE = "multiple";
- private static final String OPTIONAL = "optional";
static XMLInputFactory factory;
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/ClassUtility.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/ClassUtility.java
deleted file mode 100644
index 5764068..0000000
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/ClassUtility.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.bundlerepository.impl.metadataparser;
-
-/**
- * This class provides methods to process class name
- */
-public class ClassUtility
-{
- /**
- * This method capitalizes the first character in the provided string.
- * @return resulted string
- */
- public static String capitalize(String name)
- {
- int len = name.length();
- StringBuffer sb = new StringBuffer(len);
- boolean setCap = true;
- for (int i = 0; i < len; i++)
- {
- char c = name.charAt(i);
- if (c == '-' || c == '_')
- {
- setCap = true;
- }
- else
- {
- if (setCap)
- {
- sb.append(Character.toUpperCase(c));
- setCap = false;
- }
- else
- {
- sb.append(c);
- }
- }
- }
-
- return sb.toString();
- }
-
- /**
- * This method minusculizes all characters in the provided string.
- * @return resulted string
- */
- public static String toLowerCase(String name)
- {
- int len = name.length();
- StringBuffer sb = new StringBuffer(len);
- for (int i = 0; i < len; i++)
- {
- char c = name.charAt(i);
- sb.append(Character.toLowerCase(c));
- }
- return sb.toString();
- }
-
- /**
- * This method capitalizes all characters in the provided string.
- * @return resulted string
- */
- public static String finalstaticOf(String membername)
- {
- int len = membername.length();
- StringBuffer sb = new StringBuffer(len + 2);
- for (int i = 0; i < len; i++)
- {
- char c = membername.charAt(i);
- if (Character.isLowerCase(c))
- {
- sb.append(Character.toUpperCase(c));
- }
- else if (Character.isUpperCase(c))
- {
- sb.append('_').append(c);
- }
- else
- {
- sb.append(c);
- }
- }
-
- return sb.toString();
- }
-
- /**
- * This method returns the package name in a full class name
- * @return resulted string
- */
- public static String packageOf(String fullclassname)
- {
- int index = fullclassname.lastIndexOf(".");
- if (index > 0)
- {
- return fullclassname.substring(0, index);
- }
- else
- {
- return "";
- }
- }
-
- /**
- * This method returns the package name in a full class name
- * @return resulted string
- */
- public static String classOf(String fullclassname)
- {
- int index = fullclassname.lastIndexOf(".");
- if (index > 0)
- {
- return fullclassname.substring(index + 1);
- }
- else
- {
- return fullclassname;
- }
- }
-}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/KXml2MetadataHandler.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/KXml2MetadataHandler.java
deleted file mode 100644
index 0e48a1f..0000000
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/KXml2MetadataHandler.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.bundlerepository.impl.metadataparser;
-
-import java.io.*;
-
-import org.apache.felix.bundlerepository.impl.Logger;
-import org.apache.felix.bundlerepository.impl.metadataparser.kxmlsax.KXml2SAXParser;
-
-/**
- * handles the metadata in XML format
- * (use kXML (http://kxml.enhydra.org/) a open-source very light weight XML parser
- */
-public class KXml2MetadataHandler extends MetadataHandler
-{
- public KXml2MetadataHandler(Logger logger)
- {
- super(logger);
- }
-
- /**
- * Called to parse the InputStream and set bundle list and package hash map
- */
- public void parse(InputStream is) throws Exception
- {
- BufferedReader br = new BufferedReader(new InputStreamReader(is));
- KXml2SAXParser parser;
- parser = new KXml2SAXParser(br);
- parser.parseXML(m_handler);
- }
-}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/MappingProcessingInstructionHandler.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/MappingProcessingInstructionHandler.java
deleted file mode 100644
index 4387108..0000000
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/MappingProcessingInstructionHandler.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.bundlerepository.impl.metadataparser;
-
-/**
- * this class adds type of elements to the parser
- */
-public class MappingProcessingInstructionHandler
-{
- private XmlCommonHandler m_handler;
- private String m_name;
- private String m_classname;
-
- public MappingProcessingInstructionHandler(XmlCommonHandler handler)
- {
- m_handler = handler;
- }
-
- public void process() throws Exception
- {
- if (m_name == null)
- {
- throw new Exception("element is missing");
- }
- if (m_classname == null)
- {
- throw new Exception("class is missing");
- }
- m_handler.addType(m_name, getClass().getClassLoader().loadClass(m_classname), null, null);
- }
-
- public void setElement(String element)
- {
- m_name = element;
- }
-
- public void setClass(String classname)
- {
- m_classname = classname;
- }
-}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/MetadataHandler.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/MetadataHandler.java
deleted file mode 100644
index 4994022..0000000
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/MetadataHandler.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.bundlerepository.impl.metadataparser;
-
-import org.apache.felix.bundlerepository.impl.Logger;
-
-import java.io.InputStream;
-import java.lang.reflect.Method;
-
-public abstract class MetadataHandler
-{
- protected XmlCommonHandler m_handler;
-
- /**
- * constructor
- *
- */
- public MetadataHandler(Logger logger)
- {
- m_handler = new XmlCommonHandler(logger);
- }
-
- /**
- * Called to parse the InputStream and set bundle list and package hash map
- */
- public abstract void parse(InputStream is) throws Exception;
-
- /**
- * return the metadata after the parsing
- * @return a Object. Its class is the returned type of instanceFactory newInstance method for the root element of the XML document.
- */
- public final Object getMetadata()
- {
- return m_handler.getRoot();
- }
-
- /**
- * Add a type for a element
- * @param qname the name of the element to process
- * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
- * @throws Exception
- */
- public final void addType(String qname, Object instanceFactory) throws Exception
- {
- m_handler.addType(qname, instanceFactory, null, null);
- }
-
- /**
- * Add a type for a element
- * @param qname the name of the element to process
- * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
- * @param castClass the class used to introspect the adder/setter and parameters in parent adder/setter. if null the castClass is by default the class returned by the newInstance method of the instanceFactory.
- * @throws Exception
- */
- public final void addType(String qname, Object instanceFactory, Class castClass) throws Exception
- {
- m_handler.addType(qname, instanceFactory, castClass, null);
- }
-
- /**
- * Add a type for a element
- * @param qname the name of the element to process
- * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
- * @param castClass the class used to introspect the adder/setter and parameters in parent adder/setter. if null the castClass is by default the class returned by the newInstance method of the instanceFactory.
- * @param defaultAddMethod the method used to add the sub-elements and attributes if no adder/setter is founded. could be omitted.
- * @throws Exception
- */
- public final void addType(String qname, Object instanceFactory, Class castClass, Method defaultAddMethod) throws Exception
- {
- m_handler.addType(qname, instanceFactory, castClass, defaultAddMethod);
- }
-
- /**
- * Add a type for the default element
- * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
- * @throws Exception
- */
- public final void setDefaultType(Object instanceFactory) throws Exception
- {
- m_handler.setDefaultType(instanceFactory, null, null);
- }
-
- /**
- * Add a type for the default element
- * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
- * @param castClass the class used to introspect the adder/setter and parameters in parent adder/setter. if null the castClass is by default the class returned by the newInstance method of the instanceFactory.
- * @throws Exception
- */
- public final void setDefaultType(Object instanceFactory, Class castClass) throws Exception
- {
- m_handler.setDefaultType(instanceFactory, castClass, null);
- }
-
- /**
- * Add a type for the default element
- * @param instanceFactory the factory of objects representing an element. Must have a newInstance method. could be a class.
- * @param castClass the class used to introspect the adder/setter and parameters in parent adder/setter. if null the castClass is by default the class returned by the newInstance method of the instanceFactory.
- * @param defaultAddMethod the method used to add the sub-elements and attributes if no adder/setter is founded. could be omitted.
- * @throws Exception
- */
- public final void setDefaultType(Object instanceFactory, Class castClass, Method defaultAddMethod) throws Exception
- {
- m_handler.setDefaultType(instanceFactory, castClass, defaultAddMethod);
- }
-
- /**
- * Add a type to process the processing instruction
- * @param piname
- * @param clazz
- */
- public final void addPI(String piname, Class clazz)
- {
- m_handler.addPI(piname, clazz);
- }
-
- /**
- * set the missing PI exception flag. If during parsing, the flag is true and the processing instruction is unknown, then the parser throws a exception
- * @param flag
- */
- public final void setMissingPIExceptionFlag(boolean flag)
- {
- m_handler.setMissingPIExceptionFlag(flag);
- }
-
- /**
- *
- * @param trace
- * @since 0.9.1
- */
- public final void setTrace(boolean trace)
- {
- m_handler.setTrace(trace);
- }
-}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/ReplaceUtility.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/ReplaceUtility.java
deleted file mode 100644
index 26cb4d4..0000000
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/ReplaceUtility.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.bundlerepository.impl.metadataparser;
-
-import java.util.Map;
-
-/**
- * This class provides methods to replace ${var} substring by values stored in a map
- */
-public class ReplaceUtility
-{
- /**
- * This method replaces ${var} substring by values stored in a map.
- * @return resulted string
- */
- public static String replace(String str, Map values)
- {
- int len = str.length();
- StringBuffer sb = new StringBuffer(len);
-
- int prev = 0;
- int start = str.indexOf("${");
- int end = str.indexOf("}", start);
- while (start != -1 && end != -1)
- {
- String key = str.substring(start + 2, end);
- Object value = values.get(key);
- if (value != null)
- {
- sb.append(str.substring(prev, start));
- sb.append(value);
- }
- else
- {
- sb.append(str.substring(prev, end + 1));
- }
- prev = end + 1;
- if (prev >= str.length())
- {
- break;
- }
- start = str.indexOf("${", prev);
- if (start != -1)
- {
- end = str.indexOf("}", start);
- }
- }
-
- sb.append(str.substring(prev));
-
- return sb.toString();
- }
-
- // public static void main(String[] args){
- // Map map=new HashMap();
- // map.put("foo","FOO");
- // map.put("bar","BAR");
- // map.put("map",map);
- //
- // String str;
- // if(args.length==0) str=""; else str=args[0];
- //
- // System.out.println(replace(str,map));
- //
- // }
-}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/XmlCommonHandler.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/XmlCommonHandler.java
deleted file mode 100644
index 6920a98..0000000
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/XmlCommonHandler.java
+++ /dev/null
@@ -1,1021 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.bundlerepository.impl.metadataparser;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.*;
-
-import org.apache.felix.bundlerepository.impl.Logger;
-import org.apache.felix.bundlerepository.impl.metadataparser.kxmlsax.KXml2SAXHandler;
-import org.xml.sax.SAXException;
-
-/**
- * SAX handler for the XML file
- */
-public class XmlCommonHandler implements KXml2SAXHandler
-{
- private static final String PI_MAPPING = "mapping";
- public static final String METADATAPARSER_PIS = "METADATAPARSER_PIS";
- public static final String METADATAPARSER_TYPES = "METADATAPARSER_TYPES";
- private int m_columnNumber;
- private int m_lineNumber;
- private boolean m_traceFlag = false;
- private static String VALUE = "value";
-
- //
- // Data
- //
- private XmlStackElement m_root;
- private Stack m_elementStack;
- private Map m_pis;
- private boolean m_missingPIExceptionFlag;
- private Map m_types;
- private TypeEntry m_defaultType;
- private StringBuffer m_currentText;
- private Map m_context;
- private final Logger m_logger;
-
- private class XmlStackElement
- {
- public final String m_qname;
- public Object m_object;
-
- public XmlStackElement(String qname, Object object)
- {
- super();
- m_qname = qname;
- m_object = object;
- }
- }
-
- public class TypeEntry
- {
- public final Object m_instanceFactory;
- public final Class m_instanceClass;
- public final Method m_newInstanceMethod;
- public final Class m_castClass;
- public final Method m_defaultAddMethod;
-
- public TypeEntry(Object instanceFactory, Class castClass, Method defaultAddMethod) throws Exception
- {
- super();
- m_instanceFactory = instanceFactory;
-
- try
- {
- if (instanceFactory instanceof Class)
- {
- m_newInstanceMethod = instanceFactory.getClass().getDeclaredMethod("newInstance", null);
- if (castClass == null)
- {
- m_castClass = (Class) instanceFactory;
- }
- else
- {
- if (!castClass.isAssignableFrom((Class) instanceFactory))
- {
- throw new Exception(
- "instanceFactory " + instanceFactory.getClass().getName() + " could not instanciate objects assignable to " + castClass.getName());
- }
- m_castClass = castClass;
- }
- m_instanceClass = (Class) instanceFactory;
- }
- else
- {
- m_newInstanceMethod = instanceFactory.getClass().getDeclaredMethod("newInstance", null);
- Class returnType = m_newInstanceMethod.getReturnType();
- if (castClass == null)
- {
- m_castClass = returnType;
- }
- else if (!castClass.isAssignableFrom(returnType))
- {
- throw new Exception(
- "instanceFactory " + instanceFactory.getClass().getName() + " could not instanciate objects assignable to " + castClass.getName());
- }
- else
- {
- m_castClass = castClass;
- }
- m_instanceClass = returnType;
- }
- }
- catch (NoSuchMethodException e)
- {
- throw new Exception(
- "instanceFactory " + instanceFactory.getClass().getName() + " should have a newInstance method");
- }
-
- // TODO check method
- m_defaultAddMethod = defaultAddMethod;
- if (m_defaultAddMethod != null)
- {
- m_defaultAddMethod.setAccessible(true);
- }
- }
-
- public String toString()
- {
- StringBuffer sb = new StringBuffer();
- sb.append("[");
- if (m_instanceFactory instanceof Class)
- {
- sb.append("instanceFactory=").append(((Class) m_instanceFactory).getName());
- }
- else
- {
- sb.append("instanceFactory=").append(m_instanceFactory.getClass().getName());
- }
- sb.append(",instanceClass=").append(m_instanceClass.getName());
- sb.append(",castClass=").append(m_castClass.getName());
- sb.append(",defaultAddMethod=");
- if (m_defaultAddMethod == null)
- {
- sb.append("");
- }
- else
- {
- sb.append(m_defaultAddMethod.getName());
- }
- sb.append("]");
- return sb.toString();
- }
- }
-
- public XmlCommonHandler(Logger logger)
- {
- m_logger = logger;
- m_elementStack = new Stack();
- m_pis = new HashMap();
- m_missingPIExceptionFlag = false;
- m_types = new HashMap();
- m_context = new HashMap();
- m_context.put(METADATAPARSER_PIS, m_pis);
- m_context.put(METADATAPARSER_TYPES, m_types);
- }
-
- public void addPI(String piname, Class clazz)
- {
- m_pis.put(piname, clazz);
- }
-
- /**
- * set the missing PI exception flag. If during parsing, the flag is true
- * and the processing instruction is unknown, then the parser throws a
- * exception
- *
- * @param flag
- */
- public void setMissingPIExceptionFlag(boolean flag)
- {
- m_missingPIExceptionFlag = flag;
- }
-
- public void addType(String qname, Object instanceFactory, Class castClass, Method defaultAddMethod)
- throws Exception
- {
-
- TypeEntry typeEntry;
- try
- {
- typeEntry = new TypeEntry(
- instanceFactory,
- castClass,
- defaultAddMethod);
- }
- catch (Exception e)
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + qname + " : " + e.getMessage());
- }
- m_types.put(qname, typeEntry);
- trace("element " + qname + " : " + typeEntry.toString());
- }
-
- public void setDefaultType(Object instanceFactory, Class castClass, Method defaultAddMethod)
- throws Exception
- {
- TypeEntry typeEntry;
- try
- {
- typeEntry = new TypeEntry(
- instanceFactory,
- castClass,
- defaultAddMethod);
- }
- catch (Exception e)
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ": default element : " + e.getMessage());
- }
- m_defaultType = typeEntry;
- trace("default element " + " : " + typeEntry.toString());
- }
-
- public void setContext(Map context)
- {
- m_context = context;
- }
-
- public Map getContext()
- {
- return m_context;
- }
-
- public Object getRoot()
- {
- return m_root.m_object;
- }
-
- /* for PCDATA */
- public void characters(char[] ch, int offset, int length) throws Exception
- {
- if (m_currentText != null)
- {
- m_currentText.append(ch, offset, length);
- }
- }
-
- private String adderOf(Class clazz)
- {
- return "add" + ClassUtility.capitalize(ClassUtility.classOf(clazz.getName()));
- }
-
- private String adderOf(String key)
- {
- return "add" + ClassUtility.capitalize(key);
- }
-
- private String setterOf(Class clazz)
- {
- return "set" + ClassUtility.capitalize(ClassUtility.classOf(clazz.getName()));
- }
-
- private String setterOf(String key)
- {
- return "set" + ClassUtility.capitalize(key);
- }
-
- /**
- * set the parser context in a object
- */
- private void setObjectContext(Object object)
- throws IllegalArgumentException, IllegalAccessException,
- InvocationTargetException
- {
- Method method = null;
- try
- {
- // TODO setContext from castClass or object.getClass() ?
- method = object.getClass().getDeclaredMethod("setContext",
- new Class[]
- {
- Map.class
- });
- }
- catch (NoSuchMethodException e)
- {
- // do nothing
- }
- if (method != null)
- {
- trace(method.getName());
- try
- {
- method.invoke(object, new Object[]
- {
- m_context
- });
- }
- catch (InvocationTargetException e)
- {
- m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
- throw e;
- }
- }
- }
-
- /**
- * set the parser context in a object
- *
- * @throws Throwable
- */
- private void invokeProcess(Object object) throws Throwable
- {
- Method method = null;
- try
- {
- // TODO process from castClass or object.getClass() ?
- method = object.getClass().getDeclaredMethod("process", null);
- }
- catch (NoSuchMethodException e)
- {
- // do nothing
- }
- if (method != null)
- {
- trace(method.getName());
- try
- {
- method.invoke(object, null);
- }
- catch (InvocationTargetException e)
- {
- // m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
- throw e.getTargetException();
- }
- }
- }
-
- /**
- * set the parent in a object
- */
- private void setObjectParent(Object object, Object parent)
- throws InvocationTargetException, IllegalArgumentException,
- IllegalAccessException
- {
- Method method = null;
- try
- {
- // TODO setParent from castClass or object.getClass() ?
- method = object.getClass().getDeclaredMethod("setParent",
- new Class[]
- {
- parent.getClass()
- });
- }
- catch (NoSuchMethodException e)
- {
- // do nothing
- }
- if (method != null)
- {
- trace(method.getName());
- try
- {
- method.invoke(object, new Object[]
- {
- parent
- });
- }
- catch (InvocationTargetException e)
- {
- m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
- throw e;
- }
- }
- }
-
- /**
- * Method called when a tag opens
- *
- * @param uri
- * @param localName
- * @param qName
- * @param attrib
- * @exception SAXException
- */
- public void startElement(String uri, String localName, String qName,
- Properties attrib) throws Exception
- {
-
- trace("START (" + m_lineNumber + "," + m_columnNumber + "):" + uri + ":" + qName);
-
- // TODO: should add uri in the qname in the future
- TypeEntry type = (TypeEntry) m_types.get(qName);
- if (type == null)
- {
- type = m_defaultType;
- }
-
- Object obj = null;
- if (type != null)
- {
-
- try
- {
- // enables to access to "unmuttable" method
- type.m_newInstanceMethod.setAccessible(true);
- obj = type.m_newInstanceMethod.invoke(type.m_instanceFactory, null);
- }
- catch (InvocationTargetException e)
- {
- m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
- }
-
- // set parent
- if (!m_elementStack.isEmpty())
- {
- XmlStackElement parent = (XmlStackElement) m_elementStack.peek();
- setObjectParent(obj, parent.m_object);
- }
-
- // set the parser context
- setObjectContext(obj);
-
- // set the attributes
- Set keyset = attrib.keySet();
- Iterator iter = keyset.iterator();
- while (iter.hasNext())
- {
- String key = (String) iter.next();
-
- // substitute ${property} sbustrings by context' properties
- // values
- String value = ReplaceUtility.replace((String) attrib.get(key),
- m_context);
-
- // Firstly, test if the getter or the adder exists
-
- Method method = null;
- if (!(obj instanceof String))
- {
- try
- {
- // method = castClass.getDeclaredMethod(setterOf(key),new
- // Class[] { String.class });
- method = type.m_instanceClass.getDeclaredMethod(setterOf(key),
- new Class[]
- {
- String.class
- });
- }
- catch (NoSuchMethodException e)
- {
- // do nothing
- }
- if (method == null)
- {
- try
- {
- method = type.m_instanceClass.getDeclaredMethod(adderOf(key),
- new Class[]
- {
- String.class
- });
-
- }
- catch (NoSuchMethodException e)
- {
- /*
- * throw new Exception(lineNumber + "," +
- * columnNumber + ":" + "element " + qName + " does
- * not support the attribute " + key);
- */
- }
- }
- }
-
- if (method != null)
- {
- trace(method.getName());
- try
- {
- method.invoke(obj, new String[]
- {
- value
- });
- }
- catch (InvocationTargetException e)
- {
- m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
- throw e;
- }
- }
- else
- {
-
- if (obj instanceof String)
- {
- if (key.equals(VALUE))
- {
- obj = value;
- }
- else
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + "String element " + qName + " cannot have other attribute than value");
- }
- }
- else
- {
- if (type.m_defaultAddMethod != null)
- {
- Class[] parameterTypes = type.m_defaultAddMethod.getParameterTypes();
- if (parameterTypes.length == 2 && parameterTypes[0].isAssignableFrom(String.class) && parameterTypes[1].isAssignableFrom(String.class))
- {
- type.m_defaultAddMethod.invoke(obj, new String[]
- {
- key, value
- });
- }
- else if (parameterTypes.length == 1 && parameterTypes[0].isAssignableFrom(String.class))
- {
- type.m_defaultAddMethod.invoke(obj, new String[]
- {
- value
- });
- }
- else
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + "class " + type.m_instanceFactory.getClass().getName() + " for element " + qName + " does not support the attribute " + key);
- }
- }
- else
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + "class " + type.m_instanceFactory.getClass().getName() + " for element " + qName + " does not support the attribute " + key);
- }
- }
- }
- }
- }
- else
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + "this element " + qName + " has not corresponding class");
- }
- XmlStackElement element = new XmlStackElement(qName, obj);
- if (m_root == null)
- {
- m_root = element;
- }
- m_elementStack.push(element);
- m_currentText = new StringBuffer();
-
- trace("START/ (" + m_lineNumber + "," + m_columnNumber + "):" + uri + ":" + qName);
- }
-
- /**
- * Method called when a tag closes
- *
- * @param uri
- * @param localName
- * @param qName
- * @exception SAXException
- */
- public void endElement(java.lang.String uri, java.lang.String localName,
- java.lang.String qName) throws Exception
- {
-
- trace("END (" + m_lineNumber + "," + m_columnNumber + "):" + uri + ":" + qName);
-
- XmlStackElement element = (XmlStackElement) m_elementStack.pop();
- TypeEntry elementType = (TypeEntry) m_types.get(element.m_qname);
- if (elementType == null)
- {
- elementType = m_defaultType;
- }
-
- if (m_currentText != null && m_currentText.length() != 0)
- {
-
- String currentStr = ReplaceUtility.replace(m_currentText.toString(),
- m_context).trim();
- // TODO: trim may be not the right choice
- trace("current text:" + currentStr);
-
- Method method = null;
- try
- {
- method = elementType.m_castClass.getDeclaredMethod("addText",
- new Class[]
- {
- String.class
- });
- }
- catch (NoSuchMethodException e)
- {
- try
- {
- method = elementType.m_castClass.getDeclaredMethod("setText",
- new Class[]
- {
- String.class
- });
- }
- catch (NoSuchMethodException e2)
- {
- // do nothing
- }
- }
- if (method != null)
- {
- trace(method.getName());
- try
- {
- method.invoke(element.m_object, new String[]
- {
- currentStr
- });
- }
- catch (InvocationTargetException e)
- {
- m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
- throw e;
- }
- }
- else
- {
- if (String.class.isAssignableFrom(elementType.m_castClass))
- {
- String str = (String) element.m_object;
- if (str.length() != 0)
- {
- throw new Exception(
- m_lineNumber + "," + m_columnNumber + ":" + "String element " + qName + " cannot have both PCDATA and an attribute value");
- }
- else
- {
- element.m_object = currentStr;
- }
- }
- }
- }
-
- m_currentText = null;
-
- if (!m_elementStack.isEmpty())
- {
-
- XmlStackElement parent = (XmlStackElement) m_elementStack.peek();
- TypeEntry parentType = (TypeEntry) m_types.get(parent.m_qname);
- if (parentType == null)
- {
- parentType = m_defaultType;
- }
-
- String capqName = ClassUtility.capitalize(qName);
- Method method = null;
- try
- {
-// TODO: OBR PARSER: We should also check for instance class as a parameter.
- method = parentType.m_instanceClass.getDeclaredMethod(
- adderOf(capqName),
- new Class[]
- {
- elementType.m_castClass
-
- }); // instanceClass
- }
- catch (NoSuchMethodException e)
- {
- trace("NoSuchMethodException: " + adderOf(capqName) + "(" + elementType.m_castClass.getName() + ")");
- // do nothing
- }
- if (method == null)
- {
- try
- {
- method = parentType.m_instanceClass.getDeclaredMethod(
- setterOf(capqName),
- new Class[]
- {
- elementType.m_castClass
-
- });
- }
- catch (NoSuchMethodException e)
- {
- trace("NoSuchMethodException: " + setterOf(capqName) + "(" + elementType.m_castClass.getName() + ")");
- // do nothing
- }
- /*if (method == null)
- try {
- method = parentType.castClass.getDeclaredMethod(
- adderOf(type.castClass),
- new Class[] { type.castClass });
- } catch (NoSuchMethodException e) {
- trace("NoSuchMethodException: " + adderOf(type.castClass)+ "("+type.castClass.getName()+")");
- // do nothing
- }
- if (method == null)
- try {
- method = parentType.castClass.getDeclaredMethod(
- setterOf(type.castClass),
- new Class[] { type.castClass });
- } catch (NoSuchMethodException e) {
- trace("NoSuchMethodException: " + setterOf(type.castClass)+ "("+type.castClass.getName()+")");
- // do nothing
- }
- */
- }
- if (method != null)
- {
- trace(method.getName());
- try
- {
- method.setAccessible(true);
- method.invoke(parent.m_object, new Object[]
- {
- element.m_object
-
- });
- }
- catch (InvocationTargetException e)
- {
- m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
- throw e;
- }
- }
- else
- {
- if (parentType.m_defaultAddMethod != null)
- {
- Class[] parameterTypes = parentType.m_defaultAddMethod.getParameterTypes();
- if (parameterTypes.length == 2 && parameterTypes[0].isAssignableFrom(String.class) && parameterTypes[1].isAssignableFrom(elementType.m_castClass))
- {
- parentType.m_defaultAddMethod.invoke(parent.m_object, new Object[]
- {
- qName, element.m_object
-
- });
- }
- else if (parameterTypes.length == 1 && parameterTypes[0].isAssignableFrom(elementType.m_castClass))
- {
- parentType.m_defaultAddMethod.invoke(parent.m_object, new Object[]
- {
- element.m_object
-
- });
- }
- else
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " element " + parent.m_qname + " cannot have an attribute " + qName + " of type " + elementType.m_castClass);
- }
- }
- else
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " element " + parent.m_qname + " cannot have an attribute " + qName + " of type " + elementType.m_castClass);
- }
- }
-
- }
-
- // invoke the process method
- try
- {
- invokeProcess(element);
- }
- catch (Throwable e)
- {
- m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e);
- throw new Exception(e);
- }
-
- trace("END/ (" + m_lineNumber + "," + m_columnNumber + "):" + uri + ":" + qName);
- }
-
- public void setTrace(boolean trace)
- {
- m_traceFlag = trace;
- }
-
- private void trace(String msg)
- {
- if (m_traceFlag)
- {
- m_logger.log(Logger.LOG_DEBUG, msg);
- }
- }
-
- /**
- * @see kxml.sax.KXmlSAXHandler#setLineNumber(int)
- */
- public void setLineNumber(int lineNumber)
- {
- m_lineNumber = lineNumber;
- }
-
- /**
- * @see kxml.sax.KXmlSAXHandler#setColumnNumber(int)
- */
- public void setColumnNumber(int columnNumber)
- {
- m_columnNumber = columnNumber;
- }
-
- /**
- * @see kxml.sax.KXmlSAXHandler#processingInstruction(java.lang.String,
- * java.lang.String)
- */
- public void processingInstruction(String target, String data)
- throws Exception
- {
- trace("PI:" + target + ";" + data);
- trace("ignore PI : " + data);
- /* // reuse the kXML parser methods to parser the PI data
- Reader reader = new StringReader(data);
- XmlParser parser = new XmlParser(reader);
- parser.parsePIData();
-
- target = parser.getTarget();
- Map attributes = parser.getAttributes();
-
- // get the class
- Class clazz = (Class) pis.get(target);
- if (clazz == null) {
- if (missingPIExceptionFlag)
- throw new Exception(lineNumber + "," + columnNumber + ":"
- + "Unknown processing instruction");
- else {
- trace(lineNumber + "," + columnNumber + ":"
- + "No class for PI " + target);
- return;
- }
- }
-
- // instanciate a object
- Object object;
- Constructor ctor = null;
- try {
- ctor = clazz.getConstructor(new Class[] { XmlCommonHandler.class });
- } catch (NoSuchMethodException e) {
- // do nothing
- trace("no constructor with XmlCommonHandler parameter");
- }
- try {
- if (ctor == null) {
- object = clazz.newInstance();
- } else {
- object = ctor.newInstance(new Object[] { this });
- }
- } catch (InstantiationException e) {
- throw new Exception(
- lineNumber
- + ","
- + columnNumber
- + ":"
- + "class "
- + clazz.getName()
- + " for PI "
- + target
- + " should have an empty constructor or a constructor with XmlCommonHandler parameter");
- } catch (IllegalAccessException e) {
- throw new Exception(lineNumber + "," + columnNumber + ":"
- + "illegal access on the constructor " + clazz.getName()
- + " for PI " + target);
- }
-
- // set the context
- setObjectContext(object);
-
- // TODO: set the parent
-
- // invoke setter
- Iterator iter = attributes.keySet().iterator();
- while (iter.hasNext()) {
- String key = (String) iter.next();
- String value = ReplaceUtility.replace((String) attributes.get(key),
- context);
- Method method = null;
- try {
- method = clazz.getDeclaredMethod(setterOf(key),
- new Class[] { String.class });
- } catch (NoSuchMethodException e) {
- // do nothing
- }
- if (method != null) {
- trace(method.getName());
- try {
- method.invoke(object, new String[] { value });
- } catch (InvocationTargetException e) {
- m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e.getTargetException());
- throw e;
- }
- }
-
- }
-
- // invoke process
- try {
- invokeProcess(object);
- } catch (Throwable e) {
- m_logger.log(Logger.LOG_ERROR, "Error parsing repository metadata", e);
- throw new Exception(e);
- }
- */ }
-
- public void processingInstructionForMapping(String target, String data)
- throws Exception
- {
- if (target == null)
- { // TODO kXML
- if (!data.startsWith(PI_MAPPING))
- {
- return;
- }
- }
- else if (!target.equals(PI_MAPPING))
- {
- return; // defaultclass attribute
- }
- String datt = "defaultclass=\"";
- int dstart = data.indexOf(datt);
- if (dstart != -1)
- {
- int dend = data.indexOf("\"", dstart + datt.length());
- if (dend == -1)
- {
- throw new Exception(
- m_lineNumber + "," + m_columnNumber + ":" + " \"defaultclass\" attribute in \"mapping\" PI is not quoted");
- }
- String classname = data.substring(dstart + datt.length(), dend);
- Class clazz = null;
- try
- {
- clazz = getClass().getClassLoader().loadClass(classname);
- }
- catch (ClassNotFoundException e)
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " cannot found class " + classname + " for \"mapping\" PI");
- }
-
- // TODO Add method
- Method defaultdefaultAddMethod = null;
- setDefaultType(clazz, null, defaultdefaultAddMethod);
- return;
- }
-
- // element attribute
- String eatt = "element=\"";
- int estart = data.indexOf(eatt);
- if (estart == -1)
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " missing \"element\" attribute in \"mapping\" PI");
- }
- int eend = data.indexOf("\"", estart + eatt.length());
- if (eend == -1)
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " \"element\" attribute in \"mapping\" PI is not quoted");
- }
- String element = data.substring(estart + eatt.length(), eend);
-
- // element class
- String catt = "class=\"";
- int cstart = data.indexOf(catt);
- if (cstart == -1)
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " missing \"class\" attribute in \"mapping\" PI");
- }
- int cend = data.indexOf("\"", cstart + catt.length());
- if (cend == -1)
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " \"class\" attribute in \"mapping\" PI is not quoted");
- }
- String classname = data.substring(cstart + catt.length(), cend);
-
- // element cast (optional)
- String castname = null;
- String castatt = "cast=\"";
- int caststart = data.indexOf(castatt);
- if (caststart != -1)
- {
- int castend = data.indexOf("\"", cstart + castatt.length());
- if (castend == -1)
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " \"cast\" attribute in \"mapping\" PI is not quoted");
- }
- castname = data.substring(caststart + castatt.length(), castend);
- }
-
- Class clazz = null;
- try
- {
- clazz = getClass().getClassLoader().loadClass(classname);
- }
- catch (ClassNotFoundException e)
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " cannot found class " + classname + " for \"mapping\" PI");
- }
-
- Class castClazz = null;
- if (castname != null)
- {
- try
- {
- clazz = getClass().getClassLoader().loadClass(castname);
- }
- catch (ClassNotFoundException e)
- {
- throw new Exception(m_lineNumber + "," + m_columnNumber + ":" + " cannot found cast class " + classname + " for \"mapping\" PI");
- } // TODO Add method
- }
- Method defaultAddMethod = null;
-
- addType(element, clazz, castClazz, defaultAddMethod);
- }
-}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/XmlMetadataHandler.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/XmlMetadataHandler.java
deleted file mode 100644
index 2c6e89f..0000000
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/XmlMetadataHandler.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.bundlerepository.impl.metadataparser;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.xml.parsers.*;
-
-import org.apache.felix.bundlerepository.impl.Logger;
-import org.xml.sax.*;
-
-/**
- * handles the metadata in XML format
- */
-public class XmlMetadataHandler extends MetadataHandler
-{
- public XmlMetadataHandler(Logger logger)
- {
- super(logger);
- }
-
- /**
- * Called to parse the InputStream and set bundle list and package hash map
- */
- public void parse(InputStream istream) throws ParserConfigurationException, IOException, SAXException
- {
- // Parse the Meta-Data
-
- ContentHandler contenthandler = (ContentHandler) m_handler;
-
- InputSource is = new InputSource(istream);
-
- SAXParserFactory spf = SAXParserFactory.newInstance();
- spf.setValidating(false);
-
- SAXParser saxParser = spf.newSAXParser();
-
- XMLReader xmlReader = null;
- xmlReader = saxParser.getXMLReader();
- xmlReader.setContentHandler(contenthandler);
- xmlReader.parse(is);
- }
-}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/kxmlsax/KXml2SAXHandler.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/kxmlsax/KXml2SAXHandler.java
deleted file mode 100644
index a2b2d62..0000000
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/kxmlsax/KXml2SAXHandler.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.bundlerepository.impl.metadataparser.kxmlsax;
-
-import java.util.Properties;
-
-/**
- * Interface for SAX handler with kXML
- */
-public interface KXml2SAXHandler
-{
- /**
- * Method called when parsing text
- *
- * @param ch
- * @param offset
- * @param length
- * @exception SAXException
- */
- public void characters(char[] ch, int offset, int length) throws Exception;
-
- /**
- * Method called when a tag opens
- *
- * @param uri
- * @param localName
- * @param qName
- * @param attrib
- * @exception SAXException
- **/
- public void startElement(
- String uri,
- String localName,
- String qName,
- Properties attrib)
- throws Exception;
-
- /**
- * Method called when a tag closes
- *
- * @param uri
- * @param localName
- * @param qName
- * @exception SAXException
- */
- public void endElement(
- java.lang.String uri,
- java.lang.String localName,
- java.lang.String qName)
- throws Exception;
-
- public void processingInstruction(String target,
- String data)
- throws Exception;
-
- public void setLineNumber(int lineNumber);
-
- public void setColumnNumber(int columnNumber);
-}
\ No newline at end of file
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/kxmlsax/KXml2SAXParser.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/kxmlsax/KXml2SAXParser.java
deleted file mode 100644
index 78db998..0000000
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/metadataparser/kxmlsax/KXml2SAXParser.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.bundlerepository.impl.metadataparser.kxmlsax;
-
-import java.io.Reader;
-import java.util.Properties;
-
-import org.kxml2.io.KXmlParser;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-/**
- * The KXml2SAXParser extends the XmlParser from kxml2 (which does not take into account the DTD).
- */
-public class KXml2SAXParser extends KXmlParser
-{
- public String m_uri = "uri";
-
- /**
- * The constructor for a parser, it receives a java.io.Reader.
- *
- * @param reader The reader
- * @throws XmlPullParserException
- */
- public KXml2SAXParser(Reader reader) throws XmlPullParserException
- {
- super();
- setInput(reader);
- }
-
- /**
- * parse from the reader provided in the constructor, and call
- * the startElement and endElement in the handler
- *
- * @param handler The handler
- * @exception Exception thrown by the superclass
- */
- public void parseXML(KXml2SAXHandler handler) throws Exception
- {
- while (next() != XmlPullParser.END_DOCUMENT)
- {
- handler.setLineNumber(getLineNumber());
- handler.setColumnNumber(getColumnNumber());
- if (getEventType() == XmlPullParser.START_TAG)
- {
- Properties props = new Properties();
- for (int i = 0; i < getAttributeCount(); i++)
- {
- props.put(getAttributeName(i), getAttributeValue(i));
- }
- handler.startElement(
- getNamespace(),
- getName(),
- getName(),
- props);
- }
- else if (getEventType() == XmlPullParser.END_TAG)
- {
- handler.endElement(getNamespace(), getName(), getName());
- }
- else if (getEventType() == XmlPullParser.TEXT)
- {
- String text = getText();
- handler.characters(text.toCharArray(), 0, text.length());
- }
- else if (getEventType() == XmlPullParser.PROCESSING_INSTRUCTION)
- {
- // TODO extract the target from the evt.getText()
- handler.processingInstruction(null, getText());
- }
- else
- {
- // do nothing
- }
- }
- }
-}
\ No newline at end of file
diff --git a/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/StaxParserTest.java b/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/StaxParserTest.java
index 9223871..3d6cf2b 100644
--- a/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/StaxParserTest.java
+++ b/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/StaxParserTest.java
@@ -18,6 +18,7 @@
*/
package org.apache.felix.bundlerepository.impl;
+import java.io.File;
import java.net.URL;
import java.util.Hashtable;
@@ -52,11 +53,27 @@
assertTrue(resolver.resolve());
}
+ public void testPullParser() throws Exception
+ {
+ URL url = getClass().getResource("/repo_for_resolvertest.xml");
+ RepositoryAdminImpl repoAdmin = createRepositoryAdmin(PullParser.class);
+ RepositoryImpl repo = (RepositoryImpl) repoAdmin.addRepository(url);
+
+ Resolver resolver = repoAdmin.resolver();
+
+ Resource[] discoverResources = repoAdmin.discoverResources("(symbolicname=org.apache.felix.test*)");
+ assertNotNull(discoverResources);
+ assertEquals(1, discoverResources.length);
+
+ resolver.add(discoverResources[0]);
+ assertTrue(resolver.resolve());
+ }
+
public void testPerfs() throws Exception
{
-// for (int i = 0; i < 10; i++) {
+ for (int i = 0; i < 10; i++) {
// testPerfs(new File(System.getProperty("user.home"), ".m2/repository/repository.xml").toURI().toURL(), 0, 100);
-// }
+ }
}
protected void testPerfs(URL url, int nbWarm, int nbTest) throws Exception
@@ -98,17 +115,17 @@
for (int i = 0; i < nbWarm; i++)
{
- RepositoryAdminImpl repoAdmin = createRepositoryAdmin(RepositoryImpl.KXml2Parser.class);
+ RepositoryAdminImpl repoAdmin = createRepositoryAdmin(PullParser.class);
RepositoryImpl repo = (RepositoryImpl) repoAdmin.addRepository(url);
}
t0 = System.currentTimeMillis();
for (int i = 0; i < nbTest; i++)
{
- RepositoryAdminImpl repoAdmin = createRepositoryAdmin(RepositoryImpl.KXml2Parser.class);
+ RepositoryAdminImpl repoAdmin = createRepositoryAdmin(PullParser.class);
RepositoryImpl repo = (RepositoryImpl) repoAdmin.addRepository(url);
}
t1 = System.currentTimeMillis();
- System.err.println("KXmlParser: " + (t1 - t0) + " ms");
+ System.err.println("PullParser: " + (t1 - t0) + " ms");
}
public static void main(String[] args) throws Exception