/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.axis2.schema.writer;

import org.apache.axis2.schema.BeanWriterMetaInfoHolder;
import org.apache.axis2.schema.CompilerOptions;
import org.apache.axis2.schema.SchemaCompilationException;
import org.apache.axis2.schema.SchemaConstants;
import org.apache.axis2.schema.i18n.SchemaCompilerMessages;
import org.apache.axis2.schema.typemap.JavaTypeMap;
import org.apache.axis2.schema.util.PrimitiveTypeFinder;
import org.apache.axis2.schema.util.PrimitiveTypeWrapper;
import org.apache.axis2.schema.util.SchemaPropertyLoader;
import org.apache.axis2.util.JavaUtils;
import org.apache.axis2.util.XSLTTemplateProcessor;
import org.apache.axis2.util.XSLTUtils;
//import com.ibm.wsdl.util.xml.DOM2Writer;
import org.apache.axis2.wsdl.databinding.CUtils;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaSimpleType;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.ibm.wsdl.util.xml.DOM2Writer;

/**
 * Java Bean writer for the schema compiler.
 */
public class CStructWriter implements BeanWriter {

    public static final String WRAPPED_DATABINDING_CLASS_NAME = "WrappedDatabinder";
    public static final String AXIS2_PREFIX = "adb_";
    private String javaBeanTemplateName = null;
    private boolean templateLoaded = false;
    private Templates sourceTemplateCache;
    private Templates headerTemplateCache;

    private List namesList;
    private static int count = 0;
    private boolean wrapClasses = false;
    private boolean writeClasses = false;

    protected File rootDir;

    private Document globalWrappedSourceDocument;
    private Document globalWrappedHeaderDocument;

    private Map modelMap = new HashMap();
    private static final String ADB_CLASS_PREFIX = "adb_";
    private static final String ADB_CLASS_POSTFIX = "_t*";
    private static final String DEFAULT_C_CLASS_NAME = "axiom_node_t*";

    private Map baseTypeMap = new JavaTypeMap().getTypeMap();

    // a list of externally identified QNames to be processed. This becomes
    // useful when  only a list of external elements need to be processed

    public static final String DEFAULT_CLASS_NAME = "axiom_node_t*";
    public static final String DEFAULT_CLASS_ARRAY_NAME = "axiom_node_t*";

    public static final String DEFAULT_ATTRIB_CLASS_NAME = "axiom_attribute_t*";
    public static final String DEFAULT_ATTRIB_ARRAY_CLASS_NAME = "axiom_attribute_t*";

    public static final String DEFAULT_TYPE_NS = "http://www.w3.org/2001/XMLSchema";


    /**
     * Default constructor
     */
    public CStructWriter() {
    }

    /**
     * This returns a map of Qnames vs DOMDocument models. One can use this method to
     * obtain the raw DOMmodels used to write the classes.
     * This has no meaning when the classes are supposed to be wrapped  so the
     *
     * @return Returns Map.
     * @see BeanWriter#getModelMap()
     */
    public Map getModelMap() {
        return modelMap;
    }

    public String getDefaultClassName() {
        return DEFAULT_CLASS_NAME;
    }

    public String getDefaultClassArrayName() {
        return DEFAULT_CLASS_ARRAY_NAME;
    }

    public String getDefaultAttribClassName() {
        return DEFAULT_ATTRIB_CLASS_NAME;
    }

    public String getDefaultAttribArrayClassName() {
        return DEFAULT_ATTRIB_ARRAY_CLASS_NAME;
    }
    public void init(CompilerOptions options) throws SchemaCompilationException {
        try {
            initWithFile(options.getOutputLocation());

            writeClasses = options.isWriteOutput();
            if (!writeClasses) {
                wrapClasses = false;
            } else {
                wrapClasses = options.isWrapClasses();
            }

            //if the wrap mode is set then create a global document to keep the wrapped
            //element models
            if (options.isWrapClasses()) {
                globalWrappedSourceDocument = XSLTUtils.getDocument();
                Element rootElement = XSLTUtils.getElement(globalWrappedSourceDocument, "beans");
                globalWrappedSourceDocument.appendChild(rootElement);
                XSLTUtils.addAttribute(globalWrappedSourceDocument, "name", CStructWriter.WRAPPED_DATABINDING_CLASS_NAME, rootElement);

                globalWrappedHeaderDocument = XSLTUtils.getDocument();
                rootElement = XSLTUtils.getElement(globalWrappedHeaderDocument, "beans");
                globalWrappedHeaderDocument.appendChild(rootElement);
                XSLTUtils.addAttribute(globalWrappedHeaderDocument, "name", CStructWriter.WRAPPED_DATABINDING_CLASS_NAME, rootElement);

            }


        } catch (IOException e) {
            throw new SchemaCompilationException(e);
        } catch (ParserConfigurationException e) {
            throw new SchemaCompilationException(e); //todo need to put correct error messages
        }
    }

