|
Hi Johen, I modified the following three classes and JaxME now supports JAXB objects in children classloaders while JaxME sits in a parent classloader. Luckily, I did not have to write a custom classloader at all :). Can you look this over and give me your thoughts? Basically, the way I use JaxME now is like so //first few lines are JAXB compliant JAXBContext ctx = JAXBContext.newInstance("biz.xsoftware.impl.router.jaxme", getClass().getClassLoader()); unmarshal = ctx.createUnmarshaller(); Classloader cl = newBean.getClassLoader(); //get the new beans classloader //now we get into non-compliant stuff but there is not too much non-compliance.... jaxmeCtx = (JAXBContextImpl)ctx; jaxmeCtx.registerPackages("biz.xsoftware.impl.new.dynamicly.deployedbeans", cl); I can now dynamically now deploy new jars with JaxME objects into a VM. I bet you are probably the only JAXB implementation that can do so too. Castor can, but it is not JAXB compliant.....and of course, using this feature leaves you non-compliant, but heh, I think it is a cool feature :). Let me know what you think. thanks, dean |
/* * Copyright 2003, 2004 The Apache Software Foundation * * Licensed 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.ws.jaxme.impl; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; import javax.xml.bind.DatatypeConverter; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.MarshalException; import javax.xml.bind.Marshaller; import javax.xml.bind.UnmarshalException; import javax.xml.bind.Unmarshaller; import javax.xml.bind.ValidationException; import javax.xml.bind.Validator; import javax.xml.namespace.QName; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.apache.ws.jaxme.JMManager; import org.apache.ws.jaxme.JMMarshaller; import org.apache.ws.jaxme.JMUnmarshaller; import org.apache.ws.jaxme.JMValidator; import org.apache.ws.jaxme.PM; import org.apache.ws.jaxme.PMException; import org.apache.ws.jaxme.util.Configurator; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; /** <p>JaxMe's implementation of a JAXBContext.</p> * * @author <a href="mailto:[EMAIL PROTECTED]">Jochen Wiedmann</a> * @version $Id: JAXBContextImpl.java,v 1.9 2005/03/10 10:14:03 jochen Exp $ */ public class JAXBContextImpl extends JAXBContext { /** The namespace of JaxMe's configuration files. */ public static final String CONFIGURATION_URI = "http://ws.apache.org/jaxme/namespaces/jaxme2/configuration"; private static final SAXParserFactory spf; private static final DatatypeConverterImpl datatypeConverter = new DatatypeConverterImpl(); private ClassLoader cl; private String packageNames; private Map managersByQName = new HashMap(); private Map managersByInterface = new HashMap(); private Class jmMarshallerClass; private Class jmUnmarshallerClass; private Class jmValidatorClass; static { spf = SAXParserFactory.newInstance(); spf.setValidating(false); spf.setNamespaceAware(true); DatatypeConverter.setDatatypeConverter(datatypeConverter); } protected JAXBContextImpl() {} /** <p>Sets the ClassLoader to use.</p> */ protected void setClassLoader(ClassLoader pClassLoader) { cl = pClassLoader; } /** <p>Returns the ClassLoader to use.</p> */ public ClassLoader getClassLoader() { return cl; } /** <p>Sets the package names managed by this context.</p> */ protected void setPackageNames(String pPackageNames) { packageNames = pPackageNames; } /** <p>Returns the package names managed by this context.</p> */ public String getPackageNames() { return packageNames; } /** <p>Sets the JMMarshaller class to use.</p> */ protected void setJMMarshallerClass(Class pClass) { jmMarshallerClass = pClass; } /** <p>Returns the JMMarshaller class to use.</p> */ public Class getJMMarshallerClass() { return jmMarshallerClass; } /** <p>Sets the JMUnmarshaller class to use.</p> */ protected void setJMUnmarshallerClass(Class pClass) { jmUnmarshallerClass = pClass; } /** <p>Sets the JMUnmarshaller class to use.</p> */ public Class getJMUnmarshallerClass() { return jmUnmarshallerClass; } /** <p>Sets the JMValidator class to use.</p> */ protected void setJMValidatorClass(Class pClass) { jmValidatorClass = pClass; } /** <p>Returns the JMValidator class to use.</p> */ public Class getJMValidatorClass() { return jmValidatorClass; } public Marshaller createMarshaller() throws JAXBException { Class c = getJMMarshallerClass(); try { JMMarshaller marshaller = (JMMarshaller) c.newInstance(); marshaller.setJAXBContextImpl(this); return marshaller; } catch (InstantiationException e) { throw new JAXBException("Failed to instantiate class " + c.getName(), e); } catch (IllegalAccessException e) { throw new JAXBException("Illegal access to class " + c.getName(), e); } catch (ClassCastException e) { throw new JAXBException("Class " + c.getName() + " is not implementing " + JMMarshaller.class.getName()); } } public Unmarshaller createUnmarshaller() throws JAXBException { Class c = getJMUnmarshallerClass(); try { JMUnmarshaller unmarshaller = (JMUnmarshaller) c.newInstance(); unmarshaller.setJAXBContextImpl(this); return unmarshaller; } catch (InstantiationException e) { throw new JAXBException("Failed to instantiate class " + c.getName(), e); } catch (IllegalAccessException e) { throw new JAXBException("Illegal access to class " + c.getName(), e); } catch (ClassCastException e) { throw new JAXBException("Class " + c.getName() + " is not implementing " + JMUnmarshaller.class.getName()); } } public Validator createValidator() throws JAXBException { Class c = getJMValidatorClass(); try { JMValidator validator = (JMValidator) c.newInstance(); validator.setJAXBContextImpl(this); return validator; } catch (InstantiationException e) { throw new JAXBException("Failed to instantiate class " + c.getName(), e); } catch (IllegalAccessException e) { throw new JAXBException("Illegal access to class " + c.getName(), e); } catch (ClassCastException e) { throw new JAXBException("Class " + c.getName() + " is not implementing " + JMValidator.class.getName()); } } protected JMManager getManagerByQName(QName pQName) { return (JMManager) managersByQName.get(pQName); } protected JMManager getManagerByInterface(Class pElementInterface) { return (JMManager) managersByInterface.get(pElementInterface); } /** Returns a Manager for the given QName. * * @throws JAXBException No Manager is registered for the * given QName. */ public JMManager getManager(QName pQName) throws JAXBException { JMManager manager = getManagerByQName(pQName); if (manager == null) { throw new JAXBException("A Manager for " + pQName + " is not declared."); } return manager; } /** Returns a Manager for the given element interface. * Same method than [EMAIL PROTECTED] #getManager(Class)}, except that it * throws a [EMAIL PROTECTED] JAXBException}. * @throws JAXBException No Manager is registered for the * given QName. * @see #getManagerS(Class) */ public JMManager getManager(Class pElementInterface) throws JAXBException { JMManager manager = getManagerByInterface(pElementInterface); if (manager == null) { throw new JAXBException("A Manager for " + pElementInterface.getName() + " is not declared."); } return manager; } /** Returns a Manager for the given element interface. * Same method than [EMAIL PROTECTED] #getManager(Class)}, except that it * throws a [EMAIL PROTECTED] SAXException}. * @throws SAXException No Manager is registered for the * given QName. * @see #getManager(Class) */ public JMManager getManagerS(Class pElementInterface) throws SAXException { JMManager manager = getManagerByInterface(pElementInterface); if (manager == null) { throw new SAXException("A Manager for " + pElementInterface.getName() + " is not declared."); } return manager; } /** <p>Returns a new JMMarshaller.</p> */ public JMMarshaller getJMMarshaller() throws MarshalException { Class c = getJMMarshallerClass(); if (c == null) { throw new MarshalException("A JMMarshaller class is not set."); } try { return (JMMarshaller) c.newInstance(); } catch (Exception e) { throw new MarshalException("Failed to instantiate JMMarshaller class " + c, e); } } /** <p>Returns a new JMUnmarshaller.</p> */ public JMUnmarshaller getJMUnmarshaller() throws UnmarshalException { Class c = getJMUnmarshallerClass(); if (c == null) { throw new UnmarshalException("A JMUnmarshaller class is not set."); } try { return (JMUnmarshaller) c.newInstance(); } catch (Exception e) { throw new UnmarshalException("Failed to instantiate JMUnmarshaller class " + c, e); } } /** <p>Returns a new JMValidator.</p> */ public JMValidator getJMValidator() throws ValidationException { Class c = getJMValidatorClass(); if (c == null) { throw new ValidationException("A JMValidator class is not set."); } try { return (JMValidator) c.newInstance(); } catch (Exception e) { throw new ValidationException("Failed to instantiate JMValidator class " + c, e); } } /** <p>Returns a new instance of JMPM.</p> */ public PM getJMPM(Class pElementInterface) throws PMException { JMManager manager = getManagerByInterface(pElementInterface); Class c = manager.getPmClass(); if (c == null) { throw new PMException("No persistency class configured for " + pElementInterface.getName()); } try { PM pm = (PM) c.newInstance(); pm.init(manager); return pm; } catch (Exception e) { e.printStackTrace(System.err); throw new PMException("Could not instantiate persistence manager class " + c.getName(), e); } } /** <p>Returns a new instance of JMPM.</p> */ public PM getJMPM(QName pQName) throws PMException { JMManager manager = getManagerByQName(pQName); Class c = manager.getPmClass(); if (c == null) { throw new PMException("No persistency class configured for " + pQName); } try { PM pm = (PM) c.newInstance(); pm.init(manager); return pm; } catch (Exception e) { throw new PMException("Could not instantiate persistence manager class " + c.getName(), e); } } private boolean first = true; public void registerPackages(String packageNames, ClassLoader cl) throws JAXBException { for (StringTokenizer st = new StringTokenizer(packageNames, ":"); st .hasMoreTokens();) { String packageName = st.nextToken(); String configFileName = ((packageName.length() > 0) ? (packageName .replace('.', '/') + '/') : "") + "Configuration.xml"; URL url = cl.getResource(configFileName); if (url != null) { InputStream istream = null; try { Configuration c = new Configuration(this, cl); Configurator configurator = new Configurator(); configurator.setNamespace(CONFIGURATION_URI); configurator.setRootObject(c); SAXParser sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); xr.setContentHandler(configurator); istream = url.openStream(); InputSource isource = new InputSource(istream); isource.setSystemId(url.toString()); xr.parse(isource); istream.close(); istream = null; if (first) { first = false; setJMMarshallerClass(c.getJMMarshallerClass()); setJMUnmarshallerClass(c.getJMUnmarshallerClass()); setJMValidatorClass(c.getJMValidatorClass()); } } catch (IOException e) { throw new JAXBException( "Failed to load config file " + url, e); } catch (SAXParseException e) { Exception f = e.getException() == null ? e : e .getException(); JAXBException jaxbExc = new JAXBException("Failed to parse config file " + url + " at line " + e.getLineNumber() + ", column " + e.getColumnNumber() + ": " + f.getMessage(), f); jaxbExc.initCause(e); throw jaxbExc; } catch (SAXException e) { Exception f = e.getException() == null ? e : e .getException(); String msg = "Failed to parse config file " + url + ": " + f.getMessage(); throw new JAXBException(msg, f); } catch (ParserConfigurationException e) { throw new JAXBException("Failed to create a SAX Parser: " + e.getMessage(), e); } finally { if (istream != null) { try { istream.close(); } catch (Throwable ignore) { } } } } } if (first) { throw new JAXBException("Unable to locate configuration file Configuration.xml in " + packageNames); } } public void unregisterPackages(String packageNames) { } /** * <p> * Initializes the context by loading the configuration or the * configurations from the given classpath. * </p> */ protected void init() throws JAXBException { if (packageNames == null || packageNames.length() == 0) { packageNames = JAXBContextImpl.class.getName(); packageNames = packageNames.substring(0, packageNames.lastIndexOf('.')); } registerPackages(packageNames, getClassLoader()); } /** Creates a new instance of [EMAIL PROTECTED] javax.xml.bind.JAXBContext}. * Invoked implicitly by * [EMAIL PROTECTED] javax.xml.bind.JAXBContext#newInstance(java.lang.String)}. */ public static JAXBContextImpl createContext() throws JAXBException { return createContext(null, JAXBContextImpl.class.getClassLoader()); } /** Invoked from the SAX handler when loading the config file. */ public Configuration createConfiguration(Attributes pAttributes) throws JAXBException { String className = pAttributes.getValue("", "className"); if (className == null || className.length() == 0) { return new Configuration(this, cl); } else { try { return (Configuration) cl.loadClass(className).newInstance(); } catch (Exception e) { throw new JAXBException("Failed to instantiate Configuration class " + className, e); } } } private static boolean verbose = true; private static void showException(Exception e) { if (!verbose) { return; } System.err.println("Exception catched in " + JAXBContextImpl.class.getName() + ".createContext()."); System.err.println("Set " + JAXBContextImpl.class.getName() + ".verbose = false to suppress this message."); e.printStackTrace(System.err); } /** Creates a new instance of [EMAIL PROTECTED] javax.xml.bind.JAXBContext}. * Invoked implicitly by * [EMAIL PROTECTED] javax.xml.bind.JAXBContext#newInstance(String, ClassLoader)} */ public static JAXBContextImpl createContext(String pPackageNames, ClassLoader pClassLoader) throws JAXBException { try { JAXBContextImpl result = new JAXBContextImpl(); result.setClassLoader(pClassLoader); result.setPackageNames(pPackageNames); result.init(); return result; } catch (RuntimeException e) { showException(e); throw e; } catch (JAXBException e) { showException(e); throw e; } } /** Invoked from the SAX handler when reading the config file * for adding another instance of JMManager. */ public void addManager(JMManager pManager) throws JAXBException { Class elementInterface = pManager.getElementInterface(); if (elementInterface == null) { throw new JAXBException("The Manager must have its elementInterface set."); } if (managersByInterface.containsKey(elementInterface)) { throw new JAXBException("A Manager for interface " + elementInterface.getName() + " is already set."); } if (pManager.getDriverClass() == null) { throw new IllegalStateException("Missing driver class for " + pManager.getQName()); } if (pManager.getHandlerClass() == null) { throw new IllegalStateException("Missing driver class for " + pManager.getQName()); } QName qName = pManager.getQName(); if (qName != null && managersByQName.containsKey(qName)) { throw new JAXBException("A Manager for document type " + qName + " is already set."); } managersByInterface.put(elementInterface, pManager); if (qName != null) { managersByQName.put(qName, pManager); } } }
/* * Copyright 2003, 2004 The Apache Software Foundation * * Licensed 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.ws.jaxme.impl; import java.util.HashMap; import java.util.Map; import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; import org.apache.ws.jaxme.JMManager; import org.apache.ws.jaxme.xs.xml.XsQName; import org.xml.sax.SAXException; /** <p>An instance of this class represents a config file. * A JAXBContext requires an associated Configuration which * is located through the classpath.</p> * * @author <a href="mailto:[EMAIL PROTECTED]">Jochen Wiedmann</a> * @version $Id: Configuration.java,v 1.7 2005/03/10 10:14:03 jochen Exp $ */ public class Configuration { JAXBContextImpl context; Manager currentManager; Map managers = new HashMap(); private Class jmMarshallerClass = JMMarshallerImpl.class; private Class jmUnmarshallerClass = JMUnmarshallerImpl.class; private Class jmValidatorClass = JMValidatorImpl.class; private ClassLoader classLoader; public Configuration(JAXBContextImpl pContext, ClassLoader cl) { context = pContext; this.classLoader = cl; } public class Manager implements JMManager { public class Property { private String managerName; private String value; public String getName() { return managerName; } public void setName(String pName) { managerName = pName; } public String getValue() { return value; } public void setValue(String pValue) { value = pValue; } public void finish() throws SAXException { if (managerName == null) { throw new NullPointerException("Missing 'name' attribute in 'property' element."); } if (value == null) { throw new NullPointerException("Missing 'value' attribute in 'property' element."); } if (properties == null) { properties = new HashMap(); } if (properties.put(managerName, value) != null) { throw new IllegalStateException("The property " + managerName + " was specified more than once."); } } } private QName name; private Class elementInterface; private Class elementClass; private Class handlerClass; private Class driverClass; private Class pmClass; private String prefix; private Map properties; private ClassLoader classLoader; public Manager(ClassLoader classLoader) { this.classLoader = classLoader; } public String getPrefix() { return prefix; } /** Sets the suggested prefix for the elements namespace. */ public void setPrefix(String prefix) { this.prefix = prefix; } public void setQName(QName pName) { name = pName; } public QName getQName() { return name; } public void setElementClass(String pElementClass) throws ClassNotFoundException { elementClass = classLoader.loadClass(pElementClass); } public Class getElementClass() { return elementClass; } public void setElementInterface(String pElementInterface) throws ClassNotFoundException { elementInterface = classLoader.loadClass(pElementInterface); } public Class getElementInterface() { return elementInterface; } public Class getHandlerClass() { return handlerClass; } public void setHandlerClass(String pHandlerClass) throws ClassNotFoundException { handlerClass = classLoader.loadClass(pHandlerClass); if (!JMSAXElementParser.class.isAssignableFrom(handlerClass)) { throw new IllegalStateException("The class " + handlerClass.getName() + " is not implementing " + JMSAXElementParser.class.getName()); } } public void setDriverClass(String pMarshallerClass) throws ClassNotFoundException { driverClass = classLoader.loadClass(pMarshallerClass); if (!JMSAXDriver.class.isAssignableFrom(driverClass)) { throw new IllegalStateException("The class " + driverClass.getName() + " is not implementing " + JMSAXDriver.class.getName()); } } public Class getDriverClass() { return driverClass; } public JMSAXDriver getDriver() throws SAXException { try { return (JMSAXDriver) driverClass.newInstance(); } catch (InstantiationException e) { throw new SAXException("Unable to instantiate driver class " + driverClass.getName(), e); } catch (IllegalAccessException e) { throw new SAXException("Illegal access to driver class " + driverClass.getName(), e); } } /** Sets the persistence manager class. */ public void setPmClass(String pPersistencyClass) throws ClassNotFoundException { pmClass = classLoader.loadClass(pPersistencyClass); } public Class getPmClass() { return pmClass; } public JAXBContextImpl getFactory() { return context; } public Property createProperty() { return new Property(); } public String getProperty(String pName) { if (pName == null) { throw new IllegalArgumentException("The property name must not be null."); } if (properties == null) { return null; } return (String) properties.get(pName); } public void finish() throws SAXException { if (currentManager != this) { throw new IllegalStateException("currentManager != this"); } try { if (prefix != null) { name = new QName(name.getNamespaceURI(), name.getLocalPart(), prefix); } context.addManager(currentManager); currentManager = null; } catch (Exception e) { throw new SAXException(e.getMessage(), e); } } public JMSAXElementParser getHandler() throws SAXException { try { return (JMSAXElementParser) handlerClass.newInstance(); } catch (InstantiationException e) { throw new SAXException("Unable to instantiate handler class " + jmUnmarshallerClass.getName(), e); } catch (IllegalAccessException e) { throw new SAXException("Illegal access to handler class " + jmUnmarshallerClass.getName(), e); } } public Object getElementJ() throws JAXBException { try { return elementClass.newInstance(); } catch (InstantiationException e) { throw new JAXBException("Unable to instantiate handler class " + jmUnmarshallerClass.getName(), e); } catch (IllegalAccessException e) { throw new JAXBException("Illegal access to handler class " + jmUnmarshallerClass.getName(), e); } } public Object getElementS() throws SAXException { try { return elementClass.newInstance(); } catch (InstantiationException e) { throw new SAXException("Unable to instantiate handler class " + jmUnmarshallerClass.getName(), e); } catch (IllegalAccessException e) { throw new SAXException("Illegal access to handler class " + jmUnmarshallerClass.getName(), e); } } } /** <p>Creates a new Manager.</p> */ public Manager createManager() { if (currentManager != null) { throw new IllegalStateException("currentManager != null"); } currentManager = new Manager(classLoader); return currentManager; } /** <p>Sets the JMMarshaller class.</p> */ public void setJMMarshallerClass(Class pJMMarshallerClass) { jmMarshallerClass = pJMMarshallerClass; } /** <p>Returns the JMMarshaller class.</p> */ public Class getJMMarshallerClass() { return jmMarshallerClass; } /** <p>Sets the JMUnmarshaller class.</p> */ public void setJMUnmarshallerClass(Class pJMUnmarshallerClass) { jmUnmarshallerClass = pJMUnmarshallerClass; } /** <p>Returns the JMUnmarshaller class.</p> */ public Class getJMUnmarshallerClass() { return jmUnmarshallerClass; } /** <p>Sets the JMValidator class.</p> */ public void setJMValidatorClass(Class pJMValidatorClass) { jmValidatorClass = pJMValidatorClass; } public Class getJMValidatorClass() { return jmValidatorClass; } }
/* * Copyright 2003, 2004 The Apache Software Foundation * * Licensed 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.ws.jaxme.util; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import javax.xml.namespace.QName; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; /** <p>The Configurator is an idea borrowed by the Ant project. * It is a SAX2 handler that reads a config file which is * represented by a hierarchy of Java beans. For example:</p> * <pre> * <outerBean foo="true" bar="Quite right"> * <innerBean whatever="57"> * </innerBean * </outerBean> * </pre> * The example would create an object outerBean and call its * methods <code>setFoo(boolean)</code> and * <code>setBar(String)</code> to process the attributes. * It would also create a bean innerBean by calling the * outerBeans method <code>createInnerBean()</code>. * Finally the innerBean is configured by calling * <code>setWhatever(int)</code>.</p> * * @author <a href="mailto:[EMAIL PROTECTED]">Jochen Wiedmann</a> * @version $Id: Configurator.java,v 1.4 2005/03/10 10:14:03 jochen Exp $ */ public class Configurator implements ContentHandler, NamespaceResolver { private static final Class[] zeroClasses = new Class[0]; private static final Object[] zeroObjects = new Object[0]; private static final Class[] oneClassString = new Class[]{String.class}; private static final Class[] oneClassAttributes = new Class[]{Attributes.class}; private String[] namespaces; private List beans = new ArrayList(); private List names = new ArrayList(); private Object currentBean; private String currentName; private Locator locator; private Object beanFactory; private Object rootObject; private Object resultBean; private int ignoreLevel = 0; private NamespaceSupport nss = new NamespaceSupport(); boolean nssNeedsContext; /** <p>Sets the namespace handled by the configurator. Defaults * to no namespace. Shortcut for * <code>setNamespace(new String[]{pNamespace})</code>.</p> * * @param pNamespace The namespace being set */ public void setNamespace(String pNamespace) { setNamespaces(new String[]{pNamespace}); } /** <p>Sets the namespaces handled by the configurator. Defaults * to no namespace.</p> * * @param pNamespaces The namespaces being set */ public void setNamespaces(String[] pNamespaces) { namespaces = pNamespaces; } /** <p>Returns the namespaces handled by the configurator. Defaults * to no namespace.</p> */ public String[] getNamespaces() { return namespaces; } /** <p>Sets the Locator being used in error messages.</p> */ public void setDocumentLocator(Locator pLocator) { locator = pLocator; } /** <p>Returns the Locator being used in error messages.</p> */ public Locator getDocumentLocator() { return locator; } /** <p>Sets the bean factory, creating the outermost element. * The bean factory must have a matching <code>createElementName()</code> * method, with <samp>ElementName</samp> being the element name * of the document element.</p> */ public void setBeanFactory(Object pFactory) { beanFactory = pFactory; } /** <p>Returns the bean factory, creating the outermost element. * The bean factory must have a matching <code>createElementName()</code> * method, with <samp>ElementName</samp> being the element name * of the document element.</p> */ public Object getBeanFactory() { return beanFactory == null ? this : beanFactory; } /** <p>An alternative to using the bean factory. This object * is used as the root object, regardless of its name.</p> */ public void setRootObject(Object pRootObject) { rootObject = pRootObject; } /** <p>An alternative to using the bean factory. This object * is used as the root object, regardless of its name.</p> */ public Object getRootObject() { return rootObject; } public void startDocument() throws SAXException { currentBean = null; currentName = null; beans.clear(); names.clear(); ignoreLevel = 0; nss.reset(); nssNeedsContext = true; } public void endDocument() throws SAXException {} public void startPrefixMapping(String pPrefix, String pURI) throws SAXException { nss.declarePrefix(pPrefix, pURI); } public void endPrefixMapping(String pPrefix) throws SAXException { nss.undeclarePrefix(pPrefix); } /** <p>Returns whether a namespace is matching the configured * namespace.</p> */ protected boolean isNamespaceMatching(String pNamespace) { if (pNamespace == null) { pNamespace = ""; } String[] myNamespaces = getNamespaces(); if (myNamespaces == null || myNamespaces.length == 0) { return pNamespace.length() == 0; } else { for (int i = 0; i < myNamespaces.length; i++) { String s = myNamespaces[i]; if (s == null) { s = ""; } if (s.equals(pNamespace)) { return true; } } return false; } } /** <p>Given a prefix and a name, creates a method name matching * the prefix and the name.</p> */ protected String getMethodNameFor(String pPrefix, String pName) { StringBuffer result = new StringBuffer(pPrefix); for (int i = 0; i < pName.length(); i++) { char c = pName.charAt(i); if (i == 0) { if (Character.isJavaIdentifierStart(c)) { result.append(Character.toUpperCase(c)); } else { result.append('_'); } } else { if (Character.isJavaIdentifierPart(c)) { result.append(c); } else { result.append('_'); } } } return result.toString(); } /** <p>Creates a new bean, matching the element name <code>pLocalName</code>. * If this is the outermost bean, calls the bean factorys * <code>createBeanName()</code> method, otherwise calls the current beans * <code>createBeanName()</code> method, with <samp>beanName</samp> * being the value of the <code>pLocalName</code> parameter.</p> */ public void startElement(String pNamespaceURI, String pQName, String pLocalName, Attributes pAttr) throws SAXException { if (ignoreLevel > 0) { ++ignoreLevel; return; } if (!isNamespaceMatching(pNamespaceURI)) { if (currentBean == null) { String[] myNamespaces = getNamespaces(); if (myNamespaces == null || myNamespaces.length == 0) { throw new SAXParseException("The document element must have the default namespace.", getDocumentLocator()); } else { StringBuffer sb = new StringBuffer("The document element must have either of the namespaces: "); for (int i = 0; i < myNamespaces.length; i++) { if (i > 0) sb.append(","); String s = myNamespaces[i]; if (s == null) { s = ""; } sb.append('"').append(s).append('"'); } throw new SAXParseException(sb.toString(), getDocumentLocator()); } } ++ignoreLevel; return; // Namespace not matching, ignore this element } Object o; if (currentBean == null && rootObject != null) { o = rootObject; } else { o = null; Object factory = (currentBean == null) ? beanFactory : currentBean; String methodName = getMethodNameFor("create", pLocalName); try { o = invokeMethod(methodName, factory, oneClassAttributes, new Object[]{pAttr}); } catch (SAXParseException e) { if (e.getException() != null && e.getException() instanceof NoSuchMethodException) { try { o = invokeMethod(methodName, factory, zeroClasses, zeroObjects); e = null; } catch (SAXParseException f) { if (f.getException() != null && f.getException() instanceof NoSuchMethodException) { if (currentBean == null) { throw new SAXParseException("Invalid document element: " + pQName, getDocumentLocator()); } else { throw new SAXParseException("Invalid child element name: " + pQName, getDocumentLocator()); } } throw f; } } if (e != null) { throw e; } } if (o == null) { throw new SAXParseException("Method " + methodName + " of class " + factory.getClass().getName() + " did not return an object.", getDocumentLocator()); } } if (currentBean == null) { resultBean = o; } else { beans.add(currentBean); names.add(currentName); } currentBean = o; currentName = pQName; if (pAttr != null) { for (int i = 0; i < pAttr.getLength(); i++) { String uri = pAttr.getURI(i); if (uri == null || uri.length() == 0 || isNamespaceMatching(uri)) { String value = pAttr.getValue(i); String qName = pAttr.getQName(i); String setMethodName = getMethodNameFor("set", pAttr.getLocalName(i)); Method[] methods = currentBean.getClass().getMethods(); for (int j = 0; j < methods.length; j++) { Method method = methods[j]; if (!setMethodName.equals(method.getName())) { continue; } Class[] argClasses = method.getParameterTypes(); if (argClasses.length != 1) { continue; } Object[] args = null; if (argClasses[0] == String.class) { args = new Object[]{value}; } else if (argClasses[0] == Integer.class || argClasses[0] == Integer.TYPE) { try { args = new Object[]{new Integer(value)}; } catch (Exception e) { throw new SAXParseException("Attribute " + qName + " contains an invalid Integer value: " + value, getDocumentLocator()); } } else if (argClasses[0] == Long.class || argClasses[0] == Long.TYPE) { try { args = new Object[]{new Long(value)}; } catch (Exception e) { throw new SAXParseException("Attribute " + qName + " contains an invalid Long value: " + value, getDocumentLocator()); } } else if (argClasses[0] == Short.class || argClasses[0] == Short.TYPE) { try { args = new Object[]{new Short(value)}; } catch (Exception e) { throw new SAXParseException("Attribute " + qName + " contains an invalid Short value: " + value, getDocumentLocator()); } } else if (argClasses[0] == Byte.class || argClasses[0] == Byte.TYPE) { try { args = new Object[]{new Byte(value)}; } catch (Exception e) { throw new SAXParseException("Attribute " + qName + " contains an invalid Byte value: " + value, getDocumentLocator()); } } else if (argClasses[0] == Boolean.class || argClasses[0] == Boolean.TYPE) { try { args = new Object[]{Boolean.valueOf(value)}; } catch (Exception e) { throw new SAXParseException("Attribute " + qName + " contains an invalid Boolean value: " + value, getDocumentLocator()); } } else if (argClasses[0] == Character.class || argClasses[0] == Character.TYPE) { if (value.length() != 1) { throw new SAXParseException("Attribute " + qName + " contains an invalid Character value: " + value, getDocumentLocator()); } args = new Object[]{new Character(value.charAt(0))}; } else if (argClasses[0] == Class.class) { Class c; try { c = ClassLoader.getClass(value); } catch (Exception e) { throw new SAXParseException("Failed to load class " + value, getDocumentLocator(), e); } args = new Object[]{c}; } else if (argClasses[0] == QName.class) { try { QName name = QName.valueOf(value); args = new Object[]{name}; } catch (Exception e) { throw new SAXParseException("Failed to parse QName " + value, getDocumentLocator()); } } else { // Try a constructor class(String) try { Constructor con = argClasses[0].getConstructor(oneClassString); args = new Object[]{con.newInstance(new Object[]{value})}; } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); throw new SAXParseException("Failed to invoke constructor of class " + argClasses[0].getClass().getName(), getDocumentLocator(), (t instanceof Exception) ? ((Exception) t) : e); } catch (NoSuchMethodException e) { throw new SAXParseException("Attribute " + qName + " has an invalid type: " + argClasses[0].getClass().getName(), getDocumentLocator()); } catch (IllegalAccessException e) { throw new SAXParseException("Illegal access to constructor of class " + argClasses[0].getClass().getName(), getDocumentLocator(), e); } catch (InstantiationException e) { throw new SAXParseException("Failed to instantiate class " + argClasses[0].getClass().getName(), getDocumentLocator(), e); } } try { method.invoke(currentBean, args); } catch (IllegalAccessException e) { throw new SAXParseException("Illegal access to method " + setMethodName + " of class " + currentBean.getClass().getName(), getDocumentLocator(), e); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); SAXParseException saxExc = new SAXParseException("Failed to invoke method " + setMethodName + " of class " + currentBean.getClass().getName(), getDocumentLocator(), (t instanceof Exception) ? ((Exception) t) : e); saxExc.initCause(e); throw saxExc; } } } } } } protected Object invokeMethod(String pMethodName, Object pBean, Class[] pSignature, Object[] pArgs) throws SAXException { try { Method m = pBean.getClass().getMethod(pMethodName, pSignature); return m.invoke(pBean, pArgs); } catch (IllegalAccessException e) { throw new SAXParseException("Illegal access to method " + pMethodName + " of class " + pBean.getClass().getName(), getDocumentLocator(), e); } catch (NoSuchMethodException e) { throw new SAXParseException("No such method in class " + pBean.getClass().getName() + ": " + pMethodName, getDocumentLocator(), e); } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); throw new SAXParseException("Failed to invoke method " + pMethodName + " of class " + pBean.getClass().getName(), getDocumentLocator(), (t instanceof Exception) ? ((Exception) t) : e); } } /** <p>Terminates parsing the current bean by calling its * <code>finish()</code> method, if any.</p> */ public void endElement(String namespaceURI, String qName, String localName) throws SAXException { if (ignoreLevel > 0) { --ignoreLevel; return; } Object previousBean = currentBean; if (beans.size() > 0) { currentBean = beans.remove(beans.size()-1); currentName = names.remove(names.size()-1).toString(); } else { currentBean = null; currentName = null; } try { invokeMethod("finish", previousBean, zeroClasses, zeroObjects); } catch (SAXParseException e) { if (e.getException() == null || !(e.getException() instanceof NoSuchMethodException)) { throw e; } } } /** <p>Handles atomic child elements by invoking their method * <code>addText(String pText)</code>. Note that it may happen, * that this method is invoked multiple times, if the parser * splits a piece of text into multiple SAX events.</p> */ public void characters(char[] ch, int start, int length) throws SAXException { if (ignoreLevel > 0) { return; } String s = new String(ch, start, length); try { invokeMethod("addText", currentBean, oneClassString, new String[]{s}); } catch (SAXParseException e) { if (e.getException() != null && (e.getException() instanceof NoSuchMethodException)) { boolean allWhitespace = true; for (int i = 0; i < length; i++) { if (!Character.isWhitespace(ch[start+i])) { allWhitespace = false; break; } } if (allWhitespace) { // Ignore this } else { throw new SAXParseException("Element " + currentName + " doesn't support embedded text.", getDocumentLocator()); } } else { throw e; } } } public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { } public void processingInstruction(String target, String data) throws SAXException { } public void skippedEntity(String name) throws SAXException { } /** Returns the parsed result bean. */ public Object getResult() { return resultBean; } public boolean processName(String pName, String[] parts) { int offset = pName.indexOf(':'); if (offset == -1) { String uri = nss.getNamespaceURI(""); if (uri == null) { parts[0] = ""; } else { parts[0] = uri; } parts[1] = pName; parts[2] = pName; return true; } else { String uri = nss.getNamespaceURI(pName.substring(0, offset)); if (uri == null) { return false; } else { parts[0] = uri; parts[1] = pName.substring(offset+1); parts[2] = pName; return true; } } } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
