Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/embl/ebi/escience/scuflworkers/wsdl/WSDLBasedProcessor.java


1   /**
2    * This file is a component of the Taverna project,
3    * and is licensed under the GNU LGPL.
4    * Copyright Tom Oinn, EMBL-EBI
5    */
6   package org.embl.ebi.escience.scuflworkers.wsdl;
7   
8   import javax.wsdl.Binding;
9   import javax.wsdl.Operation;
10  import javax.wsdl.Port; // ambiguous with: org.embl.ebi.escience.scufl.Port 
11  import javax.wsdl.Service; // ambiguous with: javax.xml.rpc.Service 
12  import javax.wsdl.extensions.soap.SOAPAddress;
13  import javax.xml.namespace.QName;
14  import javax.xml.rpc.Call;
15  import org.apache.axis.wsdl.gen.Parser;
16  import org.apache.axis.wsdl.symbolTable.*;
17  import org.embl.ebi.escience.scufl.*;
18  
19  // Utility Imports
20  import java.util.*;
21  
22  
23  
24  
25  /**
26   * A processor based on an operation defined within 
27   * a WSDL file accessible to the class at construction
28   * time.
29   * @author Tom Oinn
30   */
31  public class WSDLBasedProcessor extends Processor implements java.io.Serializable {
32      
33      // Fields used by the configuration operations
34      // Output types and names
35      Vector outNames = new Vector();
36      Vector outTypes = new Vector();
37      // Input types and names
38      Vector inNames = new Vector();
39      Vector inTypes = new Vector();
40      // WSDL Parser
41      Parser wsdlParser = null;
42      // Call object to invoke this processor
43      Call call = null;
44      
45      private String wsdlLocation = null;
46      /**
47       * Get the WSDL location for this processor
48       */
49      public String getWSDLLocation() {
50    return this.wsdlLocation;
51      }
52      
53      private String operationName = null;
54      /**
55       * Get the operation name for this processor
56       */
57      public String getOperationName() {
58    return this.operationName;
59      }
60  
61      /**
62       * Construct a new processor from the given WSDL definition
63       * and operation name, delegates to superclass then instantiates
64       * ports based on WSDL inspection.
65       */
66      public WSDLBasedProcessor(ScuflModel model, String name, String wsdlLocation, String operationName)
67    throws ProcessorCreationException,
68           DuplicateProcessorNameException {
69    super(model, name);
70    this.wsdlLocation = wsdlLocation;
71    this.operationName = operationName;
72    // Load the WSDL document
73    try {
74        wsdlParser = new Parser();
75        int retryCount = 3;
76        int retryDelay = 1000;
77        boolean loaded = false;
78        while (retryCount > 0 && !loaded) {
79      try {
80          wsdlParser.run(wsdlLocation);
81          loaded = true;
82      }
83      catch (Exception ex2) {
84          retryCount--;
85          if (retryCount > 0) {
86        Thread.sleep(retryDelay);
87          }
88          else {
89        throw ex2;
90          }
91      }
92        }
93    }
94    catch (Exception ex) {
95        ProcessorCreationException pce = new ProcessorCreationException("Unable to load wsdl!");
96        pce.initCause(ex);
97        pce.printStackTrace();
98        throw pce;
99    }
100 
101   // Set up input and output vectors and create the Call object
102   configureFor(operationName);
103   
104   // Build ports from the input and output vectors
105   try {
106       for (int i = 0; i < outNames.size(); i++) {
107     String outName = (String)outNames.get(i);
108     OutputPort outputPort = new OutputPort(this, outName);
109     outputPort.setSyntacticType(xsdTypeToInternalType(((Parameter)outTypes.get(i)).getType().getQName().getLocalPart()));
110     addPort(outputPort);
111       }
112       for (int i = 0; i < inNames.size(); i++) {
113     String inName = (String)inNames.get(i);
114     InputPort inputPort = new InputPort(this, inName);
115     inputPort.setSyntacticType(xsdTypeToInternalType(((Parameter)inTypes.get(i)).getType().getQName().getLocalPart()));
116     addPort(inputPort);
117       }
118   }
119   catch (DuplicatePortNameException dpne) {
120       ProcessorCreationException pce = new ProcessorCreationException("Duplicate port names!");
121       pce.initCause(dpne);
122       throw pce;
123   }
124   catch (PortCreationException portce) {
125       ProcessorCreationException pce = new ProcessorCreationException("Port creation failure!");
126       pce.initCause(portce);
127       throw pce;
128   }
129     }
130     
131     /**
132      * Load information from the WSDL parser to populate the input and 
133      * output vectors and create the Call object
134      */
135     private void configureFor(String operationName) 
136   throws ProcessorCreationException {
137   try {
138       String portName = null;
139       Service service = ((ServiceEntry)getSymTabEntry(null, ServiceEntry.class)).getService();
140       Port port = selectPort(service.getPorts(), portName);
141       portName = port.getName();
142       Binding binding = port.getBinding();
143       org.apache.axis.client.Service dpf = new org.apache.axis.client.Service(wsdlParser, service.getQName());
144       this.call = dpf.createCall(QName.valueOf(portName), QName.valueOf(operationName));
145       
146       SymbolTable symbolTable = wsdlParser.getSymbolTable();
147       BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName());
148       
149       // Iterate over the binding entry searching for the operation
150       // specified in the argument to the invokeMethod call.
151       Operation operation = null;
152       Parameters parameters = null;
153       for (Iterator i = bEntry.getParameters().keySet().iterator(); i.hasNext(); ) {
154     Operation o = (Operation) i.next();
155     if (o.getName().equals(operationName)) {
156         operation = o;
157         parameters = (Parameters) bEntry.getParameters().get(o);
158         // Populate the input and output descriptions
159         for (int j = 0; j < parameters.list.size(); j++) {
160       Parameter p = (Parameter) parameters.list.get(j);
161       if (p.getMode() == 1) {           // IN
162           inNames.add(p.getQName().getLocalPart());
163           inTypes.add(p);
164       } else if (p.getMode() == 2) {    // OUT
165           outNames.add(p.getQName().getLocalPart());
166           outTypes.add(p);
167       } else if (p.getMode() == 3) {    // INOUT
168           inNames.add(p.getQName().getLocalPart());
169           inTypes.add(p);
170           outNames.add(p.getQName().getLocalPart());
171           outTypes.add(p);
172       }
173         }
174         // Set output type
175         if (parameters.returnParam != null) {
176       // Get the QName for the return Type
177       QName returnType = org.apache.axis.wsdl.toJava.Utils.getXSIType(parameters.returnParam);
178       QName returnQName = parameters.returnParam.getQName();
179       outNames.add(returnQName.getLocalPart());
180       outTypes.add((Parameter)parameters.returnParam);
181         }
182         // Break out of the loop  
183         break;
184     }
185       }
186       if ((operation == null) || (parameters == null)) {
187     throw new RuntimeException(operationName + " was not found.");
188       }
189       
190   }
191   catch (Exception e) {
192       e.printStackTrace();
193       ProcessorCreationException pce = new ProcessorCreationException("Problem initialising from wsdl...");
194       pce.initCause(e);
195       throw pce;
196   }
197     }
198 
199     /**
200      * Convert an XSD type into a Baclava type string
201      */
202     public String xsdTypeToInternalType(String xsdType) {
203   // System.out.println("Type conversion requested for "+xsdType);
204   // Can cope with String types and nested strings
205   if (xsdType.startsWith("ArrayOf_")) {
206       return ("l("+xsdTypeToInternalType(xsdType.replaceFirst("ArrayOf_",""))+")");
207   }
208   else if (xsdType.startsWith("ArrayOf")) {
209       return ("l("+xsdTypeToInternalType(xsdType.replaceFirst("ArrayOf",""))+")");
210   }
211   else if (xsdType.equalsIgnoreCase("base64")) {
212       return "'application/octet-stream'";
213   }
214   else {
215       return "'text/plain'";
216       /**
217          if (xsdType.equalsIgnoreCase("string")) {
218          return "'text/plain'";
219          }
220          else {
221          return "'text/x-xsd-unknown-type-"+xsdType+"'";
222          }
223       */
224   }
225     }
226 
227     
228     
229     /**
230      * Get the properties for this processor for display purposes
231      */
232     public Properties getProperties() {
233   Properties props = new Properties();
234   props.put("wsdlLocation",getWSDLLocation());
235   props.put("operation",getOperationName());
236   return props;
237     } 
238     
239     /**
240      * Method getSymTabEntry
241      * Search the symbol table for an entry with the specified
242      * class and optionally QName. If the QName is not specified
243      * then examine all entries.
244      */
245     public SymTabEntry getSymTabEntry(QName qname, Class cls) {
246         HashMap map = wsdlParser.getSymbolTable().getHashMap();
247         Iterator iterator = map.entrySet().iterator();
248 
249         while (iterator.hasNext()) {
250             Map.Entry entry = (Map.Entry) iterator.next();
251             QName key = (QName) entry.getKey();
252             Vector v = (Vector) entry.getValue();
253 
254             if ((qname == null) || qname.equals(qname)) {
255                 for (int i = 0; i < v.size(); ++i) {
256                     SymTabEntry symTabEntry = (SymTabEntry) v.elementAt(i);
257 
258                     if (cls.isInstance(symTabEntry)) {
259                         return symTabEntry;
260                     }
261                 }
262             }
263         }
264         return null;
265     }
266 
267     /**
268      * Given a map of ports, iterate across it until either
269      * a port matching the portName parameter is found or until
270      * any port is found with a SOAPAddress extensibility element.
271      * Return null if no such port can be located.
272      */
273     public Port selectPort(Map ports, String portName) throws Exception {
274         Iterator valueIterator = ports.keySet().iterator();
275         while (valueIterator.hasNext()) {
276             String name = (String) valueIterator.next();
277             if ((portName == null) || (portName.length() == 0)) {
278                 Port port = (Port) ports.get(name);
279                 List list = port.getExtensibilityElements();
280     for (int i = 0; (list != null) && (i < list.size()); i++) {
281                     Object obj = list.get(i);
282                     if (obj instanceof SOAPAddress) {
283                         return port;
284                     }
285                 }
286             } else if ((name != null) && name.equals(portName)) {
287                 return (Port) ports.get(name);
288             }
289         }
290         return null;
291     }
292 
293 }