    /**
     * @param element
     * @param typeMap
     * @param metainf
     * @return Returns String.
     * @throws org.apache.axis2.schema.SchemaCompilationException
     *
     */
    public String write(XmlSchemaElement element,
                        Map typeMap,
                        Map groupTypeMap,
                        BeanWriterMetaInfoHolder metainf) throws SchemaCompilationException {

        try {
            QName qName = element.getQName();

            return process(qName, metainf, typeMap, groupTypeMap, true, false);
        } catch (Exception e) {
            throw new SchemaCompilationException(e);
        }


    }

    /**
     * @param qName
     * @param typeMap
     * @param metainf
     * @param isAbstract
     * @throws org.apache.axis2.schema.SchemaCompilationException
     *
     * @see org.apache.axis2.schema.writer.BeanWriter
     */
    public String write(QName qName,
                        Map typeMap,
                        Map groupTypeMap,
                        BeanWriterMetaInfoHolder metainf,
                        boolean isAbstract)
            throws SchemaCompilationException {

        try {
            //determine the package for this type.
            return process(qName, metainf, typeMap, groupTypeMap, false, isAbstract);

        } catch (SchemaCompilationException e) {
            throw e;
        } catch (Exception e) {
            throw new SchemaCompilationException(e);
        }


    }

    /**
     * @throws SchemaCompilationException
     * @see org.apache.axis2.schema.writer.BeanWriter#writeBatch()
     */
    public void writeBatch() throws SchemaCompilationException {
        try {
            if (wrapClasses) {

                File outSource = createOutFile(CStructWriter.WRAPPED_DATABINDING_CLASS_NAME, ".c");
                File outHeader = createOutFile(CStructWriter.WRAPPED_DATABINDING_CLASS_NAME, ".h");
                //parse with the template and create the files
                parseSource(globalWrappedSourceDocument, outSource);
                parseHeader(globalWrappedHeaderDocument, outHeader);
            }
        } catch (Exception e) {
            throw new SchemaCompilationException(e);
        }
    }

    /**
     * @param simpleType
     * @param typeMap
     * @param metainf
     * @return Returns String.
     * @throws org.apache.axis2.schema.SchemaCompilationException
     *
     */
    public String write(XmlSchemaSimpleType simpleType,
                        Map typeMap,
                        Map groupTypeMap,
                        BeanWriterMetaInfoHolder metainf) throws SchemaCompilationException {
        try {
            //determine the package for this type.
            QName qName = simpleType.getQName();
            if (qName == null) {
                qName = (QName) simpleType.getMetaInfoMap().get(SchemaConstants.SchemaCompilerInfoHolder.FAKE_QNAME);
            }
            metainf.addtStatus(qName, SchemaConstants.SIMPLE_TYPE_OR_CONTENT);
            return process(qName, metainf, typeMap, groupTypeMap, true, false);

        } catch (SchemaCompilationException e) {
            throw e;
        } catch (Exception e) {
            throw new SchemaCompilationException(e);
        }
    }

    /**
     * @param rootDir
     * @throws java.io.IOException
     * @see org.apache.axis2.schema.writer.BeanWriter
     */
    private void initWithFile(File rootDir) throws IOException {
        if (rootDir == null) {
            this.rootDir = new File(".");
        } else if (!rootDir.isDirectory()) {
            throw new IOException(SchemaCompilerMessages.getMessage("schema.rootnotfolderexception"));
        } else {
            this.rootDir = rootDir;
        }

        namesList = new ArrayList();
        javaBeanTemplateName = SchemaPropertyLoader.getBeanTemplate();
    }


    /**
     * Make the fully qualified class name for an element or named type
     *
     * @param qName the qualified Name for this element or type in the schema
     * @return the appropriate fully qualified class name to use in generated code
     */
    public String makeFullyQualifiedClassName(QName qName) {

        String originalName = qName.getLocalPart();

        return makeUniqueCStructName(this.namesList, originalName);
    }

