KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > client > Service


1 /*
2 * The Apache Software License, Version 1.1
3 *
4 *
5 * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
6 * reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The end-user documentation included with the redistribution,
21 * if any, must include the following acknowledgment:
22 * "This product includes software developed by the
23 * Apache Software Foundation (http://www.apache.org/)."
24 * Alternately, this acknowledgment may appear in the software itself,
25 * if and wherever such third-party acknowledgments normally appear.
26 *
27 * 4. The names "Axis" and "Apache Software Foundation" must
28 * not be used to endorse or promote products derived from this
29 * software without prior written permission. For written
30 * permission, please contact apache@apache.org.
31 *
32 * 5. Products derived from this software may not be called "Apache",
33 * nor may "Apache" appear in their name, without prior written
34 * permission of the Apache Software Foundation.
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the Apache Software Foundation. For more
52 * information on the Apache Software Foundation, please see
53 * <http://www.apache.org/>.
54 */

55
56 package org.jboss.axis.client;
57
58 import org.jboss.axis.AxisEngine;
59 import org.jboss.axis.EngineConfiguration;
60 import org.jboss.axis.configuration.EngineConfigurationFactoryFinder;
61 import org.jboss.axis.utils.ClassUtils;
62 import org.jboss.axis.utils.Messages;
63 import org.jboss.axis.utils.WSDLUtils;
64 import org.jboss.axis.utils.XMLUtils;
65 import org.jboss.axis.wsdl.gen.Parser;
66 import org.jboss.axis.wsdl.symbolTable.BindingEntry;
67 import org.jboss.axis.wsdl.symbolTable.ServiceEntry;
68 import org.jboss.axis.wsdl.symbolTable.SymbolTable;
69 import org.jboss.logging.Logger;
70 import org.w3c.dom.Document JavaDoc;
71
72 import javax.naming.Reference JavaDoc;
73 import javax.naming.Referenceable JavaDoc;
74 import javax.naming.StringRefAddr JavaDoc;
75 import javax.wsdl.Binding;
76 import javax.wsdl.Operation;
77 import javax.wsdl.Port;
78 import javax.wsdl.PortType;
79 import javax.wsdl.extensions.soap.SOAPAddress;
80 import javax.xml.namespace.QName JavaDoc;
81 import javax.xml.rpc.ServiceException JavaDoc;
82 import javax.xml.rpc.encoding.TypeMappingRegistry JavaDoc;
83 import javax.xml.rpc.handler.HandlerRegistry JavaDoc;
84 import java.io.InputStream JavaDoc;
85 import java.io.Serializable JavaDoc;
86 import java.lang.reflect.Constructor JavaDoc;
87 import java.lang.reflect.Proxy JavaDoc;
88 import java.net.MalformedURLException JavaDoc;
89 import java.net.URL JavaDoc;
90 import java.rmi.Remote JavaDoc;
91 import java.util.HashMap JavaDoc;
92 import java.util.Hashtable JavaDoc;
93 import java.util.Iterator JavaDoc;
94 import java.util.List JavaDoc;
95 import java.util.Map JavaDoc;
96 import java.util.Vector JavaDoc;
97
98 /**
99  * Axis' JAXRPC Dynamic Invoation Interface implementation of the Service
100  * interface.
101  * <p/>
102  * The Service class should be used a the starting point for access
103  * SOAP Web Services. Typically, a Service will be created with a WSDL
104  * document and along with a serviceName you can then ask for a Call
105  * object that will allow you to invoke a Web Service.
106  *
107  * @author Doug Davis (dug@us.ibm.com)
108  */

