package jdiff;

import java.io.*;
import java.util.*;
import javax.xml.parsers.ParserConfigurationException;

/* For SAX parsing in APIHandler */
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.*;

/**
 * Creates an API object from an XML file. The API object is the internal
 * representation of an API.
 * All methods in this class for populating an API object are static.
 *
 * See the file LICENSE.txt for copyright details.
 * @author Matthew Doar, mdoar@pobox.com
 */
public class XMLToAPI {

    /** The instance of the API object which is populated from the file. */
    private static API api_ = null;

    /** Default constructor. */
    private XMLToAPI() {
    }

    /**
     * Read the file where the XML representing the API is stored.
     *
     * @param filename The full name of the file containing the XML
     *                 representing the API
     * @param createGlobalComments If set, then store possible comments
     * @param apiName The simple name of the API file. If -oldapidir and
     *                -newapidir are not used, then this is the same as
     *                the filename parameter
     */
    public static API readFile(String filename, boolean createGlobalComments,
            String apiName) {
        // The instance of the API object which is populated from the file.
        api_ = new API();
        api_.name_ = apiName; // Checked later
        try {
            XMLReader parser = null;
            DefaultHandler handler = new APIHandler(api_, createGlobalComments);
            try {
                parser = javax.xml.parsers.SAXParserFactory.newInstance().newSAXParser().getXMLReader();
            } catch (SAXException saxe) {
                System.out.println("SAXException: " + saxe);
                saxe.printStackTrace();
                System.exit(1);
            } catch (ParserConfigurationException pce) {
                System.out.println("ParserConfigurationException: " + pce);
                pce.printStackTrace();
                System.exit(1);
            }

            if (validateXML) {
                parser.setFeature("http://xml.org/sax/features/namespaces", true);
                parser.setFeature("http://xml.org/sax/features/validation", true);
                parser.setFeature("http://apache.org/xml/features/validation/schema", true);
            }

            parser.setContentHandler(handler);
            parser.setErrorHandler(handler);
            parser.parse(new InputSource(new FileInputStream(new File(filename))));
        } catch(org.xml.sax.SAXNotRecognizedException snre) {
            System.out.println("SAX Parser does not recognize feature: " + snre);
            snre.printStackTrace();
            System.exit(1);
        } catch(org.xml.sax.SAXNotSupportedException snse) {
            System.out.println("SAX Parser feature is not supported: " + snse);
            snse.printStackTrace();
            System.exit(1);
        } catch(org.xml.sax.SAXException saxe) {
            System.out.println("SAX Exception parsing file '" + filename + "' : " + saxe);
            saxe.printStackTrace();
            System.exit(1);
        } catch(java.io.IOException ioe) {
            System.out.println("IOException parsing file '" + filename + "' : " + ioe);
            ioe.printStackTrace();
            System.exit(1);
        }

        // Add the inherited methods and fields to each class
        addInheritedElements();
        return api_;
    } //readFile()

    /**
     * Add the inherited methods and fields to each class in turn.
     */
    public static void addInheritedElements() {
        Iterator iter = api_.packages_.iterator();
        while (iter.hasNext()) {
            PackageAPI pkg = (PackageAPI)(iter.next());
            Iterator iter2 = pkg.classes_.iterator();
            while (iter2.hasNext()) {
                ClassAPI cls = (ClassAPI)(iter2.next());
                // Look up any inherited classes or interfaces
                if (cls.extends_ != null) {
                    ClassAPI parent = (ClassAPI)api_.classes_.get(cls.extends_);
                    if (parent != null)
                        addInheritedElements(cls, parent, cls.extends_);
                }
                if (cls.implements_.size() != 0) {
                    Iterator iter3 = cls.implements_.iterator();
                    while (iter3.hasNext()) {
                        String implName = (String)(iter3.next());
                        ClassAPI parent = (ClassAPI)api_.classes_.get(implName);
                        if (parent != null)
                            addInheritedElements(cls, parent, implName);
                    }
                }
            } //while (iter2.hasNext())
        } //while (iter.hasNext())
    }

