| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 2003 The Apache Software Foundation. All rights |
| * reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. The end-user documentation included with the redistribution, |
| * if any, must include the following acknowledgment: |
| * "This product includes software developed by the |
| * Apache Software Foundation (http://www.apache.org/)." |
| * Alternately, this acknowledgment may appear in the software itself, |
| * if and wherever such third-party acknowledgments normally appear. |
| * |
| * 4. The names "Apache" and "Apache Software Foundation" must |
| * not be used to endorse or promote products derived from this |
| * software without prior written permission. For written |
| * permission, please contact apache@apache.org. |
| * |
| * 5. Products derived from this software may not be called "Apache |
| * XMLBeans", nor may "Apache" appear in their name, without prior |
| * written permission of the Apache Software Foundation. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation and was |
| * originally based on software copyright (c) 2000-2003 BEA Systems |
| * Inc., <http://www.bea.com/>. For more information on the Apache Software |
| * Foundation, please see <http://www.apache.org/>. |
| */ |
| |
| package org.apache.xmlbeans; |
| |
| import javax.xml.namespace.QName; |
| import java.lang.reflect.Field; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| |
| /** |
| * Provides an assortment of utilities |
| * for managing XML Bean types, type systems, QNames, paths, |
| * and queries. |
| */ |
| public final class XmlBeans |
| { |
| /** |
| * Thread local QName cache for general use |
| */ |
| private static final ThreadLocal _threadLocalLoaderQNameCache = |
| new ThreadLocal() |
| { |
| protected Object initialValue() |
| { |
| return new QNameCache( 32 ); |
| } |
| }; |
| |
| /** |
| * Returns a thread local QNameCache |
| */ |
| public static QNameCache getQNameCache ( ) |
| { |
| return (QNameCache) _threadLocalLoaderQNameCache.get(); |
| } |
| |
| /** |
| * Obtains a name from the thread local QNameCache |
| */ |
| public static QName getQName ( String localPart ) |
| { |
| return getQNameCache().getName( "", localPart ); |
| } |
| |
| /** |
| * Obtains a name from the thread local QNameCache |
| */ |
| |
| public static QName getQName ( String namespaceUri, String localPart ) |
| { |
| return getQNameCache().getName( namespaceUri, localPart ); |
| } |
| |
| private static final Method _getContextTypeLoaderMethod = buildGetContextTypeLoaderMethod(); |
| private static final Method _getBuiltinSchemaTypeSystemMethod = buildGetBuiltinSchemaTypeSystemMethod(); |
| private static final Method _getNoTypeMethod = buildGetNoTypeMethod(); |
| private static final Method _typeLoaderBuilderMethod = buildTypeLoaderBuilderMethod(); |
| private static final Method _compilationMethod = buildCompilationMethod(); |
| |
| private static RuntimeException causedException(RuntimeException e, Throwable cause) |
| { |
| e.initCause(cause); |
| return e; |
| } |
| |
| private static XmlException wrappedException(Throwable e) |
| { |
| if (e instanceof XmlException) |
| return (XmlException) e; |
| |
| return new XmlException( e.getMessage(), e ); |
| } |
| |
| private static Method buildGetContextTypeLoaderMethod() |
| { |
| try |
| { |
| return Class.forName("org.apache.xmlbeans.impl.schema.SchemaTypeLoaderImpl", false, XmlBeans.class.getClassLoader()).getMethod("getContextTypeLoader", new Class[0]); |
| } |
| catch (Exception e) |
| { |
| throw causedException(new IllegalStateException("Cannot load SchemaTypeLoaderImpl: verify that xbean.jar is on the classpath"), e); |
| } |
| } |
| |
| |
| private static final Method buildGetBuiltinSchemaTypeSystemMethod() |
| { |
| try |
| { |
| return Class.forName("org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem", false, XmlBeans.class.getClassLoader()).getMethod("get", new Class[0]); |
| } |
| catch (Exception e) |
| { |
| throw causedException(new IllegalStateException("Cannot load BuiltinSchemaTypeSystem: verify that xbean.jar is on the classpath"), e); |
| } |
| } |
| |
| private static final Method buildGetNoTypeMethod() |
| { |
| try |
| { |
| return Class.forName("org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem", false, XmlBeans.class.getClassLoader()).getMethod("getNoType", new Class[0]); |
| } |
| catch (Exception e) |
| { |
| throw causedException(new IllegalStateException("Cannot load BuiltinSchemaTypeSystem: verify that xbean.jar is on the classpath"), e); |
| } |
| } |
| |
| |
| private static final Method buildTypeLoaderBuilderMethod() |
| { |
| try |
| { |
| Class resourceLoaderClass = Class.forName("org.apache.xmlbeans.impl.schema.ResourceLoader", false, XmlBeans.class.getClassLoader()); |
| return Class.forName("org.apache.xmlbeans.impl.schema.SchemaTypeLoaderImpl", false, XmlBeans.class.getClassLoader()).getMethod("build", new Class[] { SchemaTypeLoader[].class, resourceLoaderClass, ClassLoader.class }); |
| } |
| catch (Exception e) |
| { |
| throw causedException(new IllegalStateException("Cannot load SchemaTypeLoaderImpl: verify that xbean.jar is on the classpath"), e); |
| } |
| } |
| |
| |
| private static final Method buildCompilationMethod() |
| { |
| try |
| { |
| return Class.forName("org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl", false, XmlBeans.class.getClassLoader()).getMethod("forSchemaXml", new Class[] { XmlObject[].class, SchemaTypeLoader.class, XmlOptions.class }); |
| } |
| catch (Exception e) |
| { |
| throw causedException(new IllegalStateException("Cannot load SchemaTypeSystemImpl: verify that xbean.jar is on the classpath"), e); |
| } |
| } |
| |
| /** |
| * Compiles an XPath, returning a String equal to that which was passed, |
| * but whose identity is that of one which has been precompiled and cached. |
| */ |
| public static String compilePath ( String pathExpr ) throws XmlException |
| { |
| return compilePath( pathExpr, null ); |
| } |
| |
| /** |
| * Compiles an XPath, returning a String equal to that which was passed, |
| * but whose identity is that of one which has been precompiled and cached; |
| * takes an option for specifying text that indicates the name of context node. |
| * The default is "this", as in "$this". |
| * |
| * @param options Options for the path. For example, you can call |
| * the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)} |
| * method to specify a particular name for the expression |
| * variable that indicates the context node. |
| */ |
| public static String compilePath ( String pathExpr, XmlOptions options ) |
| throws XmlException |
| { |
| return getContextTypeLoader().compilePath( pathExpr, options ); |
| } |
| |
| /** |
| * Compiles an XQuery, returning a String equal to that which was passed, |
| * but whose identity is that of one which has been precompiled and cached. |
| */ |
| public static String compileQuery ( String queryExpr ) throws XmlException |
| { |
| return compileQuery( queryExpr, null ); |
| } |
| |
| /** |
| * Compiles an XQuery, returning a String equal to that which was passed, |
| * but whose identity is that of one which has been precompiled and cached; |
| * takes an option for specifying text that indicates the context node. |
| * |
| * @param options Options for the query. For example, you can call |
| * the {@link XmlOptions#setXqueryCurrentNodeVar(String) XmlOptions.setXqueryCurrentNodeVar(String)} |
| * method to specify a particular name for the expression |
| * variable that indicates the context node. |
| */ |
| public static String compileQuery ( String queryExpr, XmlOptions options ) |
| throws XmlException |
| { |
| return getContextTypeLoader().compileQuery( queryExpr, options ); |
| } |
| |
| /** |
| * Gets the SchemaTypeLoader based on the current thread's context |
| * ClassLoader. This is the SchemaTypeLoader that is used to assign |
| * schema types to XML documents by default. The SchemaTypeLoader is |
| * also consulted to resolve wildcards and xsi:type attributes. |
| * <p> |
| * The "parse" methods of XmlBeans all delegate to the |
| * "parseInstance" methods of the context type loader. |
| */ |
| public static SchemaTypeLoader getContextTypeLoader() |
| { |
| try |
| { |
| return (SchemaTypeLoader)_getContextTypeLoaderMethod.invoke(null, null); |
| } |
| catch (IllegalAccessException e) |
| { |
| throw causedException(new IllegalStateException("No access to SchemaTypeLoaderImpl.getContextTypeLoader(): verify that version of xbean.jar is correct"), e); |
| } |
| catch (InvocationTargetException e) |
| { |
| throw causedException(new IllegalStateException(e.getMessage()), e.getCause()); |
| } |
| } |
| |
| /** |
| * Returns the builtin type system. This SchemaTypeSystem contains |
| * only the 46 builtin types defined by the XML Schema specification. |
| */ |
| public static SchemaTypeSystem getBuiltinTypeSystem() |
| { |
| try |
| { |
| return (SchemaTypeSystem)_getBuiltinSchemaTypeSystemMethod.invoke(null, null); |
| } |
| catch (IllegalAccessException e) |
| { |
| throw causedException(new IllegalStateException("No access to BuiltinSchemaTypeSystem.get(): verify that version of xbean.jar is correct"), e); |
| } |
| catch (InvocationTargetException e) |
| { |
| throw causedException(new IllegalStateException(e.getMessage()), e.getCause()); |
| } |
| } |
| |
| /** |
| * Returns the SchemaTypeSystem that results from compiling the XML |
| * schema definitions passed. |
| * <p> |
| * Just like compileTypeSystem, but uses the context type loader for |
| * linking, and returns a unioned typeloader that is suitable for |
| * creating instances. |
| */ |
| public static SchemaTypeLoader loadXsd(XmlObject[] schemas) throws XmlException |
| { |
| return loadXsd(schemas, null); |
| } |
| |
| /** |
| * <p>Returns the SchemaTypeSystem that results from compiling the XML |
| * schema definitions passed in <em>schemas</em>.</p> |
| * |
| * <p>This is just like compileTypeSystem, but uses the context type loader for |
| * linking, and returns a unioned typeloader that is suitable for |
| * creating instances.</p> |
| * |
| * <p>Use the <em>options</em> parameter to specify one or both of the following:</p> |
| * |
| * <ul> |
| * <li>A collection instance that should be used as an error listener during |
| * compilation, as described in {@link XmlOptions#setErrorListener}.</li> |
| * <li>Whether validation should not be done when building the SchemaTypeSystem, |
| * as described in {@link XmlOptions#setCompileNoValidation}.</li> |
| * </ul> |
| * |
| * @param schemas The schema definitions from which to build the schema type system. |
| * @param options Options specifying an error listener and/or validation behavior. |
| */ |
| public static SchemaTypeLoader loadXsd(XmlObject[] schemas, XmlOptions options) throws XmlException |
| { |
| try |
| { |
| SchemaTypeSystem sts = |
| (SchemaTypeSystem) |
| _compilationMethod.invoke( |
| null, new Object[] { schemas, getContextTypeLoader(), options }); |
| |
| if (sts == null) |
| return null; |
| |
| return |
| typeLoaderUnion( |
| new SchemaTypeLoader[] { sts, getContextTypeLoader() } ); |
| } |
| catch (IllegalAccessException e) |
| { |
| throw causedException(new IllegalStateException("No access to SchemaTypeLoaderImpl.forSchemaXml(): verify that version of xbean.jar is correct"), e); |
| } |
| catch (InvocationTargetException e) |
| { |
| throw wrappedException(e.getCause()); |
| } |
| } |
| |
| /** |
| * <p>Returns the SchemaTypeSystem that results from compiling the XML |
| * schema definitions passed.</p> |
| * |
| * <p>The XmlObjects passed in should be w3c <schema> elements whose type |
| * is org.w3c.x2001.xmlSchema.Schema. (That is, schema elements in |
| * the XML namespace http://www.w3c.org/2001/XMLSchema.) Also |
| * org.w3c.x2001.xmlSchema.SchemaDocument is permitted.</p> |
| * |
| * <p>The optional second argument is a SchemaTypeLoader which will be |
| * consulted for already-compiled schema types which may be linked |
| * while processing the given schemas.</p> |
| * |
| * <p>The SchemaTypeSystem that is returned should be combined |
| * (via {@link #typeLoaderUnion}) with the typepath typeloader in order |
| * to create a typeloader that can be used for creating and validating |
| * instances.</p> |
| * |
| * <p>Use the <em>options</em> parameter to specify the following:</p> |
| * |
| * <ul> |
| * <li>A collection instance that should be used as an error listener during |
| * compilation, as described in {@link XmlOptions#setErrorListener}.</li> |
| * <li>Whether validation should not be done when building the SchemaTypeSystem, |
| * as described in {@link XmlOptions#setCompileNoValidation}.</li> |
| * </ul> |
| * |
| * @param schemas The schema definitions from which to build the schema type system. |
| * @param typepath The path to already-compiled schema types for linking while processing. |
| * @param options Options specifying an error listener and/or validation behavior. |
| */ |
| public static SchemaTypeSystem compileXsd(XmlObject[] schemas, SchemaTypeLoader typepath, XmlOptions options) throws XmlException |
| { |
| if (typepath == null) |
| throw new IllegalArgumentException("Must supply a SchemaTypeLoader for compiletime linking"); |
| |
| try |
| { |
| return (SchemaTypeSystem)_compilationMethod.invoke(null, new Object[] { schemas, typepath, options }); |
| } |
| catch (IllegalAccessException e) |
| { |
| throw new IllegalStateException("No access to SchemaTypeLoaderImpl.forSchemaXml(): verify that version of xbean.jar is correct"); |
| } |
| catch (InvocationTargetException e) |
| { |
| throw wrappedException(e.getCause()); |
| } |
| } |
| |
| /** |
| * Returns the union of a list of typeLoaders. The returned |
| * SchemaTypeLoader searches the given list of SchemaTypeLoaders |
| * in order from first to last. |
| */ |
| public static SchemaTypeLoader typeLoaderUnion(SchemaTypeLoader[] typeLoaders) |
| { |
| try |
| { |
| if (typeLoaders.length == 1) |
| return typeLoaders[0]; |
| |
| return (SchemaTypeLoader)_typeLoaderBuilderMethod.invoke(null, new Object[] {typeLoaders, null, null}); |
| } |
| catch (IllegalAccessException e) |
| { |
| throw causedException(new IllegalStateException("No access to SchemaTypeLoaderImpl: verify that version of xbean.jar is correct"), e); |
| } |
| catch (InvocationTargetException e) |
| { |
| throw causedException(new IllegalStateException(e.getMessage()), e.getCause()); |
| } |
| } |
| |
| /** |
| * Returns a SchemaTypeLoader that searches for compiled schema types |
| * in the given ClassLoader. |
| */ |
| public static SchemaTypeLoader typeLoaderForClassLoader(ClassLoader loader) |
| { |
| try |
| { |
| return (SchemaTypeLoader)_typeLoaderBuilderMethod.invoke(null, new Object[] {null, null, loader}); |
| } |
| catch (IllegalAccessException e) |
| { |
| throw causedException(new IllegalStateException("No access to SchemaTypeLoaderImpl: verify that version of xbean.jar is correct"), e); |
| } |
| catch (InvocationTargetException e) |
| { |
| throw causedException( new IllegalStateException(e.getMessage()), e ); |
| } |
| } |
| |
| /** |
| * Returns the SchemaType from a corresponding XmlObject subclass, |
| * or null if none. |
| */ |
| public static SchemaType typeForClass(Class c) |
| { |
| if (c == null || !XmlObject.class.isAssignableFrom(c)) |
| return null; |
| |
| try |
| { |
| Field typeField = c.getField("type"); |
| |
| if (typeField == null) |
| return null; |
| |
| return (SchemaType)typeField.get(null); |
| } |
| catch (Exception e) |
| { |
| return null; |
| } |
| } |
| |
| private static SchemaType getNoType() |
| { |
| try |
| { |
| return (SchemaType)_getNoTypeMethod.invoke(null, null); |
| } |
| catch (IllegalAccessException e) |
| { |
| throw causedException(new IllegalStateException("No access to SchemaTypeLoaderImpl.getContextTypeLoader(): verify that version of xbean.jar is correct"), e); |
| } |
| catch (InvocationTargetException e) |
| { |
| throw causedException(new IllegalStateException(e.getMessage()), e.getCause()); |
| } |
| } |
| |
| /** |
| * The SchemaType object given to an XmlObject instance when |
| * no type can be determined. |
| * <p> |
| * The NO_TYPE is the universal derived type. That is, it is |
| * derived from all other schema types, and no instances of the |
| * NO_TYPE are valid. (It is not to be confused with the anyType, |
| * which is the universal base type from which all other types |
| * can be derived, and of which all instances are valid.) |
| */ |
| public static SchemaType NO_TYPE = getNoType(); |
| |
| private XmlBeans ( ) { } |
| } |