109
110 public class Service implements javax.xml.rpc.Service JavaDoc, Serializable JavaDoc, Referenceable JavaDoc
111 {
112    /** @since 4.0.2 */
113    static final long serialVersionUID = 3948774801925955759L;
114
115    private transient static Logger log = Logger.getLogger(Service.class.getName());
116
117    protected transient AxisEngine engine;
118    protected transient EngineConfiguration config;
119
120    protected QName JavaDoc serviceName;
121    protected String JavaDoc wsdlLocation;
122    protected javax.wsdl.Service wsdlService;
123
124    private boolean maintainSession;
125    private Parser wsdlParser;
126
127    private HandlerRegistryImpl registry = new HandlerRegistryImpl();
128
129    protected static HashMap JavaDoc cachedWSDL = new HashMap JavaDoc();
130    protected static boolean cachingWSDL = false;
131
132    /**
133     * A Hashtable mapping addresses (URLs) to Transports (objects)
134     */

135    private Hashtable JavaDoc transportImpls = new Hashtable JavaDoc();
136
137    /**
138     * Constructs a new Service object - this assumes the caller will set
139     * the appropriate fields by hand rather than getting them from the
140     * WSDL.
141     */

142    public Service()
143    {
144       engine = getAxisClient();
145    }
146
147    /**
148     * Constructs a new Service object - this assumes the caller will set
149     * the appropriate fields by hand rather than getting them from the
150     * WSDL.
151     */

152    public Service(QName JavaDoc serviceName)
153    {
154       this.serviceName = serviceName;
155       engine = getAxisClient();
156    }
157
158    /**
159     * Constructs a new Service object as above, but also passing in
160     * the EngineConfiguration which should be used to set up the
161     * AxisClient.
162     */

163    public Service(EngineConfiguration config)
164    {
165       this.config = config;
166       engine = getAxisClient();
167    }
168
169    /**
170     * Constructs a new Service object for the service in the WSDL document
171     * pointed to by the wsdlDoc URL and serviceName parameters.
172     *
173     * @param wsdlDoc URL of the WSDL document
174     * @param serviceName Qualified name of the desired service
175     * @throws ServiceException If there's an error finding or parsing the WSDL
176     */

177    public Service(URL JavaDoc wsdlDoc, QName JavaDoc serviceName) throws ServiceException JavaDoc
178    {
179       this.serviceName = serviceName;
180       engine = getAxisClient();
181       wsdlLocation = wsdlDoc.toString();
182       Parser parser = null;
183
184       if (cachingWSDL &&
185               (parser = (Parser)cachedWSDL.get(this.wsdlLocation.toString())) != null)
186       {
187          initService(parser, serviceName);
188       }
189       else
190       {
191          initService(wsdlDoc.toString(), serviceName);
192       }
193    }
194
195    /**
196     * Constructs a new Service object for the service in the WSDL document
197     *
198     * @param parser Parser for this service
199     * @param serviceName Qualified name of the desired service
200     * @throws ServiceException If there's an error
201     */

202    public Service(Parser parser, QName JavaDoc serviceName) throws ServiceException JavaDoc
203    {
204       this.serviceName = serviceName;
205       engine = getAxisClient();
206       initService(parser, serviceName);
207    }
208
209    /**
210     * Constructs a new Service object for the service in the WSDL document
211     * pointed to by the wsdlLocation and serviceName parameters. This is
212     * just like the previous constructor but instead of URL the
213     * wsdlLocation parameter points to a file on the filesystem relative
214     * to the current directory.
215     *
216     * @param wsdlLocation Location of the WSDL relative to the current dir
217     * @param serviceName Qualified name of the desired service
218     * @throws ServiceException If there's an error finding or parsing the WSDL
219     */

220    public Service(String JavaDoc wsdlLocation, QName JavaDoc serviceName)
221            throws ServiceException JavaDoc
222    {
223       this.serviceName = serviceName;
224       this.wsdlLocation = wsdlLocation;
225       engine = getAxisClient();
226       // Start by reading in the WSDL using Parser
227
Parser parser = null;
228       if (cachingWSDL &&
229               (parser = (Parser)cachedWSDL.get(wsdlLocation)) != null)
230       {
231          initService(parser, serviceName);
232       }
233       else
234       {
235          initService(wsdlLocation, serviceName);
236       }
237    }
238
239    /**
240     * Constructs a new Service object for the service in the WSDL document
241     * in the wsdlInputStream and serviceName parameters. This is
242     * just like the previous constructor but instead of reading the WSDL
243     * from a file (or from a URL) it is in the passed in InputStream.
244     *
245     * @param wsdlInputStream InputStream containing the WSDL
246     * @param serviceName Qualified name of the desired service
247     * @throws ServiceException If there's an error finding or parsing the WSDL
248     */

249    public Service(InputStream JavaDoc wsdlInputStream, QName JavaDoc serviceName)
250            throws ServiceException JavaDoc
251    {
252       engine = getAxisClient();
253       Document JavaDoc doc = null;
254       try
255       {
256          doc = XMLUtils.newDocument(wsdlInputStream);
257       }
258       catch (Exception JavaDoc exp)
259       {
260          throw new ServiceException JavaDoc(Messages.getMessage("wsdlError00", "" + "", "\n" + exp));
261       }
262       initService(null, doc, serviceName);
263    }
264
265    /**
266     * Common code for building up the Service from a WSDL document
267     *
268     * @param url URL for the WSDL document
269     * @param serviceName Qualified name of the desired service
270     * @throws ServiceException If there's an error finding or parsing the WSDL
271     */

272    private void initService(String JavaDoc url, QName JavaDoc serviceName)
273            throws ServiceException JavaDoc
274    {
275       try
276       {
277          // Start by reading in the WSDL using Parser
278
Parser parser = getParser();
279          parser.run(url);
280
281          if (cachingWSDL && this.wsdlLocation != null)
282             cachedWSDL.put(url, parser);
283
284          initService(parser, serviceName);
285       }
286       catch (Exception JavaDoc exp)
287       {
288          log.error(exp.getMessage(), exp);
289          throw new ServiceException JavaDoc(Messages.getMessage("wsdlError00", "" + "", "\n" + exp));
290       }
291    }
292
293    /**
294     * Stub out, to give clients the cahnce to modify parser properties
295     * TDI 15-Jun-2004
296     */

297    protected Parser getParser()
298    {
299       Parser parser = new Parser();
300       return parser;
301    }
302
303    /**
304     * Common code for building up the Service from a WSDL document
305     *
306     * @param context Context URL
307     * @param doc A DOM document containing WSDL
308     * @param serviceName Qualified name of the desired service
309     * @throws ServiceException If there's an error finding or parsing the WSDL
310     */

311    private void initService(String JavaDoc context, Document JavaDoc doc, QName JavaDoc serviceName)
312            throws ServiceException JavaDoc
313    {
314       try
315       {
316          // Start by reading in the WSDL using Parser
317
Parser parser = getParser();
318          parser.run(context, doc);
319
320          initService(parser, serviceName);
321       }
322       catch (Exception JavaDoc exp)
323       {
324          throw new ServiceException JavaDoc(Messages.getMessage("wsdlError00", "" + "", "\n" + exp));
325       }
326    }
327
328    /**
329     * Code for building up the Service from a Parser
330     *
331     * @param parser Parser for this service
332     * @param serviceName Qualified name of the desired service
333     * @throws ServiceException If there's an error finding or parsing the WSDL
334     */

335    private void initService(Parser parser, QName JavaDoc serviceName) throws ServiceException JavaDoc
336    {
337       this.wsdlParser = parser;
338
339       try
340       {
341          // In case of a partial WSDL, the service name may not be given
342
if (serviceName != null)
343          {
344             ServiceEntry serviceEntry = parser.getSymbolTable().getServiceEntry(serviceName);
345             if (serviceEntry != null)
346                this.wsdlService = serviceEntry.getService();
347             if (this.wsdlService == null)
348                throw new ServiceException JavaDoc(Messages.getMessage("noService00", "" + serviceName));
349          }
350
351       }
352       catch (Exception JavaDoc exp)
353       {
354          throw new ServiceException JavaDoc(Messages.getMessage("wsdlError00", "" + "", "\n" + exp));
355       }
356    }
357
358    protected javax.wsdl.Service getWSDLService()
359    {
360       return (wsdlService);
361    }
362
363    public Parser getWSDLParser()
364    {
365       return (wsdlParser);
366    }
367
368    protected AxisClient getAxisClient()
369    {
370       return new AxisClient(getEngineConfiguration());
371    }
372
373    /**
374     * Return either an instance of a generated stub, if it can be
375     * found, or a dynamic proxy for the given proxy interface.
376     *
377     * @param portName The name of the service port
378     * @param proxyInterface The Remote object returned by this
379     * method will also implement the given proxyInterface
380     * @return java.rmi.Remote The stub implementation.
381     * @throws ServiceException If there's an error
382     */

383    public Remote JavaDoc getPort(QName JavaDoc portName, Class JavaDoc proxyInterface)
384            throws ServiceException JavaDoc
385    {
386
387       if (wsdlService == null)
388          throw new ServiceException JavaDoc(Messages.getMessage("wsdlMissing00"));
389
390       Port port = wsdlService.getPort(portName.getLocalPart());
391       if (port == null)
392          throw new ServiceException JavaDoc(Messages.getMessage("noPort00", "" + portName));
393
394       // First, try to find a generated stub. If that
395
// returns null, then find a dynamic stub.
396
Remote JavaDoc stub = getGeneratedStub(portName, proxyInterface);
397       return stub != null ? stub : getPort(null, portName, proxyInterface);
398    }
399
400    /**
401     * With the proxyInterface and the service's portName, we have
402     * ALMOST enough info to find a generated stub. The generated
403     * stub is named after the binding, which we can get from the
404     * service's port. This binding is likely in the same namespace
405     * (ie, package) that the proxyInterface is in. So try to find
406     * and instantiate <proxyInterfacePackage>.<bindingName>Stub.
407     * If it doesn't exist, return null.
408     */

409    protected Remote JavaDoc getGeneratedStub(QName JavaDoc portName, Class JavaDoc proxyInterface) throws ServiceException JavaDoc
410    {
411       try
412       {
413          if (portName != null && proxyInterface != null)
414          {
415             String JavaDoc pkg = proxyInterface.getName();
416             pkg = pkg.substring(0, pkg.lastIndexOf('.'));
417             Port port = wsdlService.getPort(portName.getLocalPart());
418             String JavaDoc binding = port.getBinding().getQName().getLocalPart();
419             Class JavaDoc stubClass = ClassUtils.forName(pkg + "." + binding + "Stub");
420             if (proxyInterface.isAssignableFrom(stubClass))
421             {
422                Class JavaDoc[] formalArgs = {javax.xml.rpc.Service JavaDoc.class};
423                Object JavaDoc[] actualArgs = {this};
424                Constructor JavaDoc ctor = stubClass.getConstructor(formalArgs);
425                Stub stub = (Stub)ctor.newInstance(actualArgs);
426                stub._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY,
427                        WSDLUtils.getAddressFromPort(port));
428                stub.setPortName(portName);
429                return (Remote JavaDoc)stub;
430             }
431          }
432          return null;
433       }
434       catch (Throwable JavaDoc t)
435       {
436          return null;
437       }
438    } // getGeneratedStub
439