    /**
     * Add all the inherited methods and fields in the second class to
     * the first class, marking them as inherited from the second class.
     * Do not add a method or a field if it is already defined locally.
     *
     * Only elements at the specified visibility level or
     * higher appear in the XML file. All that remains to be tested for
     * a private element, which is never inherited.
     *
     * If the parent class inherits any classes or interfaces, call this
     * method recursively with those parents.
     */
    public static void addInheritedElements(ClassAPI child, ClassAPI parent,
                                            String fqParentName) {
        if (parent.methods_.size() != 0) {
            Iterator iter = parent.methods_.iterator();
            while (iter.hasNext()) {
                MethodAPI m = (MethodAPI)(iter.next());
                // See if it the method is overridden locally
                boolean overridden = false;
                Iterator iter2 = child.methods_.iterator();
                while (iter2.hasNext()) {
                    MethodAPI localM = (MethodAPI)(iter2.next());
                    if (localM.name_.compareTo(m.name_) == 0 &&
                        localM.getSignature().compareTo(m.getSignature()) == 0)
                        overridden = true;
                }
                if (!overridden && m.inheritedFrom_ == null &&
                    m.modifiers_.visibility != null &&
                    m.modifiers_.visibility.compareTo("private") != 0) {
                    MethodAPI m2 = new MethodAPI(m);
                    m2.inheritedFrom_ = fqParentName;
                    child.methods_.add(m2);
                }
            }
        }
        if (parent.fields_.size() != 0) {
            Iterator iter = parent.fields_.iterator();
            while (iter.hasNext()) {
                FieldAPI f = (FieldAPI)(iter.next());
                if (child.fields_.indexOf(f) == -1 &&
                    f.inheritedFrom_ == null &&
                    f.modifiers_.visibility != null &&
                    f.modifiers_.visibility.compareTo("private") != 0) {
                    FieldAPI f2 = new FieldAPI(f);
                    f2.inheritedFrom_ = fqParentName;
                    child.fields_.add(f2);
                }
            }
        }

        // Look up any inherited classes or interfaces
        if (parent.extends_ != null) {
            ClassAPI parent2 = (ClassAPI)api_.classes_.get(parent.extends_);
            if (parent2 != null)
                addInheritedElements(child, parent2, parent.extends_);
        }
        if (parent.implements_.size() != 0) {
            Iterator iter3 = parent.implements_.iterator();
            while (iter3.hasNext()) {
                String implName = (String)(iter3.next());
                ClassAPI parent2 = (ClassAPI)api_.classes_.get(implName);
                if (parent2 != null)
                    addInheritedElements(child, parent2, implName);
            }
        }
    }

//
// Methods to add data to an API object. Called by the XML parser.
//

    /**
     * Set the name of the API object.
     *
     * @param name The name of the package.
     */
    public static void nameAPI(String name) {
        if (name == null) {
            System.out.println("Warning: no API identifier found in the XML file '" + api_.name_ + "'");
            String filename = api_.name_.substring(0, api_.name_.lastIndexOf(".xml"));
            // System.out.println(" api level:" + filename);
            System.out.println("Using '" + filename + "' as the API identifier.");
            api_.name_ = filename;
            // System.exit(3);
            return;
        }
        // Check the given name against the filename currently stored in
        // the name_ field
        String filename2 = name.replace(' ','_');
        filename2 += ".xml";
        if (filename2.compareTo(api_.name_) != 0) {
            System.out.println("Warning: API identifier in the XML file (" +
                               name + ") differs from the name of the file '" +
                               api_.name_ + "'");
        }
        api_.name_ = name;
    }

    /**
     * Create a new package and add it to the API. Called by the XML parser.
     *
     * @param name The name of the package.
     */
    public static void addPackage(String name) {
        api_.currPkg_ = new PackageAPI(name);
        api_.packages_.add(api_.currPkg_);
    }

    /**
     * Create a new class and add it to the current package. Called by the XML parser.
     *
     * @param name The name of the class.
     * @param parent The name of the parent class, null if no class is extended.
     * @param modifiers Modifiers for this class.
     */
    public static void addClass(String name, String parent,
                                boolean isAbstract,
                                Modifiers modifiers) {
        api_.currClass_ = new ClassAPI(name, parent, false, isAbstract, modifiers);
        api_.currPkg_.classes_.add(api_.currClass_);
        String fqName = api_.currPkg_.name_ + "." + name;
        ClassAPI caOld = (ClassAPI)api_.classes_.put(fqName, api_.currClass_);
        if (caOld != null) {
            System.out.println("Warning: duplicate class : " + fqName + " found. Using the first instance only.");
        }
    }

    /**
     * Add an new interface and add it to the current package. Called by the
     * XML parser.
     *
     * @param name The name of the interface.
     * @param parent The name of the parent interface, null if no
     *               interface is extended.
     */
    public static void addInterface(String name, String parent,
                                    boolean isAbstract,
                                    Modifiers modifiers) {
        api_.currClass_ = new ClassAPI(name, parent, true, isAbstract, modifiers);
        api_.currPkg_.classes_.add(api_.currClass_);
    }

    /**
     * Add an inherited interface to the current class. Called by the XML
     * parser.
     *
     * @param name The name of the inherited interface.
     */
    public static void addImplements(String name) {
       api_.currClass_.implements_.add(name);
    }

    /**
     * Add a constructor to the current class. Called by the XML parser.
     *
     * @param name The name of the constructor (optional).
     * @param type The type of the constructor.
     * @param modifiers Modifiers for this constructor.
     */
    public static void addCtor(String name, String type, Modifiers modifiers) {
        String t = type;
        if (t == null)
            t = "void";
        api_.currCtor_ = new ConstructorAPI(name, t, modifiers);
        api_.currClass_.ctors_.add(api_.currCtor_);
    }

    /**
     * Add a method to the current class. Called by the XML parser.
     *
     * @param name The name of the method.
     * @param returnType The return type of the method, null if it is void.
     * @param modifiers Modifiers for this method.
     */
    public static void addMethod(String name, String returnType,
                                 boolean isAbstract, boolean isNative,
                                 boolean isSynchronized, Modifiers modifiers) {
        String rt = returnType;
        if (rt == null)
            rt = "void";
        api_.currMethod_ = new MethodAPI(name, rt, isAbstract, isNative,
                                         isSynchronized, modifiers);
        api_.currClass_.methods_.add(api_.currMethod_);
    }

    /**
     * Add a field to the current class. Called by the XML parser.
     *
     * @param name The name of the field.
     * @param type The type of the field, null if it is void.
     * @param modifiers Modifiers for this field.
     */
    public static void addField(String name, String type, boolean isTransient,
                                boolean isVolatile, String value, Modifiers modifiers) {
        String t = type;
        if (t == null)
            t = "void";
        api_.currField_ = new FieldAPI(name, t, isTransient, isVolatile, value, modifiers);
        api_.currClass_.fields_.add(api_.currField_);
    }

    /**
     * Add a parameter to the current method or constructor. Called by the XML parser.
     * Constuctors have their type (signature) in an attribute, since it
     * is often shorter and makes parsing a little easier.
     *
     * @param name The name of the parameter.
     * @param type The type of the parameter, null if it is void.
     * @param isConstructor Whether the given parameter is for a constructor
     */
    public static void addParam(String name, String type, boolean isConstructor) {
        String t = type;
        if (t == null)
            t = "void";
        ParamAPI paramAPI = new ParamAPI(name, t);
        if (isConstructor) {
            api_.currCtor_.params_.add(paramAPI);
        } else {
            api_.currMethod_.params_.add(paramAPI);
        }
    }

    /**
     * Add an exception to the current method or constructor.
     * Called by the XML parser.
     *
     * @param name The name of the parameter.
     * @param type The type of the parameter.
     *             May be null in JDiff1.0.8 and earlier versions.
     * @param currElement Name of the current element.
     */
    public static void addException(String name, String type, String currElement) {
	String exceptionId = type;
	if (type == null || !showExceptionTypes)
	    exceptionId = name;
        if (currElement.compareTo("method") == 0) {
            if (api_.currMethod_.exceptions_.compareTo("no exceptions") == 0)
                api_.currMethod_.exceptions_ = exceptionId;
            else
                api_.currMethod_.exceptions_ += ", " + exceptionId;
        } else {
            if (api_.currCtor_.exceptions_.compareTo("no exceptions") == 0)
                api_.currCtor_.exceptions_ = exceptionId;
            else
                api_.currCtor_.exceptions_ += ", " + exceptionId;
        }
    }

    /**
     * If set, validate the XML which represents an API. By default, this is
     * not set for reasons of efficiency, and also because if JDiff generated
     * the XML, it should not need validating.
     */
    public static boolean validateXML = false;

    /**
     * If set, then store and display the whole qualified name of exceptions.
     * If not set, then store and display just the name of the exception,
     * which is shorter, but may not detect when an exception changes class,
     * but retains the same name.
     */
    private static boolean showExceptionTypes = true;
}
