Package org.apache.axis2.schema

Source Code of org.apache.axis2.schema.ExtensionUtility

package org.apache.axis2.schema;

import org.apache.axis2.description.AxisMessage;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.axis2.wsdl.WSDLUtil;
import org.apache.axis2.wsdl.codegen.CodeGenConfiguration;
import org.apache.axis2.wsdl.databinding.DefaultTypeMapper;
import org.apache.axis2.wsdl.databinding.JavaTypeMapper;
import org.apache.axis2.wsdl.databinding.TypeMapper;
import org.apache.axis2.wsdl.util.Constants;
import org.apache.ws.commons.schema.*;

import javax.xml.namespace.QName;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/*
* Copyright 2004,2005 The Apache Software Foundation.
*
* Licensed 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.
*/

/**
* This is the utility for the extension to call by reflection.
*/
public class ExtensionUtility {


    public static void invoke(CodeGenConfiguration configuration) throws Exception {
        List schemaList = configuration.getAxisService().getSchema();

        //hashmap that keeps the targetnamespace and the xmlSchema object
        //this is a convenience to locate the relevant schema quickly
        //by looking at the target namespace
        Map schemaMap = new HashMap();
        populateSchemaMap(schemaMap, schemaList);

        if (schemaList == null || schemaList.isEmpty()) {
            //there are no types to be code generated
            //However if the type mapper is left empty it will be a problem for the other
            //processes. Hence the default type mapper is set to the configuration
            configuration.setTypeMapper(new DefaultTypeMapper());
            return;
        }
        //call the schema compiler
        CompilerOptions options = new CompilerOptions();

        //set the default options
        populateDefaultOptions(options, configuration);

        //set the user parameters. the user parameters get the preference over
        //the default ones. But the user better know what he's doing if he
        //used module specific parameters
        populateUserparameters(options, configuration);

        SchemaCompiler schemaCompiler = new SchemaCompiler(options);
        // run the schema compiler
        schemaCompiler.compile(schemaList);

        //create the type mapper
        //First try to take the one that is already there
        TypeMapper mapper = configuration.getTypeMapper();
        if (mapper == null) {
            mapper = new JavaTypeMapper();
        }

        if (options.isWriteOutput()) {
            //get the processed element map and transfer it to the type mapper
            Map processedMap = schemaCompiler.getProcessedElementMap();
            Iterator processedkeys = processedMap.keySet().iterator();
            QName qNameKey;
            while (processedkeys.hasNext()) {
                qNameKey = (QName) processedkeys.next();
                mapper.addTypeMappingName(qNameKey, processedMap.get(qNameKey).toString());
            }

        } else {
            //get the processed model map and transfer it to the type mapper
            //since the options mentiond that its not writable, it should have
            //populated the model map
            Map processedModelMap = schemaCompiler.getProcessedModelMap();
            Iterator processedkeys = processedModelMap.keySet().iterator();
            QName qNameKey;
            while (processedkeys.hasNext()) {
                qNameKey = (QName) processedkeys.next();
                mapper.addTypeMappingObject(qNameKey, processedModelMap.get(qNameKey));
            }

            Map processedMap = schemaCompiler.getProcessedElementMap();
            processedkeys = processedMap.keySet().iterator();
            while (processedkeys.hasNext()) {
                qNameKey = (QName) processedkeys.next();
                mapper.addTypeMappingName(qNameKey, processedMap.get(qNameKey).toString());
            }

            //get the ADB template from the schema compilers property bag and set the
            //template
            configuration.putProperty(Constants.EXTERNAL_TEMPLATE_PROPERTY_KEY,
                    schemaCompiler.getCompilerProperties().getProperty(
                            SchemaConstants.SchemaPropertyNames.BEAN_WRITER_TEMPLATE_KEY));

        }

        //process the unwrapped parameters
        if (!configuration.isParametersWrapped()) {
            //figure out the unwrapped operations
            AxisService axisService = configuration.getAxisService();

            for (Iterator operations = axisService.getOperations();
                 operations.hasNext();) {
                AxisOperation op = (AxisOperation) operations.next();
                if (WSDLUtil.isInputPresentForMEP(op.getMessageExchangePattern())) {
                    walkSchema(op.getMessage(
                            WSDLConstants.MESSAGE_LABEL_IN_VALUE),
                            mapper,
                            schemaMap,
                            op.getName().getLocalPart());
                }


            }
        }

        //set the type mapper to the config
        configuration.setTypeMapper(mapper);

    }