440    /**
441     * Return a dynamic proxy for the given proxy interface.
442     *
443     * @param proxyInterface The Remote object returned by this
444     * method will also implement the given proxyInterface
445     * @return java.rmi.Remote The stub implementation
446     * @throws ServiceException If there's an error
447     */

448    public Remote JavaDoc getPort(Class JavaDoc proxyInterface) throws ServiceException JavaDoc
449    {
450
451       // stub this out for ws4ee mapping
452
Port port = getWSDLPort(proxyInterface);
453
454       // For a partial wsdl the port may not be given
455
QName JavaDoc portName = (port != null ? new QName JavaDoc(port.getName()) : null);
456
457       // First, try to find a generated stub. If that
458
// returns null, then find a dynamic stub.
459
Remote JavaDoc stub = getGeneratedStub(portName, proxyInterface);
460       return stub != null ? stub : getPort(null, portName, proxyInterface);
461    }
462
463    /**
464     * Get the WSDL Port for a given service endpoint interface
465     * <p/>
466     * This implementation gets the wsdl port that corresponds to the class name,
467     * if not found it just get the first one we have.
468     *
469     * @param seiClass The service endpoint interface class
470     * @return A wsdl Port
471     * @throws ServiceException If there's an error
472     */

473    protected Port getWSDLPort(Class JavaDoc seiClass) throws ServiceException JavaDoc
474    {
475
476       if (wsdlService == null)
477          throw new ServiceException JavaDoc(Messages.getMessage("wsdlMissing00"));
478
479       Map JavaDoc ports = wsdlService.getPorts();
480       if (ports == null || ports.size() <= 0)
481          throw new ServiceException JavaDoc(Messages.getMessage("noPort00", ""));
482
483       // Get the name of the class (without package name)
484
String JavaDoc clazzName = seiClass.getName();
485       if (clazzName.lastIndexOf('.') != -1)
486       {
487          clazzName = clazzName.substring(clazzName.lastIndexOf('.') + 1);
488       }
489
490       // Pick the port with the same name as the class
491
Port port = (Port)ports.get(clazzName);
492       if (port == null)
493       {
494          // If not found, just pick the first port.
495
port = (Port)ports.values().iterator().next();
496       }
497
498       return port;
499    }
500
501    /**
502     * Return an object which acts as a dynamic proxy for the passed
503     * interface class. This is a more "dynamic" version in that it
504     * doesn't actually require WSDL, simply an endpoint address.
505     * <p/>
506     * Note: Not part of the JAX-RPC spec.
507     *
508     * @param endpoint the URL which will be used as the SOAP endpoint
509     * @param proxyInterface the interface class which we wish to mimic
510     * via a dynamic proxy
511     * @throws ServiceException
512     */

