Package org.activiti.engine.impl.webservice

Source Code of org.activiti.engine.impl.webservice.WSDLImporter

/* 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.activiti.engine.impl.webservice;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.wsdl.BindingOperation;
import javax.wsdl.Definition;
import javax.wsdl.Operation;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.Types;
import javax.wsdl.WSDLException;
import javax.wsdl.extensions.schema.Schema;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.xml.namespace.QName;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.impl.bpmn.data.SimpleStructureDefinition;
import org.activiti.engine.impl.bpmn.data.StructureDefinition;
import org.activiti.engine.impl.bpmn.parser.BpmnParse;
import org.activiti.engine.impl.bpmn.parser.XMLImporter;
import org.activiti.engine.impl.util.ReflectUtil;
import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JFieldVar;
import com.sun.tools.xjc.ConsoleErrorReporter;
import com.sun.tools.xjc.api.ErrorListener;
import com.sun.tools.xjc.api.Mapping;
import com.sun.tools.xjc.api.S2JJAXBModel;
import com.sun.tools.xjc.api.SchemaCompiler;
import com.sun.tools.xjc.api.XJC;

/**
* A WSDL importer
*
* @author Esteban Robles Luna
*/
public class WSDLImporter implements XMLImporter {

  protected Map<String, WSService> wsServices = new HashMap<String, WSService>();

  protected Map<String, WSOperation> wsOperations = new HashMap<String, WSOperation>();

  protected Map<String, StructureDefinition> structures = new HashMap<String, StructureDefinition>();

  protected String wsdlLocation;
 
  protected String namespace;
 
  public WSDLImporter() {
    this.namespace = "";
  }

  public void importFrom(org.activiti.engine.impl.util.xml.Element element, BpmnParse parse) {
    this.namespace = element.attribute("namespace") == null ? "" : element.attribute("namespace") + ":";
    this.importFrom(element.attribute("location"));
    this.transferImportsToParse(parse);
  }

  public void importFrom(String url) {
    this.wsServices.clear();
    this.wsOperations.clear();
    this.structures.clear();

    this.wsdlLocation = url;

    try {
      Definition definition = this.parseWSDLDefinition();
      this.importServicesAndOperations(definition);
      this.importTypes(definition.getTypes());
    } catch (WSDLException e) {
      throw new ActivitiException(e.getMessage(), e);
    }
  }

  /**
   * Parse the WSDL definition using WSDL4J.
   */
  private Definition parseWSDLDefinition() throws WSDLException {
    WSDLFactory wsdlFactory = WSDLFactory.newInstance();
    WSDLReader reader = wsdlFactory.newWSDLReader();
    reader.setFeature("javax.wsdl.verbose", false);
    reader.setFeature("javax.wsdl.importDocuments", true);
    Definition definition = reader.readWSDL(this.wsdlLocation);
    return definition;
  }

  /**
   * Imports services and operations from the WSDL definition
   */
  private void importServicesAndOperations(Definition definition) {
    for (Object serviceObject : definition.getServices().values()) {
      Service service = (Service) serviceObject;
      WSService wsService = this.importService(service);
      this.wsServices.put(this.namespace + wsService.getName(), wsService);
     
      Port port = (Port) service.getPorts().values().iterator().next();
      for (Object bindOperationObject : port.getBinding().getBindingOperations()) {
        BindingOperation bindOperation = (BindingOperation) bindOperationObject;
        WSOperation operation = this.processOperation(bindOperation.getOperation(), wsService);
        wsService.addOperation(operation);

        this.wsOperations.put(this.namespace + operation.getName(), operation);
      }
    }
  }
 
  /**
   * Imports the service from the WSDL service definition
   */
  private WSService importService(Service service) {
    String name = service.getQName().getLocalPart();
    Port port = (Port) service.getPorts().values().iterator().next();
    String location = "";
   
    List extensionElements = port.getExtensibilityElements();
    for (Object extension : extensionElements) {
      if (extension instanceof SOAPAddress) {
        SOAPAddress address = (SOAPAddress) extension;
        location = address.getLocationURI();
      }
    }

    WSService wsService = new WSService(this.namespace + name, location, this.wsdlLocation);
    return wsService;
  }