    /**
     * A util method that holds common code
     * for the complete schema that the generated XML complies to
     * look under other/beanGenerationSchema.xsd
     *
     * @param qName
     * @param metainf
     * @param typeMap
     * @param isElement
     * @return Returns String.
     * @throws Exception
     */
    private String process(QName qName,
                        BeanWriterMetaInfoHolder metainf,
                        Map typeMap,
                        Map groupTypeMap,
                        boolean isElement,
                        boolean isAbstract)
            throws Exception {
        String fullyQualifiedClassName = metainf.getOwnClassName();
        if (fullyQualifiedClassName == null)
            fullyQualifiedClassName = makeFullyQualifiedClassName(qName);
        String className = fullyQualifiedClassName;


        String originalName = qName == null? "" : qName.getLocalPart();
        ArrayList propertyNames = new ArrayList();

        if (!templateLoaded) {
            loadTemplate();
        }

        //if wrapped then do not write the classes now but add the models to a global document. However in order to write the
        //global class that is generated, one needs to call the writeBatch() method
        if (wrapClasses) {
            globalWrappedSourceDocument.getDocumentElement().appendChild(
                    getBeanElement(globalWrappedSourceDocument, className,
                        originalName, qName, isElement, isAbstract, 
                        metainf, propertyNames, typeMap, groupTypeMap));

            globalWrappedHeaderDocument.getDocumentElement().appendChild(
                    getBeanElement(globalWrappedHeaderDocument, className,
                        originalName, qName, isElement, isAbstract, 
                        metainf, propertyNames, typeMap, groupTypeMap));

        } else {
            //create the model
            Document modelSource = XSLTUtils.getDocument();
            Document modelHeader = XSLTUtils.getDocument();
            //make the XML
            modelSource.appendChild(getBeanElement(modelSource, className, originalName,
                    qName, isElement, isAbstract, metainf, propertyNames,
                    typeMap, groupTypeMap));
            modelHeader.appendChild(getBeanElement(modelHeader, className, originalName,
                    qName, isElement, isAbstract, metainf, propertyNames,
                    typeMap, groupTypeMap));

            if (writeClasses) {
                //create the file
                String fileName = className.substring(4, className.length() -3);
                File outSource = createOutFile(fileName, ".c");
                File outHeader = createOutFile(fileName, ".h");
                //parse with the template and create the files
                parseSource(modelSource, outSource);
                parseHeader(modelHeader, outHeader);
            }

            //add the model to the model map
            modelMap.put(
                    new QName(qName.getNamespaceURI(), className)
                    , modelSource);
            modelMap.put(
                    new QName(qName.getNamespaceURI(), className)
                    , modelHeader);

            /////////////////////////////////////////////////////
            // System.out.println(DOM2Writer.nodeToString(modelSource.getFirstChild()));
            /////////////////////////////////////////////////////

        }

        //return the fully qualified class name
        return fullyQualifiedClassName;

    }


    /**
     * @param model
     * @param className
     * @param originalName
     * @param qName
     * @param isElement
     * @param metainf
     * @param propertyNames
     * @param typeMap
     * @return Returns Element.
     * @throws org.apache.axis2.schema.SchemaCompilationException
     *
     */
    private Element getBeanElement(
            Document model,
            String className,
            String originalName,
            QName qName,
            boolean isElement,
            boolean isAbstract,
            BeanWriterMetaInfoHolder metainf,
            ArrayList propertyNames,
            Map typeMap,
            Map groupTypeMap)
     throws SchemaCompilationException {

        Element rootElt = XSLTUtils.getElement(model, "class");
        String strippedClassName = className.substring(4, className.length() -3);
        XSLTUtils.addAttribute(model, "name", strippedClassName, rootElt);
        XSLTUtils.addAttribute(model, "originalName", originalName, rootElt);
        XSLTUtils.addAttribute(model, "nsuri", qName.getNamespaceURI(), rootElt);
        XSLTUtils.addAttribute(model, "nsprefix", getPrefixForURI(qName.getNamespaceURI(), qName.getPrefix()), rootElt);

        /* use caps for macros */
        String capsName = strippedClassName.toUpperCase();
        XSLTUtils.addAttribute(model, "caps-name", capsName, rootElt);


        if (!wrapClasses) {
            XSLTUtils.addAttribute(model, "unwrapped", "yes", rootElt);
        }

        if (isAbstract) {
            XSLTUtils.addAttribute(model, "isAbstract", "yes", rootElt);
        }

        if (!writeClasses) {
            XSLTUtils.addAttribute(model, "skip-write", "yes", rootElt);
        }

        if (!isElement) {
            XSLTUtils.addAttribute(model, "type", "yes", rootElt);
        }

        if (metainf.isAnonymous()) {
            XSLTUtils.addAttribute(model, "anon", "yes", rootElt);
        }

        if (metainf.isExtension()) {
            XSLTUtils.addAttribute(model, "extension", metainf.getExtensionClassName(), rootElt);
        }

        if (metainf.isRestriction()) {
            XSLTUtils.addAttribute(model, "restriction", metainf
                    .getRestrictionClassName(), rootElt);
        }


        if (metainf.isChoice()) {
            XSLTUtils.addAttribute(model, "choice", "yes", rootElt);
        }

         if (metainf.isSimple()) {
            XSLTUtils.addAttribute(model, "simple", "yes", rootElt);
        }

        if (metainf.isUnion()) {
            XSLTUtils.addAttribute(model, "union", "yes", rootElt);
        }

        if (metainf.isList()) {
            XSLTUtils.addAttribute(model, "list", "yes", rootElt);
        }

        if (metainf.isOrdered()) {
            XSLTUtils.addAttribute(model, "ordered", "yes", rootElt);
        }

        if (isElement && metainf.isNillable(qName)) {
            XSLTUtils.addAttribute(model, "nillable", "yes", rootElt);
        }

        if (metainf.isParticleClass()) {
            XSLTUtils.addAttribute(model, "particleClass", "yes", rootElt);
        }

        if (metainf.isHasParticleType()){
            XSLTUtils.addAttribute(model, "hasParticleType", "yes", rootElt);
        }

        //populate all the information
        populateInfo(metainf, model, rootElt, propertyNames, typeMap, groupTypeMap, false);

        if (metainf.isSimple() && metainf.isUnion()) {
            populateMemberInfo(metainf, model, rootElt, typeMap);
        }

        if (metainf.isSimple() && metainf.isList()) {
            populateListInfo(metainf, model, rootElt, typeMap, groupTypeMap);
        }

        return rootElt;
    }