513    public Remote JavaDoc getPort(String JavaDoc endpoint, Class JavaDoc proxyInterface) throws ServiceException JavaDoc
514    {
515       return getPort(endpoint, null, proxyInterface);
516    }
517
518    protected Remote JavaDoc getPort(String JavaDoc endpoint, QName JavaDoc portName, Class JavaDoc proxyInterface)
519            throws ServiceException JavaDoc
520    {
521
522       if (!proxyInterface.isInterface())
523       {
524          throw new ServiceException JavaDoc(Messages.getMessage("mustBeIface00"));
525       }
526
527       if (!(Remote JavaDoc.class.isAssignableFrom(proxyInterface)))
528       {
529          throw new ServiceException JavaDoc(Messages.getMessage("mustExtendRemote00"));
530       }
531
532       try
533       {
534          Call call = null;
535          if (portName == null)
536          {
537             call = (org.jboss.axis.client.Call)createCall();
538             if (endpoint != null)
539             {
540                call.setTargetEndpointAddress(new URL JavaDoc(endpoint));
541             }
542          }
543          else
544          {
545             call = (org.jboss.axis.client.Call)createCall(portName);
546          }
547          ClassLoader JavaDoc classLoader =
548                  Thread.currentThread().getContextClassLoader();
549          return (Remote JavaDoc)Proxy.newProxyInstance(classLoader,
550                  new Class JavaDoc[]{proxyInterface, javax.xml.rpc.Stub JavaDoc.class},
551                  new AxisClientProxy(call, portName));
552       }
553       catch (ServiceException JavaDoc e)
554       {
555          throw e;
556       }
557       catch (Exception JavaDoc e)
558       {
559          throw new ServiceException JavaDoc(e);
560       }
561    }
562
563    /**
564     * Creates a new Call object - will prefill as much info from the WSDL
565     * as it can. Right now it's just the target URL of the Web Service.
566     *
567     * @param portName PortName in the WSDL doc to search for
568     * @return Call Used for invoking the Web Service
569     * @throws ServiceException If there's an error
570     */

