All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.axis2.wsdl.codegen.extension.SchemaUnwrapperExtension Maven / Gradle / Ivy

There is a newer version: 1.8.2
Show newest version
/*
 * 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.wsdl.codegen.extension;

import org.apache.axis2.AxisFault;
import org.apache.axis2.description.AxisMessage;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.axis2.wsdl.WSDLUtil;
import org.apache.axis2.wsdl.codegen.CodeGenConfiguration;
import org.apache.axis2.wsdl.codegen.CodeGenerationException;
import org.apache.axis2.wsdl.i18n.CodegenMessages;
import org.apache.axis2.wsdl.util.ConfigPropertyFileLoader;
import org.apache.axis2.wsdl.util.Constants;
import org.apache.axis2.wsdl.util.MessagePartInformationHolder;
import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaAll;
import org.apache.ws.commons.schema.XmlSchemaAny;
import org.apache.ws.commons.schema.XmlSchemaAttribute;
import org.apache.ws.commons.schema.XmlSchemaChoice;
import org.apache.ws.commons.schema.XmlSchemaComplexContent;
import org.apache.ws.commons.schema.XmlSchemaComplexContentExtension;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaContent;
import org.apache.ws.commons.schema.XmlSchemaContentModel;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaImport;
import org.apache.ws.commons.schema.XmlSchemaInclude;
import org.apache.ws.commons.schema.XmlSchemaObject;
import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
import org.apache.ws.commons.schema.XmlSchemaParticle;
import org.apache.ws.commons.schema.XmlSchemaSequence;
import org.apache.ws.commons.schema.XmlSchemaSimpleType;
import org.apache.ws.commons.schema.XmlSchemaType;

import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * This extension invokes the schema unwrapper depending on the users setting. it is desirable to
 * put this extension before other extensions since extnsions such as the databinding extension may
 * well depend on the schema being unwrapped previously. For a complete unwrap the following format
 * of the schema is expected < element > < complexType > < sequence > < element
 * /> < /sequence > < /complexType > < /element >
 * 

* When an unwrapped WSDL is encountered Axis2 generates a wrapper schema and that wrapper schema * has the above mentioned format. This unwrapping algorithm will work on a pure doc/lit WSDL if it * has the above mentioned format only */ public class SchemaUnwrapperExtension extends AbstractCodeGenerationExtension { private CodeGenConfiguration codeGenConfiguration; /** * @param configuration * @throws CodeGenerationException */ public void engage(CodeGenConfiguration configuration) throws CodeGenerationException { this.codeGenConfiguration = configuration; if (!configuration.isParametersWrapped() && !codeGenConfiguration.getOutputLanguage().equals("jax-ws")) { // A check to avoid nasty surprises - Since unwrapping is not // supported by all frameworks, we check the framework name to be // compatible if (!ConfigPropertyFileLoader.getUnwrapSupportedFrameworkNames(). contains(configuration.getDatabindingType())) { throw new CodeGenerationException( CodegenMessages.getMessage("extension.unsupportedforunwrapping")); } else if (!ConfigPropertyFileLoader.getUnwrapDirectFrameworkNames(). contains(configuration.getDatabindingType())) { //walk the schema and find the top level elements List services = configuration.getAxisServices(); AxisService axisService; for (Iterator servicesIter = services.iterator(); servicesIter.hasNext();) { axisService = (AxisService) servicesIter.next(); 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), WSDLConstants.INPUT_PART_QNAME_SUFFIX); } // get the out put parameter details as well to unwrap the responses //TODO: support xmlbeans if (configuration.getDatabindingType().equals("adb")) { if (WSDLUtil.isOutputPresentForMEP(op.getMessageExchangePattern())) { walkSchema(op.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE), WSDLConstants.OUTPUT_PART_QNAME_SUFFIX); } } } } } } } /** * walk the given schema element For a successful unwrapping the element should have the * following structure < element > < complexType > < sequence > < element * /> < /sequence > < /complexType > < /element > */ public void walkSchema(AxisMessage message, String qnameSuffix) throws CodeGenerationException { //nothing to unwrap if (message.getSchemaElement() == null) { return; } List partNameList = new LinkedList(); XmlSchemaElement schemaElement = message.getSchemaElement(); XmlSchemaType schemaType = schemaElement.getSchemaType(); QName schemaTypeQname = schemaElement.getSchemaTypeName(); if (schemaType == null) { if (schemaTypeQname != null) { // find the schema type from all the schemas // now we need to get the schema of the extension type from the parent schema. For that let's first retrieve // the parent schema AxisService axisService = message.getAxisOperation().getAxisService(); ArrayList schemasList = axisService.getSchema(); XmlSchema schema = null; for (Iterator iter = schemasList.iterator(); iter.hasNext();) { schema = (XmlSchema) iter.next(); schemaType = getSchemaType(schema, schemaTypeQname); if (schemaType != null) { break; } } } } if (schemaType instanceof XmlSchemaComplexType) { handleAllCasesOfComplexTypes(schemaType, message, partNameList, qnameSuffix); } else if ((schemaType instanceof XmlSchemaSimpleType) || ((schemaTypeQname != null) && (schemaTypeQname.equals(new QName("http://www.w3.org/2001/XMLSchema", "anyType")))) ) { QName opName = message.getAxisOperation().getName(); partNameList.add(WSDLUtil.getPartQName(opName.getLocalPart(), qnameSuffix, schemaElement.getQName().getLocalPart())); } else if (schemaType == null) { throw new CodeGenerationException("Can not determine the schema type for the " + schemaElement.getName()); } else { //we've no idea how to unwrap a non complexType!!!!!! throw new CodeGenerationException( CodegenMessages.getMessage("extension.unsupportedSchemaFormat", schemaType.getName(), "complexType")); } try { //set in the axis message that the unwrapping was success message.addParameter(getParameter( Constants.UNWRAPPED_KEY, Boolean.TRUE)); // attach the opName and the parts name list into the // axis message by using the holder MessagePartInformationHolder infoHolder = new MessagePartInformationHolder(); infoHolder.setOperationName(message.getAxisOperation().getName()); infoHolder.setPartsList(partNameList); //attach it to the parameters message.addParameter( getParameter(Constants.UNWRAPPED_DETAILS, infoHolder)); } catch (AxisFault axisFault) { throw new CodeGenerationException(axisFault); } } private void handleAllCasesOfComplexTypes(XmlSchemaType schemaType, AxisMessage message, List partNameList, String qnameSuffix) throws CodeGenerationException { // if a complex type name exits for a element then // we keep that complex type to support unwrapping if (schemaType instanceof XmlSchemaComplexType) { XmlSchemaComplexType cmplxType = (XmlSchemaComplexType) schemaType; if (cmplxType.getContentModel() == null) { if (cmplxType.getParticle() != null) { processXMLSchemaSequence(cmplxType.getParticle(), message, partNameList, qnameSuffix); } } else { // now lets handle case with extensions processComplexContentModel(cmplxType, message, partNameList, qnameSuffix); } // handle attributes here processAttributes(cmplxType, message, partNameList, qnameSuffix); } } private void processAttributes(XmlSchemaComplexType complexType, AxisMessage message, List partNameList, String qnameSuffix) { QName opName = message.getAxisOperation().getName(); XmlSchemaObjectCollection xmlObjectCollection = complexType.getAttributes(); XmlSchemaObject item; XmlSchemaAttribute xmlSchemaAttribute; for (Iterator iter = xmlObjectCollection.getIterator(); iter.hasNext();) { item = (XmlSchemaObject) iter.next(); if (item instanceof XmlSchemaAttribute) { xmlSchemaAttribute = (XmlSchemaAttribute) item; String partName = xmlSchemaAttribute.getName(); partNameList.add( WSDLUtil.getPartQName(opName.getLocalPart(), qnameSuffix, partName)); } } } private void processComplexContentModel(XmlSchemaComplexType cmplxType, AxisMessage message, List partNameList, String qnameSuffix) throws CodeGenerationException { 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 if (schemaExtension.getParticle() != null) { processXMLSchemaSequence(schemaExtension.getParticle(), message, partNameList, qnameSuffix); } // now we need to get the schema of the extension type from the parent schema. For that let's first retrieve // the parent schema AxisService axisService = message.getAxisOperation().getAxisService(); ArrayList schemasList = axisService.getSchema(); XmlSchema parentSchema = null; XmlSchema schema = null; XmlSchemaType extensionSchemaType = null; for (Iterator iter = schemasList.iterator(); iter.hasNext();) { schema = (XmlSchema) iter.next(); extensionSchemaType = getSchemaType(schema, schemaExtension.getBaseTypeName()); if (extensionSchemaType != null) { break; } } // ok now we got the parent schema. Now let's get the extension's schema type handleAllCasesOfComplexTypes(extensionSchemaType, message, partNameList, qnameSuffix); } } } private XmlSchemaType getSchemaType(XmlSchema schema, QName typeName) { XmlSchemaType xmlSchemaType = null; if (schema != null) { xmlSchemaType = schema.getTypeByName(typeName); if (xmlSchemaType == null) { // try to find in an import or an include XmlSchemaObjectCollection includes = schema.getIncludes(); if (includes != null) { Iterator includesIter = includes.getIterator(); Object object = null; while (includesIter.hasNext()) { object = includesIter.next(); if (object instanceof XmlSchemaImport) { XmlSchema schema1 = ((XmlSchemaImport) object).getSchema(); xmlSchemaType = getSchemaType(schema1, typeName); } if (object instanceof XmlSchemaInclude) { XmlSchema schema1 = ((XmlSchemaInclude) object).getSchema(); xmlSchemaType = getSchemaType(schema1, typeName); } if (xmlSchemaType != null) { break; } } } } } return xmlSchemaType; } private void processXMLSchemaSequence(XmlSchemaParticle schemaParticle, AxisMessage message, List partNameList, String qnameSuffix) throws CodeGenerationException { if (schemaParticle instanceof XmlSchemaSequence) { // get the name of the operation name and namespace, // part name and hang them somewhere ? The ideal place // would be the property bag in the codegen config! QName opName = message.getAxisOperation().getName(); XmlSchemaSequence sequence = (XmlSchemaSequence) schemaParticle; XmlSchemaObjectCollection items = sequence.getItems(); // if this is an empty sequence, return if (items.getCount() == 0) { return; } 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) { //add the element name to the part name list XmlSchemaElement xmlSchemaElement = (XmlSchemaElement) item; XmlSchemaType schemaType = xmlSchemaElement.getSchemaType(); String partName = null; if (xmlSchemaElement.getRefName() != null) { partName = xmlSchemaElement.getRefName().getLocalPart(); } else { partName = xmlSchemaElement.getName(); } // part names are not unique across messages. Hence // we need some way of making the part name a unique // one (due to the fact that the type mapper // is a global list of types). // The seemingly best way to do that is to // specify a namespace for the part QName reference which // is stored in the list. This part qname is // temporary and should not be used with it's // namespace URI (which happened to be the operation name) // with _input attached to it partNameList.add( WSDLUtil.getPartQName(opName.getLocalPart(), qnameSuffix, partName)); // if the particle contains anything other than // a XMLSchemaElement then we are not in a position // to unwrap it } 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; partNameList.add( WSDLUtil.getPartQName(opName.getLocalPart(), qnameSuffix, Constants.ANY_ELEMENT_FIELD_NAME)); } else { throw new CodeGenerationException( CodegenMessages.getMessage("extension.unsupportedSchemaFormat", "unknown type", "Element")); } } //we do not know how to deal with other particles //such as xs:all or xs:choice. Usually occurs when //passed with the user built WSDL where the style //is document. } else if (schemaParticle instanceof XmlSchemaChoice) { throw new CodeGenerationException( CodegenMessages.getMessage("extension.unsupportedSchemaFormat", "choice", "sequence")); } else if (schemaParticle instanceof XmlSchemaAll) { throw new CodeGenerationException( CodegenMessages.getMessage("extension.unsupportedSchemaFormat", "all", "sequence")); } else { throw new CodeGenerationException( CodegenMessages.getMessage("extension.unsupportedSchemaFormat", "unknown", "sequence")); } } /** * Generate a parametes object * * @param key * @param value */ private Parameter getParameter(String key, Object value) { Parameter myParameter = new Parameter(); myParameter.setName(key); myParameter.setValue(value); return myParameter; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy