KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > deployment > wsdd > WSDDService


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 JavaDoc;
47 import org.xml.sax.helpers.AttributesImpl JavaDoc;
48
49 import javax.xml.namespace.QName JavaDoc;
50 import java.io.IOException JavaDoc;
51 import java.util.ArrayList JavaDoc;
52 import java.util.List JavaDoc;
53 import java.util.StringTokenizer JavaDoc;
54 import java.util.Vector JavaDoc;
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 JavaDoc faultFlows = new Vector JavaDoc();
68     private Vector JavaDoc typeMappings = new Vector JavaDoc();
69     private Vector JavaDoc operations = new Vector JavaDoc();
70
71     /** Which namespaces should auto-dispatch to this service? */
72     private Vector JavaDoc namespaces = new Vector JavaDoc();
73
74     /** Which roles does this service support? */
75     private List JavaDoc roles = new ArrayList JavaDoc();
76
77     private String JavaDoc 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 JavaDoc 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 JavaDoc e)
121         throws WSDDException
122     {
123         super(e);
124
125         desc.setName(getQName().getLocalPart());
126
127         String JavaDoc 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 JavaDoc 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 JavaDoc streamStr = e.getAttribute(ATTR_STREAMING);
147         if (streamStr != null && streamStr.equals("on")) {
148             streaming = true;
149         }
150
151         String JavaDoc attachmentStr = e.getAttribute(ATTR_ATTACHMENT_FORMAT);
152         if (attachmentStr != null && !attachmentStr.equals("")) {
153             sendType = AttachmentsImpl.getSendType(attachmentStr);
154         }
155
156         Element JavaDoc [] 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 JavaDoc [] 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 JavaDoc [] 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 JavaDoc [] 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 JavaDoc [] namespaceElements = getChildElements(e, ELEM_WSDD_NAMESPACE);
185         for (int i = 0; i < namespaceElements.length; i++) {
186             // Register a namespace for this service
187
String JavaDoc ns = XMLUtils.getChildCharacterData(namespaceElements[i]);
188             namespaces.add(ns);
189         }
190         if (!namespaces.isEmpty())
191             desc.setNamespaceMappings(namespaces);
192
193         Element JavaDoc [] roleElements = getChildElements(e, ELEM_WSDD_ROLE);
194         for (int i = 0; i < roleElements.length; i++) {
195             String JavaDoc role = XMLUtils.getChildCharacterData(roleElements[i]);
196             roles.add(role);
197         }
198
199         Element JavaDoc wsdlElem = getChildElement(e, ELEM_WSDD_WSDLFILE);
200         if (wsdlElem != null) {
201             String JavaDoc fileName = XMLUtils.getChildCharacterData(wsdlElem);
202             desc.setWSDLFile(fileName.trim());
203         }
204
205         Element JavaDoc 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 JavaDoc urlElem = getChildElement(e, ELEM_WSDD_ENDPOINTURL);
212         if (urlElem != null) {
213             String JavaDoc endpointURL = XMLUtils.getChildCharacterData(urlElem);
214             desc.setEndpointURL(endpointURL);
215         }
216
217         String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc allowedMethods = getParameter(JavaProvider.OPTION_ALLOWEDMETHODS);
279         if (allowedMethods != null && !"*".equals(allowedMethods)) {
280             ArrayList JavaDoc methodList = new ArrayList JavaDoc();
281             StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(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 JavaDoc 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 JavaDoc 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 JavaDoc sdUrl)
328     {
329         descriptionURL = sdUrl;
330     }
331
332     public QName JavaDoc getProviderQName() {
333         return providerQName;
334     }
335
336     public void setProviderQName(QName JavaDoc 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 JavaDoc getNamespaces()
388     {
389         return namespaces;
390     }
391
392     /**
393      *
394      * @param name XXX
395      * @return XXX
396      */

397     public WSDDFaultFlow getFaultFlow(QName JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc e) {
560             log.error(Messages.getMessage("unabletoDeployTypemapping00", mapping.getQName().toString()), e);
561             throw new WSDDNonFatalException(e);
562         } catch (Exception JavaDoc 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 JavaDoc {
572         AttributesImpl JavaDoc attrs = new AttributesImpl JavaDoc();
573         QName JavaDoc 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 JavaDoc)namespaces.get(i));
630             context.endElement();
631         }
632
633         String JavaDoc 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 JavaDoc getTypeMappings() {
656         return typeMappings;
657     }
658
659     public void setTypeMappings(Vector JavaDoc 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 JavaDoc namespace = (String JavaDoc) 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 JavaDoc namespace = (String JavaDoc) namespaces.elementAt(i);
683             registry.removeNamespaceMapping(namespace);
684         }
685         registry.removeNamespaceMapping(getQName().getLocalPart());
686     }
687
688     public TypeMapping getTypeMapping(String JavaDoc 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 }
705
Popular Tags