    protected void populateListInfo(BeanWriterMetaInfoHolder metainf,
                                    Document model,
                                    Element rootElement,
                                    Map typeMap,
                                    Map groupTypeMap) {

        String cName = makeUniqueCStructName(new ArrayList(), metainf.getItemTypeQName().getLocalPart());
        Element itemType = XSLTUtils.addChildElement(model, "itemtype", rootElement);
        XSLTUtils.addAttribute(model, "type", metainf.getItemTypeClassName(), itemType);
        XSLTUtils.addAttribute(model, "nsuri", metainf.getItemTypeQName().getNamespaceURI(), itemType);
        XSLTUtils.addAttribute(model, "originalName", metainf.getItemTypeQName().getLocalPart(), itemType);
        XSLTUtils.addAttribute(model, "cname", cName.substring(4, cName.length()-3), itemType);

        if (typeMap.containsKey(metainf.getItemTypeQName()) ||
                groupTypeMap.containsKey(metainf.getItemTypeClassName())) {
            XSLTUtils.addAttribute(model, "ours", "true", itemType);
        }
        if (PrimitiveTypeFinder.isPrimitive(metainf.getItemTypeClassName())) {
            XSLTUtils.addAttribute(model, "primitive", "yes", itemType);
        }

    }

    protected void populateMemberInfo(BeanWriterMetaInfoHolder metainf,
                                      Document model,
                                      Element rootElement,
                                      Map typeMap) {
        Map memberTypes = metainf.getMemberTypes();
        QName memberQName;
        for (Iterator iter = memberTypes.keySet().iterator(); iter.hasNext();) {
            memberQName = (QName) iter.next();
            String memberClass = (String) memberTypes.get(memberQName);
            if (PrimitiveTypeFinder.isPrimitive(memberClass)) {
                 memberClass = PrimitiveTypeWrapper.getWrapper(memberClass);
            }

        // add member type element
            Element memberType = XSLTUtils.addChildElement(model, "memberType", rootElement);
            XSLTUtils.addAttribute(model, "type", memberClass, memberType);
            XSLTUtils.addAttribute(model, "nsuri", memberQName.getNamespaceURI(), memberType);
            XSLTUtils.addAttribute(model, "originalName", memberQName.getLocalPart(), memberType);
            XSLTUtils.addAttribute(model, "caps-originalName", memberQName.getLocalPart().toUpperCase(), memberType);
            if (typeMap.containsKey(memberQName)) {
                XSLTUtils.addAttribute(model, "ours", "true", memberType);
            }

        }
    }

    /**
     * @param metainf
     * @param model
     * @param rootElt
     * @param propertyNames
     * @param typeMap
     * @throws org.apache.axis2.schema.SchemaCompilationException
     *
     */
    private void populateInfo(BeanWriterMetaInfoHolder metainf,
                              Document model,
                              Element rootElt,
                              ArrayList propertyNames,
                              Map typeMap,
                              Map groupTypeMap,
                              boolean isInherited) throws SchemaCompilationException {
        if (metainf.getParent() != null && (!metainf.isRestriction() || (metainf.isRestriction() && metainf.isSimple())))
        {
            populateInfo(metainf.getParent(), model, rootElt, propertyNames,
                    typeMap, groupTypeMap, true);
        }
        addPropertyEntries(metainf, model, rootElt, propertyNames, typeMap, groupTypeMap, isInherited);

    }

