2
* Copyright 2001-2005 The Apache Software Foundation.
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
8
* http://www.apache.org/licenses/LICENSE-2.0
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.
16
package org.apache.axis.deployment.wsdd;
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;
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;
57
* A service represented in WSDD.
59
* @author Glen Daniels (gdaniels@apache.org)
61
public class WSDDService
62
extends WSDDTargetedChain
63
implements WSDDTypeMappingContainer
65
private TypeMappingRegistry tmr = null;
67
private Vector faultFlows = new Vector();
68
private Vector typeMappings = new Vector();
69
private Vector operations = new Vector();
71
/** Which namespaces should auto-dispatch to this service? */
72
private Vector namespaces = new Vector();
74
/** Which roles does this service support? */
75
private List roles = new ArrayList();
77
private String descriptionURL;
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;
84
private transient SOAPService cachedService = null;
87
* Our provider - used to figure out which Handler we use as a service
88
* pivot (see getInstance() below)
90
private QName providerQName;
92
// private HandlerInfoChainFactory _hiChainFactory;
93
private WSDDJAXRPCHandlerInfoChain _wsddHIchain;
95
JavaServiceDesc desc = new JavaServiceDesc();
98
* Is streaming (i.e. NO high-fidelity recording, deserialize on the fly)
99
* on for this service?
101
private boolean streaming = false;
104
* What attachment format should be used?
106
private int sendType = Attachments.SEND_TYPE_NOTSET;
109
* Default constructor
117
* @param e (Element) XXX
118
* @throws WSDDException XXX
120
public WSDDService(Element e)
125
desc.setName(getQName().getLocalPart());
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();
134
String useStr = e.getAttribute(ATTR_USE);
135
if (useStr != null && !useStr.equals("")) {
136
use = Use.getUse(useStr, Use.DEFAULT);
139
if (style != Style.RPC) {
140
// Default to use=literal if not style=RPC
146
String streamStr = e.getAttribute(ATTR_STREAMING);
147
if (streamStr != null && streamStr.equals("on")) {
151
String attachmentStr = e.getAttribute(ATTR_ATTACHMENT_FORMAT);
152
if (attachmentStr != null && !attachmentStr.equals("")) {
153
sendType = AttachmentsImpl.getSendType(attachmentStr);
156
Element [] operationElements = getChildElements(e, ELEM_WSDD_OPERATION);
157
for (int i = 0; i < operationElements.length; i++) {
158
WSDDOperation operation = new WSDDOperation(operationElements[i],
160
addOperation(operation);
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);
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);
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);
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]);
190
if (!namespaces.isEmpty())
191
desc.setNamespaceMappings(namespaces);
193
Element [] roleElements = getChildElements(e, ELEM_WSDD_ROLE);
194
for (int i = 0; i < roleElements.length; i++) {
195
String role = XMLUtils.getChildCharacterData(roleElements[i]);
199
Element wsdlElem = getChildElement(e, ELEM_WSDD_WSDLFILE);
200
if (wsdlElem != null) {
201
String fileName = XMLUtils.getChildCharacterData(wsdlElem);
202
desc.setWSDLFile(fileName.trim());
205
Element docElem = getChildElement(e, ELEM_WSDD_DOC);
206
if (docElem != null) {
207
WSDDDocumentation documentation = new WSDDDocumentation(docElem);
208
desc.setDocumentation(documentation.getValue());
211
Element urlElem = getChildElement(e, ELEM_WSDD_ENDPOINTURL);
212
if (urlElem != null) {
213
String endpointURL = XMLUtils.getChildCharacterData(urlElem);
214
desc.setEndpointURL(endpointURL);
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);
226
// Add in JAX-RPC support for HandlerInfo chains
227
Element hcEl = getChildElement(e, ELEM_WSDD_JAXRPC_CHAIN);
229
_wsddHIchain = new WSDDJAXRPCHandlerInfoChain(hcEl);
232
// Initialize TypeMappingRegistry
235
// call to validate standard descriptors for this service
236
validateDescriptors();
240
* Initialize a TypeMappingRegistry with the
242
* Note: Extensions of WSDDService may override
243
* initTMR to popluate the tmr with different
246
protected void initTMR() throws WSDDException
248
// If not created, construct a tmr
249
// and populate it with the type mappings.
252
for (int i=0; i<typeMappings.size(); i++) {
253
deployTypeMapping((WSDDTypeMapping)
254
typeMappings.get(i));
259
private void createTMR() {
260
tmr = new TypeMappingRegistryImpl(false);
261
String version = getParameter("typeMappingVersion");
262
((TypeMappingRegistryImpl)tmr).doRegisterFromVersion(version);
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().
270
public void validateDescriptors() throws WSDDException
275
desc.setTypeMappingRegistry(tmr);
276
desc.setTypeMapping(getTypeMapping(desc.getUse().getEncoding()));
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());
285
desc.setAllowedMethods(methodList);
290
* Add a WSDDTypeMapping to the Service.
293
public void addTypeMapping(WSDDTypeMapping mapping) {
294
typeMappings.add(mapping);
298
* Add a WSDDOperation to the Service.
299
* @param operation the operation to add
301
public void addOperation(WSDDOperation operation) {
302
operations.add(operation);
303
desc.addOperationDesc(operation.getOperationDesc());
306
protected QName getElementName()
308
return QNAME_SERVICE;
312
* Get any service description URL which might be associated with this
315
* @return a String containing a URL, or null.
317
public String getServiceDescriptionURL()
319
return descriptionURL;
323
* Set the service description URL for this service.
325
* @param sdUrl a String containing a URL
327
public void setServiceDescriptionURL(String sdUrl)
329
descriptionURL = sdUrl;
332
public QName getProviderQName() {
333
return providerQName;
336
public void setProviderQName(QName providerQName) {
337
this.providerQName = providerQName;
340
public ServiceDesc getServiceDesc() {
345
* Get the service style - document or RPC
347
public Style getStyle() {
352
* Set the service style - document or RPC
354
public void setStyle(Style style) {
359
* Get the service use - literal or encoded
361
public Use getUse() {
366
* Set the service use - literal or encoded
368
public void setUse(Use use) {
375
public WSDDFaultFlow[] getFaultFlows()
377
WSDDFaultFlow[] t = new WSDDFaultFlow[faultFlows.size()];
378
faultFlows.toArray(t);
383
* Obtain the list of namespaces registered for this service
384
* @return a Vector of namespaces (Strings) which should dispatch to
387
public Vector getNamespaces()
397
public WSDDFaultFlow getFaultFlow(QName name)
399
WSDDFaultFlow[] t = getFaultFlows();
401
for (int n = 0; n < t.length; n++) {
402
if (t[n].getQName().equals(name)) {
412
* @param registry XXX
414
* @throws ConfigurationException XXX
416
public Handler makeNewInstance(EngineConfiguration registry)
417
throws ConfigurationException
419
if (cachedService != null) {
420
return cachedService;
423
// Make sure tmr is initialized.
426
Handler reqHandler = null;
427
WSDDChain request = getRequestFlow();
429
if (request != null) {
430
reqHandler = request.getInstance(registry);
433
Handler providerHandler = null;
435
if (providerQName != null) {
437
providerHandler = WSDDProvider.getInstance(providerQName,
440
} catch (Exception e) {
441
throw new ConfigurationException(e);
443
if (providerHandler == null)
444
throw new WSDDException(
445
Messages.getMessage("couldntConstructProvider00"));
448
Handler respHandler = null;
449
WSDDChain response = getResponseFlow();
451
if (response != null) {
452
respHandler = response.getInstance(registry);
455
SOAPService service = new SOAPService(reqHandler, providerHandler,
457
service.setStyle(style);
459
service.setServiceDescription(desc);
461
service.setHighFidelityRecording(!streaming);
462
service.setSendType(sendType);
464
if ( getQName() != null )
465
service.setName(getQName().getLocalPart());
466
service.setOptions(getParametersTable());
468
service.setRoles(roles);
470
service.setEngine(((WSDDDeployment)registry).getEngine());
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);
479
// Set handlerInfoChain
480
if (_wsddHIchain != null) {
481
HandlerInfoChainFactory hiChainFactory = _wsddHIchain.getHandlerChainFactory();
483
service.setOption(Constants.ATTR_HANDLERINFOCHAIN, hiChainFactory);
486
AxisEngine.normaliseOptions(service);
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(),
500
service.getInitializedServiceDesc(MessageContext.getCurrentContext());
501
} catch (AxisFault axisFault) {
502
throw new ConfigurationException(axisFault);
505
cachedService = service;
509
public void deployTypeMapping(WSDDTypeMapping mapping)
512
if (!typeMappings.contains(mapping)) {
513
typeMappings.add(mapping);
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();
525
TypeMapping tm = tmr.getOrMakeTypeMapping(encodingStyle);
526
desc.setTypeMappingRegistry(tmr);
527
desc.setTypeMapping(tm);
529
SerializerFactory ser = null;
530
DeserializerFactory deser = null;
532
// Try to construct a serializerFactory by introspecting for the
534
// public static create(Class javaType, QName xmlType)
535
// public <constructor>(Class javaType, QName xmlType)
536
// public <constructor>()
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(),
546
if (mapping instanceof WSDDArrayMapping && ser instanceof ArraySerializerFactory) {
547
WSDDArrayMapping am = (WSDDArrayMapping) mapping;
548
ArraySerializerFactory factory = (ArraySerializerFactory) ser;
549
factory.setComponentType(am.getInnerType());
552
if (mapping.getDeserializerName() != null &&
553
!mapping.getDeserializerName().equals("")) {
554
deser = BaseDeserializerFactory.createFactory(mapping.getDeserializer(),
555
mapping.getLanguageSpecificType(),
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);
568
* Write this element out to a SerializationContext
570
public void writeToContext(SerializationContext context)
572
AttributesImpl attrs = new AttributesImpl();
573
QName name = getQName();
575
attrs.addAttribute("", ATTR_NAME, ATTR_NAME,
576
"CDATA", context.qName2String(name));
578
if (providerQName != null) {
579
attrs.addAttribute("", ATTR_PROVIDER, ATTR_PROVIDER,
580
"CDATA", context.qName2String(providerQName));
582
if (style != Style.DEFAULT) {
583
attrs.addAttribute("", ATTR_STYLE, ATTR_STYLE,
584
"CDATA", style.getName());
587
if (use != Use.DEFAULT) {
588
attrs.addAttribute("", ATTR_USE, ATTR_USE,
589
"CDATA", use.getName());
593
attrs.addAttribute("", ATTR_STREAMING, ATTR_STREAMING,
597
if (sendType != Attachments.SEND_TYPE_NOTSET) {
598
attrs.addAttribute("", ATTR_ATTACHMENT_FORMAT,
599
ATTR_ATTACHMENT_FORMAT, "CDATA",
600
AttachmentsImpl.getSendTypeString(sendType));
602
context.startElement(WSDDConstants.QNAME_SERVICE, attrs);
604
if (desc.getWSDLFile() != null) {
605
context.startElement(QNAME_WSDLFILE, null);
606
context.writeSafeString(desc.getWSDLFile());
607
context.endElement();
610
if (desc.getDocumentation() != null) {
611
WSDDDocumentation documentation = new WSDDDocumentation(desc.getDocumentation());
612
documentation.writeToContext(context);
615
for (int i = 0; i < operations.size(); i++) {
616
WSDDOperation operation = (WSDDOperation) operations.elementAt(i);
617
operation.writeToContext(context);
619
writeFlowsToContext(context);
620
writeParamsToContext(context);
623
for (int i=0; i < typeMappings.size(); i++) {
624
((WSDDTypeMapping) typeMappings.elementAt(i)).writeToContext(context);
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();
633
String endpointURL = desc.getEndpointURL();
634
if (endpointURL != null) {
635
context.startElement(QNAME_ENDPOINTURL, null);
636
context.writeSafeString(endpointURL);
637
context.endElement();
640
if (_wsddHIchain != null) {
641
_wsddHIchain.writeToContext(context);
645
context.endElement();
650
public void setCachedService(SOAPService service)
652
cachedService = service;
655
public Vector getTypeMappings() {
659
public void setTypeMappings(Vector typeMappings) {
660
this.typeMappings = typeMappings;
663
public void deployToRegistry(WSDDDeployment registry)
665
registry.addService(this);
667
// Register the name of the service as a valid namespace, just for
668
// backwards compatibility
669
registry.registerNamespaceForService(getQName().getLocalPart(), this);
671
for (int i = 0; i < namespaces.size(); i++) {
672
String namespace = (String) namespaces.elementAt(i);
673
registry.registerNamespaceForService(namespace, this);
676
super.deployToRegistry(registry);
679
public void removeNamespaceMappings(WSDDDeployment registry)
681
for (int i = 0; i < namespaces.size(); i++) {
682
String namespace = (String) namespaces.elementAt(i);
683
registry.removeNamespaceMapping(namespace);
685
registry.removeNamespaceMapping(getQName().getLocalPart());
688
public TypeMapping getTypeMapping(String encodingStyle) {
689
// If type mapping registry not initialized yet, return null.
693
return (TypeMapping) tmr.getOrMakeTypeMapping(encodingStyle);
697
public WSDDJAXRPCHandlerInfoChain getHandlerInfoChain() {
701
public void setHandlerInfoChain(WSDDJAXRPCHandlerInfoChain hichain) {
702
_wsddHIchain = hichain;