571    public javax.xml.rpc.Call JavaDoc createCall(QName JavaDoc portName) throws ServiceException JavaDoc
572    {
573
574       Call call = (org.jboss.axis.client.Call)createCall();
575       call.setPortName(portName);
576
577       // We can't prefill information if WSDL is not specified,
578
// So just return the call that we just created.
579
if (wsdlParser == null)
580          return call;
581
582       // First see if the service provides it
583
String JavaDoc targetEndpointAddress = getTargetEnpointAddress();
584
585       // If not read it from the wsdl port
586
if (targetEndpointAddress == null)
587       {
588          Port port = wsdlService.getPort(portName.getLocalPart());
589          if (port == null)
590             throw new ServiceException JavaDoc(Messages.getMessage("noPort00", "" + portName));
591
592          Binding binding = port.getBinding();
593          PortType portType = binding.getPortType();
594          if (portType == null)
595             throw new ServiceException JavaDoc(Messages.getMessage("noPortType00", "" + portName));
596
597          // Get the URL
598
////////////////////////////////////////////////////////////////////
599
List JavaDoc list = port.getExtensibilityElements();
600          for (int i = 0; list != null && i < list.size(); i++)
601          {
602             Object JavaDoc obj = list.get(i);
603             if (obj instanceof SOAPAddress)
604             {
605                SOAPAddress addr = (SOAPAddress)obj;
606                targetEndpointAddress = addr.getLocationURI();
607             }
608          }
609       }
610
611       try
612       {
613          call.setTargetEndpointAddress(new URL JavaDoc(targetEndpointAddress));
614       }
615       catch (Exception JavaDoc exp)
616       {
617          throw new ServiceException JavaDoc(Messages.getMessage("cantSetURI00", "" + exp));
618       }
619
620       return (call);
621    }
622
623    /**
624     * The service may provide the target endpoint address, in case the client wsdl port
625     * does not contain a valid address. This maybe the case for ws4ee clients that use a
626     * port-component-link element.
627     */

