0001 /* 0002 * The Apache Software License, Version 1.1 0003 * 0004 * 0005 * Copyright (c) 2001-2003 The Apache Software Foundation. All rights 0006 * reserved. 0007 * 0008 * Redistribution and use in source and binary forms, with or without 0009 * modification, are permitted provided that the following conditions 0010 * are met: 0011 * 0012 * 1. Redistributions of source code must retain the above copyright 0013 * notice, this list of conditions and the following disclaimer. 0014 * 0015 * 2. Redistributions in binary form must reproduce the above copyright 0016 * notice, this list of conditions and the following disclaimer in 0017 * the documentation and/or other materials provided with the 0018 * distribution. 0019 * 0020 * 3. The end-user documentation included with the redistribution, 0021 * if any, must include the following acknowledgment: 0022 * "This product includes software developed by the 0023 * Apache Software Foundation (http://www.apache.org/)." 0024 * Alternately, this acknowledgment may appear in the software itself, 0025 * if and wherever such third-party acknowledgments normally appear. 0026 * 0027 * 4. The names "Axis" and "Apache Software Foundation" must 0028 * not be used to endorse or promote products derived from this 0029 * software without prior written permission. For written 0030 * permission, please contact apache@apache.org. 0031 * 0032 * 5. Products derived from this software may not be called "Apache", 0033 * nor may "Apache" appear in their name, without prior written 0034 * permission of the Apache Software Foundation. 0035 * 0036 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 0037 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 0038 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 0039 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 0040 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 0041 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 0042 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 0043 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 0044 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 0045 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 0046 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 0047 * SUCH DAMAGE. 0048 * ==================================================================== 0049 * 0050 * This software consists of voluntary contributions made by many 0051 * individuals on behalf of the Apache Software Foundation. For more 0052 * information on the Apache Software Foundation, please see 0053 * <http://www.apache.org/>. 0054 */ 0055 0056 package org.apache.axis.wsdl.fromJava; 0057 0058 import com.ibm.wsdl.BindingFaultImpl; 0059 import com.ibm.wsdl.extensions.soap.SOAPAddressImpl; 0060 import com.ibm.wsdl.extensions.soap.SOAPBindingImpl; 0061 import com.ibm.wsdl.extensions.soap.SOAPBodyImpl; 0062 import com.ibm.wsdl.extensions.soap.SOAPOperationImpl; 0063 import org.apache.axis.AxisFault; 0064 import org.apache.axis.Constants; 0065 import org.apache.axis.description.FaultDesc; 0066 import org.apache.axis.description.OperationDesc; 0067 import org.apache.axis.description.ParameterDesc; 0068 import org.apache.axis.description.ServiceDesc; 0069 import org.apache.axis.encoding.DefaultTypeMappingImpl; 0070 import org.apache.axis.encoding.TypeMapping; 0071 import org.apache.axis.enum.Style; 0072 import org.apache.axis.enum.Use; 0073 import org.apache.axis.utils.ClassUtils; 0074 import org.apache.axis.utils.JavaUtils; 0075 import org.apache.axis.utils.XMLUtils; 0076 import org.w3c.dom.Document; 0077 import org.w3c.dom.Element; 0078 import org.xml.sax.SAXException; 0079 0080 import javax.wsdl.Binding; 0081 import javax.wsdl.BindingFault; 0082 import javax.wsdl.BindingInput; 0083 import javax.wsdl.BindingOperation; 0084 import javax.wsdl.BindingOutput; 0085 import javax.wsdl.Definition; 0086 import javax.wsdl.Fault; 0087 import javax.wsdl.Import; 0088 import javax.wsdl.Input; 0089 import javax.wsdl.Message; 0090 import javax.wsdl.Operation; 0091 import javax.wsdl.Output; 0092 import javax.wsdl.Part; 0093 import javax.wsdl.Port; 0094 import javax.wsdl.PortType; 0095 import javax.wsdl.Service; 0096 import javax.wsdl.WSDLException; 0097 import javax.wsdl.extensions.ExtensibilityElement; 0098 import javax.wsdl.extensions.soap.SOAPAddress; 0099 import javax.wsdl.extensions.soap.SOAPBinding; 0100 import javax.wsdl.extensions.soap.SOAPBody; 0101 import javax.wsdl.extensions.soap.SOAPFault; 0102 import javax.wsdl.extensions.soap.SOAPOperation; 0103 import javax.wsdl.factory.WSDLFactory; 0104 import javax.xml.namespace.QName; 0105 import javax.xml.parsers.ParserConfigurationException; 0106 import java.io.File; 0107 import java.io.FileOutputStream; 0108 import java.io.IOException; 0109 import java.io.StringWriter; 0110 import java.util.ArrayList; 0111 import java.util.HashMap; 0112 import java.util.Iterator; 0113 import java.util.Map; 0114 import java.util.StringTokenizer; 0115 import java.util.Vector; 0116 0117 /** 0118 * This class emits WSDL from Java classes. It is used by the ?WSDL 0119 * Axis browser function and Java2WSDL commandline utility. 0120 * See Java2WSDL and Java2WSDLFactory for more information. 0121 * 0122 * @author Glen Daniels (gdaniels@macromedia.com) 0123 * @author Rich Scheuerle (scheu@us.ibm.com) 0124 */ 0125 public class Emitter { 0126 // Generated WSDL Modes 0127 public static final int MODE_ALL = 0; 0128 public static final int MODE_INTERFACE = 1; 0129 public static final int MODE_IMPLEMENTATION = 2; 0130 0131 private Class cls; 0132 private Class[] extraClasses; // Extra classes to emit WSDL for 0133 private Class implCls; // Optional implementation class 0134 private Vector allowedMethods = null; // Names of methods to consider 0135 private Vector disallowedMethods = null; // Names of methods to exclude 0136 private ArrayList stopClasses = new ArrayList();// class names which halt inheritace searches 0137 private boolean useInheritedMethods = false; 0138 private String intfNS; 0139 private String implNS; 0140 private String inputSchema; 0141 private String inputWSDL; 0142 private String locationUrl; 0143 private String importUrl; 0144 private String servicePortName; 0145 private String serviceElementName; 0146 private String targetService = null; 0147 private String description; 0148 private Style style = Style.RPC; 0149 private Use use = null; // Default depends on style setting 0150 private TypeMapping tm = null; // Registered type mapping 0151 private TypeMapping defaultTM = null; // Default TM 0152 private Namespaces namespaces; 0153 private Map exceptionMsg = null; 0154 0155 private ArrayList encodingList; 0156 protected Types types; 0157 private String clsName; 0158 private String portTypeName; 0159 private String bindingName; 0160 0161 private ServiceDesc serviceDesc; 0162 private ServiceDesc serviceDesc2; 0163 private String soapAction = "DEFAULT"; 0164 0165 // Style Modes 0166 /** DEPRECATED - Indicates style=rpc use=encoded */ 0167 public static final int MODE_RPC = 0; 0168 /** DEPRECATED - Indicates style=document use=literal */ 0169 public static final int MODE_DOCUMENT = 1; 0170 /** DEPRECATED - Indicates style=wrapped use=literal */ 0171 public static final int MODE_DOC_WRAPPED = 2; 0172 0173 /** 0174 * Construct Emitter. 0175 * Set the contextual information using set* methods 0176 * Invoke emit to emit the code 0177 */ 0178 public Emitter () { 0179 namespaces = new Namespaces(); 0180 exceptionMsg = new HashMap(); 0181 } 0182 0183 /** 0184 * Generates WSDL documents for a given <code>Class</code> 0185 * 0186 * @param filename1 interface WSDL 0187 * @param filename2 implementation WSDL 0188 * @throws IOException 0189 * @throws WSDLException 0190 * @throws SAXException 0191 * @throws ParserConfigurationException 0192 */ 0193 public void emit(String filename1, String filename2) 0194 throws IOException, WSDLException, 0195 SAXException, ParserConfigurationException 0196 { 0197 // Get interface and implementation defs 0198 Definition intf = getIntfWSDL(); 0199 Definition impl = getImplWSDL(); 0200 0201 // Supply reasonable file names if not supplied 0202 if (filename1 == null) { 0203 filename1 = getServicePortName() + "_interface.wsdl"; 0204 } 0205 if (filename2 == null) { 0206 filename2 = getServicePortName() + "_implementation.wsdl"; 0207 } 0208 0209 for (int i = 0; extraClasses != null && i < extraClasses.length; i++) { 0210 types.writeTypeForPart(extraClasses[i], null); 0211 } 0212 //types.updateNamespaces(); 0213 // Write out the interface def 0214 Document doc = WSDLFactory.newInstance(). 0215 newWSDLWriter().getDocument(intf); 0216 types.insertTypesFragment(doc); 0217 prettyDocumentToFile(doc, filename1); 0218 0219 // Write out the implementation def 0220 doc = WSDLFactory.newInstance().newWSDLWriter().getDocument(impl); 0221 prettyDocumentToFile(doc, filename2); 0222 } 0223 0224 /** 0225 * Generates a complete WSDL document for a given <code>Class</code> 0226 * 0227 * @param filename WSDL 0228 * @throws IOException 0229 * @throws WSDLException 0230 * @throws SAXException 0231 * @throws ParserConfigurationException 0232 */ 0233 public void emit(String filename) 0234 throws IOException, WSDLException, 0235 SAXException, ParserConfigurationException 0236 { 0237 emit(filename, MODE_ALL); 0238 } 0239 0240 /** 0241 * Generates a WSDL document for a given <code>Class</code>. 0242 * The WSDL generated is controlled by the mode parameter 0243 * mode 0: All 0244 * mode 1: Interface 0245 * mode 2: Implementation 0246 * 0247 * @param mode generation mode - all, interface, implementation 0248 * @return Document 0249 * @throws IOException 0250 * @throws WSDLException 0251 * @throws SAXException 0252 * @throws ParserConfigurationException 0253 */ 0254 public Document emit(int mode) 0255 throws IOException, WSDLException, 0256 SAXException, ParserConfigurationException 0257 { 0258 Document doc = null; 0259 Definition def = null; 0260 switch (mode) { 0261 case MODE_ALL: 0262 def = getWSDL(); 0263 for (int i = 0; extraClasses != null && i < extraClasses.length; i++) { 0264 types.writeTypeForPart(extraClasses[i], null); 0265 } 0266 //types.updateNamespaces(); 0267 doc = WSDLFactory.newInstance(). 0268 newWSDLWriter().getDocument(def); 0269 types.insertTypesFragment(doc); 0270 break; 0271 case MODE_INTERFACE: 0272 def = getIntfWSDL(); 0273 for (int i = 0; extraClasses != null && i < extraClasses.length; i++) { 0274 types.writeTypeForPart(extraClasses[i], null); 0275 } 0276 //types.updateNamespaces(); 0277 doc = WSDLFactory.newInstance(). 0278 newWSDLWriter().getDocument(def); 0279 types.insertTypesFragment(doc); 0280 break; 0281 case MODE_IMPLEMENTATION: 0282 def = getImplWSDL(); 0283 doc = WSDLFactory.newInstance(). 0284 newWSDLWriter().getDocument(def); 0285 break; 0286 } 0287 0288 // Return the document 0289 return doc; 0290 } 0291 0292 /** 0293 * Generates a String containing the WSDL for a given <code>Class</code>. 0294 * The WSDL generated is controlled by the mode parameter 0295 * mode 0: All 0296 * mode 1: Interface 0297 * mode 2: Implementation 0298 * 0299 * @param mode generation mode - all, interface, implementation 0300 * @return String 0301 * @throws IOException 0302 * @throws WSDLException 0303 * @throws SAXException 0304 * @throws ParserConfigurationException 0305 */ 0306 public String emitToString(int mode) 0307 throws IOException, WSDLException, 0308 SAXException, ParserConfigurationException 0309 { 0310 Document doc = emit(mode); 0311 StringWriter sw = new StringWriter(); 0312 XMLUtils.PrettyDocumentToWriter(doc, sw); 0313 return sw.toString(); 0314 } 0315 0316 /** 0317 * Generates a WSDL document for a given <code>Class</code>. 0318 * The WSDL generated is controlled by the mode parameter 0319 * mode 0: All 0320 * mode 1: Interface 0321 * mode 2: Implementation 0322 * 0323 * @param filename WSDL 0324 * @param mode generation mode - all, interface, implementation 0325 * @throws IOException 0326 * @throws WSDLException 0327 * @throws SAXException 0328 * @throws ParserConfigurationException 0329 */ 0330 public void emit(String filename, int mode) 0331 throws IOException, WSDLException, 0332 SAXException, ParserConfigurationException 0333 { 0334 Document doc = emit(mode); 0335 0336 // Supply a reasonable file name if not supplied 0337 if (filename == null) { 0338 filename = getServicePortName(); 0339 switch (mode) { 0340 case MODE_ALL: 0341 filename +=".wsdl"; 0342 break; 0343 case MODE_INTERFACE: 0344 filename +="_interface.wsdl"; 0345 break; 0346 case MODE_IMPLEMENTATION: 0347 filename +="_implementation.wsdl"; 0348 break; 0349 } 0350 } 0351 0352 prettyDocumentToFile(doc, filename); 0353 } 0354 0355 /** 0356 * Get a Full WSDL <code>Definition</code> for the current 0357 * configuration parameters 0358 * 0359 * @return WSDL <code>Definition</code> 0360 * @throws IOException 0361 * @throws WSDLException 0362 * @throws SAXException 0363 * @throws ParserConfigurationException 0364 */ 0365 public Definition getWSDL() 0366 throws IOException, WSDLException, 0367 SAXException, ParserConfigurationException 0368 { 0369 // Invoke the init() method to ensure configuration is setup 0370 init(MODE_ALL); 0371 0372 // Create a Definition for the output wsdl 0373 Definition def = createDefinition(); 0374 0375 // Write interface header 0376 writeDefinitions(def, intfNS); 0377 0378 // Create Types 0379 types = createTypes(def); 0380 0381 // Write the WSDL constructs and return full Definition 0382 Binding binding = writeBinding(def, true); 0383 writePortType(def, binding); 0384 writeService(def, binding); 0385 return def; 0386 } 0387 0388 /** 0389 * Get a interface WSDL <code>Definition</code> for the 0390 * current configuration parameters 0391 * 0392 * @return WSDL <code>Definition</code> 0393 * @throws IOException 0394 * @throws WSDLException 0395 * @throws SAXException 0396 * @throws ParserConfigurationException 0397 */ 0398 public Definition getIntfWSDL() 0399 throws IOException, WSDLException, 0400 SAXException, ParserConfigurationException 0401 { 0402 // Invoke the init() method to ensure configuration is setup 0403 init(MODE_INTERFACE); 0404 0405 // Create a definition for the output wsdl 0406 Definition def = createDefinition(); 0407 0408 // Write interface header 0409 writeDefinitions(def, intfNS); 0410 0411 // Create Types 0412 types = createTypes(def); 0413 0414 // Write the interface WSDL constructs and return the Definition 0415 Binding binding = writeBinding(def, true); 0416 writePortType(def, binding); 0417 return def; 0418 } 0419 0420 /** 0421 * Get implementation WSDL <code>Definition</code> for the 0422 * current configuration parameters 0423 * 0424 * @return WSDL <code>Definition</code> 0425 * @throws IOException 0426 * @throws WSDLException 0427 * @throws SAXException 0428 * @throws ParserConfigurationException 0429 */ 0430 public Definition getImplWSDL() 0431 throws IOException, WSDLException, 0432 SAXException, ParserConfigurationException { 0433 // Invoke the init() method to ensure configuration is setup 0434 init(MODE_IMPLEMENTATION); 0435 0436 // Create a Definition for the output wsdl 0437 Definition def = createDefinition(); 0438 0439 // Write implementation header and import 0440 writeDefinitions(def, implNS); 0441 writeImport(def, intfNS, importUrl); 0442 0443 // Write the implementation WSDL constructs and return Definition 0444 Binding binding = writeBinding(def, false); // Don't add binding to def 0445 writeService(def, binding); 0446 return def; 0447 } 0448 0449 /** 0450 * Invoked prior to building a definition to ensure parms 0451 * and data are set up. 0452 */ 0453 protected void init(int mode) { 0454 0455 // Default use depending on setting of style 0456 if (use == null) { 0457 if (style == Style.RPC) { 0458 use = Use.ENCODED; 0459 } else { 0460 use = Use.LITERAL; 0461 } 0462 } 0463 0464 // Get a default TM if not specified. 0465 if (defaultTM == null) { 0466 defaultTM = DefaultTypeMappingImpl.getSingleton(); 0467 } 0468 0469 // Set up a ServiceDesc to use to introspect the Service 0470 if (serviceDesc == null) { 0471 serviceDesc = new ServiceDesc(); 0472 serviceDesc.setImplClass(cls); 0473 0474 // Set the typeMapping to the one provided. 0475 // If not available use the default TM 0476 if (tm != null) { 0477 serviceDesc.setTypeMapping(tm); 0478 } else { 0479 serviceDesc.setTypeMapping(defaultTM); 0480 } 0481 0482 serviceDesc.setStopClasses(stopClasses); 0483 serviceDesc.setAllowedMethods(allowedMethods); 0484 serviceDesc.setDisallowedMethods(disallowedMethods); 0485 serviceDesc.setStyle(style); 0486 0487 // If the class passed in is a portType, 0488 // there may be an implClass that is used to 0489 // obtain the method parameter names. In this case, 0490 // a serviceDesc2 is built to get the method parameter names. 0491 if (implCls != null && 0492 implCls != cls && 0493 serviceDesc2 == null) { 0494 serviceDesc2 = new ServiceDesc(); 0495 serviceDesc2.setImplClass(implCls); 0496 0497 // Set the typeMapping to the one provided. 0498 // If not available use the default TM 0499 if (tm != null) { 0500 serviceDesc2.setTypeMapping(tm); 0501 } else { 0502 serviceDesc2.setTypeMapping(defaultTM); 0503 } 0504 serviceDesc2.setStopClasses(stopClasses); 0505 serviceDesc2.setAllowedMethods(allowedMethods); 0506 serviceDesc2.setDisallowedMethods(disallowedMethods); 0507 serviceDesc2.setStyle(style); 0508 } 0509 } 0510 0511 if (encodingList == null) { 0512 clsName = cls.getName(); 0513 clsName = clsName.substring(clsName.lastIndexOf('.') + 1); 0514 0515 // Default the portType name 0516 if (getPortTypeName() == null) { 0517 setPortTypeName(clsName); 0518 } 0519 0520 // Default the serviceElementName 0521 if (getServiceElementName() == null) { 0522 setServiceElementName(getPortTypeName() + "Service"); 0523 } 0524 0525 // If service port name is null, construct it from location or className 0526 if (getServicePortName() == null) { 0527 String name = getLocationUrl(); 0528 if (name != null) { 0529 if (name.lastIndexOf('/') > 0) { 0530 name = name.substring(name.lastIndexOf('/') + 1); 0531 } else if (name.lastIndexOf('\\') > 0) { 0532 name = name.substring(name.lastIndexOf('\\') + 1); 0533 } else { 0534 name = null; 0535 } 0536 // if we got the name from the location, strip .jws from it 0537 if (name != null && name.endsWith(".jws") ) { 0538 name = name.substring(0, 0539 (name.length() - ".jws".length())); 0540 } 0541 } 0542 if (name == null || name.equals("")) { 0543 name = clsName; 0544 } 0545 setServicePortName(name); 0546 } 0547 0548 // Default the bindingName 0549 if (getBindingName() == null) { 0550 setBindingName(getServicePortName() + "SoapBinding"); 0551 } 0552 0553 encodingList = new ArrayList(); 0554 encodingList.add(Constants.URI_DEFAULT_SOAP_ENC); 0555 0556 if (intfNS == null) { 0557 Package pkg = cls.getPackage(); 0558 intfNS = namespaces.getCreate( 0559 pkg == null ? null : pkg.getName()); 0560 } 0561 // Default the implementation namespace to the interface 0562 // namespace if not split wsdl mode. 0563 if (implNS == null) { 0564 if (mode == MODE_ALL) { 0565 implNS = intfNS; 0566 } else { 0567 implNS = intfNS + "-impl"; 0568 } 0569 } 0570 0571 // set the namespaces in the serviceDesc(s) 0572 serviceDesc.setDefaultNamespace(intfNS); 0573 if (serviceDesc2 != null) { 0574 serviceDesc2.setDefaultNamespace(implNS); 0575 } 0576 0577 if(cls != null) { 0578 namespaces.put(cls.getName(), intfNS, "intf"); 0579 } 0580 namespaces.putPrefix(implNS, "impl"); 0581 } 0582 } 0583 0584 0585 /** 0586 * Build a Definition from the input wsdl file or create 0587 * a new Definition 0588 * 0589 * @return WSDL Definition 0590 */ 0591 protected Definition createDefinition() 0592 throws WSDLException, SAXException, IOException, 0593 ParserConfigurationException { 0594 Definition def; 0595 if (inputWSDL == null) { 0596 def = WSDLFactory.newInstance().newDefinition(); 0597 } else { 0598 javax.wsdl.xml.WSDLReader reader = 0599 WSDLFactory.newInstance().newWSDLReader(); 0600 Document doc = XMLUtils.newDocument(inputWSDL); 0601 def = reader.readWSDL(null, doc); 0602 // The input wsdl types section is deleted. The 0603 // types will be added back in at the end of processing. 0604 def.setTypes(null); 0605 } 0606 return def; 0607 } 0608 0609 protected static TypeMapping standardTypes = 0610 (TypeMapping)new org.apache.axis.encoding.TypeMappingRegistryImpl().getTypeMapping(null); 0611 0612 0613 /** 0614 * Build a Types object and load the input wsdl types 0615 * @param def Corresponding wsdl Definition 0616 * @return Types object 0617 */ 0618 protected Types createTypes(Definition def) 0619 throws IOException, WSDLException, SAXException, 0620 ParserConfigurationException { 0621 types = new Types(def, tm, defaultTM, namespaces, 0622 intfNS, stopClasses, serviceDesc); 0623 if (inputWSDL != null) { 0624 types.loadInputTypes(inputWSDL); 0625 } 0626 if (inputSchema != null) { 0627 types.loadInputSchema(inputSchema); 0628 } 0629 0630 if (tm != null) 0631 { 0632 Class [] mappedTypes = tm.getAllClasses(); 0633 for (int i = 0; i < mappedTypes.length; i++) 0634 { 0635 Class mappedType = mappedTypes[i]; 0636 QName name = tm.getTypeQName(mappedType); 0637 /** 0638 * If it's a non-standard type, make sure it shows up in 0639 * our WSDL 0640 */ 0641 if (standardTypes.getSerializer(mappedType) == null) 0642 { 0643 types.writeTypeForPart(mappedType, name); 0644 } 0645 } 0646 } 0647 0648 return types; 0649 } 0650 0651 0652 /** 0653 * Create the definition header information. 0654 * 0655 * @param def <code>Definition</code> 0656 * @param tns target namespace 0657 */ 0658 protected void writeDefinitions(Definition def, String tns) { 0659 def.setTargetNamespace(tns); 0660 0661 def.addNamespace("intf", intfNS); 0662 def.addNamespace("impl", implNS); 0663 0664 def.addNamespace(Constants.NS_PREFIX_WSDL_SOAP, 0665 Constants.URI_WSDL11_SOAP); 0666 namespaces.putPrefix(Constants.URI_WSDL11_SOAP, 0667 Constants.NS_PREFIX_WSDL_SOAP); 0668 0669 def.addNamespace(Constants.NS_PREFIX_WSDL, 0670 Constants.NS_URI_WSDL11); 0671 namespaces.putPrefix(Constants.NS_URI_WSDL11, 0672 Constants.NS_PREFIX_WSDL); 0673 0674 def.addNamespace(Constants.NS_PREFIX_SOAP_ENC, 0675 Constants.URI_DEFAULT_SOAP_ENC); 0676 namespaces.putPrefix(Constants.URI_DEFAULT_SOAP_ENC, 0677 Constants.NS_PREFIX_SOAP_ENC); 0678 0679 def.addNamespace(Constants.NS_PREFIX_SCHEMA_XSD, 0680 Constants.URI_DEFAULT_SCHEMA_XSD); 0681 namespaces.putPrefix(Constants.URI_DEFAULT_SCHEMA_XSD, 0682 Constants.NS_PREFIX_SCHEMA_XSD); 0683 0684 def.addNamespace(Constants.NS_PREFIX_XMLSOAP, 0685 Constants.NS_URI_XMLSOAP); 0686 namespaces.putPrefix(Constants.NS_URI_XMLSOAP, 0687 Constants.NS_PREFIX_XMLSOAP); 0688 } 0689 0690 /** 0691 * Create and add an import 0692 * 0693 * @param def <code>Definition</code> 0694 * @param tns target namespace 0695 * @param loc target location 0696 */ 0697 protected void writeImport(Definition def, String tns, String loc) { 0698 Import imp = def.createImport(); 0699 0700 imp.setNamespaceURI(tns); 0701 if (loc != null && !loc.equals("")) 0702 imp.setLocationURI(loc); 0703 def.addImport(imp); 0704 } 0705 0706 /** 0707 * Create the binding. 0708 * 0709 * @param def <code>Definition</code> 0710 * @param add true if binding should be added to the def 0711 */ 0712 protected Binding writeBinding(Definition def, boolean add) { 0713 QName bindingQName = 0714 new QName(intfNS, getBindingName()); 0715 0716 // If a binding already exists, don't replace it. 0717 Binding binding = def.getBinding(bindingQName); 0718 if (binding != null) { 0719 return binding; 0720 } 0721 0722 // Create a binding 0723 binding = def.createBinding(); 0724 binding.setUndefined(false); 0725 binding.setQName(bindingQName); 0726 0727 SOAPBinding soapBinding = new SOAPBindingImpl(); 0728 String styleStr = (style == Style.RPC) ? "rpc" : "document"; 0729 soapBinding.setStyle(styleStr); 0730 soapBinding.setTransportURI(Constants.URI_SOAP11_HTTP); 0731 0732 binding.addExtensibilityElement(soapBinding); 0733 0734 if (add) { 0735 def.addBinding(binding); 0736 } 0737 return binding; 0738 } 0739 0740 /** 0741 * Create the service. 0742 * 0743 * @param def 0744 * @param binding 0745 */ 0746 protected void writeService(Definition def, Binding binding) { 0747 0748 QName serviceElementQName = 0749 new QName(implNS, 0750 getServiceElementName()); 0751 0752 // Locate an existing service, or get a new service 0753 Service service = def.getService(serviceElementQName); 0754 if (service == null) { 0755 service = def.createService(); 0756 service.setQName(serviceElementQName); 0757 def.addService(service); 0758 } 0759 0760 // Add the port 0761 Port port = def.createPort(); 0762 port.setBinding(binding); 0763 // Probably should use the end of the location Url 0764 port.setName(getServicePortName()); 0765 0766 SOAPAddress addr = new SOAPAddressImpl(); 0767 addr.setLocationURI(locationUrl); 0768 0769 port.addExtensibilityElement(addr); 0770 0771 service.addPort(port); 0772 } 0773 0774 /** Create a PortType 0775 * 0776 * @param def 0777 * @param binding 0778 * @throws WSDLException 0779 * @throws AxisFault 0780 */ 0781 protected void writePortType(Definition def, Binding binding) 0782 throws WSDLException, AxisFault { 0783 0784 QName portTypeQName = new QName(intfNS, getPortTypeName()); 0785 0786 // Get or create a portType 0787 PortType portType = def.getPortType(portTypeQName); 0788 boolean newPortType = false; 0789 if (portType == null) { 0790 portType = def.createPortType(); 0791 portType.setUndefined(false); 0792 portType.setQName(portTypeQName); 0793 newPortType = true; 0794 } else if (binding.getBindingOperations().size() > 0) { 0795 // If both portType and binding already exist, 0796 // no additional processing is needed. 0797 return; 0798 } 0799 0800 // Add the port and binding operations. 0801 ArrayList operations = serviceDesc.getOperations(); 0802 for (Iterator i = operations.iterator(); i.hasNext();) { 0803 OperationDesc thisOper = (OperationDesc)i.next(); 0804 0805 BindingOperation bindingOper = writeOperation(def, 0806 binding, 0807 thisOper); 0808 Operation oper = bindingOper.getOperation(); 0809 0810 OperationDesc messageOper = thisOper; 0811 if (serviceDesc2 != null) { 0812 // If a serviceDesc containing an impl class is provided, 0813 // try and locate the corresponding operation 0814 // (same name, same parm types and modes). If a 0815 // corresponding operation is found, it is sent 0816 // to the writeMessages method so that its parameter 0817 // names will be used in the wsdl file. 0818 OperationDesc[] operArray = 0819 serviceDesc2.getOperationsByName(thisOper.getName()); 0820 boolean found = false; 0821 if (operArray != null) { 0822 for (int j=0; 0823 j < operArray.length && !found; 0824 j++) { 0825 OperationDesc tryOper = operArray[j]; 0826 if (tryOper.getParameters().size() == 0827 thisOper.getParameters().size()) { 0828 boolean parmsMatch = true; 0829 for (int k=0; 0830 k<thisOper.getParameters().size() && parmsMatch; 0831 k++) { 0832 if (tryOper.getParameter(k).getMode() != 0833 thisOper.getParameter(k).getMode() || 0834 (! tryOper.getParameter(k).getJavaType(). 0835 equals(thisOper.getParameter(k).getJavaType()))) { 0836 parmsMatch = false; 0837 } 0838 } 0839 if (parmsMatch) { 0840 messageOper = tryOper; 0841 found = true; 0842 } 0843 } 0844 } 0845 } 0846 } 0847 0848 writeMessages(def, oper, messageOper, 0849 bindingOper); 0850 if (newPortType) { 0851 portType.addOperation(oper); 0852 } 0853 } 0854 0855 if (newPortType) { 0856 def.addPortType(portType); 0857 } 0858 0859 binding.setPortType(portType); 0860 } 0861 0862 /** Create a Message 0863 * 0864 * @param def Definition, the WSDL definition 0865 * @param oper Operation, the wsdl operation 0866 * @param desc OperationDesc, the Operation Description 0867 * @param bindingOper BindingOperation, corresponding Binding Operation 0868 * @throws WSDLException 0869 * @throws AxisFault 0870 */ 0871 protected void writeMessages(Definition def, 0872 Operation oper, 0873 OperationDesc desc, 0874 BindingOperation bindingOper) 0875 throws WSDLException, AxisFault { 0876 Input input = def.createInput(); 0877 0878 Message msg = writeRequestMessage(def, desc); 0879 input.setMessage(msg); 0880 0881 // Give the input element a name that matches the 0882 // message. This is necessary for overloading. 0883 // The msg QName is unique. 0884 String name = msg.getQName().getLocalPart(); 0885 input.setName(name); 0886 bindingOper.getBindingInput().setName(name); 0887 0888 oper.setInput(input); 0889 def.addMessage(msg); 0890 0891 msg = writeResponseMessage(def, desc); 0892 Output output = def.createOutput(); 0893 output.setMessage(msg); 0894 0895 // Give the output element a name that matches the 0896 // message. This is necessary for overloading. 0897 // The message QName is unique. 0898 name = msg.getQName().getLocalPart(); 0899 output.setName(name); 0900 bindingOper.getBindingOutput().setName(name); 0901 0902 oper.setOutput(output); 0903 def.addMessage(msg); 0904 0905 ArrayList exceptions = desc.getFaults(); 0906 0907 for (int i = 0; exceptions != null && i < exceptions.size(); i++) { 0908 FaultDesc faultDesc = (FaultDesc) exceptions.get(i); 0909 msg = writeFaultMessage(def, faultDesc); 0910 0911 // Add the fault to the portType 0912 Fault fault = def.createFault(); 0913 fault.setMessage(msg); 0914 fault.setName(faultDesc.getName()); 0915 oper.addFault(fault); 0916 0917 // Add the fault to the binding 0918 BindingFault bFault = def.createBindingFault(); 0919 bFault.setName(faultDesc.getName()); 0920 SOAPFault soapFault = writeSOAPFault(faultDesc); 0921 bFault.addExtensibilityElement(soapFault); 0922 bindingOper.addBindingFault(bFault); 0923 0924 // Add the fault message 0925 if (def.getMessage(msg.getQName()) == null) { 0926 def.addMessage(msg); 0927 } 0928 } 0929 0930 // Set the parameter ordering using the parameter names 0931 ArrayList parameters = desc.getParameters(); 0932 Vector names = new Vector(); 0933 for (int i = 0; i < parameters.size(); i++) { 0934 ParameterDesc param = (ParameterDesc)parameters.get(i); 0935 names.add(param.getName()); 0936 } 0937 0938 if (names.size() > 0) { 0939 if (style == Style.WRAPPED) { 0940 names.clear(); 0941 } 0942 oper.setParameterOrdering(names); 0943 } 0944 } 0945 0946 /** Create a Operation 0947 * 0948 * @param def 0949 * @param binding 0950 */ 0951 protected BindingOperation writeOperation(Definition def, 0952 Binding binding, 0953 OperationDesc desc) { 0954 Operation oper = def.createOperation(); 0955 oper.setName(desc.getName()); 0956 oper.setUndefined(false); 0957 return writeBindingOperation(def, binding, oper, desc); 0958 } 0959 0960 /** Create a Binding Operation 0961 * 0962 * @param def 0963 * @param binding 0964 * @param oper 0965 */ 0966 protected BindingOperation writeBindingOperation (Definition def, 0967 Binding binding, 0968 Operation oper, 0969 OperationDesc desc) { 0970 BindingOperation bindingOper = def.createBindingOperation(); 0971 BindingInput bindingInput = def.createBindingInput(); 0972 BindingOutput bindingOutput = def.createBindingOutput(); 0973 0974 bindingOper.setName(oper.getName()); 0975 bindingOper.setOperation(oper); 0976 0977 SOAPOperation soapOper = new SOAPOperationImpl(); 0978 0979 0980 // If the soapAction option is OPERATION, force 0981 // soapAction to the name of the operation. If NONE, 0982 // force soapAction to "". 0983 // Otherwise use the information in the operationDesc. 0984 String soapAction = ""; 0985 if (getSoapAction().equals("OPERATION")) { 0986 soapAction = oper.getName(); 0987 } else if (getSoapAction().equals("NONE")) { 0988 soapAction = ""; 0989 } else { 0990 soapAction = desc.getSoapAction(); 0991 if (soapAction == null) { 0992 soapAction = ""; 0993 } 0994 } 0995 soapOper.setSoapActionURI(soapAction); 0996 0997 // Until we have per-operation configuration, this will always be 0998 // the same as the binding default. 0999 // soapOper.setStyle("rpc"); 1000 1001 bindingOper.addExtensibilityElement(soapOper); 1002 1003 // Input clause 1004 ExtensibilityElement input = null; 1005 input = writeSOAPBody(desc.getElementQName()); 1006 bindingInput.addExtensibilityElement(input); 1007 1008 //Output clause 1009 ExtensibilityElement output = null; 1010 output = writeSOAPBody(desc.getReturnQName()); 1011 1012 bindingOutput.addExtensibilityElement(output); 1013 1014 // Ad input and output to operation 1015 bindingOper.setBindingInput(bindingInput); 1016 bindingOper.setBindingOutput(bindingOutput); 1017 1018 // Faults clause 1019 ArrayList faultList = desc.getFaults(); 1020 if (faultList != null) { 1021 for (Iterator it = faultList.iterator(); it.hasNext();) { 1022 FaultDesc faultDesc = (FaultDesc) it.next(); 1023 // Get a soap:fault 1024 ExtensibilityElement soapFault = writeSOAPFault(faultDesc); 1025 // Get a wsdl:fault to put the soap:fault in 1026 BindingFault bindingFault = new BindingFaultImpl(); 1027 bindingFault.setName(faultDesc.getName()); 1028 bindingFault.addExtensibilityElement(soapFault); 1029 bindingOper.addBindingFault(bindingFault); 1030 } 1031 } 1032 1033 binding.addBindingOperation(bindingOper); 1034 1035 return bindingOper; 1036 } 1037 1038 protected ExtensibilityElement writeSOAPBody(QName operQName) { 1039 SOAPBody soapBody = new SOAPBodyImpl(); 1040 // for now, if its document, it is literal use. 1041 if (use == Use.ENCODED) { 1042 soapBody.setUse("encoded"); 1043 soapBody.setEncodingStyles(encodingList); 1044 } else { 1045 soapBody.setUse("literal"); 1046 } 1047 if (targetService == null) 1048 soapBody.setNamespaceURI(intfNS); 1049 else 1050 soapBody.setNamespaceURI(targetService); 1051 if (operQName != null && 1052 !operQName.getNamespaceURI().equals("")) { 1053 soapBody.setNamespaceURI(operQName.getNamespaceURI()); 1054 } 1055 return soapBody; 1056 } // writeSOAPBody 1057 1058 protected SOAPFault writeSOAPFault(FaultDesc faultDesc) { 1059 SOAPFault soapFault = new com.ibm.wsdl.extensions.soap.SOAPFaultImpl(); 1060 if (use != Use.ENCODED) { 1061 soapFault.setUse("literal"); 1062 // no namespace for literal, gets it from the element 1063 } else { 1064 soapFault.setUse("encoded"); 1065 soapFault.setEncodingStyles(encodingList); 1066 1067 // Set the namespace from the fault QName if it exists 1068 // otherwise use the target (or interface) namespace 1069 QName faultQName = faultDesc.getQName(); 1070 if (faultQName != null && 1071 !faultQName.getNamespaceURI().equals("")) { 1072 soapFault.setNamespaceURI(faultQName.getNamespaceURI()); 1073 } else { 1074 if (targetService == null) { 1075 soapFault.setNamespaceURI(intfNS); 1076 } else { 1077 soapFault.setNamespaceURI(targetService); 1078 } 1079 } 1080 } 1081 return soapFault; 1082 } // writeSOAPFault 1083 1084 1085 /** Create a Request Message 1086 * 1087 * @param def 1088 * @throws WSDLException 1089 * @throws AxisFault 1090 */ 1091 protected Message writeRequestMessage(Definition def, 1092 OperationDesc oper) 1093 throws WSDLException, AxisFault 1094 { 1095 Message msg = def.createMessage(); 1096 1097 QName qName = createMessageName(def, oper.getName() + "Request"); 1098 1099 msg.setQName(qName); 1100 msg.setUndefined(false); 1101 1102 if (oper.getStyle() == Style.MESSAGE) { 1103 // If this is a MESSAGE-style operation, just write out 1104 // <xsd:any> for now. 1105 // TODO: Support custom schema in WSDD for these operations 1106 QName qname = oper.getElementQName(); 1107 Element el = types.createElementDecl(qname.getLocalPart(), 1108 Object.class, 1109 Constants.XSD_ANYTYPE, 1110 false, false); 1111 types.writeSchemaElement(qname, el); 1112 1113 Part part = def.createPart(); 1114 part.setName("part"); 1115 part.setElementName(qname); 1116 msg.addPart(part); 1117 } else if (oper.getStyle() == Style.WRAPPED) { 1118 // If we're WRAPPED, write the wrapper element first, and then 1119 // fill in any params. If there aren't any params, we'll see 1120 // an empty <complexType/> for the wrapper element. 1121 writeWrapperPart(def, msg, oper, true); 1122 } else { 1123 // Otherwise, write parts for the parameters. 1124 ArrayList parameters = oper.getParameters(); 1125 for(int i=0; i<parameters.size(); i++) { 1126 ParameterDesc parameter = (ParameterDesc) parameters.get(i); 1127 writePartToMessage(def, msg, true, parameter); 1128 } 1129 } 1130 1131 return msg; 1132 } 1133 1134 protected QName getRequestQName(OperationDesc oper) { 1135 QName qname = oper.getElementQName(); 1136 if (qname == null) { 1137 qname = new QName(oper.getName()); 1138 } 1139 return qname; 1140 } 1141 protected QName getResponseQName(OperationDesc oper) { 1142 QName qname = oper.getElementQName(); 1143 if (qname == null) { 1144 return new QName(oper.getName() + "Response"); 1145 } 1146 return new QName(qname.getNamespaceURI(), 1147 qname.getLocalPart() + "Response"); 1148 } 1149 /** 1150 * Write out the schema definition for a WRAPPED operation request or 1151 * response. 1152 * 1153 * @param oper 1154 * @param request 1155 */ 1156 public void writeWrapperPart(Definition def, Message msg, 1157 OperationDesc oper, boolean request) 1158 throws AxisFault { 1159 QName qname = request ? getRequestQName(oper) : getResponseQName(oper) ; 1160 boolean hasParams = false; 1161 if (request) { 1162 hasParams = (oper.getNumInParams() > 0); 1163 } else { 1164 if (oper.getReturnClass() != void.class) { 1165 hasParams = true; 1166 } else { 1167 hasParams = (oper.getNumOutParams() > 0); 1168 } 1169 } 1170 1171 // First write the wrapper element itself. 1172 Element sequence = types.writeWrapperElement(qname, request, hasParams); 1173 1174 // If we got anything back above, there must be parameters in the 1175 // operation, and it's a <sequence> node in which to write them... 1176 if (sequence != null) { 1177 ArrayList parameters = request ? oper.getAllInParams() : 1178 oper.getAllOutParams(); 1179 if (!request) { 1180 String retName; 1181 if (oper.getReturnQName() == null) { 1182 retName = oper.getName() + "Return"; 1183 } else { 1184 retName = oper.getReturnQName().getLocalPart(); 1185 } 1186 types.writeWrappedParameter(sequence, retName, 1187 oper.getReturnType(), 1188 oper.getReturnClass()); 1189 } 1190 for(int i=0; i<parameters.size(); i++) { 1191 ParameterDesc parameter = (ParameterDesc) parameters.get(i); 1192 types.writeWrappedParameter(sequence, 1193 parameter.getName(), // QName?? 1194 parameter.getTypeQName(), 1195 parameter.getJavaType()); 1196 } 1197 } 1198 1199 // Finally write the part itself 1200 Part part = def.createPart(); 1201 part.setName("parameters"); // We always se "parameters" 1202 part.setElementName(qname); 1203 msg.addPart(part); 1204 } 1205 1206 /** Create a Response Message 1207 * 1208 * @param def 1209 * @throws WSDLException 1210 * @throws AxisFault 1211 */ 1212 protected Message writeResponseMessage(Definition def, 1213 OperationDesc desc) 1214 throws WSDLException, AxisFault 1215 { 1216 Message msg = def.createMessage(); 1217 1218 QName qName = createMessageName(def, desc.getName() + "Response"); 1219 1220 msg.setQName(qName); 1221 msg.setUndefined(false); 1222 1223 if (desc.getStyle() == Style.WRAPPED) { 1224 writeWrapperPart(def, msg, desc, false); 1225 } else { 1226 // Write the part 1227 ParameterDesc retParam = new ParameterDesc(); 1228 if (desc.getReturnQName() == null) { 1229 String ns = ""; 1230 if (desc.getStyle() != Style.RPC) { 1231 ns = getServiceDesc().getDefaultNamespace(); 1232 if (ns == null || "".equals(ns)) { 1233 ns = "http://ws.apache.org/axis/defaultNS"; 1234 } 1235 } 1236 retParam.setQName(new QName(ns, desc.getName()+"Return")); 1237 } else { 1238 retParam.setQName(desc.getReturnQName()); 1239 } 1240 retParam.setTypeQName(desc.getReturnType()); 1241 retParam.setMode(ParameterDesc.OUT); 1242 retParam.setIsReturn(true); 1243 retParam.setJavaType(desc.getReturnClass()); 1244 writePartToMessage(def, msg, false, retParam); 1245 1246 ArrayList parameters = desc.getAllOutParams(); 1247 for (Iterator i = parameters.iterator(); i.hasNext();) { 1248 ParameterDesc param = (ParameterDesc)i.next(); 1249 writePartToMessage(def, msg, false, param); 1250 } 1251 } 1252 return msg; 1253 } 1254 1255 /** Create a Fault Message 1256 * 1257 * @param def 1258 * @param exception (an ExceptionRep object) 1259 * @throws WSDLException 1260 * @throws AxisFault 1261 */ 1262 protected Message writeFaultMessage(Definition def, 1263 FaultDesc exception) 1264 throws WSDLException, AxisFault 1265 { 1266 1267 String pkgAndClsName = exception.getClassName(); 1268 String clsName = pkgAndClsName.substring(pkgAndClsName.lastIndexOf('.') + 1, 1269 pkgAndClsName.length()); 1270 1271 // Do this to cover the complex type case with no meta data 1272 exception.setName(clsName); 1273 1274 // The following code uses the class name for both the name= attribute 1275 // and the message= attribute. 1276 1277 Message msg = (Message) exceptionMsg.get(pkgAndClsName); 1278 1279 if (msg == null) { 1280 msg = def.createMessage(); 1281 QName qName = createMessageName(def, clsName); 1282 1283 msg.setQName(qName); 1284 msg.setUndefined(false); 1285 1286 ArrayList parameters = exception.getParameters(); 1287 if (parameters != null) { 1288 for (int i=0; i<parameters.size(); i++) { 1289 ParameterDesc parameter = (ParameterDesc) parameters.get(i); 1290 writePartToMessage(def, msg, true, parameter); 1291 } 1292 } 1293 exceptionMsg.put(pkgAndClsName, msg); 1294 } 1295 1296 return msg; 1297 1298 } 1299 1300 /** Create a Part 1301 * 1302 * @param def 1303 * @param msg 1304 * @param request message is for a request 1305 * @param param ParamRep object 1306 * @return The parameter name added or null 1307 * @throws WSDLException 1308 * @throws AxisFault 1309 */ 1310 public String writePartToMessage(Definition def, 1311 Message msg, 1312 boolean request, 1313 ParameterDesc param) throws WSDLException, AxisFault 1314 { 1315 // Return if this is a void type 1316 if (param == null || 1317 param.getJavaType() == java.lang.Void.TYPE) 1318 return null; 1319 1320 // If Request message, only continue if IN or INOUT 1321 // If Response message, only continue if OUT or INOUT 1322 if (request && 1323 param.getMode() == ParameterDesc.OUT) { 1324 return null; 1325 } 1326 if (!request && 1327 param.getMode() == ParameterDesc.IN) { 1328 return null; 1329 } 1330 1331 // Create the Part 1332 Part part = def.createPart(); 1333 1334 // Get the java type to represent in the wsdl 1335 // (if the mode is OUT or INOUT and this 1336 // parameter does not represent the return type, 1337 // the type held in the Holder is the one that should 1338 // be written.) 1339 Class javaType = param.getJavaType(); 1340 if (param.getMode() != ParameterDesc.IN && 1341 param.getIsReturn() == false) { 1342 javaType = JavaUtils.getHolderValueType(javaType); 1343 } 1344 1345 if (use == Use.ENCODED || style == Style.RPC) { 1346 // Add the type representing the param 1347 // For convenience, add an element for the param 1348 // Write <part name=param_name type=param_type> 1349 QName typeQName = param.getTypeQName(); 1350 if(javaType != null) 1351 typeQName = types.writeTypeForPart(javaType, 1352 typeQName); 1353 //types.writeElementForPart(javaType, param.getTypeQName()); 1354 if (typeQName != null) { 1355 part.setName(param.getName()); 1356 part.setTypeName(typeQName); 1357 msg.addPart(part); 1358 } 1359 } else if (use == Use.LITERAL) { 1360 // This is doc/lit. So we should write out an element 1361 // declaration whose name and type may be found in the 1362 // ParameterDesc. 1363 QName qname = param.getQName(); 1364 Element el = types.createElementDecl(qname.getLocalPart(), 1365 param.getJavaType(), 1366 param.getTypeQName(), 1367 false, false); 1368 types.writeSchemaElement(qname, el); 1369 1370 part.setName(param.getName()); 1371 part.setElementName(qname); 1372 msg.addPart(part); 1373 } 1374 return param.getName(); 1375 } 1376 1377 /* 1378 * Return a message QName which has not already been defined in the WSDL 1379 */ 1380 protected QName createMessageName(Definition def, String methodName) { 1381 1382 QName qName = new QName(intfNS, methodName); 1383 1384 // Check the make sure there isn't a message with this name already 1385 int messageNumber = 1; 1386 while (def.getMessage(qName) != null) { 1387 StringBuffer namebuf = new StringBuffer(methodName); 1388 namebuf.append(messageNumber); 1389 qName = new QName(intfNS, namebuf.toString()); 1390 messageNumber++; 1391 } 1392 return qName; 1393 } 1394 1395 /** 1396 * Write a prettified document to a file. 1397 * 1398 * @param doc the Document to write 1399 * @param filename the name of the file to be written 1400 * @throws IOException various file i/o exceptions 1401 */ 1402 protected void prettyDocumentToFile(Document doc, String filename) 1403 throws IOException { 1404 FileOutputStream fos = new FileOutputStream(new File(filename)); 1405 XMLUtils.PrettyDocumentToStream(doc, fos); 1406 fos.close(); 1407 } 1408 1409 // -------------------- Parameter Query Methods ----------------------------// 1410 1411 /** 1412 * Returns the <code>Class</code> to export 1413 * @return the <code>Class</code> to export 1414 */ 1415 public Class getCls() { 1416 return cls; 1417 } 1418 1419 /** 1420 * Sets the <code>Class</code> to export 1421 * @param cls the <code>Class</code> to export 1422 */ 1423 public void setCls(Class cls) { 1424 this.cls = cls; 1425 } 1426 1427 /** 1428 * Sets the <code>Class</code> to export. 1429 * @param cls the <code>Class</code> to export 1430 */ 1431 public void setClsSmart(Class cls, String location) { 1432 1433 if (cls == null || location == null) 1434 return; 1435 1436 // Strip off \ and / from location 1437 if (location.lastIndexOf('/') > 0) { 1438 location = 1439 location.substring(location.lastIndexOf('/') + 1); 1440 } else if (location.lastIndexOf('\\') > 0) { 1441 location = 1442 location.substring(location.lastIndexOf('\\') + 1); 1443 } 1444 1445 // Get the constructors of the class Rate1446 java.lang.reflect.Constructor[] constructors = 1447 cls.getDeclaredConstructors(); 1448 Class intf = null; 1449 for (int i=0; i<constructors.length && intf == null; i++) { 1450 Class[] parms = constructors[i].getParameterTypes(); 1451 // If the constructor has a single parameter 1452 // that is an interface which 1453 // matches the location, then use this as the interface class. 1454 if (parms.length == 1 && 1455 parms[0].isInterface() && 1456 parms[0].getName() != null && 1457 Types.getLocalNameFromFullName( 1458 parms[0].getName()).equals(location)) { 1459 intf = parms[0]; 1460 } 1461 } 1462 if (intf != null) { 1463 setCls(intf); 1464 if (implCls == null) { 1465 setImplCls(cls); 1466 } 1467 } 1468 else 1469 setCls(cls); 1470 } 1471 1472 /** 1473 * Sets the <code>Class</code> to export 1474 * @param className the name of the <code>Class</code> to export 1475 */ 1476 public void setCls(String className) throws ClassNotFoundException { 1477 cls = ClassUtils.forName(className); 1478 } 1479 1480 /** 1481 * Returns the implementation <code>Class</code> if set 1482 * @return the implementation Class or null 1483 */ 1484 public Class getImplCls() { 1485 return implCls; 1486 } 1487 1488 /** 1489 * Sets the implementation <code>Class</code> 1490 * @param implCls the <code>Class</code> to export 1491 */ 1492 public void setImplCls(Class implCls) { 1493 this.implCls = implCls; 1494 } 1495 1496 /** 1497 * Sets the implementation <code>Class</code> 1498 * @param className the name of the implementation <code>Class</code> 1499 */ 1500 public void setImplCls(String className) { 1501 try { 1502 implCls = ClassUtils.forName(className); 1503 } 1504 catch (Exception ex) { 1505 ex.printStackTrace(); 1506 } 1507 } 1508 1509 /** 1510 * Returns the interface namespace 1511 * @return interface target namespace 1512 */ 1513 public String getIntfNamespace() { 1514 return intfNS; 1515 } 1516 1517 /** 1518 * Set the interface namespace 1519 * @param ns interface target namespace 1520 */ 1521 public void setIntfNamespace(String ns) { 1522 this.intfNS = ns; 1523 } 1524 1525 /** 1526 * Returns the implementation namespace 1527 * @return implementation target namespace 1528 */ 1529 public String getImplNamespace() { 1530 return implNS; 1531 } 1532 1533 /** 1534 * Set the implementation namespace 1535 * @param ns implementation target namespace 1536 */ 1537 public void setImplNamespace(String ns) { 1538 this.implNS = ns; 1539 } 1540 1541 /** 1542 * Returns a vector of methods to export 1543 * @return a space separated list of methods to export 1544 */ 1545 public Vector getAllowedMethods() { 1546 return allowedMethods; 1547 } 1548 1549 /** 1550 * Add a list of methods to export 1551 */ 1552 public void setAllowedMethods(String text) { 1553 if (text != null) { 1554 StringTokenizer tokenizer = new StringTokenizer(text, " ,+"); 1555 if (allowedMethods == null) { 1556 allowedMethods = new Vector(); 1557 } 1558 while (tokenizer.hasMoreTokens()) { 1559 allowedMethods.add(tokenizer.nextToken()); 1560 } 1561 } 1562 } 1563 1564 /** 1565 * Add a Vector of methods to export 1566 * @param allowedMethods a vector of methods to export 1567 */ 1568 public void setAllowedMethods(Vector allowedMethods) { 1569 if (this.allowedMethods == null) { 1570 this.allowedMethods = new Vector(); 1571 } 1572 this.allowedMethods.addAll(allowedMethods); 1573 } 1574 1575 /** 1576 * Indicates if the emitter will search classes for inherited methods 1577 */ 1578 public boolean getUseInheritedMethods() { 1579 return useInheritedMethods; 1580 } 1581 1582 /** 1583 * Turn on or off inherited method WSDL generation. 1584 */ 1585 public void setUseInheritedMethods(boolean useInheritedMethods) { 1586 this.useInheritedMethods = useInheritedMethods; 1587 } 1588 1589 /** 1590 * Add a list of methods NOT to export 1591 * @param disallowedMethods vector of method name strings 1592 */ 1593 public void setDisallowedMethods(Vector disallowedMethods) { 1594 if (this.disallowedMethods == null) { 1595 this.disallowedMethods = new Vector(); 1596 } 1597 this.disallowedMethods.addAll(disallowedMethods); 1598 } 1599 1600 /** 1601 * Add a list of methods NOT to export 1602 * @param text space separated list of method names 1603 */ 1604 public void setDisallowedMethods(String text) { 1605 if (text != null) { 1606 StringTokenizer tokenizer = new StringTokenizer(text, " ,+"); 1607 if (disallowedMethods == null) { 1608 disallowedMethods = new Vector(); 1609 } 1610 disallowedMethods = new Vector(); 1611 while (tokenizer.hasMoreTokens()) { 1612 disallowedMethods.add(tokenizer.nextToken()); 1613 } 1614 } 1615 } 1616 1617 /** 1618 * Return list of methods that should not be exported 1619 */ 1620 public Vector getDisallowedMethods() { 1621 return disallowedMethods; 1622 } 1623 1624 /** 1625 * Adds a list of classes (fully qualified) that will stop the traversal 1626 * of the inheritance tree if encounter in method or complex type generation 1627 * 1628 * @param stopClasses vector of class name strings 1629 */ 1630 public void setStopClasses(ArrayList stopClasses) { 1631 if (this.stopClasses == null) { 1632 this.stopClasses = new ArrayList(); 1633 } 1634 this.stopClasses.addAll(stopClasses); 1635 } 1636 1637 /** 1638 * Add a list of classes (fully qualified) that will stop the traversal 1639 * of the inheritance tree if encounter in method or complex type generation 1640 * 1641 * @param text space separated list of class names 1642 */ 1643 public void setStopClasses(String text) { 1644 if (text != null) { 1645 StringTokenizer tokenizer = new StringTokenizer(text, " ,+"); 1646 if (stopClasses == null) { 1647 stopClasses = new ArrayList(); 1648 } 1649 while (tokenizer.hasMoreTokens()) { 1650 stopClasses.add(tokenizer.nextToken()); 1651 } 1652 } 1653 } 1654 1655 /** 1656 * Return the list of classes which stop inhertance searches 1657 */ 1658 public ArrayList getStopClasses() { 1659 return stopClasses; 1660 } 1661 1662 /** 1663 * get the packagename to namespace map 1664 * @return <code>Map</code> 1665 */ 1666 public Map getNamespaceMap() { 1667 return namespaces; 1668 } 1669 1670 /** 1671 * Set the packagename to namespace map with the given map 1672 * @param map packagename/namespace <code>Map</code> 1673 */ 1674 public void setNamespaceMap(Map map) { 1675 if (map != null) 1676 namespaces.putAll(map); 1677 } 1678 1679 /** 1680 * Get the name of the input WSDL 1681 * @return name of the input wsdl or null 1682 */ 1683 public String getInputWSDL() { 1684 return inputWSDL; 1685 } 1686 1687 /** 1688 * Set the name of the input WSDL 1689 * @param inputWSDL the name of the input WSDL 1690 */ 1691 public void setInputWSDL(String inputWSDL) { 1692 this.inputWSDL = inputWSDL; 1693 } 1694 1695 /** 1696 * @return the name of the input schema, or null 1697 */ 1698 public String getInputSchema() { 1699 return inputSchema; 1700 } 1701 1702 /** 1703 * Set the name of the input schema 1704 * @param inputSchema the name of the input schema 1705 */ 1706 public void setInputSchema(String inputSchema) { 1707 this.inputSchema = inputSchema; 1708 } 1709 1710 /** 1711 * Returns the String representation of the service endpoint URL 1712 * @return String representation of the service endpoint URL 1713 */ 1714 public String getLocationUrl() { 1715 return locationUrl; 1716 } 1717 1718 /** 1719 * Set the String representation of the service endpoint URL 1720 * @param locationUrl the String representation of the service endpoint URL 1721 */ 1722 public void setLocationUrl(String locationUrl) { 1723 this.locationUrl = locationUrl; 1724 } 1725 1726 /** 1727 * Returns the String representation of the interface import location URL 1728 * @return String representation of the interface import location URL 1729 */ 1730 public String getImportUrl() { 1731 return importUrl; 1732 } 1733 1734 /** 1735 * Set the String representation of the interface location URL 1736 * for importing 1737 * @param importUrl the String representation of the interface 1738 * location URL for importing 1739 */ 1740 public void setImportUrl(String importUrl) { 1741 this.importUrl = importUrl; 1742 } 1743 1744 /** 1745 * Returns the String representation of the service port name 1746 * @return String representation of the service port name 1747 */ 1748 public String getServicePortName() { 1749 return servicePortName; 1750 } 1751 1752 /** 1753 * Set the String representation of the service port name 1754 * @param servicePortName the String representation of the service port name 1755 */ 1756 public void setServicePortName(String servicePortName) { 1757 this.servicePortName = servicePortName; 1758 } 1759 1760 /** 1761 * Returns the String representation of the service element name 1762 * @return String representation of the service element name 1763 */ 1764 public String getServiceElementName() { 1765 return serviceElementName; 1766 } 1767 1768 /** 1769 * Set the String representation of the service element name 1770 * @param serviceElementName the String representation of the service element name 1771 */ 1772 public void setServiceElementName(String serviceElementName) { 1773 this.serviceElementName = serviceElementName; 1774 } 1775 1776 /** 1777 * Returns the String representation of the portType name 1778 * @return String representation of the portType name 1779 */ 1780 public String getPortTypeName() { 1781 return portTypeName; 1782 } 1783 1784 /** 1785 * Set the String representation of the portType name 1786 * @param portTypeName the String representation of the portType name 1787 */ 1788 public void setPortTypeName(String portTypeName) { 1789 this.portTypeName = portTypeName; 1790 } 1791 1792 /** 1793 * Returns the String representation of the binding name 1794 * @return String representation of the binding name 1795 */ 1796 public String getBindingName() { 1797 return bindingName; 1798 } 1799 1800 /** 1801 * Set the String representation of the binding name 1802 * @param bindingName the String representation of the binding name 1803 */ 1804 public void setBindingName(String bindingName) { 1805 this.bindingName = bindingName; 1806 } 1807 1808 /** 1809 * Returns the target service name 1810 * @return the target service name 1811 */ 1812 public String getTargetService() { 1813 return targetService; 1814 } 1815 1816 /** 1817 * Set the target service name 1818 * @param targetService the target service name 1819 */ 1820 public void setTargetService(String targetService) { 1821 this.targetService = targetService; 1822 } 1823 1824 /** 1825 * Returns the service description 1826 * @return service description String 1827 */ 1828 public String getDescription() { 1829 return description; 1830 } 1831 1832 /** 1833 * Set the service description 1834 * @param description service description String 1835 */ 1836 public void setDescription(String description) { 1837 this.description = description; 1838 } 1839 1840 /** 1841 * Returns the soapAction option value 1842 * @return the String DEFAULT, NONE or OPERATION 1843 */ 1844 public String getSoapAction() { 1845 return soapAction; 1846 } 1847 1848 /** 1849 * Sets the soapAction option value 1850 * @param value must be DEFAULT, NONE, or OPERATION 1851 */ 1852 public void setSoapAction(String value) { 1853 soapAction = value; 1854 } 1855 1856 /** 1857 * Returns the <code>TypeMapping</code> used by the service 1858 * @return the <code>TypeMapping</code> used by the service 1859 */ 1860 public TypeMapping getTypeMapping() { 1861 return tm; 1862 } 1863 1864 /** 1865 * Sets the <code>TypeMapping</code> used by the service 1866 * @param tm the <code>TypeMapping</code> used by the service 1867 */ 1868 public void setTypeMapping(TypeMapping tm) { 1869 this.tm = tm; 1870 } 1871 1872 /** 1873 * Returns the default <code>TypeMapping</code> used by the service 1874 * @return the default <code>TypeMapping</code> used by the service 1875 */ 1876 public TypeMapping getDefaultTypeMapping() { 1877 return defaultTM; 1878 } 1879 1880 /** 1881 * Sets the default <code>TypeMapping</code> used by the service 1882 * @param defaultTM the default <code>TypeMapping</code> used by the service 1883 */ 1884 public void setDefaultTypeMapping(TypeMapping defaultTM) { 1885 this.defaultTM = defaultTM; 1886 } 1887 1888 1889 1890 1891 /** 1892 * getStyle 1893 * @return Style setting (Style.RPC, Style.DOCUMENT, Style.WRAPPED, etc.) 1894 */ 1895 public Style getStyle() { 1896 return style; 1897 } 1898 1899 /** 1900 * setStyle 1901 * @param value String representing a style ("document", "rpc", "wrapped") 1902 * Note that the case of the string is not important. "document" and "DOCUMENT" 1903 * are both treated as document style. 1904 * If the value is not a know style, the default setting is used. 1905 * See org.apache.axis.enum.Style for a description of the interaction between 1906 * Style/Use 1907 * <br>NOTE: If style is specified as "wrapped", use is set to literal. 1908 */ 1909 public void setStyle(String value) { 1910 setStyle(Style.getStyle(value)); 1911 } 1912 1913 /** 1914 * setStyle 1915 * @param value Style setting 1916 */ 1917 public void setStyle(Style value) { 1918 style = value; 1919 if (style.equals(Style.WRAPPED)) { 1920 setUse(Use.LITERAL); 1921 } 1922 } 1923 1924 /** 1925 * getUse 1926 * @return Use setting (Use.ENCODED, Use.LITERAL) 1927 */ 1928 public Use getUse() { 1929 return use; 1930 } 1931 1932 /** 1933 * setUse 1934 * @param value String representing a use ("literal", "encoded") 1935 * Note that the case of the string is not important. "literal" and "LITERAL" 1936 * are both treated as literal use. 1937 * If the value is not a know use, the default setting is used. 1938 * See org.apache.axis.enum.Style for a description of the interaction between 1939 * Style/Use 1940 */ 1941 public void setUse(String value) { 1942 use = Use.getUse(value); 1943 } 1944 1945 /** 1946 * setUse 1947 * @param value Use setting 1948 */ 1949 public void setUse(Use value) { 1950 use = value; 1951 } 1952 1953 /** 1954 * setMode (sets style and use) 1955 * @deprecated (use setStyle and setUse) 1956 */ 1957 public void setMode(int mode) { 1958 if (mode == MODE_RPC) { 1959 setStyle(Style.RPC); 1960 setUse(Use.ENCODED); 1961 } else if (mode == MODE_DOCUMENT) { 1962 setStyle(Style.DOCUMENT); 1963 setUse(Use.LITERAL); 1964 } else if (mode == MODE_DOC_WRAPPED) { 1965 setStyle(Style.WRAPPED); 1966 setUse(Use.LITERAL); 1967 } 1968 } 1969 1970 /** 1971 * getMode (gets the mode based on the style setting) 1972 * @deprecated (use getStyle and getUse) 1973 * @return returns the mode (-1 if invalid) 1974 */ 1975 public int getMode() { 1976 if (style == Style.RPC) { 1977 return MODE_RPC; 1978 } else if (style == Style.DOCUMENT) { 1979 return MODE_DOCUMENT; 1980 } else if (style == Style.WRAPPED) { 1981 return MODE_DOC_WRAPPED; 1982 } 1983 return -1; 1984 } 1985 1986 public ServiceDesc getServiceDesc() { 1987 return serviceDesc; 1988 } 1989 1990 public void setServiceDesc(ServiceDesc serviceDesc) { 1991 this.serviceDesc = serviceDesc; 1992 } 1993 1994 /** 1995 * Return the list of extra classes that the emitter will produce WSDL for. 1996 */ 1997 public Class[] getExtraClasses() { 1998 return extraClasses; 1999 } 2000 2001 /** 2002 * Provide a list of classes which the emitter will produce WSDL 2003 * type definitions for. 2004 */ 2005 public void setExtraClasses(Class[] extraClasses) { 2006 this.extraClasses = extraClasses; 2007 } 2008 2009 /** 2010 * Provide a comma or space seperated list of classes which 2011 * the emitter will produce WSDL type definitions for. 2012 * The classes will be added to the current list. 2013 */ 2014 public void setExtraClasses(String text) throws ClassNotFoundException { 2015 ArrayList clsList = new ArrayList(); 2016 if (text != null) { 2017 StringTokenizer tokenizer = new StringTokenizer(text, " ,"); 2018 while (tokenizer.hasMoreTokens()) { 2019 String clsName = tokenizer.nextToken(); 2020 // Let the caller handler ClassNotFoundException 2021 Class cls = ClassUtils.forName(clsName); 2022 clsList.add(cls); 2023 } 2024 } 2025 // Allocate the new array 2026 Class[] ec; 2027 if (extraClasses != null) { 2028 ec = new Class[clsList.size() + extraClasses.length]; 2029 // copy existing elements 2030 for (int i = 0; i < extraClasses.length; i++) { 2031 Class c = extraClasses[i]; 2032 ec[i] = c; 2033 } 2034 } else { 2035 ec = new Class[clsList.size()]; 2036 } 2037 // copy the new classes 2038 for (int i = 0; i < clsList.size(); i++) { 2039 Class c = (Class) clsList.get(i); 2040 ec[i] = c; 2041 } 2042 // set the member variable 2043 this.extraClasses = ec; 2044 } 2045 2046 }