View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.geronimo.ews.jaxrpcmapping;
17  
18  import org.apache.axis.Constants;
19  import org.apache.axis.utils.Messages;
20  import org.apache.axis.wsdl.symbolTable.BindingEntry;
21  import org.apache.axis.wsdl.symbolTable.FaultInfo;
22  import org.apache.axis.wsdl.symbolTable.Parameter;
23  import org.apache.axis.wsdl.symbolTable.Parameters;
24  import org.apache.axis.wsdl.symbolTable.SymbolTable;
25  import org.apache.axis.wsdl.toJava.JavaClassWriter;
26  import org.apache.axis.wsdl.toJava.Utils;
27  
28  import javax.wsdl.Binding;
29  import javax.wsdl.BindingInput;
30  import javax.wsdl.BindingOperation;
31  import javax.wsdl.BindingOutput;
32  import javax.wsdl.Operation;
33  import javax.wsdl.OperationType;
34  import javax.wsdl.extensions.ExtensibilityElement;
35  import javax.wsdl.extensions.UnknownExtensibilityElement;
36  import javax.wsdl.extensions.soap.SOAPBody;
37  import javax.wsdl.extensions.soap.SOAPOperation;
38  import javax.xml.namespace.QName;
39  import java.io.IOException;
40  import java.io.PrintWriter;
41  import java.util.ArrayList;
42  import java.util.Iterator;
43  import java.util.List;
44  
45  /***
46   * This is Wsdl2java's skeleton writer.  It writes the <BindingName>Skeleton.java
47   * file which contains the <bindingName>Skeleton class.
48   *
49   * @author Ias (iasandcb@tmax.co.kr)
50   */
51  public class J2eeSkelWriter extends JavaClassWriter {
52      private BindingEntry bEntry;
53      private Binding binding;
54      private SymbolTable symbolTable;
55  
56      /***
57       * Constructor.
58       */
59      protected J2eeSkelWriter(J2eeEmitter emitter,
60                               BindingEntry bEntry,
61                               SymbolTable symbolTable) {
62          super(emitter, bEntry.getName() + "Skeleton", "skeleton");
63          this.bEntry = bEntry;
64          this.binding = bEntry.getBinding();
65          this.symbolTable = symbolTable;
66      } // ctor
67  
68      /***
69       * Returns "implements <SEI>, org.apache.axis.wsdl.Skeleton ".
70       */
71      protected String getImplementsText() {
72          return "implements " + bEntry.getDynamicVar(J2eeBindingWriter.INTERFACE_NAME)
73                  + ", org.apache.axis.wsdl.Skeleton ";
74      } // getImplementsText
75  
76      /***
77       * Write the body of the binding's stub file.
78       */
79      protected void writeFileBody(PrintWriter pw) throws IOException {
80          String portTypeName = (String) bEntry.getDynamicVar(J2eeBindingWriter.INTERFACE_NAME);
81          String implType = portTypeName + " impl";
82  
83          // Declare private impl and skeleton base delegates
84          pw.println("    private " + implType + ";");
85          pw.println("    private static java.util.Map _myOperations = new java.util.Hashtable();");
86          pw.println("    private static java.util.Collection _myOperationsList = new java.util.ArrayList();");
87          pw.println();
88          pw.println("    /**");
89          pw.println("    * Returns List of OperationDesc objects with this name");
90          pw.println("    */");
91          pw.println("    public static java.util.List getOperationDescByName(java.lang.String methodName) {");
92          pw.println("        return (java.util.List)_myOperations.get(methodName);");
93          pw.println("    }");
94          pw.println();
95          pw.println("    /**");
96          pw.println("    * Returns Collection of OperationDescs");
97          pw.println("    */");
98          pw.println("    public static java.util.Collection getOperationDescs() {");
99          pw.println("        return _myOperationsList;");
100         pw.println("    }");
101         pw.println();
102 
103         // Initialize operation parameter names
104         pw.println("    static {");
105         pw.println("        org.apache.axis.description.OperationDesc _oper;");
106         pw.println("        org.apache.axis.description.FaultDesc _fault;");
107         pw.println("        org.apache.axis.description.ParameterDesc [] _params;");
108         List operations = binding.getBindingOperations();
109         for (int i = 0; i < operations.size(); ++i) {
110             BindingOperation bindingOper = (BindingOperation) operations.get(i);
111             Operation operation = bindingOper.getOperation();
112             OperationType type = operation.getStyle();
113             // These operation types are not supported.  The signature
114             // will be a string stating that fact.
115             if (type == OperationType.NOTIFICATION
116                     || type == OperationType.SOLICIT_RESPONSE) {
117                 continue;
118             }
119             Parameters parameters =
120                     bEntry.getParameters(bindingOper.getOperation());
121             if (parameters != null) {
122                 // The invoked java name of the bindingOper is stored.
123                 String opName = bindingOper.getOperation().getName();
124                 String javaOpName = Utils.xmlNameToJava(opName);
125                 pw.println("        _params = new org.apache.axis.description.ParameterDesc [] {");
126                 for (int j = 0; j < parameters.list.size(); j++) {
127                     Parameter p = (Parameter) parameters.list.get(j);
128                     String modeStr;
129                     switch (p.getMode()) {
130                         case Parameter.IN:
131                             modeStr = "org.apache.axis.description.ParameterDesc.IN";
132                             break;
133                         case Parameter.OUT:
134                             modeStr = "org.apache.axis.description.ParameterDesc.OUT";
135                             break;
136                         case Parameter.INOUT:
137                             modeStr = "org.apache.axis.description.ParameterDesc.INOUT";
138                             break;
139                         default:
140                             throw new IOException(Messages.getMessage("badParmMode00",
141                                     (new Byte(p.getMode())).toString()));
142                     }
143 
144                     // Get the QNames representing the parameter name and type
145                     QName paramName = p.getQName();
146                     QName paramType = Utils.getXSIType(p);
147 
148                     // Is this parameter a header?
149                     String inHeader = p.isInHeader() ? "true" : "false";
150                     String outHeader = p.isOutHeader() ? "true" : "false";
151                     pw.println("            " +
152                             "new org.apache.axis.description.ParameterDesc(" +
153                             Utils.getNewQName(paramName) +
154                             ", " + modeStr +
155                             ", " + Utils.getNewQName(paramType) +
156                             ", " + Utils.getParameterTypeName(p) + ".class" +
157                             ", " + inHeader +
158                             ", " + outHeader + "), ");
159                 }
160                 pw.println("        };");
161 
162                 // Get the return name QName and type
163                 QName retName = null;
164                 QName retType = null;
165                 if (parameters.returnParam != null) {
166                     retName = parameters.returnParam.getQName();
167                     retType = Utils.getXSIType(parameters.returnParam);
168                 }
169                 String returnStr;
170                 if (retName != null) {
171                     returnStr = Utils.getNewQName(retName);
172                 } else {
173                     returnStr = "null";
174                 }
175                 pw.println("        _oper = new org.apache.axis.description.OperationDesc(\"" +
176                         javaOpName + "\", _params, " + returnStr + ");");
177                 if (retType != null) {
178                     pw.println("        _oper.setReturnType(" +
179                             Utils.getNewQName(retType) + ");");
180                     if (parameters.returnParam != null &&
181                             parameters.returnParam.isOutHeader()) {
182                         pw.println("        _oper.setReturnHeader(true);");
183                     }
184                 }
185 
186                 // If we need to know the QName (if we have a namespace or
187                 // the actual method name doesn't match the XML we expect),
188                 // record it in the OperationDesc
189                 QName elementQName =
190                         Utils.getOperationQName(bindingOper, bEntry, symbolTable);
191                 if (elementQName != null) {
192                     pw.println("        _oper.setElementQName(" +
193                             Utils.getNewQName(elementQName) + ");");
194                 }
195 
196                 // Find the SOAPAction.
197                 List elems = bindingOper.getExtensibilityElements();
198                 Iterator it = elems.iterator();
199                 boolean found = false;
200                 while (!found && it.hasNext()) {
201                     ExtensibilityElement elem = (ExtensibilityElement) it.next();
202                     if (elem instanceof SOAPOperation) {
203                         SOAPOperation soapOp = (SOAPOperation) elem;
204                         String action = soapOp.getSoapActionURI();
205                         if (action != null) {
206                             pw.println("        _oper.setSoapAction(\"" + action + "\");");
207                             found = true;
208                         }
209                     } else if (elem instanceof UnknownExtensibilityElement) {
210                         //TODO: After WSDL4J supports soap12, change this code
211                         UnknownExtensibilityElement unkElement = (UnknownExtensibilityElement) elem;
212                         QName name = unkElement.getElementType();
213                         if (name.getNamespaceURI().equals(Constants.URI_WSDL12_SOAP) &&
214                                 name.getLocalPart().equals("operation")) {
215                             String action = unkElement.getElement().getAttribute("soapAction");
216                             if (action != null) {
217                                 pw.println("        _oper.setSoapAction(\"" + action + "\");");
218                                 found = true;
219                             }
220                         }
221                     }
222                 }
223                 pw.println("        _myOperationsList.add(_oper);");
224                 pw.println("        if (_myOperations.get(\"" + javaOpName + "\") == null) {");
225                 pw.println("            _myOperations.put(\"" + javaOpName + "\", new java.util.ArrayList());");
226                 pw.println("        }");
227                 pw.println("        ((java.util.List)_myOperations.get(\"" + javaOpName + "\")).add(_oper);");
228             }
229 
230             // Now generate FaultDesc
231             if (bEntry.getFaults() != null) {
232                 ArrayList faults = (ArrayList) bEntry.getFaults().get(bindingOper);
233                 if (faults != null) {
234                     // Operation was not created if there were no parameters
235                     if (parameters == null) {
236                         String opName = bindingOper.getOperation().getName();
237                         String javaOpName = Utils.xmlNameToJava(opName);
238                         pw.println("        _oper = " +
239                                 "new org.apache.axis.description.OperationDesc();");
240                         pw.println("        _oper.setName(\"" +
241                                 javaOpName + "\");");
242                     }
243                     // Create FaultDesc items for each fault
244                     Iterator it = faults.iterator();
245                     while (it.hasNext()) {
246                         FaultInfo faultInfo = (FaultInfo) it.next();
247                         QName faultQName = faultInfo.getQName();
248                         QName faultXMLType = faultInfo.getXMLType();
249                         String faultName = faultInfo.getName();
250                         String className =
251                                 Utils.getFullExceptionName(faultInfo.getMessage(), symbolTable);
252                         pw.println("        _fault = " +
253                                 "new org.apache.axis.description.FaultDesc();");
254                         if (faultName != null) {
255                             pw.println("        _fault.setName(\"" +
256                                     faultName + "\");");
257                         }
258                         if (faultQName != null) {
259                             pw.println("        _fault.setQName(" +
260                                     Utils.getNewQName(faultQName) + ");");
261                         }
262                         if (className != null) {
263                             pw.println("        _fault.setClassName(\"" +
264                                     className + "\");");
265                         }
266                         if (faultXMLType != null) {
267                             pw.println("        _fault.setXmlType(" +
268                                     Utils.getNewQName(faultXMLType) + ");");
269                         }
270                         pw.println("        _oper.addFault(_fault);");
271                     }
272                 }
273             }
274         }
275         pw.println("    }");
276         pw.println();
277 
278         // Skeleton constructors
279         pw.println("    public " + className + "() {");
280         pw.println("        this.impl = new " + bEntry.getName() + "Impl();");
281         pw.println("    }");
282         pw.println();
283         pw.println("    public " + className + "(" + implType + ") {");
284         pw.println("        this.impl = impl;");
285         pw.println("    }");
286 
287         // Now write each of the operation methods
288         for (int i = 0; i < operations.size(); ++i) {
289             BindingOperation operation = (BindingOperation) operations.get(i);
290             Parameters parameters =
291                     bEntry.getParameters(operation.getOperation());
292 
293             // Get the soapAction from the <soap:operation>
294             String soapAction = "";
295             Iterator operationExtensibilityIterator = operation.getExtensibilityElements().iterator();
296             for (; operationExtensibilityIterator.hasNext();) {
297                 Object obj = operationExtensibilityIterator.next();
298                 if (obj instanceof SOAPOperation) {
299                     soapAction = ((SOAPOperation) obj).getSoapActionURI();
300                     break;
301                 } else if (obj instanceof UnknownExtensibilityElement) {
302                     //TODO: After WSDL4J supports soap12, change this code
303                     UnknownExtensibilityElement unkElement = (UnknownExtensibilityElement) obj;
304                     QName name = unkElement.getElementType();
305                     if (name.getNamespaceURI().equals(Constants.URI_WSDL12_SOAP) &&
306                             name.getLocalPart().equals("operation")) {
307                         if (unkElement.getElement().getAttribute("soapAction") != null) {
308                             soapAction = unkElement.getElement().getAttribute("soapAction");
309                         }
310                     }
311                 }
312             }
313             // Get the namespace for the operation from the <soap:body>
314             // RJB: is this the right thing to do?
315             String namespace = "";
316             Iterator bindingMsgIterator = null;
317             BindingInput input = operation.getBindingInput();
318             BindingOutput output;
319             if (input != null) {
320                 bindingMsgIterator =
321                         input.getExtensibilityElements().iterator();
322             } else {
323                 output = operation.getBindingOutput();
324                 if (output != null) {
325                     bindingMsgIterator =
326                             output.getExtensibilityElements().iterator();
327                 }
328             }
329             if (bindingMsgIterator != null) {
330                 for (; bindingMsgIterator.hasNext();) {
331                     Object obj = bindingMsgIterator.next();
332                     if (obj instanceof SOAPBody) {
333                         namespace = ((SOAPBody) obj).getNamespaceURI();
334                         if (namespace == null) {
335                             namespace = symbolTable.getDefinition().getTargetNamespace();
336                         }
337                         if (namespace == null)
338                             namespace = "";
339                         break;
340                     } else if (obj instanceof UnknownExtensibilityElement) {
341                         //TODO: After WSDL4J supports soap12, change this code
342                         UnknownExtensibilityElement unkElement = (UnknownExtensibilityElement) obj;
343                         QName name = unkElement.getElementType();
344                         if (name.getNamespaceURI().equals(Constants.URI_WSDL12_SOAP) &&
345                                 name.getLocalPart().equals("body")) {
346                             namespace = unkElement.getElement().getAttribute("namespace");
347                             if (namespace == null) {
348                                 namespace = symbolTable.getDefinition().getTargetNamespace();
349                             }
350                             if (namespace == null)
351                                 namespace = "";
352                             break;
353                         }
354                     }
355                 }
356             }
357             Operation ptOperation = operation.getOperation();
358             OperationType type = ptOperation.getStyle();
359 
360             // These operation types are not supported.  The signature
361             // will be a string stating that fact.
362             if (type == OperationType.NOTIFICATION
363                     || type == OperationType.SOLICIT_RESPONSE) {
364                 pw.println(parameters.signature);
365                 pw.println();
366             } else {
367                 writeOperation(pw,
368                         operation, parameters, soapAction, namespace);
369             }
370         }
371     } // writeFileBody
372 
373     /***
374      * Write the skeleton code for the given operation.
375      */
376     private void writeOperation(PrintWriter pw,
377                                 BindingOperation operation,
378                                 Parameters parms,
379                                 String soapAction,
380                                 String namespace) {
381         writeComment(pw, operation.getDocumentationElement(), true);
382 
383         // The skeleton used to have specialized operation signatures.
384         // now the same signature is used as the portType
385         pw.println(parms.signature);
386         pw.println("    {");
387 
388         // Note: The holders are now instantiated by the runtime and passed 
389         // in as parameters.
390 
391         // Call the real implementation
392         if (parms.returnParam == null) {
393             pw.print("        ");
394         } else {
395             pw.print("        " + Utils.getParameterTypeName(parms.returnParam) + " ret = ");
396         }
397         String call = "impl." + Utils.xmlNameToJava(operation.getName()) + "(";
398         boolean needComma = false;
399         for (int i = 0; i < parms.list.size(); ++i) {
400             if (needComma)
401                 call = call + ", ";
402             else
403                 needComma = true;
404             Parameter p = (Parameter) parms.list.get(i);
405             call = call + Utils.xmlNameToJava(p.getName());
406         }
407         call = call + ")";
408         pw.println(call + ";");
409         if (parms.returnParam != null) {
410             pw.println("        return ret;");
411         }
412         pw.println("    }");
413         pw.println();
414     } // writeSkeletonOperation
415 
416 }