628    protected String JavaDoc getTargetEnpointAddress()
629    {
630       return null;
631    }
632
633    /**
634     * Creates a new Call object - will prefill as much info from the WSDL
635     * as it can. Right now it's target URL, SOAPAction, Parameter types,
636     * and return type of the Web Service.
637     *
638     * @param portName PortName in the WSDL doc to search for
639     * @param operationName Operation(method) that's going to be invoked
640     * @return Call Used for invoking the Web Service
641     * @throws ServiceException If there's an error
642     */

643    public javax.xml.rpc.Call JavaDoc createCall(QName JavaDoc portName,
644                                         String JavaDoc operationName)
645            throws ServiceException JavaDoc
646    {
647
648       Call call = (org.jboss.axis.client.Call)createCall();
649       call.setOperation(portName, operationName);
650       return (call);
651    }
652
653    /**
654     * Creates a new Call object - will prefill as much info from the WSDL
655     * as it can. Right now it's target URL, SOAPAction, Parameter types,
656     * and return type of the Web Service.
657     *
658     * @param portName PortName in the WSDL doc to search for
659     * @param operationName Operation(method) that's going to be invoked
660     * @return Call Used for invoking the Web Service
661     * @throws ServiceException If there's an error
662     */

663    public javax.xml.rpc.Call JavaDoc createCall(QName JavaDoc portName,
664                                         QName JavaDoc operationName)
665            throws ServiceException JavaDoc
666    {
667
668       Call call = (org.jboss.axis.client.Call)createCall();
669       call.setOperation(portName, operationName.getLocalPart());
670       return (call);
671    }
672
673    /**
674     * Creates a new Call object with no prefilled data. This assumes
675     * that the caller will set everything manually - no checking of
676     * any kind will be done against the WSDL.
677     *
678     * @return Call Used for invoking the Web Service
679     * @throws ServiceException If there's an error
680     */

681    public javax.xml.rpc.Call JavaDoc createCall() throws ServiceException JavaDoc
682    {
683       Call call = new org.jboss.axis.client.Call(this);
684       return call;
685    }
686
687    /**
688     * Gets an array of preconfigured Call objects for invoking operations
689     * on the specified port. There is one Call object per operation that
690     * can be invoked on the specified port. Each Call object is
691     * pre-configured and does not need to be configured using the setter
692     * methods on Call interface.
693     * <p/>
694     * This method requires the Service implementation class to have access
695     * to the WSDL related metadata.
696     *
697     * @throws ServiceException - If this Service class does not have access
698     * to the required WSDL metadata or if an illegal portName is specified.
699     */

700    public javax.xml.rpc.Call JavaDoc[] getCalls(QName JavaDoc portName) throws ServiceException JavaDoc
701    {
702       if (portName == null)
703          throw new ServiceException JavaDoc(Messages.getMessage("badPort00"));
704
705       if (wsdlService == null)
706          throw new ServiceException JavaDoc(Messages.getMessage("wsdlMissing00"));
707
708       Port port = wsdlService.getPort(portName.getLocalPart());
709       if (port == null)
710          throw new ServiceException JavaDoc(Messages.getMessage("noPort00", "" + portName));
711
712       Binding binding = port.getBinding();
713       SymbolTable symbolTable = wsdlParser.getSymbolTable();
714       BindingEntry bEntry =
715               symbolTable.getBindingEntry(binding.getQName());
716       Iterator JavaDoc i = bEntry.getParameters().keySet().iterator();
717
718       Vector JavaDoc calls = new Vector JavaDoc();
719       while (i.hasNext())
720       {
721          Operation operation = (Operation)i.next();
722          javax.xml.rpc.Call JavaDoc call = createCall(QName.valueOf(port.getName()),
723                  QName.valueOf(operation.getName()));
724          calls.add(call);
725       }
726       javax.xml.rpc.Call JavaDoc[] array = new javax.xml.rpc.Call JavaDoc[calls.size()];
727       calls.toArray(array);
728       return array;
729    }
730
731    /**
732     * Returns the configured HandlerRegistry instance for this Service
733     * instance.
734     * <p/>
735     * NOTE: This Service currently does not support the configuration
736     * of a HandlerRegistry! It will throw a
737     * java.lang.UnsupportedOperationException.
738     *
739     * @return HandlerRegistry
740     * @throws java.lang.UnsupportedOperationException
741     * - if the Service
742     * class does not support the configuration of a
743     * HandlerRegistry.
744     */

