/*
* 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.impl.schema;

import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.values.XmlStore;
import org.apache.xmlbeans.impl.validator.ValidatingXMLInputStream;

import org.apache.xmlbeans.SchemaAttributeGroup;
import org.apache.xmlbeans.SchemaField;
import org.apache.xmlbeans.SchemaGlobalAttribute;
import org.apache.xmlbeans.SchemaGlobalElement;
import org.apache.xmlbeans.SchemaModelGroup;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeLoader;
import org.apache.xmlbeans.XmlSaxHandler;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlFactoryHook;

import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.io.InputStream;
import java.io.Reader;
import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.util.List;
import java.util.ArrayList;
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamReader;

import org.w3c.dom.Node;

import weblogic.xml.stream.XMLInputStream;
import weblogic.xml.stream.XMLStreamException;

public abstract class SchemaTypeLoaderBase implements SchemaTypeLoader
{
    private static final Method _rootBuilder = getMethod( "org.apache.xmlbeans.impl.store.Root", "newStore", new Class[] { SchemaTypeLoader.class, SchemaType.class, XmlOptions.class } );
    private static final Method _pathCompiler = getMethod( "org.apache.xmlbeans.impl.store.Path", "getCompiledPath", new Class[] { String.class, XmlOptions.class } );
    private static final Method _queryCompiler = getMethod( "org.apache.xmlbeans.impl.store.Path", "getCompiledQuery", new Class[] { String.class, XmlOptions.class } );

    private static Method getMethod ( String className, String methodName, Class[] args )
    {
        try
        {
            return
                Class.forName( className ).
                    getDeclaredMethod( methodName, args );
        }
        catch (Exception e)
        {
            throw new IllegalStateException(
                "Cannot find " + className + "." + methodName +
                    ".  verify that xmlstore " +
                        "(from xbean.jar) is on classpath" );
        }
    }

    private static Object invokeMethod ( Method method, Object[] args )
    {
        try
        {
            return method.invoke( method, args );
        }
        catch ( InvocationTargetException e )
        {
            IllegalStateException ise = new IllegalStateException( e.getCause().getMessage() );
            ise.initCause( e );
            throw ise;
        }
        catch ( Exception e )
        {
            IllegalStateException ise = new IllegalStateException( e.getMessage() );
            ise.initCause( e );
            throw ise;
        }
    }

    private XmlStore createNewStore ( SchemaType type, XmlOptions options )
    {
        return
            (XmlStore)
                invokeMethod( _rootBuilder, new Object[] { this, type, options } );
    }

    private static String doCompilePath ( String pathExpr, XmlOptions options ) { return (String) invokeMethod( _pathCompiler, new Object[] { pathExpr, options } ); }
    private static String doCompileQuery ( String queryExpr, XmlOptions options ) { return (String) invokeMethod( _queryCompiler, new Object[] { queryExpr, options } ); }

    public SchemaType findType(QName name)
    {
        SchemaType.Ref ref = findTypeRef(name);
        if (ref == null)
            return null;
        SchemaType result = ref.get();
        assert(result != null);
        return result;
    }

    public SchemaType findDocumentType(QName name)
    {
        SchemaType.Ref ref = findDocumentTypeRef(name);
        if (ref == null)
            return null;
        SchemaType result = ref.get();
        assert(result != null);
        return result;
    }

    public SchemaType findAttributeType(QName name)
    {
        SchemaType.Ref ref = findAttributeTypeRef(name);
        if (ref == null)
            return null;
        SchemaType result = ref.get();
        assert(result != null);
        return result;
    }

    public SchemaModelGroup findModelGroup(QName name)
    {
        SchemaModelGroup.Ref ref = findModelGroupRef(name);
        if (ref == null)
            return null;
        SchemaModelGroup result = ref.get();
        assert(result != null);
        return result;
    }

    public SchemaAttributeGroup findAttributeGroup(QName name)
    {
        SchemaAttributeGroup.Ref ref = findAttributeGroupRef(name);
        if (ref == null)
            return null;
        SchemaAttributeGroup result = ref.get();
        assert(result != null);
        return result;
    }

    public SchemaGlobalElement findElement(QName name)
    {
        SchemaGlobalElement.Ref ref = findElementRef(name);
        if (ref == null)
            return null;
        SchemaGlobalElement result = ref.get();
        assert(result != null);
        return result;
    }

    public SchemaGlobalAttribute findAttribute(QName name)
    {
        SchemaGlobalAttribute.Ref ref = findAttributeRef(name);
        if (ref == null)
            return null;
        SchemaGlobalAttribute result = ref.get();
        assert(result != null);
        return result;
    }

    //
    //
    //

    public XmlObject newInstance ( SchemaType type, XmlOptions options )
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.newInstance( this, type, options );

        return createNewStore( type, options ).getObject();
    }

    public XmlObject parse ( String xmlText, SchemaType type, XmlOptions options ) throws XmlException
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.parse( this, xmlText, type, options );

        return createNewStore( null, options ).loadXml( xmlText, type, options );
    }

    public XmlObject parse ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.parse( this, xis, type, options );

        return createNewStore( null, options ).loadXml( xis, type, options );
    }

    public XmlObject parse ( File file, SchemaType type, XmlOptions options ) throws XmlException, IOException
    {
        if (options == null)
        {
            options = new XmlOptions();
            options.put( XmlOptions.DOCUMENT_SOURCE_NAME, file.toURI().normalize().toString() );
        }

        else if (! options.hasOption(XmlOptions.DOCUMENT_SOURCE_NAME))
        {
            options = new XmlOptions( options );
            options.put( XmlOptions.DOCUMENT_SOURCE_NAME, file.toURI().normalize().toString() );
        }

        InputStream fis = new FileInputStream( file );

        try
        {
            return parse( fis, type, options );
        }
        finally
        {
            fis.close();
        }
    }

    public XmlObject parse ( URL url, SchemaType type, XmlOptions options ) throws XmlException, IOException
    {
        if (options == null)
        {
            options = new XmlOptions();
            options.put( XmlOptions.DOCUMENT_SOURCE_NAME, url.toString() );
        }

        else if (! options.hasOption(XmlOptions.DOCUMENT_SOURCE_NAME))
        {
            options = new XmlOptions( options );
            options.put( XmlOptions.DOCUMENT_SOURCE_NAME, url.toString() );
        }

        URLConnection conn = null;
        InputStream stream = null;
        download: try
        {

            boolean redirected = false;
            int count = 0;

            do {
                conn = url.openConnection();
                conn.addRequestProperty("User-Agent", "BEA XML Beans/1.0");
                conn.addRequestProperty("Accept", "application/xml, text/xml, */*");
                if (conn instanceof HttpURLConnection)
                {
                    HttpURLConnection httpcon = (HttpURLConnection)conn;
                    int code = httpcon.getResponseCode();
                    redirected = (code == HttpURLConnection.HTTP_MOVED_PERM || code == HttpURLConnection.HTTP_MOVED_TEMP);
                    if (redirected && count > 5)
                        redirected = false;

                    if (redirected)
                    {
                        String newLocation = httpcon.getHeaderField("Location");
                        if (newLocation == null)
                            redirected = false;
                        else
                        {
                            url = new URL(newLocation);
                            count ++;
                        }
                    }
                }
            } while (redirected);

            stream = conn.getInputStream();
            return parse( stream, type, options );
        }
        finally
        {
            if (stream != null)
                stream.close();
        }
    }

    public XmlObject parse ( XMLStreamReader xsr, SchemaType type, XmlOptions options ) throws XmlException
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.parse( this, xsr, type, options );

        return createNewStore( null, options ).loadXml( xsr, type, options );
    }
    
    public XmlObject parse ( InputStream jiois, SchemaType type, XmlOptions options ) throws XmlException, IOException
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        DigestInputStream digestStream = null;
        setupDigest: if (options != null && options.hasOption(XmlOptions.LOAD_MESSAGE_DIGEST))
        {
            MessageDigest sha;
            try
            {
                sha = MessageDigest.getInstance("SHA");
            }
            catch (NoSuchAlgorithmException e)
            {
                break setupDigest;
            }

            digestStream = new DigestInputStream(jiois, sha);
            jiois = digestStream;
        }

        if (hook != null)
            return hook.parse( this, jiois, type, options );

        XmlObject result = createNewStore( null, options ).loadXml( jiois, type, options );

        if (digestStream != null)
            result.documentProperties().setMessageDigest(digestStream.getMessageDigest().digest());

        return result;
    }

    public XmlObject parse ( Reader jior, SchemaType type, XmlOptions options ) throws XmlException, IOException
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.parse( this, jior, type, options );

        return createNewStore( null, options ).loadXml( jior, type, options );
    }

    public XmlObject parse ( Node node, SchemaType type, XmlOptions options ) throws XmlException
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.parse( this, node, type, options );

        return createNewStore( null, options ).loadXml( node, type, options );
    }

    public XmlSaxHandler newXmlSaxHandler ( SchemaType type, XmlOptions options )
    {
        XmlFactoryHook hook = XmlFactoryHook.ThreadContext.getHook();
        if (hook != null)
            return hook.newXmlSaxHandler( this, type, options );

        return createNewStore( null, options ).newSaxHandler( type, options );
    }

    public XMLInputStream newValidatingXMLInputStream ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException
    {
        return new ValidatingXMLInputStream( xis, this, type, options );
    }

    //
    //
    //

    public String compilePath ( String pathExpr )
    {
        return compilePath( pathExpr, null );
    }

    public String compilePath ( String pathExpr, XmlOptions options )
    {
        return doCompilePath( pathExpr, options );
    }

    public String compileQuery ( String queryExpr )
    {
        return compileQuery( queryExpr, null );
    }

    public String compileQuery ( String queryExpr, XmlOptions options )
    {
        return doCompileQuery( queryExpr, options );
    }

    /**
     * Utility function to load a type from a signature.
     *
     * A signature is the string you get from type.toString().
     */
    public SchemaType typeForSignature(String signature)
    {
        int end = signature.indexOf('@');
        String uri;

        if (end < 0)
        {
            uri = "";
            end = signature.length();
        }
        else
        {
            uri = signature.substring(end + 1);
        }

        List parts = new ArrayList();

        for (int index = 0; index < end; )
        {
            int nextc = signature.indexOf(':', index);
            int nextd = signature.indexOf('|', index);
            int next = (nextc < 0 ? nextd : nextd < 0 ? nextc : nextc < nextd ? nextc : nextd);
            if (next < 0 || next > end)
                next = end;
            String part = signature.substring(index, next);
            parts.add(part);
            index = next + 1;
        }

        SchemaType curType = null;

        outer: for (int i = parts.size() - 1; i >= 0; i -= 1)
        {
            String part = (String)parts.get(i);
            if (part.length() < 1)
                throw new IllegalArgumentException();
            int offset = (part.length() >= 2 && part.charAt(1) == '=') ? 2 : 1;
            cases: switch (part.charAt(0))
            {
                case 'T':
                    if (curType != null)
                        throw new IllegalArgumentException();
                    curType = findType(QNameHelper.forLNS(part.substring(offset), uri));
                    if (curType == null)
                        return null;
                    break;

                case 'D':
                    if (curType != null)
                        throw new IllegalArgumentException();
                    curType = findDocumentType(QNameHelper.forLNS(part.substring(offset), uri));
                    if (curType == null)
                        return null;
                    break;

                case 'C': // deprecated
                case 'R': // current
                    if (curType != null)
                        throw new IllegalArgumentException();
                    curType = findAttributeType(QNameHelper.forLNS(part.substring(offset), uri));
                    if (curType == null)
                        return null;
                    break;

                case 'E':
                case 'U': // distinguish qualified/unqualified TBD
                    if (curType != null)
                    {
                        if (curType.getContentType() < SchemaType.ELEMENT_CONTENT)
                            return null;
                        SchemaType[] subTypes = curType.getAnonymousTypes();
                        String localName = part.substring(offset);
                        for (int j = 0; j < subTypes.length; j++)
                        {
                            SchemaField field = subTypes[j].getContainerField();
                            if (field != null && !field.isAttribute() && field.getName().getLocalPart().equals(localName))
                            {
                                curType = subTypes[j];
                                break cases;
                            }
                        }
                        return null;
                    }
                    else
                    {
                        SchemaGlobalElement elt = findElement(QNameHelper.forLNS(part.substring(offset), uri));
                        if (elt == null)
                            return null;
                        curType = elt.getType();
                    }
                    break;

                case 'A':
                case 'Q': // distinguish qualified/unqualified TBD
                    if (curType != null)
                    {
                        if (curType.isSimpleType())
                            return null;
                        SchemaType[] subTypes = curType.getAnonymousTypes();
                        String localName = part.substring(offset);
                        for (int j = 0; j < subTypes.length; j++)
                        {
                            SchemaField field = subTypes[j].getContainerField();
                            if (field != null && field.isAttribute() && field.getName().getLocalPart().equals(localName))
                            {
                                curType = subTypes[j];
                                break cases;
                            }
                        }
                        return null;
                    }
                    else
                    {
                        SchemaGlobalAttribute attr = findAttribute(QNameHelper.forLNS(part.substring(offset), uri));
                        if (attr == null)
                            return null;
                        curType = attr.getType();
                    }
                    break;

                case 'B':
                    if (curType == null)
                    {
                        throw new IllegalArgumentException();
                    }
                    else
                    {
                        if (curType.getSimpleVariety() != SchemaType.ATOMIC)
                            return null;
                        SchemaType[] subTypes = curType.getAnonymousTypes();
                        if (subTypes.length != 1)
                            return null;
                        curType = subTypes[0];
                    }
                    break;

                case 'I':
                    if (curType == null)
                    {
                        throw new IllegalArgumentException();
                    }
                    else
                    {
                        if (curType.getSimpleVariety() != SchemaType.LIST)
                            return null;
                        SchemaType[] subTypes = curType.getAnonymousTypes();
                        if (subTypes.length != 1)
                            return null;
                        curType = subTypes[0];
                    }
                    break;

                case 'M':
                    if (curType == null)
                    {
                        throw new IllegalArgumentException();
                    }
                    else
                    {
                        int index;
                        try
                        {
                            index = Integer.parseInt(part.substring(offset));
                        }
                        catch (Exception e)
                        {
                            throw new IllegalArgumentException();
                        }

                        if (curType.getSimpleVariety() != SchemaType.UNION)
                            return null;
                        SchemaType[] subTypes = curType.getAnonymousTypes();
                        if (subTypes.length <= index)
                            return null;
                        curType = subTypes[index];
                    }
                    break;

                default:
                    throw new IllegalArgumentException();
            }
        }
        return curType;
    }
}