    /**
     * @param metainf
     * @param model
     * @param rootElt
     * @param propertyNames
     * @param typeMap
     * @throws org.apache.axis2.schema.SchemaCompilationException
-     *
     */
    private void addPropertyEntries(BeanWriterMetaInfoHolder metainf,
                                    Document model, Element rootElt,
                                    ArrayList propertyNames,
                                    Map typeMap,
                                    Map groupTypeMap,
                                    boolean isInherited) throws SchemaCompilationException {
        // go in the loop and add the part elements
        QName[] qName;
        ArrayList missingQNames = new ArrayList();
        ArrayList qNames = new ArrayList();
        BeanWriterMetaInfoHolder parentMetaInf = metainf.getParent();

        if (metainf.isOrdered()) {
            qName = metainf.getOrderedQNameArray();
        } else {
            qName = metainf.getQNameArray();
        }

        for (int i = 0; i < qName.length; i++) {
            qNames.add(qName[i]);
        }
        //adding missing QNames to the end, including elements & attributes.
        // for the simple types we have already add the parent elements
        // it is almost consider as an extension
        if (metainf.isRestriction() && !metainf.isSimple()) {
            addMissingQNames(metainf, qNames, missingQNames);
        }

        QName name;
        for (int i = 0; i < qName.length; i++) {
            Element property = XSLTUtils.addChildElement(model, "property", rootElt);
            name = qName[i];
            String xmlName = makeUniqueCStructName(new ArrayList(), name.getLocalPart());

            XSLTUtils.addAttribute(model, "name", name.getLocalPart(), property);
            XSLTUtils.addAttribute(model, "originalName", name.getLocalPart(), property);


            XSLTUtils.addAttribute(model, "nsuri", name.getNamespaceURI(), property);
            XSLTUtils.addAttribute(model, "prefix", name.getPrefix(), property);

            XSLTUtils.addAttribute(model, "cname", xmlName.substring(4, xmlName.length() -3), property);


            String CClassNameForElement = metainf.getClassNameForQName(name);

            if (CClassNameForElement == null) {
                CClassNameForElement = CStructWriter.DEFAULT_C_CLASS_NAME;
            }
            CClassNameForElement = getShortTypeName(CClassNameForElement);


            XSLTUtils.addAttribute(model, "type", CClassNameForElement, property);

            /**
             * Caps for use in C macros
             */
            XSLTUtils.addAttribute(model, "caps-cname", xmlName.substring(4, xmlName.length() -3 ).toUpperCase(), property);
            XSLTUtils.addAttribute(model, "caps-type", CClassNameForElement.toUpperCase(), property);

            if (PrimitiveTypeFinder.isPrimitive(CClassNameForElement)) {
                XSLTUtils.addAttribute(model, "primitive", "yes", property);
            }
            //add an attribute that says the type is default
            if (isDefault(CClassNameForElement)) {
                XSLTUtils.addAttribute(model, "default", "yes", property);
            }

             // add the default value
            if (metainf.isDefaultValueAvailable(name)){
                QName schemaQName = metainf.getSchemaQNameForQName(name);
                if (baseTypeMap.containsKey(schemaQName)){
                    XSLTUtils.addAttribute(model, "defaultValue",
                            metainf.getDefaultValueForQName(name), property);
                }
            }

            if (typeMap.containsKey(metainf.getSchemaQNameForQName(name)) ||
                    (metainf.getSchemaQNameForQName(name) == null ||
                    !metainf.getSchemaQNameForQName(name).getNamespaceURI().equals(DEFAULT_TYPE_NS))
                     && !CClassNameForElement.equals(DEFAULT_C_CLASS_NAME)
                     && !CClassNameForElement.equals(DEFAULT_ATTRIB_CLASS_NAME)) {
                XSLTUtils.addAttribute(model, "ours", "yes", property);

            }

            if (metainf.getAttributeStatusForQName(name)) {
                XSLTUtils.addAttribute(model, "attribute", "yes", property);
            }else{
                XSLTUtils.addAttribute(model, "notattribute", "yes", property);
            }

            if (metainf.isNillable(name)) {
                XSLTUtils.addAttribute(model, "nillable", "yes", property);
            }

            String shortTypeName;
            if (metainf.getSchemaQNameForQName(name) != null) {
                //see whether the QName is a basetype
                if (baseTypeMap.containsKey(metainf.getSchemaQNameForQName(name))) {
                    shortTypeName = metainf.getSchemaQNameForQName(name).getLocalPart();
                } else {
                    shortTypeName = getShortTypeName(CClassNameForElement);
                }
            } else {
                shortTypeName = getShortTypeName(CClassNameForElement);
            }
            XSLTUtils.addAttribute(model, "shorttypename", shortTypeName, property);

            if (isInherited) {
                XSLTUtils.addAttribute(model, "inherited", "yes", property);
            }

            if (metainf.getAnyStatusForQName(name)) {
                XSLTUtils.addAttribute(model, "any", "yes", property);
            }

            if (metainf.getBinaryStatusForQName(name)) {
                XSLTUtils.addAttribute(model, "binary", "yes", property);
            }

            if (metainf.getSimpleStatusForQName(name)) {
                XSLTUtils.addAttribute(model, "simple", "yes", property);
            }

            //put the min occurs count irrespective of whether it's an array or not
            long minOccurs = metainf.getMinOccurs(name);
            XSLTUtils.addAttribute(model, "minOccurs", minOccurs + "", property);


            if (metainf.getArrayStatusForQName(name)) {
                String attrName = name.getLocalPart();
                int arrayTokenStart = attrName.indexOf("Array");
                if (arrayTokenStart >= 0) {
                    String arrayEle = attrName.substring(0, arrayTokenStart);
                    XSLTUtils.addAttribute(model, "arrayele", arrayEle, property);
                }
                XSLTUtils.addAttribute(model, "isarray", "yes", property);
                XSLTUtils.addAttribute(
                        model,
                        "arrayBaseType",
                        CClassNameForElement,
                        property);

                long maxOccurs = metainf.getMaxOccurs(name);
                if (maxOccurs == Long.MAX_VALUE) {
                    XSLTUtils.addAttribute(model, "unbound", "yes", property);
                }
                XSLTUtils.addAttribute(model, "maxOccurs", maxOccurs + "", property);

            }

            if ((parentMetaInf != null) && metainf.isRestriction() && missingQNames.contains(name)) {
                // this element details should be there with the parent meta Inf
                addAttributesToProperty(
                        parentMetaInf,
                        name,
                        model,
                        property,
                        typeMap,
                        groupTypeMap,
                        CClassNameForElement);

            } else {
                addAttributesToProperty(
                        metainf,
                        name,
                        model,
                        property,
                        typeMap,
                        groupTypeMap,
                        CClassNameForElement);
            }
        }
    }