745    public HandlerRegistry JavaDoc getHandlerRegistry()
746    {
747       return registry;
748    }
749
750    /**
751     * Returns the location of the WSDL document used to prefill the data
752     * (if one was used at all).
753     *
754     * @return URL URL pointing to the WSDL doc
755     */

756    public URL JavaDoc getWSDLDocumentLocation()
757    {
758       try
759       {
760          return new URL JavaDoc(wsdlLocation);
761       }
762       catch (MalformedURLException JavaDoc e)
763       {
764          return null;
765       }
766    }
767
768    /**
769     * Returns the qualified name of the service (if one is set).
770     *
771     * @return QName Fully qualified name of this service.
772     */

773    public QName JavaDoc getServiceName()
774    {
775
776       if (serviceName != null)
777          return serviceName;
778
779       if (wsdlService == null)
780          return null;
781
782       QName JavaDoc qn = wsdlService.getQName();
783       return (new QName JavaDoc(qn.getNamespaceURI(), qn.getLocalPart()));
784    }
785
786    /**
787     * Returns an <code>Iterator</code> for the list of
788     * <code>QName</code>s of service endpoints grouped by this
789     * service
790     *
791     * @return Returns <code>java.util.Iterator</code> with elements
792     * of type <code>javax.xml.namespace.QName</code>
793     * @throws ServiceException If this Service class does not
794     * have access to the required WSDL metadata
795     */

796    public Iterator JavaDoc getPorts() throws ServiceException JavaDoc
797    {
798
799       if (wsdlService == null)
800          throw new ServiceException JavaDoc(Messages.getMessage("wsdlMissing00"));
801
802       if (wsdlService.getPorts() == null)
803          return new Vector JavaDoc().iterator();
804
805       return wsdlService.getPorts().keySet().iterator();
806    }
807
808    /**
809     * Defines the current Type Mappig Registry.
810     *
811     * @param registry The TypeMappingRegistry
812     * @throws ServiceException if there's an error
813     */

814    public void setTypeMappingRegistry(TypeMappingRegistry JavaDoc registry)
815            throws ServiceException JavaDoc
816    {
817    }
818
819    /**
820     * Returns the current TypeMappingRegistry or null.
821     *
822     * @return TypeMappingRegistry The registry
823     */

824    public TypeMappingRegistry JavaDoc getTypeMappingRegistry()
825    {
826       return (engine.getTypeMappingRegistry());
827    }
828
829    /**
830     * Returns a reference to this object.
831     *
832     * @return Reference ...
833     */

834    public Reference JavaDoc getReference()
835    {
836       String JavaDoc classname = this.getClass().getName();
837       Reference JavaDoc reference = new Reference JavaDoc(classname,
838               "org.jboss.axis.client.ServiceFactory", null);
839       StringRefAddr JavaDoc addr = null;
840       if (!classname.equals("org.jboss.axis.client.Service"))
841       {
842          // This is a generated derived class. Don't bother with
843
// all the Service instance variables.
844
addr = new StringRefAddr JavaDoc(ServiceFactory.SERVICE_CLASSNAME, classname);
845          reference.add(addr);
846       }
847       else
848       {
849          if (wsdlLocation != null)
850          {
851             addr = new StringRefAddr JavaDoc(ServiceFactory.WSDL_LOCATION, wsdlLocation.toString());
852             reference.add(addr);
853          }
854          QName JavaDoc serviceName = getServiceName();
855          if (serviceName != null)
856          {
857             addr = new StringRefAddr JavaDoc(ServiceFactory.SERVICE_NAMESPACE,
858                     serviceName.getNamespaceURI());
859             reference.add(addr);
860             addr = new StringRefAddr JavaDoc(ServiceFactory.SERVICE_LOCAL_PART,
861                     serviceName.getLocalPart());
862             reference.add(addr);
863          }
864       }
865       if (maintainSession)
866       {
867          addr = new StringRefAddr JavaDoc(ServiceFactory.MAINTAIN_SESSION, "true");
868          reference.add(addr);
869       }
870       return reference;
871    }
872
873    /**
874     * Sets this Service's AxisEngine. This engine will be shared by all
875     * Call objects created from this Service object.
876     * <p/>
877     * Note: Not part of the JAX-RPC spec.
878     *
879     * @param engine Sets this Service's AxisEngine to the passed in one
880     */

