Source code: org/apache/axis/deployment/wsdd/WSDDDeployment.java
1 /*
2 * Copyright 2001-2004 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.ConfigurationException;
20 import org.apache.axis.Constants;
21 import org.apache.axis.Handler;
22 import org.apache.axis.WSDDEngineConfiguration;
23 import org.apache.axis.components.logger.LogFactory;
24 import org.apache.axis.encoding.DeserializerFactory;
25 import org.apache.axis.encoding.SerializationContext;
26 import org.apache.axis.encoding.SerializerFactory;
27 import org.apache.axis.encoding.TypeMapping;
28 import org.apache.axis.encoding.TypeMappingRegistry;
29 import org.apache.axis.encoding.TypeMappingRegistryImpl;
30 import org.apache.axis.encoding.ser.ArraySerializerFactory;
31 import org.apache.axis.encoding.ser.BaseDeserializerFactory;
32 import org.apache.axis.encoding.ser.BaseSerializerFactory;
33 import org.apache.axis.handlers.soap.SOAPService;
34 import org.apache.axis.utils.Messages;
35 import org.apache.commons.logging.Log;
36 import org.w3c.dom.Element;
37
38 import javax.xml.namespace.QName;
39 import java.io.IOException;
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.Hashtable;
43 import java.util.Iterator;
44 import java.util.List;
45
46 /**
47 * WSDD deployment element
48 *
49 * @author James Snell
50 * @author Glen Daniels (gdaniels@apache.org)
51 */
52 public class WSDDDeployment
53 extends WSDDElement
54 implements WSDDTypeMappingContainer,
55 WSDDEngineConfiguration
56 {
57 protected static Log log =
58 LogFactory.getLog(WSDDDeployment.class.getName());
59 private HashMap handlers = new HashMap();
60 private HashMap services = new HashMap();
61 private HashMap transports = new HashMap();
62 private HashMap typeMappings = new HashMap();
63 private WSDDGlobalConfiguration globalConfig = null;
64 /**
65 * Mapping of namespaces -> services
66 */
67 private HashMap namespaceToServices = new HashMap();
68 private AxisEngine engine;
69
70 protected void addHandler(WSDDHandler handler) {
71 handlers.put(handler.getQName(), handler);
72 }
73
74 protected void addService(WSDDService service) {
75 WSDDService oldService = (WSDDService) services.get(service.getQName());
76 if (oldService != null) {
77 oldService.removeNamespaceMappings(this);
78 }
79 services.put(service.getQName(), service);
80 }
81
82 protected void addTransport(WSDDTransport transport) {
83 transports.put(transport.getQName(), transport);
84 }
85
86 /**
87 * Put a WSDDHandler into this deployment, replacing any other
88 * WSDDHandler which might already be present with the same QName.
89 *
90 * @param handler a WSDDHandler to insert in this deployment
91 */
92 public void deployHandler(WSDDHandler handler) {
93 handler.deployToRegistry(this);
94 }
95
96 /**
97 * Put a WSDDTransport into this deployment, replacing any other
98 * WSDDTransport which might already be present with the same QName.
99 *
100 * @param transport a WSDDTransport to insert in this deployment
101 */
102 public void deployTransport(WSDDTransport transport) {
103 transport.deployToRegistry(this);
104 }
105
106 /**
107 * Put a WSDDService into this deployment, replacing any other
108 * WSDDService which might already be present with the same QName.
109 *
110 * @param service a WSDDHandler to insert in this deployment
111 */
112 public void deployService(WSDDService service) {
113 service.deployToRegistry(this);
114 }
115
116 /**
117 * Remove a named handler
118 *
119 * @param qname the QName of the handler to remove
120 */
121 public void undeployHandler(QName qname) {
122 handlers.remove(qname);
123 }
124
125 /**
126 * Remove a named service
127 *
128 * @param qname the QName of the service to remove
129 */
130 public void undeployService(QName qname) {
131 WSDDService service = (WSDDService) services.get(qname);
132 if (service != null) {
133 service.removeNamespaceMappings(this);
134 services.remove(qname);
135 }
136 }
137
138 /**
139 * Remove a named transport
140 *
141 * @param qname the QName of the transport to remove
142 */
143 public void undeployTransport(QName qname) {
144 transports.remove(qname);
145 }
146
147 public void deployTypeMapping(WSDDTypeMapping typeMapping)
148 throws WSDDException {
149 QName qname = typeMapping.getQName();
150 String encoding = typeMapping.getEncodingStyle();
151 // We have to include the encoding in the key
152 // because otherwise we would overwrite exiting mappings
153 typeMappings.put(qname + encoding, typeMapping);
154 if (tmrDeployed)
155 deployMapping(typeMapping);
156 }
157
158 /**
159 * Default constructor
160 */
161 public WSDDDeployment() {
162 }
163
164 /**
165 * Create an element in WSDD that wraps an extant DOM element
166 *
167 * @param e the element to create the deployment from
168 * @throws WSDDException when problems occur deploying a service or type mapping.
169 */
170 public WSDDDeployment(Element e)
171 throws WSDDException {
172 super(e);
173 Element [] elements = getChildElements(e, ELEM_WSDD_HANDLER);
174 int i;
175 for (i = 0; i < elements.length; i++) {
176 WSDDHandler handler = new WSDDHandler(elements[i]);
177 deployHandler(handler);
178 }
179 elements = getChildElements(e, ELEM_WSDD_CHAIN);
180 for (i = 0; i < elements.length; i++) {
181 WSDDChain chain = new WSDDChain(elements[i]);
182 deployHandler(chain);
183 }
184 elements = getChildElements(e, ELEM_WSDD_TRANSPORT);
185 for (i = 0; i < elements.length; i++) {
186 WSDDTransport transport = new WSDDTransport(elements[i]);
187 deployTransport(transport);
188 }
189 elements = getChildElements(e, ELEM_WSDD_SERVICE);
190 for (i = 0; i < elements.length; i++) {
191 try {
192 WSDDService service = new WSDDService(elements[i]);
193 deployService(service);
194 } catch (WSDDNonFatalException ex) {
195 // If it's non-fatal, just keep on going
196 log.info(Messages.getMessage("ignoringNonFatalException00"), ex);
197 } catch (WSDDException ex) {
198 // otherwise throw it upwards
199 throw ex;
200 }
201 }
202 elements = getChildElements(e, ELEM_WSDD_TYPEMAPPING);
203 for (i = 0; i < elements.length; i++) {
204 try {
205 WSDDTypeMapping mapping = new WSDDTypeMapping(elements[i]);
206 deployTypeMapping(mapping);
207 } catch (WSDDNonFatalException ex) {
208 // If it's non-fatal, just keep on going
209 log.info(Messages.getMessage("ignoringNonFatalException00"), ex);
210 } catch (WSDDException ex) {
211 // otherwise throw it upwards
212 throw ex;
213 }
214 }
215 elements = getChildElements(e, ELEM_WSDD_BEANMAPPING);
216 for (i = 0; i < elements.length; i++) {
217 WSDDBeanMapping mapping = new WSDDBeanMapping(elements[i]);
218 deployTypeMapping(mapping);
219 }
220
221 elements = getChildElements(e, ELEM_WSDD_ARRAYMAPPING);
222 for (i = 0; i < elements.length; i++) {
223 WSDDArrayMapping mapping =
224 new WSDDArrayMapping(elements[i]);
225 deployTypeMapping(mapping);
226 }
227
228 Element el = getChildElement(e, ELEM_WSDD_GLOBAL);
229 if (el != null)
230 globalConfig = new WSDDGlobalConfiguration(el);
231 }
232
233 protected QName getElementName() {
234 return QNAME_DEPLOY;
235 }
236
237 public void deployToRegistry(WSDDDeployment target)
238 throws ConfigurationException {
239 WSDDGlobalConfiguration global = getGlobalConfiguration();
240 if (global != null) {
241 target.setGlobalConfiguration(global);
242 }
243 Iterator i = handlers.values().iterator();
244 while (i.hasNext()) {
245 WSDDHandler handler = (WSDDHandler) i.next();
246 target.deployHandler(handler);
247 }
248 i = transports.values().iterator();
249 while (i.hasNext()) {
250 WSDDTransport transport = (WSDDTransport) i.next();
251 target.deployTransport(transport);
252 }
253 i = services.values().iterator();
254 while (i.hasNext()) {
255 WSDDService service = (WSDDService) i.next();
256 service.deployToRegistry(target);
257 }
258 i = typeMappings.values().iterator();
259 while (i.hasNext()) {
260 WSDDTypeMapping mapping = (WSDDTypeMapping) i.next();
261 target.deployTypeMapping(mapping);
262 }
263 }
264
265 private void deployMapping(WSDDTypeMapping mapping)
266 throws WSDDException {
267 try {
268 String encodingStyle = mapping.getEncodingStyle();
269 if (encodingStyle == null) {
270 encodingStyle = Constants.URI_DEFAULT_SOAP_ENC;
271 }
272 TypeMapping tm = tmr.getOrMakeTypeMapping(encodingStyle);
273 SerializerFactory ser = null;
274 DeserializerFactory deser = null;
275 // Try to construct a serializerFactory by introspecting for the
276 // following:
277 // public static create(Class javaType, QName xmlType)
278 // public <constructor>(Class javaType, QName xmlType)
279 // public <constructor>()
280 //
281 // The BaseSerializerFactory createFactory() method is a utility
282 // that does this for us.
283 //log.debug("start creating sf and df");
284 if (mapping.getSerializerName() != null &&
285 !mapping.getSerializerName().equals("")) {
286 ser = BaseSerializerFactory.createFactory(mapping.getSerializer(),
287 mapping.getLanguageSpecificType(),
288 mapping.getQName());
289 }
290
291 if ((mapping instanceof WSDDArrayMapping) && (ser instanceof ArraySerializerFactory)) {
292 WSDDArrayMapping am = (WSDDArrayMapping) mapping;
293 ArraySerializerFactory factory = (ArraySerializerFactory) ser;
294 factory.setComponentType(am.getInnerType());
295 }
296
297 //log.debug("set ser factory");
298
299 if (mapping.getDeserializerName() != null &&
300 !mapping.getDeserializerName().equals("")) {
301 deser = BaseDeserializerFactory.createFactory(mapping.getDeserializer(),
302 mapping.getLanguageSpecificType(),
303 mapping.getQName());
304 }
305 //log.debug("set dser factory");
306 tm.register(mapping.getLanguageSpecificType(), mapping.getQName(), ser, deser);
307 //log.debug("registered");
308 } catch (ClassNotFoundException e) {
309 log.error(Messages.getMessage("unabletoDeployTypemapping00", mapping.getQName().toString()), e);
310 throw new WSDDNonFatalException(e);
311 } catch (Exception e) {
312 throw new WSDDException(e);
313 }
314 }
315
316 public void writeToContext(SerializationContext context)
317 throws IOException {
318 context.registerPrefixForURI(NS_PREFIX_WSDD, URI_WSDD);
319 context.registerPrefixForURI(NS_PREFIX_WSDD_JAVA, URI_WSDD_JAVA);
320 context.startElement(QNAME_DEPLOY, null);
321 if (globalConfig != null) {
322 globalConfig.writeToContext(context);
323 }
324 Iterator i = handlers.values().iterator();
325 while (i.hasNext()) {
326 WSDDHandler handler = (WSDDHandler) i.next();
327 handler.writeToContext(context);
328 }
329 i = services.values().iterator();
330 while (i.hasNext()) {
331 WSDDService service = (WSDDService) i.next();
332 service.writeToContext(context);
333 }
334 i = transports.values().iterator();
335 while (i.hasNext()) {
336 WSDDTransport transport = (WSDDTransport) i.next();
337 transport.writeToContext(context);
338 }
339 i = typeMappings.values().iterator();
340 while (i.hasNext()) {
341 WSDDTypeMapping mapping = (WSDDTypeMapping) i.next();
342 mapping.writeToContext(context);
343 }
344 context.endElement();
345 }
346
347 /**
348 * Get our global configuration
349 *
350 * @return a global configuration object
351 */
352 public WSDDGlobalConfiguration getGlobalConfiguration() {
353 return globalConfig;
354 }
355
356 public void setGlobalConfiguration(WSDDGlobalConfiguration globalConfig) {
357 this.globalConfig = globalConfig;
358 }
359
360 /**
361 * @return an array of type mappings in this deployment
362 */
363 public WSDDTypeMapping[] getTypeMappings() {
364 WSDDTypeMapping[] t = new WSDDTypeMapping[typeMappings.size()];
365 typeMappings.values().toArray(t);
366 return t;
367 }
368
369 /**
370 * Return an array of the services in this deployment
371 */
372 public WSDDService[] getServices() {
373 WSDDService [] serviceArray = new WSDDService[services.size()];
374 services.values().toArray(serviceArray);
375 return serviceArray;
376 }
377
378 /**
379 * Return the WSDD description for a given named service
380 */
381 public WSDDService getWSDDService(QName qname) {
382 return (WSDDService) services.get(qname);
383 }
384
385 /**
386 * Return an instance of the named handler.
387 *
388 * @param name the name of the handler to get
389 * @return an Axis handler with the specified QName or null of not found
390 */
391 public Handler getHandler(QName name) throws ConfigurationException {
392 WSDDHandler h = (WSDDHandler) handlers.get(name);
393 if (h != null) {
394 return h.getInstance(this);
395 }
396 return null;
397 }
398
399 /**
400 * Retrieve an instance of the named transport.
401 *
402 * @param name the <code>QName</code> of the transport
403 * @return a <code>Handler</code> implementing the transport
404 * @throws ConfigurationException if there was an error resolving the
405 * transport
406 */
407 public Handler getTransport(QName name) throws ConfigurationException {
408 WSDDTransport t = (WSDDTransport) transports.get(name);
409 if (t != null) {
410 return t.getInstance(this);
411 }
412 return null;
413 }
414
415 /**
416 * Retrieve an instance of the named service.
417 *
418 * @param name the <code>QName</code> identifying the
419 * <code>Service</code>
420 * @return the <code>Service</code> associated with <code>qname</code>
421 * @throws ConfigurationException if there was an error resolving the
422 * qname
423 */
424 public SOAPService getService(QName name) throws ConfigurationException {
425 WSDDService s = (WSDDService) services.get(name);
426 if (s != null) {
427 return (SOAPService) s.getInstance(this);
428 }
429 return null;
430 }
431
432 public SOAPService getServiceByNamespaceURI(String namespace)
433 throws ConfigurationException {
434 WSDDService s = (WSDDService) namespaceToServices.get(namespace);
435 if (s != null) {
436 return (SOAPService) s.getInstance(this);
437 }
438 return null;
439 }
440
441 public void configureEngine(AxisEngine engine)
442 throws ConfigurationException {
443 this.engine = engine;
444 }
445
446 public void writeEngineConfig(AxisEngine engine) throws ConfigurationException {
447 }
448
449 TypeMappingRegistry tmr = new TypeMappingRegistryImpl();
450
451 public TypeMapping getTypeMapping(String encodingStyle) throws ConfigurationException {
452 return (TypeMapping) getTypeMappingRegistry().getTypeMapping(encodingStyle);
453 }
454
455 private boolean tmrDeployed = false;
456
457 public TypeMappingRegistry getTypeMappingRegistry() throws ConfigurationException {
458 if (false == tmrDeployed) {
459 Iterator i = typeMappings.values().iterator();
460 while (i.hasNext()) {
461 WSDDTypeMapping mapping = (WSDDTypeMapping) i.next();
462 deployMapping(mapping);
463 }
464 tmrDeployed = true;
465 }
466 return tmr;
467 }
468
469 public Handler getGlobalRequest() throws ConfigurationException {
470 if (globalConfig != null) {
471 WSDDRequestFlow reqFlow = globalConfig.getRequestFlow();
472 if (reqFlow != null)
473 return reqFlow.getInstance(this);
474 }
475 return null;
476 }
477
478 public Handler getGlobalResponse() throws ConfigurationException {
479 if (globalConfig != null) {
480 WSDDResponseFlow respFlow = globalConfig.getResponseFlow();
481 if (respFlow != null)
482 return respFlow.getInstance(this);
483 }
484 return null;
485 }
486
487 public Hashtable getGlobalOptions() throws ConfigurationException {
488 return globalConfig.getParametersTable();
489 }
490
491 public List getRoles() {
492 return globalConfig == null ? new ArrayList() : globalConfig.getRoles();
493 }
494
495 /**
496 * Get an enumeration of the services deployed to this engine
497 */
498 public Iterator getDeployedServices() throws ConfigurationException {
499 ArrayList serviceDescs = new ArrayList();
500 for (Iterator i = services.values().iterator(); i.hasNext();) {
501 WSDDService service = (WSDDService) i.next();
502 try {
503 service.makeNewInstance(this);
504 serviceDescs.add(service.getServiceDesc());
505 } catch (WSDDNonFatalException ex) {
506 // If it's non-fatal, just keep on going
507 log.info(Messages.getMessage("ignoringNonFatalException00"), ex);
508 }
509 }
510 return serviceDescs.iterator();
511 }
512
513 /**
514 * Register a particular namepsace which maps to a given WSDDService.
515 * This will be used for namespace-based dispatching.
516 *
517 * @param namespace a namespace URI
518 * @param service the target WSDDService
519 */
520 public void registerNamespaceForService(String namespace,
521 WSDDService service) {
522 namespaceToServices.put(namespace, service);
523 }
524
525 /**
526 * Remove a namespace -> WSDDService mapping.
527 *
528 * @param namespace the namespace URI to unmap
529 */
530 public void removeNamespaceMapping(String namespace) {
531 namespaceToServices.remove(namespace);
532 }
533
534 public AxisEngine getEngine() {
535 return engine;
536 }
537
538 public WSDDDeployment getDeployment() {
539 return this;
540 }
541
542 public WSDDHandler[] getHandlers() {
543 WSDDHandler [] handlerArray = new WSDDHandler[handlers.size()];
544 handlers.values().toArray(handlerArray);
545 return handlerArray;
546 }
547
548 public WSDDHandler getWSDDHandler(QName qname) {
549 return (WSDDHandler) handlers.get(qname);
550 }
551
552 public WSDDTransport[] getTransports() {
553 WSDDTransport [] transportArray = new WSDDTransport[transports.size()];
554 transports.values().toArray(transportArray);
555 return transportArray;
556 }
557
558 public WSDDTransport getWSDDTransport(QName qname) {
559 return (WSDDTransport) transports.get(qname);
560 }
561 }