001: /*
002: * Copyright 2001-2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package samples.client;
017:
018: import org.apache.axis.Constants;
019: import org.apache.axis.utils.XMLUtils;
020: import org.apache.axis.encoding.ser.SimpleDeserializer;
021: import org.apache.axis.encoding.ser.ElementSerializerFactory;
022: import org.apache.axis.encoding.ser.ElementDeserializerFactory;
023: import org.apache.axis.encoding.ser.ElementDeserializer;
024: import org.apache.axis.wsdl.gen.Parser;
025: import org.apache.axis.wsdl.symbolTable.BaseType;
026: import org.apache.axis.wsdl.symbolTable.BindingEntry;
027: import org.apache.axis.wsdl.symbolTable.Parameter;
028: import org.apache.axis.wsdl.symbolTable.Parameters;
029: import org.apache.axis.wsdl.symbolTable.ServiceEntry;
030: import org.apache.axis.wsdl.symbolTable.SymTabEntry;
031: import org.apache.axis.wsdl.symbolTable.SymbolTable;
032: import org.apache.axis.wsdl.symbolTable.TypeEntry;
033: import org.w3c.dom.Element;
034:
035: import javax.wsdl.Binding;
036: import javax.wsdl.Operation;
037: import javax.wsdl.Port;
038: import javax.wsdl.Service;
039: import javax.wsdl.extensions.soap.SOAPAddress;
040: import javax.xml.namespace.QName;
041: import javax.xml.rpc.Call;
042: import javax.xml.rpc.encoding.Deserializer;
043: import javax.xml.rpc.encoding.DeserializerFactory;
044: import java.util.HashMap;
045: import java.util.Iterator;
046: import java.util.List;
047: import java.util.Map;
048: import java.util.Vector;
049:
050: /**
051: * This sample shows how to use Axis for completely dynamic invocations
052: * as it is completely stubless execution. It supports both doc/lit and rpc/encoded
053: * services. But this sample does not support complex types
054: * (it could if there was defined a to encode complex values as command line arguments).
055: *
056: * @author Davanum Srinivas (dims@yahoo.com)
057: */
058: public class DynamicInvoker {
059:
060: /** Field wsdlParser */
061: private Parser wsdlParser = null;
062:
063: /**
064: * Constructor DynamicInvoker
065: *
066: * @param wsdlURL
067: *
068: * @throws Exception
069: */
070: public DynamicInvoker(String wsdlURL) throws Exception {
071: // Start by reading in the WSDL using Parser
072: wsdlParser = new Parser();
073: System.out.println("Reading WSDL document from '" + wsdlURL
074: + "'");
075: wsdlParser.run(wsdlURL);
076: }
077:
078: /**
079: * Method usage
080: */
081: private static void usage() {
082: System.err.println("Usage: java "
083: + DynamicInvoker.class.getName() + " wsdlLocation "
084: + "operationName[(portName)] " + "[argument1 ...]");
085: System.exit(1);
086: }
087:
088: /**
089: * Method main
090: *
091: * @param args
092: *
093: * @throws Exception
094: */
095: public static void main(String[] args) throws Exception {
096: if (args.length < 2) {
097: usage();
098: }
099: String wsdlLocation = (args.length > 0) ? args[0] : null;
100: String operationName = (args.length > 1) ? args[1] : null;
101: String portName = null;
102: try {
103: portName = operationName.substring(operationName
104: .indexOf("(") + 1, operationName.indexOf(")"));
105: operationName = operationName.substring(0, operationName
106: .indexOf("("));
107: } catch (Exception ignored) {
108: }
109:
110: DynamicInvoker invoker = new DynamicInvoker(wsdlLocation);
111: HashMap map = invoker.invokeMethod(operationName, portName,
112: args);
113:
114: for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
115: Map.Entry entry = (Map.Entry) it.next();
116: String key = (String) entry.getKey();
117: Object value = entry.getValue();
118: if (value instanceof Element) {
119: System.out.println("====== " + key + " ======");
120: XMLUtils.ElementToStream((Element) value, System.out);
121: System.out.println("=========================");
122: } else {
123: System.out.println(key + "=" + value);
124: }
125: }
126: System.out.println("\nDone!");
127: }
128:
129: /**
130: * Method invokeMethod
131: *
132: * @param wsdlLocation
133: * @param operationName
134: * @param inputName
135: * @param outputName
136: * @param portName
137: * @param args
138: *
139: * @return
140: *
141: * @throws Exception
142: */
143: public HashMap invokeMethod(String operationName, String portName,
144: String[] args) throws Exception {
145: String serviceNS = null;
146: String serviceName = null;
147: String operationQName = null;
148:
149: System.out.println("Preparing Axis dynamic invocation");
150: Service service = selectService(serviceNS, serviceName);
151: Operation operation = null;
152: org.apache.axis.client.Service dpf = new org.apache.axis.client.Service(
153: wsdlParser, service.getQName());
154:
155: Vector inputs = new Vector();
156: Port port = selectPort(service.getPorts(), portName);
157: if (portName == null) {
158: portName = port.getName();
159: }
160: Binding binding = port.getBinding();
161: Call call = dpf.createCall(QName.valueOf(portName), QName
162: .valueOf(operationName));
163: ((org.apache.axis.client.Call) call).setTimeout(new Integer(
164: 15 * 1000));
165: ((org.apache.axis.client.Call) call).setProperty(
166: ElementDeserializer.DESERIALIZE_CURRENT_ELEMENT,
167: Boolean.TRUE);
168:
169: // Output types and names
170: Vector outNames = new Vector();
171:
172: // Input types and names
173: Vector inNames = new Vector();
174: Vector inTypes = new Vector();
175: SymbolTable symbolTable = wsdlParser.getSymbolTable();
176: BindingEntry bEntry = symbolTable.getBindingEntry(binding
177: .getQName());
178: Parameters parameters = null;
179: Iterator i = bEntry.getParameters().keySet().iterator();
180:
181: while (i.hasNext()) {
182: Operation o = (Operation) i.next();
183: if (o.getName().equals(operationName)) {
184: operation = o;
185: parameters = (Parameters) bEntry.getParameters().get(o);
186: break;
187: }
188: }
189: if ((operation == null) || (parameters == null)) {
190: throw new RuntimeException(operationName
191: + " was not found.");
192: }
193:
194: // loop over paramters and set up in/out params
195: for (int j = 0; j < parameters.list.size(); ++j) {
196: Parameter p = (Parameter) parameters.list.get(j);
197:
198: if (p.getMode() == 1) { // IN
199: inNames.add(p.getQName().getLocalPart());
200: inTypes.add(p);
201: } else if (p.getMode() == 2) { // OUT
202: outNames.add(p.getQName().getLocalPart());
203: } else if (p.getMode() == 3) { // INOUT
204: inNames.add(p.getQName().getLocalPart());
205: inTypes.add(p);
206: outNames.add(p.getQName().getLocalPart());
207: }
208: }
209:
210: // set output type
211: if (parameters.returnParam != null) {
212:
213: if (!parameters.returnParam.getType().isBaseType()) {
214: ((org.apache.axis.client.Call) call)
215: .registerTypeMapping(org.w3c.dom.Element.class,
216: parameters.returnParam.getType()
217: .getQName(),
218: new ElementSerializerFactory(),
219: new ElementDeserializerFactory());
220: }
221:
222: // Get the QName for the return Type
223: QName returnType = org.apache.axis.wsdl.toJava.Utils
224: .getXSIType(parameters.returnParam);
225: QName returnQName = parameters.returnParam.getQName();
226:
227: outNames.add(returnQName.getLocalPart());
228: }
229:
230: if (inNames.size() != args.length - 2)
231: throw new RuntimeException("Need " + inNames.size()
232: + " arguments!!!");
233:
234: for (int pos = 0; pos < inNames.size(); ++pos) {
235: String arg = args[pos + 2];
236: Parameter p = (Parameter) inTypes.get(pos);
237: inputs.add(getParamData((org.apache.axis.client.Call) call,
238: p, arg));
239: }
240: System.out.println("Executing operation " + operationName
241: + " with parameters:");
242: for (int j = 0; j < inputs.size(); j++) {
243: System.out.println(inNames.get(j) + "=" + inputs.get(j));
244: }
245: Object ret = call.invoke(inputs.toArray());
246: Map outputs = call.getOutputParams();
247: HashMap map = new HashMap();
248:
249: for (int pos = 0; pos < outNames.size(); ++pos) {
250: String name = (String) outNames.get(pos);
251: Object value = outputs.get(name);
252:
253: if ((value == null) && (pos == 0)) {
254: map.put(name, ret);
255: } else {
256: map.put(name, value);
257: }
258: }
259: return map;
260: }
261:
262: /**
263: * Method getParamData
264: *
265: * @param c
266: * @param arg
267: */
268: private Object getParamData(org.apache.axis.client.Call c,
269: Parameter p, String arg) throws Exception {
270: // Get the QName representing the parameter type
271: QName paramType = org.apache.axis.wsdl.toJava.Utils
272: .getXSIType(p);
273:
274: TypeEntry type = p.getType();
275: if (type instanceof BaseType && ((BaseType) type).isBaseType()) {
276: DeserializerFactory factory = c.getTypeMapping()
277: .getDeserializer(paramType);
278: Deserializer deserializer = factory
279: .getDeserializerAs(Constants.AXIS_SAX);
280: if (deserializer instanceof SimpleDeserializer) {
281: return ((SimpleDeserializer) deserializer)
282: .makeValue(arg);
283: }
284: }
285: throw new RuntimeException("not know how to convert '" + arg
286: + "' into " + c);
287: }
288:
289: /**
290: * Method selectService
291: *
292: * @param def
293: * @param serviceNS
294: * @param serviceName
295: *
296: * @return
297: *
298: * @throws Exception
299: */
300: public Service selectService(String serviceNS, String serviceName)
301: throws Exception {
302: QName serviceQName = (((serviceNS != null) && (serviceName != null)) ? new QName(
303: serviceNS, serviceName)
304: : null);
305: ServiceEntry serviceEntry = (ServiceEntry) getSymTabEntry(
306: serviceQName, ServiceEntry.class);
307: return serviceEntry.getService();
308: }
309:
310: /**
311: * Method getSymTabEntry
312: *
313: * @param qname
314: * @param cls
315: *
316: * @return
317: */
318: public SymTabEntry getSymTabEntry(QName qname, Class cls) {
319: HashMap map = wsdlParser.getSymbolTable().getHashMap();
320: Iterator iterator = map.entrySet().iterator();
321:
322: while (iterator.hasNext()) {
323: Map.Entry entry = (Map.Entry) iterator.next();
324: QName key = (QName) entry.getKey();
325: Vector v = (Vector) entry.getValue();
326:
327: if ((qname == null) || qname.equals(qname)) {
328: for (int i = 0; i < v.size(); ++i) {
329: SymTabEntry symTabEntry = (SymTabEntry) v
330: .elementAt(i);
331:
332: if (cls.isInstance(symTabEntry)) {
333: return symTabEntry;
334: }
335: }
336: }
337: }
338: return null;
339: }
340:
341: /**
342: * Method selectPort
343: *
344: * @param ports
345: * @param portName
346: *
347: * @return
348: *
349: * @throws Exception
350: */
351: public Port selectPort(Map ports, String portName) throws Exception {
352: Iterator valueIterator = ports.keySet().iterator();
353: while (valueIterator.hasNext()) {
354: String name = (String) valueIterator.next();
355:
356: if ((portName == null) || (portName.length() == 0)) {
357: Port port = (Port) ports.get(name);
358: List list = port.getExtensibilityElements();
359:
360: for (int i = 0; (list != null) && (i < list.size()); i++) {
361: Object obj = list.get(i);
362: if (obj instanceof SOAPAddress) {
363: return port;
364: }
365: }
366: } else if ((name != null) && name.equals(portName)) {
367: return (Port) ports.get(name);
368: }
369: }
370: return null;
371: }
372: }
|