    private void addAttributesToProperty(BeanWriterMetaInfoHolder metainf,
                                             QName name,
                                             Document model,
                                             Element property,
                                             Map typeMap,
                                             Map groupTypeMap,
                                             String CClassNameForElement) {
            // add an attribute that says the type is default
            if (metainf.getDefaultStatusForQName(name)) {
                XSLTUtils.addAttribute(model, "default", "yes", property);
            }

            if (typeMap.containsKey(metainf.getSchemaQNameForQName(name)) ||
                    groupTypeMap.containsKey(metainf.getSchemaQNameForQName(name)) ||
                    (metainf.getSchemaQNameForQName(name) == null ||
                    !metainf.getSchemaQNameForQName(name).getNamespaceURI().equals(DEFAULT_TYPE_NS))
                     && !CClassNameForElement.equals(DEFAULT_C_CLASS_NAME)
                     && !CClassNameForElement.equals(DEFAULT_ATTRIB_CLASS_NAME)) {
                XSLTUtils.addAttribute(model, "ours", "yes", property);
            }

            if (metainf.getAttributeStatusForQName(name)) {
                XSLTUtils.addAttribute(model, "attribute", "yes", property);
            }

            if (metainf.isNillable(name)) {
                XSLTUtils.addAttribute(model, "nillable", "yes", property);
            }

            if (metainf.getOptionalAttributeStatusForQName(name)) {
                XSLTUtils.addAttribute(model, "optional", "yes", property);
            }

            String shortTypeName;
            if (metainf.getSchemaQNameForQName(name) != null) {
                // see whether the QName is a basetype
                if (baseTypeMap.containsKey(metainf.getSchemaQNameForQName(name))) {
                    shortTypeName = metainf.getSchemaQNameForQName(name).getLocalPart();
                } else {
                    shortTypeName = getShortTypeName(CClassNameForElement);
                }
            } else {
                shortTypeName = getShortTypeName(CClassNameForElement);
            }
            XSLTUtils.addAttribute(model, "shorttypename", shortTypeName, property);


            if (metainf.getAnyStatusForQName(name)) {
                XSLTUtils.addAttribute(model, "any", "yes", property);
            }

            if (metainf.getBinaryStatusForQName(name)) {
                XSLTUtils.addAttribute(model, "binary", "yes", property);
            }

            if (metainf.isSimple() || metainf.getSimpleStatusForQName(name)) {
                XSLTUtils.addAttribute(model, "simple", "yes", property);
            }

            // put the min occurs count irrespective of whether it's an array or
            // not
            long minOccurs = metainf.getMinOccurs(name);
            XSLTUtils.addAttribute(model, "minOccurs", minOccurs + "", property);


            if (metainf.getArrayStatusForQName(name)) {

                XSLTUtils.addAttribute(model, "array", "yes", property);

                int endIndex = CClassNameForElement.indexOf("[");
                if (endIndex >= 0) {
                    XSLTUtils.addAttribute(model, "arrayBaseType",
                            CClassNameForElement.substring(0, endIndex), property);
                } else {
                    XSLTUtils.addAttribute(model, "arrayBaseType",
                            CClassNameForElement, property);
                }

                long maxOccurs = metainf.getMaxOccurs(name);
                if (maxOccurs == Long.MAX_VALUE) {
                    XSLTUtils.addAttribute(model, "unbound", "yes", property);
                } else {
                    XSLTUtils.addAttribute(model, "maxOccurs", maxOccurs + "", property);
                }
            }
            if (metainf.isRestrictionBaseType(name)) {
                XSLTUtils.addAttribute(model, "restrictionBaseType", "yes", property);
            }

            if (metainf.isExtensionBaseType(name)) {
                XSLTUtils.addAttribute(model, "extensionBaseType", "yes", property);
            }

            if (metainf.isRestrictionBaseType(name) && metainf.getLengthFacet() != -1) {
                XSLTUtils.addAttribute(model, "lenFacet", metainf.getLengthFacet() + "", property);
            }

            if (metainf.isRestrictionBaseType(name) && metainf.getMaxLengthFacet() != -1) {
                XSLTUtils.addAttribute(model, "maxLenFacet", metainf.getMaxLengthFacet() + "", property);
            }

            if (metainf.isRestrictionBaseType(name) && metainf.getMinLengthFacet() != -1) {
                XSLTUtils.addAttribute(model, "minLenFacet", metainf.getMinLengthFacet() + "", property);
            }

            if (metainf.isRestrictionBaseType(name) && metainf.getMaxExclusiveFacet() != null) {
                XSLTUtils.addAttribute(model, "maxExFacet", metainf.getMaxExclusiveFacet() + "", property);
            }

            if (metainf.isRestrictionBaseType(name) && metainf.getMinExclusiveFacet() != null) {
                XSLTUtils.addAttribute(model, "minExFacet", metainf.getMinExclusiveFacet() + "", property);
            }

            if (metainf.isRestrictionBaseType(name) && metainf.getMaxInclusiveFacet() != null) {
                XSLTUtils.addAttribute(model, "maxInFacet", metainf.getMaxInclusiveFacet() + "", property);
            }

            if (metainf.isRestrictionBaseType(name) && metainf.getMinInclusiveFacet() != null) {
                XSLTUtils.addAttribute(model, "minInFacet", metainf.getMinInclusiveFacet() + "", property);
            }

            if (!metainf.getEnumFacet().isEmpty()) {
                boolean validJava = true;    // Assume all enum values are valid ids

                Iterator iterator = metainf.getEnumFacet().iterator();
                // Walk the values looking for invalid ids
                while (iterator.hasNext()) {
                    String value = (String) iterator.next();
                    if (!JavaUtils.isJavaId(value)) {
                        validJava = false;
                    }
                }

                int id = 0;
                iterator = metainf.getEnumFacet().iterator();
                while (iterator.hasNext()) {
                    Element enumFacet = XSLTUtils.addChildElement(model, "enumFacet", property);
                    String attribValue = (String) iterator.next();
                    XSLTUtils.addAttribute(model, "value", attribValue, enumFacet);
                    if (validJava) {
                        XSLTUtils.addAttribute(model, "id", attribValue.toUpperCase(), enumFacet);
                    } else {
                        id++;
                        // Replace all invalid characters and append an id to avoid collisions
                        XSLTUtils.addAttribute(model, "id", 
                                attribValue.toUpperCase().replaceAll("[^A-Z0-9]", "_") + "_" + id, enumFacet);
                    }
                }
            }

            if (metainf.isRestrictionBaseType(name) && metainf.getPatternFacet() != null) {
                XSLTUtils.addAttribute(model, "patternFacet", metainf.getPatternFacet(), property);
            }
        }



