001: /*
002: * The Apache Software License, Version 1.1
003: *
004: *
005: * Copyright (c) 2002 The Apache Software Foundation. All rights
006: * reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: *
012: * 1. Redistributions of source code must retain the above copyright
013: * notice, this list of conditions and the following disclaimer.
014: *
015: * 2. Redistributions in binary form must reproduce the above copyright
016: * notice, this list of conditions and the following disclaimer in
017: * the documentation and/or other materials provided with the
018: * distribution.
019: *
020: * 3. The end-user documentation included with the redistribution,
021: * if any, must include the following acknowledgment:
022: * "This product includes software developed by the
023: * Apache Software Foundation (http://www.apache.org/)."
024: * Alternately, this acknowledgment may appear in the software itself,
025: * if and wherever such third-party acknowledgments normally appear.
026: *
027: * 4. The names "WSIF" and "Apache Software Foundation" must
028: * not be used to endorse or promote products derived from this
029: * software without prior written permission. For written
030: * permission, please contact apache@apache.org.
031: *
032: * 5. Products derived from this software may not be called "Apache",
033: * nor may "Apache" appear in their name, without prior written
034: * permission of the Apache Software Foundation.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This software consists of voluntary contributions made by many
051: * individuals on behalf of the Apache Software Foundation and was
052: * originally based on software copyright (c) 2001, 2002, International
053: * Business Machines, Inc., http://www.apache.org. For more
054: * information on the Apache Software Foundation, please see
055: * <http://www.apache.org/>.
056: */
057:
058: package clients;
059:
060: import java.util.HashMap;
061: import java.util.Iterator;
062: import java.util.List;
063: import java.util.Map;
064: import java.util.StringTokenizer;
065:
066: import javax.wsdl.Definition;
067: import javax.wsdl.Input;
068: import javax.wsdl.Operation;
069: import javax.wsdl.Output;
070: import javax.wsdl.Part;
071: import javax.wsdl.Port;
072: import javax.wsdl.PortType;
073: import javax.wsdl.Service;
074: import javax.xml.namespace.QName;
075:
076: import org.apache.wsif.WSIFException;
077: import org.apache.wsif.WSIFMessage;
078: import org.apache.wsif.WSIFOperation;
079: import org.apache.wsif.WSIFPort;
080: import org.apache.wsif.WSIFService;
081: import org.apache.wsif.WSIFServiceFactory;
082: import org.apache.wsif.providers.soap.apacheaxis.WSIFDynamicProvider_ApacheAxis;
083: import org.apache.wsif.util.WSIFPluggableProviders;
084: import org.apache.wsif.util.WSIFUtils;
085:
086: /**
087: * This sample shows how to use WSIF for completely dynamic invocations
088: * as it is completely stubless execution. This sample does not support
089: * complex types (it could if there was defined a to encode complex
090: * values as command line arguments).
091: *
092: * @author Sanjiva Weerawarana
093: * @author Alekander Slominski
094: */
095:
096: public class DynamicInvoker {
097: private static void usage() {
098: System.err
099: .println("Usage: java "
100: + DynamicInvoker.class.getName()
101: + " wsdlLocation "
102: + "operationName[(portName)]:[inputMessageName]:[outputMessageName] "
103: + "[soap|axis] [argument1 ...]");
104: System.exit(1);
105: }
106:
107: public static void main(String[] args) throws Exception {
108: if (args.length < 2)
109: usage();
110:
111: String wsdlLocation = args.length > 0 ? args[0] : null;
112: String operationKey = args.length > 1 ? args[1] : null;
113: String portName = null;
114: String operationName = null;
115: String inputName = null;
116: String outputName = null;
117:
118: StringTokenizer st = new StringTokenizer(operationKey, ":");
119: int tokens = st.countTokens();
120: int specType = 0;
121: if (tokens == 2) {
122: specType = operationKey.endsWith(":") ? 1 : 2;
123: } else if (tokens != 1 && tokens != 3)
124: usage();
125:
126: while (st.hasMoreTokens()) {
127: if (operationName == null)
128: operationName = st.nextToken();
129: else if (inputName == null && specType != 2)
130: inputName = st.nextToken();
131: else if (outputName == null)
132: outputName = st.nextToken();
133: else
134: break;
135: }
136:
137: try {
138: portName = operationName.substring(operationName
139: .indexOf("(") + 1, operationName.indexOf(")"));
140: operationName = operationName.substring(0, operationName
141: .indexOf("("));
142: } catch (Exception ignored) {
143: }
144:
145: String protocol = args.length > 2 ? args[2] : "";
146: int shift = 2;
147: if (protocol.equals("soap") || protocol.equals("axis"))
148: shift = 3;
149:
150: HashMap map = invokeMethod(wsdlLocation, operationName,
151: inputName, outputName, portName, protocol, args, shift);
152:
153: // print result
154: System.out.println("Result:");
155: for (Iterator it = map.keySet().iterator(); it.hasNext();) {
156: String name = (String) it.next();
157: System.out.println(name + "=" + map.get(name));
158: }
159: System.out.println("\nDone!");
160:
161: }
162:
163: public static HashMap invokeMethod(String wsdlLocation,
164: String operationName, String inputName, String outputName,
165: String portName, String protocol, String[] args,
166: int argShift) throws Exception {
167:
168: String serviceNS = null;
169: String serviceName = null;
170: String portTypeNS = null;
171: String portTypeName = null;
172:
173: // The default SOAP provider is the Apache SOAP provider. If Axis was specified
174: // then change that
175: if ("axis".equals(protocol)) {
176: WSIFPluggableProviders.overrideDefaultProvider(
177: "http://schemas.xmlsoap.org/wsdl/soap/",
178: new WSIFDynamicProvider_ApacheAxis());
179: }
180:
181: System.out.println("Reading WSDL document from '"
182: + wsdlLocation + "'");
183: Definition def = WSIFUtils.readWSDL(null, wsdlLocation);
184:
185: System.out.println("Preparing WSIF dynamic invocation");
186:
187: Service service = WSIFUtils.selectService(def, serviceNS,
188: serviceName);
189:
190: Map portTypes = WSIFUtils.getAllItems(def, "PortType");
191: // Really there should be a way to specify the portType
192: // for now just try to find one with the portName
193: if (portTypes.size() > 1 && portName != null) {
194: for (Iterator i = portTypes.keySet().iterator(); i
195: .hasNext();) {
196: QName qn = (QName) i.next();
197: if (portName.equals(qn.getLocalPart())) {
198: portTypeName = qn.getLocalPart();
199: portTypeNS = qn.getNamespaceURI();
200: break;
201: }
202: }
203: }
204: PortType portType = WSIFUtils.selectPortType(def, portTypeNS,
205: portTypeName);
206:
207: WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
208: WSIFService dpf = factory.getService(def, service, portType);
209: WSIFPort port = null;
210: if (portName == null)
211: port = dpf.getPort();
212: else
213: port = dpf.getPort(portName);
214:
215: if (inputName == null && outputName == null) {
216: // retrieve list of operations
217: List operationList = portType.getOperations();
218:
219: // try to find input and output names for the operation specified
220: boolean found = false;
221: for (Iterator i = operationList.iterator(); i.hasNext();) {
222: Operation op = (Operation) i.next();
223: String name = op.getName();
224: if (!name.equals(operationName)) {
225: continue;
226: }
227: if (found) {
228: throw new RuntimeException(
229: "Operation '"
230: + operationName
231: + "' is overloaded. "
232: + "Please specify the operation in the form "
233: + "'operationName:inputMessageName:outputMesssageName' to distinguish it");
234: }
235: found = true;
236: Input opInput = op.getInput();
237: inputName = (opInput.getName() == null) ? null
238: : opInput.getName();
239: Output opOutput = op.getOutput();
240: outputName = (opOutput.getName() == null) ? null
241: : opOutput.getName();
242: }
243: }
244:
245: WSIFOperation operation = port.createOperation(operationName,
246: inputName, outputName);
247: WSIFMessage input = operation.createInputMessage();
248: WSIFMessage output = operation.createOutputMessage();
249: WSIFMessage fault = operation.createFaultMessage();
250:
251: // retrieve list of names and types for input and names for output
252: List operationList = portType.getOperations();
253:
254: // find portType operation to prepare in/oout message w/ parts
255: boolean found = false;
256: String[] outNames = new String[0];
257: Class[] outTypes = new Class[0];
258: for (Iterator i = operationList.iterator(); i.hasNext();) {
259: Operation op = (Operation) i.next();
260: String name = op.getName();
261: if (!name.equals(operationName)) {
262: continue;
263: }
264: if (found) {
265: throw new RuntimeException(
266: "overloaded operations are not supported in this sample");
267: }
268: found = true;
269:
270: //System.err.println("op = "+op);
271: Input opInput = op.getInput();
272:
273: // first determine list of arguments
274: String[] inNames = new String[0];
275: Class[] inTypes = new Class[0];
276: if (opInput != null) {
277: List parts = opInput.getMessage().getOrderedParts(null);
278: unWrapIfWrappedDocLit(parts, name, def);
279: int count = parts.size();
280: inNames = new String[count];
281: inTypes = new Class[count];
282: retrieveSignature(parts, inNames, inTypes);
283: }
284: // now prepare out parameters
285:
286: for (int pos = 0; pos < inNames.length; ++pos) {
287: String arg = args[pos + argShift];
288: Object value = null;
289: Class c = inTypes[pos];
290: if (c.equals(String.class)) {
291: value = arg;
292: } else if (c.equals(Double.TYPE)) {
293: value = new Double(arg);
294: } else if (c.equals(Float.TYPE)) {
295: value = new Float(arg);
296: } else if (c.equals(Integer.TYPE)) {
297: value = new Integer(arg);
298: } else if (c.equals(Boolean.TYPE)) {
299: value = new Boolean(arg);
300: } else {
301: throw new RuntimeException(
302: "not know how to convert '" + arg
303: + "' into " + c);
304: }
305:
306: input.setObjectPart(inNames[pos], value);
307: }
308:
309: Output opOutput = op.getOutput();
310: if (opOutput != null) {
311: List parts = opOutput.getMessage()
312: .getOrderedParts(null);
313: unWrapIfWrappedDocLit(parts, name + "Response", def);
314: int count = parts.size();
315: outNames = new String[count];
316: outTypes = new Class[count];
317: retrieveSignature(parts, outNames, outTypes);
318: }
319:
320: }
321: if (!found) {
322: throw new RuntimeException("no operation " + operationName
323: + " was found in port type " + portType.getQName());
324: }
325:
326: System.out.println("Executing operation " + operationName);
327: operation.executeRequestResponseOperation(input, output, fault);
328:
329: HashMap map = new HashMap();
330: for (int pos = 0; pos < outNames.length; ++pos) {
331: String name = outNames[pos];
332: map.put(name, output.getObjectPart(name));
333: }
334:
335: return map;
336: }
337:
338: private static void retrieveSignature(List parts, String[] names,
339: Class[] types) {
340: // get parts in correct order
341: for (int i = 0; i < names.length; ++i) {
342: Part part = (Part) parts.get(i);
343: names[i] = part.getName();
344: QName partType = part.getTypeName();
345: if (partType == null) {
346: partType = part.getElementName();
347: }
348: if (partType == null) {
349: throw new RuntimeException("part " + names[i]
350: + " must have type name declared");
351: }
352: // only limited number of types is supported
353: // cheerfully ignoring schema namespace ...
354: String s = partType.getLocalPart();
355: if ("string".equals(s)) {
356: types[i] = String.class;
357: } else if ("double".equals(s)) {
358: types[i] = Integer.TYPE;
359: } else if ("float".equals(s)) {
360: types[i] = Float.TYPE;
361: } else if ("int".equals(s)) {
362: types[i] = Integer.TYPE;
363: } else if ("boolean".equals(s)) {
364: types[i] = Boolean.TYPE;
365: } else {
366: throw new RuntimeException("part type " + partType
367: + " not supported in this sample");
368: }
369: }
370: }
371:
372: /**
373: * Unwraps the top level part if this a wrapped DocLit message.
374: */
375: private static void unWrapIfWrappedDocLit(List parts,
376: String operationName, Definition def) throws WSIFException {
377: Part p = WSIFUtils.getWrappedDocLiteralPart(parts,
378: operationName);
379: if (p != null) {
380: List unWrappedParts = WSIFUtils.unWrapPart(p, def);
381: parts.remove(p);
382: parts.addAll(unWrappedParts);
383: }
384: }
385:
386: }
|