    /**
     * Populate the schema objects into the
     *
     * @param schemaMap
     * @param schemaList
     */
    private static void populateSchemaMap(Map schemaMap, List schemaList) {
        for (int i = 0; i < schemaList.size(); i++) {
            XmlSchema xmlSchema = (XmlSchema) schemaList.get(i);
            schemaMap.put(xmlSchema.getTargetNamespace(), xmlSchema);
        }
    }

    /**
     * @param message
     * @param mapper
     */
    private static void walkSchema(AxisMessage message,
                                   TypeMapper mapper,
                                   Map schemaMap,
                                   String opName) {

        if (message.getParameter(Constants.UNWRAPPED_KEY) != null) {
            XmlSchemaType schemaType = message.getSchemaElement().getSchemaType();
            //create a type mapper
            processXMLSchemaComplexType(schemaType, mapper, opName, schemaMap);
        }
    }

    private static void processXMLSchemaComplexType(XmlSchemaType schemaType, TypeMapper mapper, String opName, Map schemaMap) {
        if (schemaType instanceof XmlSchemaComplexType) {
            XmlSchemaComplexType cmplxType = (XmlSchemaComplexType) schemaType;
            if (cmplxType.getContentModel() == null) {
                processSchemaSequence(cmplxType.getParticle(), mapper, opName, schemaMap);
            } else {
                processComplexContentModel(cmplxType, mapper, opName, schemaMap);
            }
        }
    }

    private static void processComplexContentModel(XmlSchemaComplexType cmplxType, TypeMapper mapper, String opName, Map schemaMap) {
        XmlSchemaContentModel contentModel = cmplxType.getContentModel();
        if (contentModel instanceof XmlSchemaComplexContent) {
            XmlSchemaComplexContent xmlSchemaComplexContent = (XmlSchemaComplexContent) contentModel;
            XmlSchemaContent content = xmlSchemaComplexContent.getContent();
            if (content instanceof XmlSchemaComplexContentExtension) {
                XmlSchemaComplexContentExtension schemaExtension = (XmlSchemaComplexContentExtension) content;

                // process particles inside this extension, if any
                processSchemaSequence(schemaExtension.getParticle(), mapper, opName, schemaMap);

                // now we need to get the schema of the extension type from the parent schema. For that let's first retrieve
                // the parent schema
                XmlSchema parentSchema = (XmlSchema) schemaMap.get(schemaExtension.getBaseTypeName().getNamespaceURI());

                // ok now we got the parent schema. Now let's get the extension's schema type

                XmlSchemaType extensionSchemaType = parentSchema.getTypeByName(schemaExtension.getBaseTypeName());

                processXMLSchemaComplexType(extensionSchemaType, mapper, opName, schemaMap);
            }
        }
    }