    private void addMissingQNames(BeanWriterMetaInfoHolder metainf, ArrayList qName, ArrayList missingQNames) {

        QName[] qNames = null;
        QName[] pQNames = null;

        BeanWriterMetaInfoHolder parentMetaInf = metainf.getParent();

        if (metainf.isOrdered()) {
            qNames = metainf.getOrderedQNameArray();
        } else {
            qNames = metainf.getQNameArray();
        }

        if (parentMetaInf != null) {
            if (parentMetaInf.isOrdered()) {
                pQNames = parentMetaInf.getOrderedQNameArray();
            } else {
                pQNames = parentMetaInf.getQNameArray();
            }
        }


        for (int i = 0; pQNames != null && i < pQNames.length; i++) {
            if (qNameNotFound(pQNames[i], metainf)) {
                missingQNames.add(pQNames[i]);
            }
        }
        //adding missing QNames to the end of list.
        if (!missingQNames.isEmpty()) {
            for (int i = 0; i < missingQNames.size(); i++) {
                qName.add(missingQNames.get(i));
            }
        }

    }

    private boolean qNameNotFound(QName qname, BeanWriterMetaInfoHolder metainf) {

        boolean found = false;
        QName[] qNames;

        if (metainf.isOrdered()) {
            qNames = metainf.getOrderedQNameArray();
        } else {
            qNames = metainf.getQNameArray();
        }

        for (int j = 0; j < qNames.length; j++) {
            if (qname.getLocalPart().equals(qNames[j].getLocalPart())) {
                found = true;
            }
        }
        return !found;
    }

    /**
     * Test whether the given class name matches the default
     *
     * @param CClassNameForElement
     * @return bool
     */
    private boolean isDefault(String CClassNameForElement) {
        return getDefaultClassName().equals(CClassNameForElement) ||
                getDefaultClassArrayName().equals(CClassNameForElement);
    }


    /**
     * Given the xml name, make a unique class name taking into account that some
     * file systems are case sensitive and some are not.
     * -Consider the Jax-WS spec for this
     *
     * @param listOfNames
     * @param xmlName
     * @return Returns String.
     */
    private String makeUniqueCStructName(List listOfNames, String xmlName) {
        String cName;
        if (CUtils.isCKeyword(xmlName)) {
            cName = CUtils.makeNonCKeyword(xmlName);
        } else {
            //javaName = JavaUtils.capitalizeFirstChar(JavaUtils.xmlNameToJava(xmlName));
            cName = xmlName;
        }

        cName = cName.replace('.','_');
        cName = cName.replace('-','_');

        while (listOfNames.contains(cName.toLowerCase())) {
            if (!listOfNames.contains((cName + "E").toLowerCase())){
                cName = cName + "E";
            } else {
                cName = cName + count++;
            }
            cName = cName + CStructWriter.count++;
        }

        listOfNames.add(cName.toLowerCase());

        String modifiedCName = ADB_CLASS_PREFIX  + cName + ADB_CLASS_POSTFIX;
        return modifiedCName;
    }


