/*
* 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 &lt;schema&gt; 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 ( ) { }
}