  private WSOperation processOperation(Operation wsOperation, WSService service) {
    WSOperation operation = new WSOperation(this.namespace + wsOperation.getName(), wsOperation.getName(), service);
    return operation;
  }

  /**
   * Import the Types from the WSDL definition using the same strategy that
   * Cxf uses taking advantage of JAXB
   */
  private void importTypes(Types types) {
    SchemaCompiler compiler = XJC.createSchemaCompiler();
    ErrorListener elForRun = new ConsoleErrorReporter();
    compiler.setErrorListener(elForRun);

    Element rootTypes = this.getRootTypes();
    this.createDefaultStructures(rootTypes);

   
    S2JJAXBModel intermediateModel = this.compileModel(types, compiler, rootTypes);
    Collection<? extends Mapping> mappings = intermediateModel.getMappings();

    for (Mapping mapping : mappings){
      this.importStructure(mapping);
    }
  }

  private void importStructure(Mapping mapping) {
    QName qname = mapping.getElement();
    JDefinedClass theClass = (JDefinedClass) mapping.getType().getTypeClass();
    SimpleStructureDefinition structure = (SimpleStructureDefinition) this.structures.get(this.namespace + qname.getLocalPart());
   
    Map<String, JFieldVar> fields = theClass.fields();
    int index = 0;
    for (Entry<String, JFieldVar> entry : fields.entrySet()) {
      Class<?> fieldClass = ReflectUtil.loadClass(entry.getValue().type().boxify().fullName());
      structure.setFieldName(index, entry.getKey(), fieldClass);
      index++;
    }
  }

  private S2JJAXBModel compileModel(Types types, SchemaCompiler compiler, Element rootTypes) {
    Schema schema = (Schema) types.getExtensibilityElements().get(0);
    compiler.parseSchema(schema.getDocumentBaseURI() + "#types1", rootTypes);
    S2JJAXBModel intermediateModel = compiler.bind();
    return intermediateModel;
  }

  private void createDefaultStructures(Element rootTypes) {
    NodeList complexTypes = rootTypes.getElementsByTagNameNS("http://www.w3.org/2001/XMLSchema", "complexType");
    for (int i = 0; i < complexTypes.getLength(); i++) {
      Element element = (Element) complexTypes.item(i);
      String structureName = this.namespace + element.getAttribute("name");
      SimpleStructureDefinition structure = new SimpleStructureDefinition(structureName);
      this.structures.put(structure.getId(), structure);
    }
  }

  private Element getRootTypes() {
    try {
      DOMParser parser = new DOMParser();
      parser.parse(this.wsdlLocation);
      Document doc = parser.getDocument();
      Element root = (Element) doc.getFirstChild();
      Element typesElement = (Element) root.getElementsByTagName("wsdl:types").item(0);
      return (Element) typesElement.getElementsByTagNameNS("http://www.w3.org/2001/XMLSchema", "schema").item(0);
    } catch (SAXException e) {
      throw new ActivitiException(e.getMessage(), e);
    } catch (IOException e) {
      throw new ActivitiException(e.getMessage(), e);
    }
  }

  private void transferImportsToParse(BpmnParse parse) {
    if (parse != null) {
      for (StructureDefinition structure : this.structures.values()) {
        parse.addStructure(structure);
      }
      for (WSService service : this.wsServices.values()) {
        parse.addService(service);
      }
      for (WSOperation operation : this.wsOperations.values()) {
        parse.addOperation(operation);
      }
    }
  }

  public Collection<StructureDefinition> getStructures() {
    return this.structures.values();
  }

  public Collection<WSService> getServices() {
    return this.wsServices.values();
  }

  public Collection<WSOperation> getOperations() {
    return this.wsOperations.values();
  }
}
TOP

Related Classes of org.activiti.engine.impl.webservice.WSDLImporter

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.