881    public void setEngine(AxisEngine engine)
882    {
883       this.engine = engine;
884    }
885
886    /**
887     * Returns the current AxisEngine used by this Service and all of the
888     * Call objects created from this Service object.
889     * <p/>
890     * Note: Not part of the JAX-RPC spec.
891     *
892     * @return AxisEngine the engine
893     */

894    public AxisEngine getEngine()
895    {
896       return (engine);
897    }
898
899    /**
900     * Set this Service's engine configuration.
901     * <p/>
902     * Note that since all of the constructors create the AxisClient right
903     * now, this is basically a no-op. Putting it in now so that we can make
904     * lazy engine instantiation work, and not have to duplicate every single
905     * Service constructor with a EngineConfiguration argument.
906     * <p/>
907     * If you need to use a non-default <code>EngineConfiguration</code>, do
908     * the following before calling the Service constructor:<p><code>
909     * <p/>
910     * AxisProperties.setProperty(EngineConfigurationFactory.SYSTEM_PROPERTY_NAME,
911     * "classname.of.new.EngineConfigurationFactory");
912     * </code><p>
913     * Where the second parameter is the name of your new class that implements
914     * <code>EngineConfigurationFactory</code> and a<code><br>
915     * public static EngineConfigurationFactory newFactory(Object param)
916     * </code>
917     * method. See <code>EngineConfigurationFactoryDefault</code> for an example
918     * of how to do this.<p>
919     * <p/>
920     * This way, when the Service class constructor calls<br><code>
921     * <p/>
922     * EngineConfigurationFactoryFinder.newFactory().getClientEngineConfig()
923     * </code>
924     * the getClientEngineConfig() of your own EngineConfigurationFactory will be
925     * called, and your configuration will be used in the constructed Service object.<p>
926     * <p/>
927     * Another way is to use the "discovery" method of
928     * <code>EngineConfigurationFactoryFinder</code>.
929     *
930     * @param config the EngineConfiguration we want to use.
931     */

932    public void setEngineConfiguration(EngineConfiguration config)
933    {
934       this.config = config;
935    }
936
937    /**
938     * Constructs a EngineConfig if one is not available.
939     */

940    protected EngineConfiguration getEngineConfiguration()
941    {
942       if (this.config == null)
943       {
944          this.config = EngineConfigurationFactoryFinder.newFactory().getClientEngineConfig();
945       }
946       return config;
947    }
948
949    /**
950     * Determine whether we'd like to track sessions or not.
951     * This information is passed to all Call objects created
952     * from this service. Calling setMaintainSession will
953     * only affect future instantiations of the Call object,
954     * not those that already exist.
955     * <p/>
956     * Note: Not part of JAX-RPC specification.
957     *
958     * @param yesno true if session state is desired, false if not.
959     */

960    public void setMaintainSession(boolean yesno)
961    {
962       maintainSession = yesno;
963    }
964
965    /**
966     * If true, this service wants to track sessions.
967     */

968    public boolean getMaintainSession()
969    {
970       return maintainSession;
971    }
972
973    /**
974     * Tells whether or not we're caching WSDL
975     */

976    public boolean getCacheWSDL()
977    {
978       return cachingWSDL;
979    }
980
981    /**
982     * Allows users to turn caching of WSDL documents on or off.
983     * Default is 'true' (on).
984     */

985    public void setCacheWSDL(boolean flag)
986    {
987       cachingWSDL = flag;
988    }
989
990    protected static class HandlerRegistryImpl implements HandlerRegistry JavaDoc
991    {
992       Map JavaDoc map = new HashMap JavaDoc();
993
994       public List JavaDoc getHandlerChain(QName JavaDoc portName)
995       {
996          List JavaDoc list = (List JavaDoc)map.get(portName);
997          if (list == null)
998          {
999             list = new java.util.ArrayList JavaDoc();
1000            setHandlerChain(portName, list);
1001         }
1002         return list;
1003      }
1004
1005      public void setHandlerChain(QName JavaDoc portName, List JavaDoc chain)
1006      {
1007         map.put(portName, chain);
1008      }
1009   }
1010
1011   /**
1012    * Register a Transport for a particular URL.
1013    */

1014   void registerTransportForURL(URL JavaDoc url, Transport transport)
1015   {
1016      transportImpls.put(url, transport);
1017   }
1018
1019   /**
1020    * Get any registered Transport object for a given URL.
1021    */

1022   Transport getTransportForURL(URL JavaDoc url)
1023   {
1024      return (Transport)transportImpls.get(url);
1025   }
1026
1027}
1028
Popular Tags