Package org.apache.muse.tools.generator.util

Source Code of org.apache.muse.tools.generator.util.DefinitionInfo

/*=============================================================================*
*  Copyright 2006 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.
*=============================================================================*/

package org.apache.muse.tools.generator.util;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.wsdl.Binding;
import javax.wsdl.BindingFault;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
import javax.wsdl.BindingOutput;
import javax.wsdl.Definition;
import javax.wsdl.Fault;
import javax.wsdl.Input;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.Output;
import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.PortType;
import javax.wsdl.Service;
import javax.wsdl.Types;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.ExtensionRegistry;
import javax.wsdl.extensions.schema.Schema;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.extensions.soap.SOAPBinding;
import javax.wsdl.extensions.soap.SOAPBody;
import javax.wsdl.extensions.soap.SOAPFault;
import javax.wsdl.extensions.soap.SOAPOperation;
import javax.wsdl.factory.WSDLFactory;
import javax.xml.namespace.QName;

import org.apache.muse.util.xml.XmlUtils;
import org.apache.muse.util.xml.XsdUtils;
import org.apache.muse.ws.addressing.WsaConstants;
import org.apache.muse.ws.resource.properties.WsrpConstants;
import org.apache.muse.ws.wsdl.WsdlUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.ibm.wsdl.extensions.schema.SchemaConstants;
import com.ibm.wsdl.extensions.soap.SOAPConstants;

/**
* Wraps a WSDL <code>Definition</code> for WsdlMerge.
* Also helps in creating the merged WSDL document using
* wsdl4j.
*
* @author Andrew Eberbach (aeberbac)
*
* @see org.apache.muse.tools.generator.WsdlMerge
*/
public class DefinitionInfo implements DefinitionConstants{

  private Definition _definition;

  private PortType _portType;

  private HashMap _operationNameMap = new HashMap();

  private WSDLFactory _factory;

  private String _uri;
 
  private String _prefix;
 
  private int _prefixCounter = 0;

  private Element _propertiesElementSequence;

  private Document _document;
 
  private Binding _binding;

  private ExtensionRegistry _registry;

  private Schema _schema;

  private Set _schemaImports = new HashSet();

  private HashMap _schemas = new HashMap();

  public DefinitionInfo(Definition definition, String uri) {
    _uri = uri;   
    _factory = getFactory();
    _registry = _factory.newPopulatedExtensionRegistry();
   
    if (definition == null) {     
      _definition = createDefinition();
      _prefix = addPrefix(_uri)
      addPrefix(WsrpConstants.NAMESPACE_URI);
      addPrefix(WsaConstants.NAMESPACE_URI);
    } else {
      _definition = definition;     
    }
   
    extractOperations();
  }