    /**
     * A bit of code from the old code generator. We are better off using the template
     * engines and such stuff that's already there. But the class writers are hard to be
     * reused so some code needs to be repeated (atleast a bit)
     */
    private void loadTemplate() throws SchemaCompilationException {

        //first get the language specific property map
        Class clazz = this.getClass();
        InputStream xslStream;
        String templateName = javaBeanTemplateName;
        if (templateName != null) {
            try {
                String sourceTemplateName = templateName + "Source.xsl";
                xslStream = clazz.getResourceAsStream(sourceTemplateName);
                sourceTemplateCache = TransformerFactory.newInstance().newTemplates(new StreamSource(xslStream));

                String headerTemplateName = templateName + "Header.xsl";
                xslStream = clazz.getResourceAsStream(headerTemplateName);
                headerTemplateCache = TransformerFactory.newInstance().newTemplates(new StreamSource(xslStream));

                templateLoaded = true;
            } catch (TransformerConfigurationException e) {
                throw new SchemaCompilationException(SchemaCompilerMessages.getMessage("schema.templateLoadException"), e);
            }
        } else {
            throw new SchemaCompilationException(SchemaCompilerMessages.getMessage("schema.templateNotFoundException"));
        }
    }


    /**
     * Creates the output file
     *
     * @param fileName
     * @param extension
     * @throws Exception
     */
    protected File createOutFile(String fileName, String extension) throws Exception {
        return org.apache.axis2.util.FileWriter.createClassFile(this.rootDir,
                "",
                AXIS2_PREFIX + fileName,
                extension);
    }

    /**
     * Writes the output file
     *
     * @param doc
     * @param outputFile
     * @throws Exception
     */
    private void parseSource(Document doc, File outputFile) throws Exception {
        OutputStream outStream = new FileOutputStream(outputFile);
        XSLTTemplateProcessor.parse(outStream,
                doc,
                this.sourceTemplateCache.newTransformer());
        outStream.write('\n');
        outStream.write('\n');
        outStream.flush();
        outStream.close();

    }

    /**
     * Writes the output file
     *
     * @param doc
     * @param outputFile
     * @throws Exception
     */
    private void parseHeader(Document doc, File outputFile) throws Exception {
        OutputStream outStream = new FileOutputStream(outputFile);
        XSLTTemplateProcessor.parse(outStream,
                doc,
                this.headerTemplateCache.newTransformer());
        outStream.write('\n');
        outStream.write('\n');
        outStream.flush();
        outStream.close();

    }

    /**
     * Get a prefix for a namespace URI.  This method will ALWAYS
     * return a valid prefix - if the given URI is already mapped in this
     * serialization, we return the previous prefix.  If it is not mapped,
     * we will add a new mapping and return a generated prefix of the form
     * "ns<num>".
     *
     * @param uri is the namespace uri
     * @return Returns prefix.
     */
    public String getPrefixForURI(String uri) {
        return getPrefixForURI(uri, null);
    }

    /**
     * Last used index suffix for "ns"
     */
    private int lastPrefixIndex = 1;

    /**
     * Map of namespaces URI to prefix(es)
     */
    HashMap mapURItoPrefix = new HashMap();
    HashMap mapPrefixtoURI = new HashMap();

    /**
     * Get a prefix for the given namespace URI.  If one has already been
     * defined in this serialization, use that.  Otherwise, map the passed
     * default prefix to the URI, and return that.  If a null default prefix
     * is passed, use one of the form "ns<num>"
     */
    public String getPrefixForURI(String uri, String defaultPrefix) {
        if ((uri == null) || (uri.length() == 0))
            return null;
        String prefix = (String) mapURItoPrefix.get(uri);
        if (prefix == null) {
            if (defaultPrefix == null || defaultPrefix.length() == 0) {
                prefix = "ns" + lastPrefixIndex++;
                while (mapPrefixtoURI.get(prefix) != null) {
                    prefix = "ns" + lastPrefixIndex++;
                }
            } else {
                prefix = defaultPrefix;
            }
            mapPrefixtoURI.put(prefix, uri);
            mapURItoPrefix.put(uri, prefix);
        }
        return prefix;
    }

    private String getShortTypeName(String typeClassName) {
        if (typeClassName.endsWith("[]")) {
            typeClassName = typeClassName.substring(0, typeClassName.lastIndexOf("["));
        }
        return typeClassName;

    }

    /**
     * Keep unimplemented
     *
     * @param mapperPackageName
     * @see BeanWriter#registerExtensionMapperPackageName(String)
     */
    public void registerExtensionMapperPackageName(String mapperPackageName) {
        //unimplemented
    }

    /**
     * Keep unimplemented
     *
     * @param metainfArray
     * @see BeanWriter#writeExtensionMapper(org.apache.axis2.schema.BeanWriterMetaInfoHolder[])
     */
    public void writeExtensionMapper(BeanWriterMetaInfoHolder[] metainfArray) throws SchemaCompilationException {
        //unimplemented
    }

    /**
     * Keep unimplemented
     *
     * @see BeanWriter#getExtensionMapperPackageName()
     */
    public String getExtensionMapperPackageName() {
        return null;
    }
}
