Updated the metadata XML parser.
git-svn-id: https://svn.apache.org/repos/asf/incubator/felix/trunk@396571 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.apache.felix.bundlerepository/pom.xml b/org.apache.felix.bundlerepository/pom.xml
index 18198be..9d62c0a 100644
--- a/org.apache.felix.bundlerepository/pom.xml
+++ b/org.apache.felix.bundlerepository/pom.xml
@@ -43,7 +43,7 @@
<bundleUrl>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}.jar</bundleUrl>
<bundleSource>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}-src.jar</bundleSource>
<bundleSymbolicName>${pom.artifactId}</bundleSymbolicName>
- <importPackage>org.osgi.framework</importPackage>
+ <importPackage>org.osgi.framework,org.xml.sax,javax.xml.parsers</importPackage>
<dynamicImportPackage>org.apache.felix.shell</dynamicImportPackage>
<exportPackage>org.osgi.service.obr</exportPackage>
<exportService>org.osgi.service.obr.RepositoryAdmin</exportService>
diff --git a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java
index 1647cd2..2f45aad 100644
--- a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java
+++ b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/CapabilityImpl.java
@@ -50,7 +50,7 @@
return m_map;
}
- public void addP(PropertyImpl prop)
+ protected void addP(PropertyImpl prop)
{
m_map.put(prop.getN(), prop.getV());
}
diff --git a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryImpl.java b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryImpl.java
index c82b81e..c4ca31d 100644
--- a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryImpl.java
+++ b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/RepositoryImpl.java
@@ -17,6 +17,7 @@
package org.apache.felix.bundlerepository;
import java.io.*;
+import java.lang.reflect.Method;
import java.net.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -59,7 +60,7 @@
}
// TODO: OBR - Wrong parameter type from metadata parser.
- public void addResource(ResourceImpl resource)
+ public void addResource(Resource resource)
{
// Set resource's repository.
((ResourceImpl) resource).setRepository(this);
@@ -143,13 +144,19 @@
return RepositoryImpl.this;
}
};
- handler.addType("repository", factory, Repository.class);
- handler.addType("resource", ResourceImpl.class, Resource.class);
- handler.addType("category", CategoryImpl.class, null);
- handler.addType("require", RequirementImpl.class, Requirement.class);
- handler.addType("capability", CapabilityImpl.class, Capability.class);
- handler.addType("p", PropertyImpl.class, null);
- handler.setDefaultType(String.class, null);
+
+ // Get default setter method for Resource.
+ Method resourceSetter = ResourceImpl.class.getDeclaredMethod(
+ "put", new Class[] { Object.class, Object.class });
+
+ // Map XML tags to types.
+ handler.addType("repository", factory, Repository.class, null);
+ handler.addType("resource", ResourceImpl.class, Resource.class, resourceSetter);
+ 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);
}
catch (Exception ex)
{
diff --git a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResourceImpl.java b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResourceImpl.java
index 26ec16c..55fa422 100644
--- a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResourceImpl.java
+++ b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/ResourceImpl.java
@@ -23,7 +23,7 @@
import org.osgi.framework.Version;
import org.osgi.service.obr.*;
-public class ResourceImpl implements Resource, Map
+public class ResourceImpl implements Resource
{
private final String URI = "uri";
@@ -55,7 +55,7 @@
if (resource != null)
{
- resource.putAll(resource.getProperties());
+ m_map.putAll(resource.getProperties());
m_catList.addAll(resource.m_catList);
m_capList.addAll(resource.m_capList);
m_reqList.addAll(resource.m_reqList);
@@ -120,7 +120,7 @@
return (Requirement[]) m_reqList.toArray(new Requirement[m_reqList.size()]);
}
- public void addRequire(Requirement req)
+ protected void addRequire(Requirement req)
{
m_reqList.add(req);
}
@@ -130,8 +130,7 @@
return (Capability[]) m_capList.toArray(new Capability[m_capList.size()]);
}
- // TODO: OBR - Should this be a property?
- public void addCapability(Capability cap)
+ protected void addCapability(Capability cap)
{
m_capList.add(cap);
}
@@ -141,7 +140,7 @@
return (String[]) m_catList.toArray(new String[m_catList.size()]);
}
- public void addCategory(CategoryImpl cat)
+ protected void addCategory(CategoryImpl cat)
{
m_catList.add(cat.getId());
}
@@ -156,66 +155,10 @@
m_repo = repo;
}
- //
- // Map interface methods.
- //
-
- public int size()
- {
- return m_map.size();
- }
-
- public void clear()
- {
- m_map.clear();
- }
-
- public boolean isEmpty()
- {
- return m_map.isEmpty();
- }
-
- public boolean containsKey(Object key)
- {
- return m_map.containsKey(key);
- }
-
- public boolean containsValue(Object value)
- {
- return m_map.containsValue(value);
- }
-
- public Collection values()
- {
- return m_map.values();
- }
-
- public void putAll(Map t)
- {
- m_map.putAll(t);
- }
-
- public Set entrySet()
- {
- return m_map.entrySet();
- }
-
- public Set keySet()
- {
- return m_map.keySet();
- }
-
- public Object get(Object key)
- {
- return m_map.get(key);
- }
-
- public Object remove(Object key)
- {
- return m_map.remove(key);
- }
-
- public Object put(Object key, Object value)
+ /**
+ * Default setter method when setting parsed data from the XML file.
+ **/
+ protected Object put(Object key, Object value)
{
// Capture the URIs since they might be relative, so we
// need to defer setting the actual URL value until they
@@ -247,22 +190,6 @@
{
value = Long.valueOf(value.toString());
}
- // TODO: OBR - These should be handled by the "add" methods above.
- else if (key.equals("require"))
- {
- m_reqList.add(value);
- return null;
- }
- else if (key.equals("capability"))
- {
- m_capList.add(value);
- return null;
- }
- else if (key.equals("category"))
- {
- m_catList.add(value);
- return null;
- }
return m_map.put(key, value);
}
diff --git a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/KXml2MetadataHandler.java b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/KXml2MetadataHandler.java
index ac2103a..16b909d 100644
--- a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/KXml2MetadataHandler.java
+++ b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/KXml2MetadataHandler.java
@@ -23,8 +23,6 @@
/**
* handles the metadata in XML format
* (use kXML (http://kxml.enhydra.org/) a open-source very light weight XML parser
- * @version 1.00 11 Nov 2003
- * @author Didier Donsez
*/
public class KXml2MetadataHandler extends MetadataHandler {
diff --git a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MappingProcessingInstructionHandler.java b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MappingProcessingInstructionHandler.java
index 51a019c..7f0963e 100644
--- a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MappingProcessingInstructionHandler.java
+++ b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MappingProcessingInstructionHandler.java
@@ -19,8 +19,6 @@
/**
* this class adds type of elements to the parser
- *
- * @author Didier Donsez (didier.donsez@imag.fr)
*/
public class MappingProcessingInstructionHandler {
@@ -39,7 +37,7 @@
if(classname==null) {
throw new Exception("class is missing");
}
- handler.addType(name,this.getClass().getClassLoader().loadClass(classname),null);
+ handler.addType(name,this.getClass().getClassLoader().loadClass(classname),null,null);
}
public void setElement(String element) {
diff --git a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MetadataHandler.java b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MetadataHandler.java
index 3fc299a..53fccb1 100644
--- a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MetadataHandler.java
+++ b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/MetadataHandler.java
@@ -17,16 +17,16 @@
package org.apache.felix.bundlerepository.metadataparser;
import java.io.InputStream;
+import java.lang.reflect.Method;
-
-/**
- * @version 1.00 9 Jul 2004
- * @author Didier Donsez
- */
public abstract class MetadataHandler {
protected XmlCommonHandler handler;
+ /**
+ * constructor
+ *
+ */
public MetadataHandler() {
handler = new XmlCommonHandler();
}
@@ -37,29 +37,80 @@
public abstract void parse(InputStream is) throws Exception;
/**
- * return the metadata
- * @return a Objet
+ * 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 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 {
- handler.addType(qname, instanceFactory, null);
+ 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 {
- handler.addType(qname, instanceFactory, castClass);
+ 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 {
+ 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 {
- handler.setDefaultType(instanceFactory,null);
+ 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 {
- handler.setDefaultType(instanceFactory, castClass);
+ 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 {
+ 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) {
handler.addPI(piname, clazz);
}
diff --git a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlCommonHandler.java b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlCommonHandler.java
index 0dc6dc1..639eac3 100644
--- a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlCommonHandler.java
+++ b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlCommonHandler.java
@@ -26,8 +26,6 @@
/**
* SAX handler for the XML file
- *
- * @author Didier Donsez (didier.donsez@imag.fr)
*/
public class XmlCommonHandler implements KXml2SAXHandler {
@@ -35,7 +33,7 @@
public static final String METADATAPARSER_PIS = "METADATAPARSER_PIS";
- public static final String METADATAPARSER_INSTANCEFACTORY = "METADATAPARSER_INSTANCEFACTORY";
+ public static final String METADATAPARSER_TYPES = "METADATAPARSER_TYPES";
private int columnNumber;
@@ -49,43 +47,116 @@
// Data
//
- private Object root;
+ private XmlStackElement root;
- private Stack objectStack;
-
- private Stack qnameStack;
-
+ private Stack elementStack;
+
private Map pis;
private boolean missingPIExceptionFlag;
- private Map instanceFactories;
+ private Map types;
- private Map instanceClasses;
-
- private Map castClasses;
-
- private Map context;
-
- private Object defaultInstanceFactory;
-
- private Class defaultInstanceClass;
-
- private Class defaultCastClass;
+ private TypeEntry defaultType;
private StringBuffer currentText;
+ private Map context;
+
+ private class XmlStackElement {
+
+ public final String qname;
+ public Object object;
+
+ public XmlStackElement(String qname, Object object) {
+ super();
+ this.qname = qname;
+ this.object = object;
+ };
+ }
+
+ public class TypeEntry {
+ public final Object instanceFactory;
+ public final Class instanceClass;
+ public final Method newInstanceMethod;
+ public final Class castClass;
+ public final Method defaultAddMethod;
+
+ public TypeEntry(Object instanceFactory, Class castClass, Method defaultAddMethod) throws Exception {
+ super();
+ this.instanceFactory = instanceFactory;
+
+ try {
+ if (instanceFactory instanceof Class) {
+ newInstanceMethod = instanceFactory.getClass()
+ .getDeclaredMethod("newInstance", null);
+ if (castClass == null) {
+ this.castClass = (Class) instanceFactory;
+ } else {
+ if (!castClass.isAssignableFrom((Class) instanceFactory)) {
+ throw new Exception(
+ "instanceFactory "
+ + instanceFactory.getClass().getName()
+ + " could not instanciate objects assignable to "
+ + castClass.getName());
+ }
+ this.castClass=castClass;
+ }
+ instanceClass = (Class) instanceFactory;
+ } else {
+ newInstanceMethod = instanceFactory.getClass()
+ .getDeclaredMethod("newInstance", null);
+ Class returnType = newInstanceMethod.getReturnType();
+ if (castClass == null) {
+ this.castClass = returnType;
+ } else if (!castClass.isAssignableFrom(returnType)) {
+ throw new Exception(
+ "instanceFactory "
+ + instanceFactory.getClass().getName()
+ + " could not instanciate objects assignable to "
+ + castClass.getName());
+ } else
+ this.castClass=castClass;
+ instanceClass = returnType;
+ }
+ } catch (NoSuchMethodException e) {
+ throw new Exception(
+ "instanceFactory " + instanceFactory.getClass().getName()
+ + " should have a newInstance method");
+ }
+
+ // TODO check method
+ this.defaultAddMethod = defaultAddMethod;
+ if (this.defaultAddMethod != null)
+ {
+ this.defaultAddMethod.setAccessible(true);
+ }
+ }
+
+ public String toString(){
+ StringBuffer sb=new StringBuffer();
+ sb.append("[");
+ if(instanceFactory instanceof Class)
+ sb.append("instanceFactory=").append(((Class)instanceFactory).getName());
+ else
+ sb.append("instanceFactory=").append(instanceFactory.getClass().getName());
+ sb.append(",instanceClass=").append(instanceClass.getName());
+ sb.append(",castClass=").append(castClass.getName());
+ sb.append(",defaultAddMethod=");
+ if(defaultAddMethod==null) sb.append(""); else sb.append(defaultAddMethod.getName());
+ sb.append("]");
+ return sb.toString();
+ }
+ }
+
public XmlCommonHandler() {
- objectStack = new Stack();
- qnameStack = new Stack();
+ elementStack = new Stack();
pis = new HashMap();
missingPIExceptionFlag = false;
- instanceFactories = new HashMap();
- instanceClasses = new HashMap();
- castClasses = new HashMap();
+ types = new HashMap();
context = new HashMap();
context.put(METADATAPARSER_PIS, pis);
- context.put(METADATAPARSER_INSTANCEFACTORY, instanceFactories);
+ context.put(METADATAPARSER_TYPES, types);
}
public void addPI(String piname, Class clazz) {
@@ -102,79 +173,41 @@
public void setMissingPIExceptionFlag(boolean flag) {
missingPIExceptionFlag = flag;
}
+
+ public void addType(String qname, Object instanceFactory, Class castClass, Method defaultAddMethod)
+ throws Exception {
- private Class checkAndGetInstanceClass(String qname,
- Object instanceFactory, Class castClass) throws Exception {
- String typeMsg = (qname == null) ? " for default type "
- : (" for type " + qname);
+ TypeEntry typeEntry;
try {
- if (instanceFactory instanceof Class) {
- if (castClass == null) {
- castClass = (Class) instanceFactory;
- } else {
- if (!castClass.isAssignableFrom((Class) instanceFactory)) {
- throw new Exception(
- lineNumber
- + ","
- + columnNumber
- + ":"
- + "instanceFactory "
- + instanceFactory.getClass().getName()
- + typeMsg
- + " could not instanciate objects assignable to "
- + castClass.getName());
- }
- }
- return (Class) instanceFactory;
- } else {
- Method newInstanceMethod = instanceFactory.getClass()
- .getDeclaredMethod("newInstance", null);
- Class returnType = newInstanceMethod.getReturnType();
- if (castClass == null) {
- castClass = returnType;
- } else if (!castClass.isAssignableFrom(returnType)) {
- throw new Exception(lineNumber + "," + columnNumber + ":"
- + "instanceFactory "
- + instanceFactory.getClass().getName() + typeMsg
- + " could not instanciate objects assignable to "
- + castClass.getName());
- }
- return returnType;
- }
- } catch (NoSuchMethodException e) {
- throw new Exception(lineNumber + "," + columnNumber + ":"
- + "instanceFactory " + instanceFactory.getClass().getName()
- + " for type " + qname
- + " should have a newInstance method");
+ typeEntry = new TypeEntry(
+ instanceFactory,
+ castClass,
+ defaultAddMethod
+ );
+ } catch (Exception e) {
+ throw new Exception(lineNumber + "," + columnNumber + ":" + qname + " : " + e.getMessage());
}
- }
-
- public void addType(String qname, Object instanceFactory, Class castClass)
- throws Exception {
- Class instanceClass = checkAndGetInstanceClass(qname, instanceFactory,
- castClass);
- instanceClasses.put(qname, instanceClass);
- instanceFactories.put(qname, instanceFactory);
- castClasses.put(qname, castClass != null ? castClass : instanceClass);
+ types.put(qname,typeEntry);
trace("element "
+ qname
- + " : instanceFactory="
- + (instanceFactory instanceof Class ? ((Class) instanceFactory)
- .getName() : instanceFactory.getClass().getName())
- + " castClass="
- + (castClass != null ? castClass : instanceClass).getName());
+ + " : " + typeEntry.toString());
}
-
- public void setDefaultType(Object instanceFactory, Class castClass)
+
+ public void setDefaultType(Object instanceFactory, Class castClass, Method defaultAddMethod)
throws Exception {
- defaultInstanceClass = checkAndGetInstanceClass(null, instanceFactory,
- castClass);
- defaultInstanceFactory = instanceFactory;
- defaultCastClass = castClass != null ? castClass : defaultInstanceClass;
- trace("defaut type : instanceFactory="
- + (instanceFactory instanceof Class ? ((Class) instanceFactory)
- .getName() : instanceFactory.getClass().getName())
- + " castClass=" + defaultCastClass.getName());
+ TypeEntry typeEntry;
+ try {
+ typeEntry = new TypeEntry(
+ instanceFactory,
+ castClass,
+ defaultAddMethod
+ );
+ } catch (Exception e) {
+ throw new Exception(lineNumber + "," + columnNumber + ": default element : " + e.getMessage());
+ }
+ defaultType=typeEntry;
+ trace("default element "
+ + " : " + typeEntry.toString());
}
public void setContext(Map context) {
@@ -186,7 +219,7 @@
}
public Object getRoot() {
- return root;
+ return root.object;
}
/* for PCDATA */
@@ -224,7 +257,7 @@
Method method = null;
try {
// TODO setContext from castClass or object.getClass() ?
- method = object.getClass().getMethod("setContext",
+ method = object.getClass().getDeclaredMethod("setContext",
new Class[] { Map.class });
} catch (NoSuchMethodException e) {
// do nothing
@@ -249,7 +282,7 @@
Method method = null;
try {
// TODO process from castClass or object.getClass() ?
- method = object.getClass().getMethod("process", null);
+ method = object.getClass().getDeclaredMethod("process", null);
} catch (NoSuchMethodException e) {
// do nothing
}
@@ -274,7 +307,7 @@
Method method = null;
try {
// TODO setParent from castClass or object.getClass() ?
- method = object.getClass().getMethod("setParent",
+ method = object.getClass().getDeclaredMethod("setParent",
new Class[] { parent.getClass() });
} catch (NoSuchMethodException e) {
// do nothing
@@ -306,53 +339,26 @@
+ qName);
// TODO: should add uri in the qname in the future
- Object instanceFactory = instanceFactories.get(qName); // instanceFactory
- // can be a
- // java.lang.Class
- // or a object
- // with a
- // newInstance()
- // method
- Class castClass = null;
- Class instanceClass = null;
-
- if (instanceFactory == null) {
- if (defaultInstanceFactory != null) {
- instanceFactory = defaultInstanceFactory;
- castClass = defaultCastClass;
- instanceClass = defaultInstanceClass;
- }
- } else {
- castClass = (Class) castClasses.get(qName);
- instanceClass = (Class) instanceClasses.get(qName);
+ TypeEntry type=(TypeEntry) types.get(qName);
+ if(type==null) {
+ type=defaultType;
}
Object obj = null;
- if (instanceFactory != null) {
- Method newInstanceMethod = null;
- try {
- newInstanceMethod = instanceFactory.getClass().getMethod(
- "newInstance", null);
- } catch (NoSuchMethodException e) {
- // never catch since checked by addType and setDefaultType
- throw new Exception(lineNumber + "," + columnNumber + ":"
- + "instanceFactory "
- + instanceFactory.getClass().getName()
- + " for element " + qName
- + " should have a newInstance method");
- }
+ if (type != null) {
try {
- newInstanceMethod.setAccessible(true);
- obj = newInstanceMethod.invoke(instanceFactory, null);
+ // enables to access to "unmuttable" method
+ type.newInstanceMethod.setAccessible(true);
+ obj = type.newInstanceMethod.invoke(type.instanceFactory, null);
} catch (Exception e) {
// do nothing
}
// set parent
- if (!objectStack.isEmpty()) {
- Object parent = objectStack.peek();
- setObjectParent(obj, parent);
+ if (!elementStack.isEmpty()) {
+ XmlStackElement parent = (XmlStackElement) elementStack.peek();
+ setObjectParent(obj, parent.object);
}
// set the parser context
@@ -374,16 +380,16 @@
Method method = null;
if (!(obj instanceof String)) {
try {
- // method = castClass.getMethod(setterOf(key),new
+ // method = castClass.getDeclaredMethod(setterOf(key),new
// Class[] { String.class });
- method = instanceClass.getMethod(setterOf(key),
+ method = type.instanceClass.getDeclaredMethod(setterOf(key),
new Class[] { String.class });
} catch (NoSuchMethodException e) {
// do nothing
}
if (method == null)
try {
- method = instanceClass.getMethod(adderOf(key),
+ method = type.instanceClass.getDeclaredMethod(adderOf(key),
new Class[] { String.class });
} catch (NoSuchMethodException e) {
@@ -395,6 +401,7 @@
}
}
+
if (method != null) {
trace(method.getName());
try {
@@ -404,19 +411,9 @@
throw e;
}
} else {
- // Secondly, test if object if a map, a dictionary, a
- // collection, or a string
-
- if (obj instanceof Map) {
- ((Map) obj).put(key, value);
- } else if (obj instanceof Dictionary) {
- ((Dictionary) obj).put(key, value);
- } else if (obj instanceof Collection) {
- throw new Exception(lineNumber + "," + columnNumber
- + ":" + "List element " + qName
- + " cannot have any attribute");
- } else if (obj instanceof String) {
- if (key.equals("value")) {
+
+ if (obj instanceof String) {
+ if (key.equals(VALUE)) {
obj = value;
} else {
throw new Exception(lineNumber + "," + columnNumber
@@ -424,12 +421,32 @@
+ " cannot have other attribute than value");
}
} else {
- throw new Exception(lineNumber + "," + columnNumber
+ if (type.defaultAddMethod != null) {
+ Class[] parameterTypes=type.defaultAddMethod.getParameterTypes();
+ if(parameterTypes.length==2
+ && parameterTypes[0].isAssignableFrom(String.class)
+ && parameterTypes[1].isAssignableFrom(String.class)
+ ){
+ type.defaultAddMethod.invoke(obj,new String[]{key, value});
+ } else if(parameterTypes.length==1
+ && parameterTypes[0].isAssignableFrom(String.class)
+ ){
+ type.defaultAddMethod.invoke(obj,new String[]{value});
+ } else
+ throw new Exception(lineNumber + "," + columnNumber
+ + ":" + "class "
+ + type.instanceFactory.getClass().getName()
+ + " for element " + qName
+ + " does not support the attribute " + key
+ );
+ } else {
+ throw new Exception(lineNumber + "," + columnNumber
+ ":" + "class "
- + instanceFactory.getClass().getName()
+ + type.instanceFactory.getClass().getName()
+ " for element " + qName
+ " does not support the attribute " + key
- + "or List.add or Map.put");
+ );
+ }
}
}
@@ -440,11 +457,10 @@
throw new Exception(lineNumber + "," + columnNumber + ":"
+ "this element " + qName + " has not corresponding class");
}
-
+ XmlStackElement element=new XmlStackElement(qName,obj);
if (root == null)
- root = obj;
- objectStack.push(obj);
- qnameStack.push(qName);
+ root = element;
+ elementStack.push(element);
currentText = new StringBuffer();
trace("START/ (" + lineNumber + "," + columnNumber + "):" + uri + ":"
@@ -465,9 +481,12 @@
trace("END (" + lineNumber + "," + columnNumber + "):" + uri + ":"
+ qName);
- Object obj = objectStack.pop();
- Class objClass = obj.getClass();
-
+ XmlStackElement element = (XmlStackElement) elementStack.pop();
+ TypeEntry elementType=(TypeEntry) types.get(element.qname);
+ if(elementType==null) {
+ elementType=defaultType;
+ }
+
if (currentText != null && currentText.length() != 0) {
String currentStr = ReplaceUtility.replace(currentText.toString(),
@@ -477,11 +496,11 @@
Method method = null;
try {
- method = objClass.getMethod("addText",
+ method = elementType.castClass.getDeclaredMethod("addText",
new Class[] { String.class });
} catch (NoSuchMethodException e) {
try {
- method = objClass.getMethod("setText",
+ method = elementType.castClass.getDeclaredMethod("setText",
new Class[] { String.class });
} catch (NoSuchMethodException e2) {
// do nothing
@@ -490,21 +509,14 @@
if (method != null) {
trace(method.getName());
try {
- method.invoke(obj, new String[] { currentStr });
+ method.invoke(element.object, new String[] { currentStr });
} catch (InvocationTargetException e) {
e.getTargetException().printStackTrace(System.err);
throw e;
}
} else {
- if (Map.class.isAssignableFrom(objClass)) {
- ((Map) obj).put(qName, currentStr);
- } else if (Dictionary.class.isAssignableFrom(objClass)) {
- ((Dictionary) obj).put(qName, currentStr);
- } else if (Collection.class.isAssignableFrom(objClass)) {
- throw new Exception(lineNumber + "," + columnNumber + ":"
- + "List element " + qName + " cannot have PCDATAs");
- } else if (String.class.isAssignableFrom(objClass)) {
- String str = (String) obj;
+ if (String.class.isAssignableFrom(elementType.castClass)) {
+ String str = (String) element.object;
if (str.length() != 0) {
throw new Exception(
lineNumber
@@ -515,7 +527,7 @@
+ qName
+ " cannot have both PCDATA and an attribute value");
} else {
- obj = currentStr;
+ element.object = currentStr;
}
}
}
@@ -524,69 +536,87 @@
currentText = null;
- if (!objectStack.isEmpty()) {
+ if (!elementStack.isEmpty()) {
- Object parent = objectStack.peek();
- String parentName = (String) qnameStack.peek();
- // TODO Class parentClass = (castClasses(parentName)).getClass() ????
- Class parentClass = parent.getClass();
+ XmlStackElement parent = (XmlStackElement) elementStack.peek();
+ TypeEntry parentType = (TypeEntry) types.get(parent.qname);
+ if(parentType==null) {
+ parentType=defaultType;
+ }
+ String capqName=ClassUtility.capitalize(qName);
Method method = null;
try {
- method = parentClass.getMethod(adderOf(ClassUtility
- .capitalize(qName)), new Class[] { objClass }); // instanceClass
+// TODO: OBR PARSER: We should also check for instance class as a parameter.
+ method = parentType.instanceClass.getDeclaredMethod(
+ adderOf(capqName),
+ new Class[] { elementType.castClass }); // instanceClass
} catch (NoSuchMethodException e) {
trace("NoSuchMethodException: "
- + adderOf(ClassUtility.capitalize(qName)));
+ + adderOf(capqName) + "("+elementType.castClass.getName()+")");
// do nothing
}
if (method == null)
- try {
- method = parent.getClass().getMethod(
- setterOf(ClassUtility.capitalize(qName)),
- new Class[] { objClass });
+ try {
+ method = parentType.instanceClass.getDeclaredMethod(
+ setterOf(capqName),
+ new Class[] { elementType.castClass });
} catch (NoSuchMethodException e) {
trace("NoSuchMethodException: "
- + setterOf(ClassUtility.capitalize(qName)));
+ + setterOf(capqName) + "("+elementType.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 = parent.getClass().getMethod(adderOf(objClass),
- new Class[] { objClass });
+ method = parentType.castClass.getDeclaredMethod(
+ setterOf(type.castClass),
+ new Class[] { type.castClass });
} catch (NoSuchMethodException e) {
- trace("NoSuchMethodException: " + adderOf(objClass));
+ trace("NoSuchMethodException: " + setterOf(type.castClass)+ "("+type.castClass.getName()+")");
// do nothing
}
- if (method == null)
- try {
- method = parent.getClass().getMethod(setterOf(objClass),
- new Class[] { objClass });
- } catch (NoSuchMethodException e) {
- trace("NoSuchMethodException: " + setterOf(objClass));
- // do nothing
- }
-
+ */
if (method != null) {
trace(method.getName());
try {
- method.invoke(parent, new Object[] { obj });
+ method.setAccessible(true);
+ method.invoke(parent.object, new Object[] { element.object });
} catch (InvocationTargetException e) {
e.getTargetException().printStackTrace(System.err);
throw e;
}
} else {
- if (Map.class.isAssignableFrom(parentClass)) {
- ((Map) parent).put(qName, obj);
- } else if (Dictionary.class.isAssignableFrom(parentClass)) {
- ((Dictionary) parent).put(qName, obj);
- } else if (Collection.class.isAssignableFrom(parentClass)) {
- ((Collection) parent).add(obj);
+ if (parentType.defaultAddMethod != null) {
+ Class[] parameterTypes=parentType.defaultAddMethod.getParameterTypes();
+ if(parameterTypes.length==2
+ && parameterTypes[0].isAssignableFrom(String.class)
+ && parameterTypes[1].isAssignableFrom(elementType.castClass)
+ ){
+ parentType.defaultAddMethod.invoke(parent.object,new Object[]{qName, element.object});
+ } else if(parameterTypes.length==1
+ && parameterTypes[0].isAssignableFrom(elementType.castClass)
+ ){
+ parentType.defaultAddMethod.invoke(parent.object,new Object[]{element.object});
+ } else {
+ throw new Exception(lineNumber + "," + columnNumber + ":"
+ + " element " + parent.qname
+ + " cannot have an attribute " + qName
+ + " of type " + elementType.castClass);
+ }
} else {
throw new Exception(lineNumber + "," + columnNumber + ":"
- + " element " + parentName
+ + " element " + parent.qname
+ " cannot have an attribute " + qName
- + " of type " + objClass);
+ + " of type " + elementType.castClass);
}
}
@@ -594,7 +624,7 @@
// invoke the process method
try {
- invokeProcess(obj);
+ invokeProcess(element);
} catch (Throwable e) {
e.printStackTrace();
throw new Exception(e);
@@ -704,7 +734,7 @@
context);
Method method = null;
try {
- method = clazz.getMethod(setterOf(key),
+ method = clazz.getDeclaredMethod(setterOf(key),
new Class[] { String.class });
} catch (NoSuchMethodException e) {
// do nothing
@@ -762,7 +792,10 @@
+ " cannot found class " + classname
+ " for \"mapping\" PI");
}
- setDefaultType(clazz, null);
+
+ // TODO Add method
+ Method defaultdefaultAddMethod=null;
+ setDefaultType(clazz, null,defaultdefaultAddMethod);
return;
}
@@ -824,6 +857,9 @@
+ " for \"mapping\" PI");
}
- addType(element, clazz, castClazz);
+ // TODO Add method
+ Method defaultAddMethod=null;
+
+ addType(element, clazz, castClazz, defaultAddMethod);
}
}
\ No newline at end of file
diff --git a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlMetadataHandler.java b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlMetadataHandler.java
index aef14de..bab5b94 100644
--- a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlMetadataHandler.java
+++ b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/XmlMetadataHandler.java
@@ -25,9 +25,6 @@
/**
* handles the metadata in XML format
- *
- * @version 1.00 18 May 2003
- * @author Didier Donsez
*/
public class XmlMetadataHandler extends MetadataHandler {
diff --git a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXHandler.java b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXHandler.java
index 0014c51..2ba350c 100644
--- a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXHandler.java
+++ b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXHandler.java
@@ -20,8 +20,6 @@
/**
* Interface for SAX handler with kXML
- *
- * @author Didier Donsez (didier.donsez@imag.fr)
*/
public interface KXml2SAXHandler {
diff --git a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXParser.java b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXParser.java
index 3bc3b83..907a65e 100644
--- a/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXParser.java
+++ b/org.apache.felix.bundlerepository/src/main/java/org/apache/felix/bundlerepository/metadataparser/kxmlsax/KXml2SAXParser.java
@@ -24,19 +24,12 @@
import org.xmlpull.v1.XmlPullParserException;
/**
- * The KXml2SAXParser extends the XmlParser from kxml. This is a very
- * simple parser that does not take into account the DTD
- *
- * @version 1.0 08 Nov 2002
- * @version 1.1 24 Apr 2004
- * @author Humberto Cervantes, Didier Donsez
+ * The KXml2SAXParser extends the XmlParser from kxml2 (which does not take into account the DTD).
*/
public class KXml2SAXParser extends KXmlParser {
public String uri="uri";
- private Reader reader;
-
/**
* The constructor for a parser, it receives a java.io.Reader.
*
@@ -45,15 +38,14 @@
*/
public KXml2SAXParser(Reader reader) throws XmlPullParserException {
super();
- this.reader=reader;
setInput(reader);
}
/**
- * Parser from the reader provided in the constructor, and call
- * the startElement and endElement in a KxmlHandler
+ * parse from the reader provided in the constructor, and call
+ * the startElement and endElement in the handler
*
- * @param reader The reader
+ * @param handler The handler
* @exception Exception thrown by the superclass
*/
public void parseXML(KXml2SAXHandler handler) throws Exception {