  public DefinitionInfo(String uri) {
    this(null, uri);
 

  public Definition getDefinition() {
    return _definition;
  }

  public Collection getOperations() {
    return _operationNameMap.values();
  }
 
  public Types getTypes() {
    return _definition.getTypes();
  }

  private void extractOperations() {

    Map portTypes = _definition.getPortTypes();
   
    if(portTypes.size() != 1) {
      return;
    }
   
    _portType = (PortType) portTypes.values().iterator().next();

    for (Iterator i = _portType.getOperations().iterator(); i.hasNext();) {
      Operation nextOperation = (Operation) i.next();
      String name = nextOperation.getName();
      _operationNameMap.put(name, nextOperation);
    }
  }

  private Operation createOperation(Operation operation, Map localMessageMap) {
    String name = operation.getName();

    Operation newOperation = _definition.createOperation();
    newOperation.setName(name);

    newOperation.setInput(createInput(operation.getInput(), localMessageMap));
    newOperation.setOutput(createOutput(operation.getOutput(),localMessageMap));

    for (Iterator i = operation.getFaults().values().iterator(); i.hasNext();) {
      newOperation.addFault(createFault((Fault) i.next(), localMessageMap));
    }

    newOperation.setUndefined(false);
   
    return newOperation;
  }

  private Fault createFault(Fault fault, Map localMessageMap) {
    Fault newFault = _definition.createFault();
    newFault.setName(fault.getName());

    Message newMessage = createMessage(fault.getMessage());
    _definition.addMessage(newMessage);
   
    newFault.setMessage(newMessage);

    return newFault;
  }

  private Output createOutput(Output output, Map localMessageMap) {
    Output newOutput = _definition.createOutput();
    newOutput.setName(output.getName());

    Message newMessage = createMessage(output.getMessage());
    _definition.addMessage(newMessage);

    newOutput.setMessage(newMessage);
       
    for(Iterator i = output.getExtensionAttributes().entrySet().iterator(); i.hasNext();) {
      Map.Entry next = (Entry) i.next();
      Object value = next.getValue();
      Object key = next.getKey();
      newOutput.setExtensionAttribute((QName)key, value);
    }
   
    return newOutput;
  }

  private Input createInput(Input input, Map localMessageMap) {
    Input newInput = _definition.createInput();
    newInput.setName(input.getName());

    Message newMessage = createMessage(input.getMessage());
    _definition.addMessage(newMessage);

    newInput.setMessage(newMessage);
   
    for(Iterator i = input.getExtensionAttributes().entrySet().iterator(); i.hasNext();) {
      Map.Entry next = (Entry) i.next();
      Object value = next.getValue();
      Object key = next.getKey();
      newInput.setExtensionAttribute((QName)key, value);
    }
       
    return newInput;
  }

  private Message createMessage(Message message) {
    Message newMessage = _definition.createMessage();   
    newMessage.setQName(makeLocalQName(message.getQName()));
   
    for (Iterator i = message.getParts().values().iterator(); i.hasNext();) {
      Part nextPart = (Part) i.next();
     
      Part newPart = _definition.createPart();
      newPart.setName(nextPart.getName());
     
      QName qname = nextPart.getElementName();
      if(qname == null) {
        qname = nextPart.getTypeName();
        newPart.setTypeName(qname);
      } else {
        newPart.setElementName(qname);
      }
     
      addPrefix(qname.getNamespaceURI());     
      newMessage.addPart(newPart);
    }

    newMessage.setUndefined(false);
    return newMessage;
  }
 
  private Definition createDefinition() {
    Definition definition = _factory.newDefinition();
    definition.setTargetNamespace(_uri);
   
    PortType portType = definition.createPortType();
    portType.setQName(new QName(_uri, PORT_TYPE));
    portType.setExtensionAttribute(WsrpConstants.DEFAULT_DOCUMENT_QNAME, new QName(_uri,RESOURCE_PROPERTIES));
    portType.setUndefined(false);
   
    definition.addPortType(portType);
       
    _schema = (Schema)createExtension(Types.class, SchemaConstants.Q_ELEM_XSD_2001);
    _schema.setElement(createEmptyProperties());
   
    Types types = definition.createTypes();
    types.addExtensibilityElement(_schema);   
   
    definition.setTypes(types);   
   
    return definition;
  }

  private Element createEmptyProperties() {
    _document = XmlUtils.createDocument();
    Element schema = XmlUtils.createElement(_document, XsdUtils.SCHEMA_QNAME);
    Element element = XmlUtils.createElement(_document, XsdUtils.ELEMENT_QNAME);
    Element complexType = XmlUtils.createElement(_document, XsdUtils.COMPLEX_TYPE_QNAME);
    Element sequence = XmlUtils.createElement(_document, XsdUtils.SEQUENCE_QNAME);
   
    complexType.appendChild(sequence);
    element.appendChild(complexType);
    element.setAttribute(XsdUtils.NAME, RESOURCE_PROPERTIES);
    schema.appendChild(element);
    schema.setAttribute(XmlUtils.TARGET_NS, _uri);
   
    _propertiesElementSequence = sequence;
   
    return schema;
  }

  public void addOperation(Operation operation, Map localMessageMap) {
    String name = operation.getName();
 
    if (_operationNameMap.containsKey(name)) {
      throw new RuntimeException("Duplicate name " + name);
    }
 
    Operation newOperation = createOperation(operation, localMessageMap);
   
    _portType.addOperation(newOperation);
    _operationNameMap.put(name, newOperation);
  }

  public void addSchema(Schema schema) {
    String uri = schema.getElement().getAttribute(XmlUtils.TARGET_NS);
    if(uri != null) {

      if(!_schemas.containsKey(uri)) {
        _schemas.put(uri, schema);
        _definition.getTypes().addExtensibilityElement(schema);
      }
    }   
  }

  public void mergeProperties(DefinitionInfo sourceDefinition) {
    Element[] properties = sourceDefinition.getPropertiesDef();
   
    if(properties != null) {
      for(int i=0; i < properties.length; i++) {
        Element property = (Element)_document.importNode(properties[i],true);
       
        String ref = property.getAttribute(XsdUtils.REF);
        QName qname = XmlUtils.parseQName(ref, properties[i]);
               
        String uri = qname.getNamespaceURI();
        String prefix = addPrefix(uri);
       
        property.setAttribute(XsdUtils.REF,makeQName(prefix, qname));
        _propertiesElementSequence.appendChild(property);
       
        addImport(qname);
      }
    }
  }

  private void addImport(QName qname) {
    if (!_schemaImports .contains(qname.getNamespaceURI())) {         
      Element importElement = XmlUtils.createElement(_schema.getElement().getOwnerDocument(),
          XsdUtils.IMPORT_QNAME);
      importElement.setAttribute(XsdUtils.NAMESPACE, qname.getNamespaceURI());

      Element firstElement = XmlUtils.getFirstElement(_schema.getElement());
      _schema.getElement().insertBefore(importElement, firstElement);
      _schemaImports.add(qname.getNamespaceURI());
    }
  }

  public void createBinding() {
    _binding = _definition.createBinding();
    _binding.setPortType(_portType);
    _binding.setQName(new QName(_uri,BINDING));
    _binding.setUndefined(false);

    SOAPBinding binding = (SOAPBinding)createExtension(Binding.class, SOAPConstants.Q_ELEM_SOAP_BINDING);
    binding.setStyle(DOCUMENT_STYLE);

    addPrefix(HTTP_SOAP_URI);
    addPrefix(SOAP_WSDL_URI);
    binding.setTransportURI(HTTP_SOAP_URI);
   
    _binding.addExtensibilityElement(binding);     
    _definition.addBinding(_binding);
   
    for(Iterator i = _portType.getOperations().iterator(); i.hasNext(); ) {
      BindingOperation bindingOperation = createOperationBinding((Operation)i.next());
      _binding.addBindingOperation(bindingOperation);
    }     
  }
 
  public BindingOperation createOperationBinding(Operation operation) {
    BindingOperation bindingOperation = _definition.createBindingOperation();
    bindingOperation.setName(operation.getName());

    SOAPOperation soapOperation = (SOAPOperation)createExtension(BindingOperation.class, SOAPConstants.Q_ELEM_SOAP_OPERATION);
    bindingOperation.addExtensibilityElement(soapOperation);
   
    bindingOperation.setBindingInput(createInputBinding(operation.getInput()));
    bindingOperation.setBindingOutput(createOutputBinding(operation.getOutput()));

    for(Iterator i = operation.getFaults().values().iterator(); i.hasNext();) {
      bindingOperation.addBindingFault(createFaultBinding((Fault)i.next()));
    }
       
    return bindingOperation;
  }

  private BindingFault createFaultBinding(Fault fault) {
    BindingFault bindingFault = _definition.createBindingFault();
    bindingFault.setName(fault.getName());
   
    SOAPFault soapFault = (SOAPFault)createExtension(BindingFault.class, SOAPConstants.Q_ELEM_SOAP_FAULT);
    soapFault.setUse(ENCODED_USE);
    soapFault.setName(fault.getName());
    bindingFault.addExtensibilityElement(soapFault);

    return bindingFault;
  }

  private BindingOutput createOutputBinding(Output output) {
    BindingOutput bindingOutput = _definition.createBindingOutput();
    bindingOutput.setName(output.getName());
   
    SOAPBody soapBody = (SOAPBody)createExtension(BindingOutput.class, SOAPConstants.Q_ELEM_SOAP_BODY);
    soapBody.setUse(ENCODED_USE);
   
    ArrayList list = new ArrayList();
    list.add(ENCODING_URI);   
    soapBody.setEncodingStyles(list);
   
    bindingOutput.addExtensibilityElement(soapBody);
    return bindingOutput;
  }

  private BindingInput createInputBinding(Input input) {
    BindingInput bindingInput = _definition.createBindingInput();
    bindingInput.setName(input.getName());
   
    SOAPBody soapBody = (SOAPBody) createExtension(BindingInput.class, SOAPConstants.Q_ELEM_SOAP_BODY);
    soapBody.setUse(ENCODED_USE);
    ArrayList list = new ArrayList();
    list.add(ENCODING_URI);
    soapBody.setEncodingStyles(list);
    bindingInput.addExtensibilityElement(soapBody);

    return bindingInput;
  }

  public void createService(String location) {
    Service service = _definition.createService();
    service.setQName(new QName(_uri,SERVICE));
    Port port = _definition.createPort();
    port.setBinding(_binding);
    port.setName(PORT);
    service.addPort(port);

    SOAPAddress soapAddress = (SOAPAddress)createExtension(Port.class, SOAPConstants.Q_ELEM_SOAP_ADDRESS);
    soapAddress.setLocationURI(location);
    port.addExtensibilityElement(soapAddress);
       
    _definition.addService(service);
  }

  private String addPrefix(String uri) {
    String prefix = getPrefix(uri);   
    _definition.addNamespace(prefix, uri);   
    return prefix;
  }
 
  private Object createExtension(Class targetClass, QName qname) {
    try {
      return _registry.createExtension(targetClass, qname);
    } catch (WSDLException e) {
      //TODO
//        AcitLog.logError("Could not create WSDL extension", e);
    }
    return null;
  }
 
  private QName makeLocalQName(QName name) {
    return new QName(_uri, name.getLocalPart(), _prefix);
  }

  private String getPrefix(String uri) {
    String prefix = _definition.getPrefix(uri)
    if(prefix == null) {
      prefix =  PREFIX + _prefixCounter++;
    }
    return prefix;
  }
 
  private static WSDLFactory getFactory() {
    try {
      return WSDLFactory.newInstance();
    } catch (WSDLException e) {
      throw new RuntimeException("Could not get factory");
    }       
  }

  private String makeQName(String prefix, QName qname) {
    return prefix  + ":" + qname.getLocalPart();
  }
 
  private Element[] getPropertiesDef() {
    if(_portType == null) {
      return null;
    }
    Object propertiesDef = _portType.getExtensionAttribute(WsrpConstants.DEFAULT_DOCUMENT_QNAME);
    if(propertiesDef != null && propertiesDef instanceof QName) {
      QName qname = (QName)propertiesDef;
      Element propertiesElement = find(qname)
     
      if(propertiesElement != null) {
        return XmlUtils.findInSubTree(propertiesElement, XsdUtils.ELEMENT_QNAME);
      }
    }
    return null;
  }

  private Element find(QName qname) {
    Types types = _definition.getTypes();
   
    for(Iterator i = types.getExtensibilityElements().iterator(); i.hasNext();) {
      Object next = i.next();
      if(next instanceof Schema) {
        Schema nextSchema = (Schema)next;
        Element type = WsdlUtils.getTypeDeclaration(nextSchema.getElement(), qname);
        if(type != null) {
          return type;
        }
      }
    }
    return null;
  }
}
TOP

Related Classes of org.apache.muse.tools.generator.util.DefinitionInfo

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.