    private static void processSchemaSequence(XmlSchemaParticle particle, TypeMapper mapper, String opName, Map schemaMap) {
        if (particle instanceof XmlSchemaSequence) {
            XmlSchemaObjectCollection items =
                    ((XmlSchemaSequence) particle).getItems();
            for (Iterator i = items.getIterator(); i.hasNext();) {
                Object item = i.next();
                // get each and every element in the sequence and
                // traverse through them
                if (item instanceof XmlSchemaElement) {
                    //populate the map with the partname - class name
                    //attached to the schema element
                    XmlSchemaElement xmlSchemaElement = (XmlSchemaElement) item;
                    XmlSchemaType eltSchemaType = xmlSchemaElement.getSchemaType();
                    if (eltSchemaType != null) {
                        //there is a schema type object.We can utilize that
                        populateClassName(eltSchemaType, mapper, opName, xmlSchemaElement);
                    } else if (xmlSchemaElement.getSchemaTypeName() != null) {
                        //there is no schema type object but there is a
                        //schema type QName.  Use that Qname to look up the
                        //schematype in other schema objects
                        eltSchemaType = findSchemaType(schemaMap,
                                xmlSchemaElement.getSchemaTypeName());
                        if (eltSchemaType != null) {
                            populateClassName(eltSchemaType, mapper, opName, xmlSchemaElement);
                        } else if (xmlSchemaElement.getSchemaTypeName().equals(SchemaConstants.XSD_ANYTYPE)) {
                            QName partQName = WSDLUtil.getPartQName(opName,
                                    WSDLConstants.INPUT_PART_QNAME_SUFFIX,
                                    xmlSchemaElement.getName());

                            if (xmlSchemaElement.getMaxOccurs() > 1) {
                                mapper.addTypeMappingName(partQName, "org.apache.axiom.om.OMElement[]");
                            } else {
                                mapper.addTypeMappingName(partQName, "org.apache.axiom.om.OMElement");
                            }
                        }
                    }
                } else if (item instanceof XmlSchemaAny) {

                    // if this is an instance of xs:any, then there is no part name for it. Using ANY_ELEMENT_FIELD_NAME
                    // for it for now

                    //we have to handle both maxoccurs 1 and maxoccurs > 1 situation
                    XmlSchemaAny xmlSchemaAny = (XmlSchemaAny) item;

                    QName partQName = WSDLUtil.getPartQName(opName,
                            WSDLConstants.INPUT_PART_QNAME_SUFFIX,
                            Constants.ANY_ELEMENT_FIELD_NAME);

                    if (((XmlSchemaAny) item).getMaxOccurs() > 1) {
                        mapper.addTypeMappingName(partQName, "org.apache.axiom.om.OMElement[]");
                    } else {
                        mapper.addTypeMappingName(partQName, "org.apache.axiom.om.OMElement");
                    }

                }

            }

        }
    }

    // private static void

    /**
     * Util method to populate the class name into the typeMap
     *
     * @param eltSchemaType
     */
    private static void populateClassName(XmlSchemaType eltSchemaType,
                                          TypeMapper typeMap,
                                          String opName,
                                          XmlSchemaElement xmlSchemaElement) {

        boolean isArray = xmlSchemaElement.getMaxOccurs() > 1;

        Map metaInfoMap = eltSchemaType.getMetaInfoMap();

        if (metaInfoMap != null) {
            String className = (String) metaInfoMap.
                    get(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY);

            // this is a temporary patch
            // the acual problem is keeping the class name details on the schemaType in
            // XmlSchema compiler.
            // we have to store them in XmlElement
            if (isArray && !className.endsWith("[]")) {
                className += "[]";
            } else if (!isArray && className.endsWith("[]")) {
                className = className.substring(0, className.length() - 2);
            }


            QName partQName = WSDLUtil.getPartQName(opName,
                    WSDLConstants.INPUT_PART_QNAME_SUFFIX,
                    xmlSchemaElement.getName());
            typeMap.addTypeMappingName(partQName, className);
            if (Boolean.TRUE.equals(
                    metaInfoMap.get(SchemaConstants.
                            SchemaCompilerInfoHolder.CLASSNAME_PRIMITVE_KEY))) {

                //this type is primitive - add that to the type mapper status
                //for now lets add a boolean
                typeMap.addTypeMappingStatus(partQName, Boolean.TRUE);
            }
        }
    }


    /**
     * Look for a given schema type given the schema type Qname
     *
     * @param schemaMap
     * @return null if the schema is not found
     */
    private static XmlSchemaType findSchemaType(Map schemaMap, QName schemaTypeName) {
        //find the schema
        XmlSchema schema = (XmlSchema) schemaMap.get(schemaTypeName.getNamespaceURI());
        if (schema != null) {
            return schema.getTypeByName(schemaTypeName);
        }
        return null;
    }

    /**
     * populate parameters from the user
     *
     * @param options
     */
    private static void populateUserparameters(CompilerOptions options, CodeGenConfiguration configuration) {
        Map propertyMap = configuration.getProperties();
        if (propertyMap.containsKey(SchemaConstants.SchemaCompilerArguments.WRAP_SCHEMA_CLASSES)) {
            if (Boolean.valueOf(
                    propertyMap.get(SchemaConstants.SchemaCompilerArguments.WRAP_SCHEMA_CLASSES).toString()).
                    booleanValue()) {
                options.setWrapClasses(true);
            } else {
                options.setWrapClasses(false);
            }
        }

        if (propertyMap.containsKey(SchemaConstants.SchemaCompilerArguments.WRITE_SCHEMA_CLASSES)) {
            if (Boolean.valueOf(
                    propertyMap.get(SchemaConstants.SchemaCompilerArguments.WRITE_SCHEMA_CLASSES).toString()).
                    booleanValue()) {
                options.setWriteOutput(true);
            } else {
                options.setWriteOutput(false);
            }
        }

        // add the custom package name
        if (propertyMap.containsKey(SchemaConstants.SchemaCompilerArguments.PACKAGE)) {
            String packageName = (String) propertyMap.get(SchemaConstants.SchemaCompilerArguments.PACKAGE);
            if (packageName != null || !"".equals(packageName)) {
                options.setPackageName(packageName);
            }

        }

        // set the package namespace to uri details
        options.setNs2PackageMap(configuration.getUri2PackageNameMap());

        //add custom mapper package name
        if (propertyMap.containsKey(SchemaConstants.SchemaCompilerArguments.MAPPER_PACKAGE)) {
            String packageName = (String) propertyMap.get(SchemaConstants.SchemaCompilerArguments.MAPPER_PACKAGE);
            if (packageName != null || !"".equals(packageName)) {
                options.setMapperClassPackage(packageName);
            }

        }

        //set helper mode
        //this becomes effective only if the classes are unpacked
        if (!options.isWrapClasses()) {
            if (propertyMap.containsKey(SchemaConstants.SchemaCompilerArguments.HELPER_MODE)) {
                options.setHelperMode(true);
            }
        }
    }


    /**
     * populate the default options - called before the applying of user parameters
     *
     * @param options
     */
    private static void populateDefaultOptions(CompilerOptions options,
                                               CodeGenConfiguration configuration) {
        //create the output directory
        File outputDir = configuration.isFlattenFiles() ?
                configuration.getOutputLocation() :
                new File(configuration.getOutputLocation(), configuration.getSourceLocation());

        if (!outputDir.exists()) {
            outputDir.mkdirs();
        }

        /// these options need to be taken from the command line
        options.setOutputLocation(outputDir);
        options.setNs2PackageMap(configuration.getUri2PackageNameMap() == null ?
                new HashMap() :
                configuration.getUri2PackageNameMap());

        //default setting is to set the wrap status depending on whether it's
        //the server side or the client side
        if (configuration.isServerSide()) {
            //for the serverside we generate unwrapped  by default
            options.setWrapClasses(false);
            //for the serverside we write the output by default
            options.setWriteOutput(true);
        } else {
            // for the client let the users preference be the word here
            options.setWrapClasses(configuration.isPackClasses());
            //for the client side the default setting is not to write the
            //output
            options.setWriteOutput(!configuration.isPackClasses());
        }

        if (configuration.isGenerateAll()) {
            options.setGenerateAll(true);
        }

        if (configuration.isBackwordCompatibilityMode()) {
            options.setBackwordCompatibilityMode(true);
        }

        if (configuration.isSuppressPrefixesMode()) {
            options.setSuppressPrefixesMode(true);
        }
    }

}
TOP

Related Classes of org.apache.axis2.schema.ExtensionUtility

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.