Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/axis/deployment/wsdd/WSDDService.java


1   /*
2    * Copyright 2001-2005 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.axis.deployment.wsdd;
17  
18  import org.apache.axis.AxisEngine;
19  import org.apache.axis.AxisFault;
20  import org.apache.axis.ConfigurationException;
21  import org.apache.axis.Constants;
22  import org.apache.axis.EngineConfiguration;
23  import org.apache.axis.FaultableHandler;
24  import org.apache.axis.Handler;
25  import org.apache.axis.MessageContext;
26  import org.apache.axis.attachments.Attachments;
27  import org.apache.axis.attachments.AttachmentsImpl;
28  import org.apache.axis.constants.Style;
29  import org.apache.axis.constants.Use;
30  import org.apache.axis.description.JavaServiceDesc;
31  import org.apache.axis.description.ServiceDesc;
32  import org.apache.axis.encoding.DeserializerFactory;
33  import org.apache.axis.encoding.SerializationContext;
34  import org.apache.axis.encoding.SerializerFactory;
35  import org.apache.axis.encoding.TypeMapping;
36  import org.apache.axis.encoding.TypeMappingRegistry;
37  import org.apache.axis.encoding.TypeMappingRegistryImpl;
38  import org.apache.axis.encoding.ser.ArraySerializerFactory;
39  import org.apache.axis.encoding.ser.BaseDeserializerFactory;
40  import org.apache.axis.encoding.ser.BaseSerializerFactory;
41  import org.apache.axis.handlers.HandlerInfoChainFactory;
42  import org.apache.axis.handlers.soap.SOAPService;
43  import org.apache.axis.providers.java.JavaProvider;
44  import org.apache.axis.utils.Messages;
45  import org.apache.axis.utils.XMLUtils;
46  import org.w3c.dom.Element;
47  import org.xml.sax.helpers.AttributesImpl;
48  
49  import javax.xml.namespace.QName;
50  import java.io.IOException;
51  import java.util.ArrayList;
52  import java.util.List;
53  import java.util.StringTokenizer;
54  import java.util.Vector;
55  
56  /**
57   * A service represented in WSDD.
58   *
59   * @author Glen Daniels (gdaniels@apache.org)
60   */
61  public class WSDDService
62      extends WSDDTargetedChain
63      implements WSDDTypeMappingContainer
64  {
65      private TypeMappingRegistry tmr = null;
66  
67      private Vector faultFlows = new Vector();
68      private Vector typeMappings = new Vector();
69      private Vector operations = new Vector();
70  
71      /** Which namespaces should auto-dispatch to this service? */
72      private Vector namespaces = new Vector();
73  
74      /** Which roles does this service support? */
75      private List roles = new ArrayList();
76  
77      private String descriptionURL;
78  
79      /** Style - document, wrapped, message, or RPC (the default) */
80      private Style style = Style.DEFAULT;
81      /** Use   - encoded (the default) or literal */
82      private Use use = Use.DEFAULT;
83  
84      private transient SOAPService cachedService = null;
85  
86      /**
87       * Our provider - used to figure out which Handler we use as a service
88       * pivot (see getInstance() below)
89       */
90      private QName providerQName;
91  
92  //    private HandlerInfoChainFactory _hiChainFactory;
93    private WSDDJAXRPCHandlerInfoChain _wsddHIchain;
94  
95      JavaServiceDesc desc = new JavaServiceDesc();
96  
97      /**
98       * Is streaming (i.e. NO high-fidelity recording, deserialize on the fly)
99       * on for this service?
100      */
101     private boolean streaming = false;
102 
103     /**
104      * What attachment format should be used?
105      */
106     private int sendType = Attachments.SEND_TYPE_NOTSET;
107 
108     /**
109      * Default constructor
110      */
111     public WSDDService()
112     {
113     }
114 
115     /**
116      *
117      * @param e (Element) XXX
118      * @throws WSDDException XXX
119      */
120     public WSDDService(Element e)
121         throws WSDDException
122     {
123         super(e);
124 
125         desc.setName(getQName().getLocalPart());
126 
127         String styleStr = e.getAttribute(ATTR_STYLE);
128         if (styleStr != null && !styleStr.equals("")) {
129             style = Style.getStyle(styleStr, Style.DEFAULT);
130             desc.setStyle(style);
131             providerQName = style.getProvider();
132         }
133 
134         String useStr = e.getAttribute(ATTR_USE);
135         if (useStr != null && !useStr.equals("")) {
136             use = Use.getUse(useStr, Use.DEFAULT);
137             desc.setUse(use);
138         } else {
139             if (style != Style.RPC) {
140                 // Default to use=literal if not style=RPC
141                 use = Use.LITERAL;
142                 desc.setUse(use);
143             }
144         }
145 
146         String streamStr = e.getAttribute(ATTR_STREAMING);
147         if (streamStr != null && streamStr.equals("on")) {
148             streaming = true;
149         }
150 
151         String attachmentStr = e.getAttribute(ATTR_ATTACHMENT_FORMAT);
152         if (attachmentStr != null && !attachmentStr.equals("")) {
153             sendType = AttachmentsImpl.getSendType(attachmentStr);
154         }
155 
156         Element [] operationElements = getChildElements(e, ELEM_WSDD_OPERATION);
157         for (int i = 0; i < operationElements.length; i++) {
158             WSDDOperation operation = new WSDDOperation(operationElements[i],
159                                                         desc);
160             addOperation(operation);
161         }
162 
163         Element [] typeMappingElements = getChildElements(e, ELEM_WSDD_TYPEMAPPING);
164         for (int i = 0; i < typeMappingElements.length; i++) {
165             WSDDTypeMapping mapping =
166                     new WSDDTypeMapping(typeMappingElements[i]);
167             typeMappings.add(mapping);
168         }
169 
170         Element [] beanMappingElements = getChildElements(e, ELEM_WSDD_BEANMAPPING);
171         for (int i = 0; i < beanMappingElements.length; i++) {
172             WSDDBeanMapping mapping =
173                     new WSDDBeanMapping(beanMappingElements[i]);
174             typeMappings.add(mapping);
175         }
176 
177         Element [] arrayMappingElements = getChildElements(e, ELEM_WSDD_ARRAYMAPPING);
178         for (int i = 0; i < arrayMappingElements.length; i++) {
179             WSDDArrayMapping mapping =
180                     new WSDDArrayMapping(arrayMappingElements[i]);
181             typeMappings.add(mapping);
182         }
183 
184         Element [] namespaceElements = getChildElements(e, ELEM_WSDD_NAMESPACE);
185         for (int i = 0; i < namespaceElements.length; i++) {
186             // Register a namespace for this service
187             String ns = XMLUtils.getChildCharacterData(namespaceElements[i]);
188             namespaces.add(ns);
189         }
190         if (!namespaces.isEmpty())
191             desc.setNamespaceMappings(namespaces);
192 
193         Element [] roleElements = getChildElements(e, ELEM_WSDD_ROLE);
194         for (int i = 0; i < roleElements.length; i++) {
195             String role = XMLUtils.getChildCharacterData(roleElements[i]);
196             roles.add(role);
197         }
198 
199         Element wsdlElem = getChildElement(e, ELEM_WSDD_WSDLFILE);
200         if (wsdlElem != null) {
201             String fileName = XMLUtils.getChildCharacterData(wsdlElem);
202             desc.setWSDLFile(fileName.trim());
203         }
204 
205         Element docElem = getChildElement(e, ELEM_WSDD_DOC);
206         if (docElem != null) {
207             WSDDDocumentation documentation = new WSDDDocumentation(docElem);
208             desc.setDocumentation(documentation.getValue());
209         }        
210 
211         Element urlElem = getChildElement(e, ELEM_WSDD_ENDPOINTURL);
212         if (urlElem != null) {
213             String endpointURL = XMLUtils.getChildCharacterData(urlElem);
214             desc.setEndpointURL(endpointURL);
215         }
216 
217         String providerStr = e.getAttribute(ATTR_PROVIDER);
218         if (providerStr != null && !providerStr.equals("")) {
219             providerQName = XMLUtils.getQNameFromString(providerStr, e);
220             if (WSDDConstants.QNAME_JAVAMSG_PROVIDER.equals(providerQName)) {
221                 // Message style if message provider...
222                 desc.setStyle(Style.MESSAGE);
223             }
224         }
225 
226     // Add in JAX-RPC support for HandlerInfo chains
227         Element hcEl = getChildElement(e, ELEM_WSDD_JAXRPC_CHAIN);
228         if (hcEl != null) {
229             _wsddHIchain = new WSDDJAXRPCHandlerInfoChain(hcEl);
230         }
231 
232         // Initialize TypeMappingRegistry
233         initTMR();
234 
235         // call to validate standard descriptors for this service
236         validateDescriptors();
237     }
238 
239     /**
240      * Initialize a TypeMappingRegistry with the
241      * WSDDTypeMappings.
242      * Note: Extensions of WSDDService may override
243      * initTMR to popluate the tmr with different
244      * type mappings.
245      */
246     protected void initTMR() throws WSDDException
247     {
248         // If not created, construct a tmr
249         // and populate it with the type mappings.
250         if (tmr == null) {
251             createTMR();
252             for (int i=0; i<typeMappings.size(); i++) {
253                 deployTypeMapping((WSDDTypeMapping)
254                                   typeMappings.get(i));
255             }
256         }
257     }
258 
259     private void createTMR() {
260         tmr = new TypeMappingRegistryImpl(false);
261         String version = getParameter("typeMappingVersion");
262         ((TypeMappingRegistryImpl)tmr).doRegisterFromVersion(version);
263     }
264 
265     /**
266      * This method can be used for dynamic deployment using new WSDDService()
267      * etc.  It validates some standard parameters for some standard providers
268      * (if present).  Do this before deployment.deployService().
269      */
270     public void validateDescriptors() throws WSDDException
271     {
272         if (tmr == null) {
273             initTMR();
274         }
275         desc.setTypeMappingRegistry(tmr);
276         desc.setTypeMapping(getTypeMapping(desc.getUse().getEncoding()));
277 
278         String allowedMethods = getParameter(JavaProvider.OPTION_ALLOWEDMETHODS);
279         if (allowedMethods != null && !"*".equals(allowedMethods)) {
280             ArrayList methodList = new ArrayList();
281             StringTokenizer tokenizer = new StringTokenizer(allowedMethods, " ,");
282             while (tokenizer.hasMoreTokens()) {
283                 methodList.add(tokenizer.nextToken());
284             }
285             desc.setAllowedMethods(methodList);
286         }
287     }
288 
289     /**
290      * Add a WSDDTypeMapping to the Service.
291      * @param mapping
292      **/
293     public void addTypeMapping(WSDDTypeMapping mapping) {
294         typeMappings.add(mapping);
295     }
296 
297     /**
298      * Add a WSDDOperation to the Service.
299      * @param operation the operation to add
300      **/
301     public void addOperation(WSDDOperation operation) {
302         operations.add(operation);
303         desc.addOperationDesc(operation.getOperationDesc());
304     }
305 
306     protected QName getElementName()
307     {
308         return QNAME_SERVICE;
309     }
310 
311     /**
312      * Get any service description URL which might be associated with this
313      * service.
314      *
315      * @return a String containing a URL, or null.
316      */
317     public String getServiceDescriptionURL()
318     {
319         return descriptionURL;
320     }
321 
322     /**
323      * Set the service description URL for this service.
324      *
325      * @param sdUrl a String containing a URL
326      */
327     public void setServiceDescriptionURL(String sdUrl)
328     {
329         descriptionURL = sdUrl;
330     }
331 
332     public QName getProviderQName() {
333         return providerQName;
334     }
335 
336     public void setProviderQName(QName providerQName) {
337         this.providerQName = providerQName;
338     }
339 
340     public ServiceDesc getServiceDesc() {
341         return desc;
342     }
343 
344     /**
345      * Get the service style - document or RPC
346      */
347     public Style getStyle() {
348         return style;
349     }
350 
351     /**
352      * Set the service style - document or RPC
353      */
354     public void setStyle(Style style) {
355         this.style = style;
356     }
357 
358     /**
359      * Get the service use - literal or encoded
360      */
361     public Use getUse() {
362         return use;
363     }
364 
365     /**
366      * Set the service use - literal or encoded
367      */
368     public void setUse(Use use) {
369         this.use = use;
370     }
371     /**
372      *
373      * @return XXX
374      */
375     public WSDDFaultFlow[] getFaultFlows()
376     {
377         WSDDFaultFlow[] t = new WSDDFaultFlow[faultFlows.size()];
378         faultFlows.toArray(t);
379         return t;
380     }
381 
382     /**
383      * Obtain the list of namespaces registered for this service
384      * @return a Vector of namespaces (Strings) which should dispatch to
385      *         this service
386      */
387     public Vector getNamespaces()
388     {
389         return namespaces;
390     }
391 
392     /**
393      *
394      * @param name XXX
395      * @return XXX
396      */
397     public WSDDFaultFlow getFaultFlow(QName name)
398     {
399         WSDDFaultFlow[] t = getFaultFlows();
400 
401         for (int n = 0; n < t.length; n++) {
402             if (t[n].getQName().equals(name)) {
403                 return t[n];
404             }
405         }
406 
407         return null;
408     }
409 
410     /**
411      *
412      * @param registry XXX
413      * @return XXX
414      * @throws ConfigurationException XXX
415      */
416     public Handler makeNewInstance(EngineConfiguration registry)
417         throws ConfigurationException
418     {
419         if (cachedService != null) {
420             return cachedService;
421         }
422 
423         // Make sure tmr is initialized.
424         initTMR();
425 
426         Handler reqHandler = null;
427         WSDDChain request = getRequestFlow();
428 
429         if (request != null) {
430             reqHandler = request.getInstance(registry);
431         }
432 
433         Handler providerHandler = null;
434 
435         if (providerQName != null) {
436             try {
437                 providerHandler = WSDDProvider.getInstance(providerQName,
438                                                            this,
439                                                            registry);
440             } catch (Exception e) {
441                 throw new ConfigurationException(e);
442             }
443             if (providerHandler == null)
444                 throw new WSDDException(
445                           Messages.getMessage("couldntConstructProvider00"));
446         }
447 
448         Handler respHandler = null;
449         WSDDChain response = getResponseFlow();
450 
451         if (response != null) {
452             respHandler = response.getInstance(registry);
453         }
454 
455         SOAPService service = new SOAPService(reqHandler, providerHandler,
456                                               respHandler);
457         service.setStyle(style);
458         service.setUse(use);
459         service.setServiceDescription(desc);
460 
461         service.setHighFidelityRecording(!streaming);
462         service.setSendType(sendType);
463 
464         if ( getQName() != null )
465             service.setName(getQName().getLocalPart());
466         service.setOptions(getParametersTable());
467 
468         service.setRoles(roles);
469 
470         service.setEngine(((WSDDDeployment)registry).getEngine());
471 
472         if (use != Use.ENCODED) {
473             // If not encoded, turn off multi-refs and prefer
474             // not to sent xsi:type and xsi:nil
475             service.setOption(AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
476             service.setOption(AxisEngine.PROP_SEND_XSI, Boolean.FALSE);
477         }
478 
479         // Set handlerInfoChain
480         if (_wsddHIchain != null) {
481             HandlerInfoChainFactory hiChainFactory = _wsddHIchain.getHandlerChainFactory();
482 
483             service.setOption(Constants.ATTR_HANDLERINFOCHAIN, hiChainFactory);
484         }
485 
486         AxisEngine.normaliseOptions(service);
487 
488         WSDDFaultFlow [] faultFlows = getFaultFlows();
489         if (faultFlows != null && faultFlows.length > 0) {
490             FaultableHandler wrapper = new FaultableHandler(service);
491             for (int i = 0; i < faultFlows.length; i++) {
492                 WSDDFaultFlow flow = faultFlows[i];
493                 Handler faultHandler = flow.getInstance(registry);
494                 wrapper.setOption("fault-" + flow.getQName().getLocalPart(),
495                                   faultHandler);
496             }
497         }
498 
499         try {
500             service.getInitializedServiceDesc(MessageContext.getCurrentContext());
501         } catch (AxisFault axisFault) {
502             throw new ConfigurationException(axisFault);
503         }
504 
505         cachedService = service;
506         return service;
507     }
508 
509     public void deployTypeMapping(WSDDTypeMapping mapping)
510         throws WSDDException
511     {
512         if (!typeMappings.contains(mapping)) {
513             typeMappings.add(mapping);
514         }
515         if (tmr == null) {
516             createTMR();
517         }
518         try {
519             // Get the encoding style from the mapping, if it isn't set
520             // use the use of the service to map doc/lit or rpc/enc
521             String encodingStyle = mapping.getEncodingStyle();
522             if (encodingStyle == null) {
523                 encodingStyle = use.getEncoding();
524             }
525             TypeMapping tm = tmr.getOrMakeTypeMapping(encodingStyle);
526             desc.setTypeMappingRegistry(tmr);
527             desc.setTypeMapping(tm);
528 
529             SerializerFactory   ser   = null;
530             DeserializerFactory deser = null;
531 
532             // Try to construct a serializerFactory by introspecting for the
533             // following:
534             // public static create(Class javaType, QName xmlType)
535             // public <constructor>(Class javaType, QName xmlType)
536             // public <constructor>()
537             //
538             // The BaseSerializerFactory createFactory() method is a utility
539             // that does this for us.
540             if (mapping.getSerializerName() != null &&
541                 !mapping.getSerializerName().equals("")) {
542                 ser = BaseSerializerFactory.createFactory(mapping.getSerializer(),
543                                                           mapping.getLanguageSpecificType(),
544                                                           mapping.getQName());
545             }
546             if (mapping instanceof WSDDArrayMapping && ser instanceof ArraySerializerFactory) {
547                 WSDDArrayMapping am = (WSDDArrayMapping) mapping;
548                 ArraySerializerFactory factory = (ArraySerializerFactory) ser;
549                 factory.setComponentType(am.getInnerType());
550             }
551 
552             if (mapping.getDeserializerName() != null &&
553                 !mapping.getDeserializerName().equals("")) {
554                 deser = BaseDeserializerFactory.createFactory(mapping.getDeserializer(),
555                                                           mapping.getLanguageSpecificType(),
556                                                           mapping.getQName());
557             }
558             tm.register( mapping.getLanguageSpecificType(), mapping.getQName(), ser, deser);
559         } catch (ClassNotFoundException e) {
560             log.error(Messages.getMessage("unabletoDeployTypemapping00", mapping.getQName().toString()), e);
561             throw new WSDDNonFatalException(e);
562         } catch (Exception e) {
563             throw new WSDDException(e);
564         }
565     }
566 
567     /**
568      * Write this element out to a SerializationContext
569      */
570     public void writeToContext(SerializationContext context)
571             throws IOException {
572         AttributesImpl attrs = new AttributesImpl();
573         QName name = getQName();
574         if (name != null) {
575             attrs.addAttribute("", ATTR_NAME, ATTR_NAME,
576                                "CDATA", context.qName2String(name));
577         }
578         if (providerQName != null) {
579             attrs.addAttribute("", ATTR_PROVIDER, ATTR_PROVIDER,
580                                "CDATA", context.qName2String(providerQName));
581         }
582         if (style != Style.DEFAULT) {
583             attrs.addAttribute("", ATTR_STYLE, ATTR_STYLE,
584                                "CDATA", style.getName());
585         }
586 
587         if (use != Use.DEFAULT) {
588             attrs.addAttribute("", ATTR_USE, ATTR_USE,
589                                "CDATA", use.getName());
590         }
591 
592         if (streaming) {
593             attrs.addAttribute("", ATTR_STREAMING, ATTR_STREAMING,
594                                "CDATA", "on");
595         }
596 
597         if (sendType != Attachments.SEND_TYPE_NOTSET) {
598             attrs.addAttribute("", ATTR_ATTACHMENT_FORMAT,
599                                ATTR_ATTACHMENT_FORMAT, "CDATA",
600                                AttachmentsImpl.getSendTypeString(sendType));
601         }
602         context.startElement(WSDDConstants.QNAME_SERVICE, attrs);
603 
604         if (desc.getWSDLFile() != null) {
605             context.startElement(QNAME_WSDLFILE, null);
606             context.writeSafeString(desc.getWSDLFile());
607             context.endElement();
608         }
609         
610         if (desc.getDocumentation() != null) {
611           WSDDDocumentation documentation = new WSDDDocumentation(desc.getDocumentation());
612           documentation.writeToContext(context);
613         }
614 
615         for (int i = 0; i < operations.size(); i++) {
616             WSDDOperation operation = (WSDDOperation) operations.elementAt(i);
617             operation.writeToContext(context);
618         }
619         writeFlowsToContext(context);
620         writeParamsToContext(context);
621 
622 
623         for (int i=0; i < typeMappings.size(); i++) {
624             ((WSDDTypeMapping) typeMappings.elementAt(i)).writeToContext(context);
625         }
626 
627         for (int i=0; i < namespaces.size(); i++ ) {
628             context.startElement(QNAME_NAMESPACE, null);
629             context.writeString((String)namespaces.get(i));
630             context.endElement();
631         }
632 
633         String endpointURL = desc.getEndpointURL();
634         if (endpointURL != null) {
635             context.startElement(QNAME_ENDPOINTURL, null);
636             context.writeSafeString(endpointURL);
637             context.endElement();
638         }
639 
640       if (_wsddHIchain != null) {
641           _wsddHIchain.writeToContext(context);
642 
643         }
644 
645         context.endElement();
646 
647 
648     }
649 
650     public void setCachedService(SOAPService service)
651     {
652         cachedService = service;
653     }
654 
655     public Vector getTypeMappings() {
656         return typeMappings;
657     }
658 
659     public void setTypeMappings(Vector typeMappings) {
660         this.typeMappings = typeMappings;
661     }
662 
663     public void deployToRegistry(WSDDDeployment registry)
664     {
665         registry.addService(this);
666 
667         // Register the name of the service as a valid namespace, just for
668         // backwards compatibility
669         registry.registerNamespaceForService(getQName().getLocalPart(), this);
670 
671         for (int i = 0; i < namespaces.size(); i++) {
672             String namespace = (String) namespaces.elementAt(i);
673             registry.registerNamespaceForService(namespace, this);
674         }
675 
676         super.deployToRegistry(registry);
677     }
678 
679     public void removeNamespaceMappings(WSDDDeployment registry)
680     {
681         for (int i = 0; i < namespaces.size(); i++) {
682             String namespace = (String) namespaces.elementAt(i);
683             registry.removeNamespaceMapping(namespace);
684         }
685         registry.removeNamespaceMapping(getQName().getLocalPart());
686     }
687 
688     public TypeMapping getTypeMapping(String encodingStyle) {
689         // If type mapping registry not initialized yet, return null.
690         if (tmr == null) {
691             return null;
692         }
693         return (TypeMapping) tmr.getOrMakeTypeMapping(encodingStyle);
694     }
695 
696  
697      public WSDDJAXRPCHandlerInfoChain getHandlerInfoChain() {
698          return _wsddHIchain;
699      }
700  
701      public void setHandlerInfoChain(WSDDJAXRPCHandlerInfoChain hichain) {
702          _wsddHIchain = hichain;
703      }
704 }