001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.wsdl11;
019:
020: import java.util.ArrayList;
021: import java.util.Collection;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.LinkedHashMap;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.Map.Entry;
028: import java.util.logging.Logger;
029:
030: import javax.wsdl.Binding;
031: import javax.wsdl.BindingFault;
032: import javax.wsdl.BindingOperation;
033: import javax.wsdl.Definition;
034: import javax.wsdl.Fault;
035: import javax.wsdl.Import;
036: import javax.wsdl.Input;
037: import javax.wsdl.Message;
038: import javax.wsdl.Operation;
039: import javax.wsdl.Output;
040: import javax.wsdl.Part;
041: import javax.wsdl.Port;
042: import javax.wsdl.PortType;
043: import javax.wsdl.Service;
044: import javax.wsdl.Types;
045: import javax.wsdl.extensions.ExtensibilityElement;
046: import javax.wsdl.extensions.UnknownExtensibilityElement;
047: import javax.wsdl.extensions.schema.Schema;
048: import javax.wsdl.extensions.schema.SchemaImport;
049: import javax.wsdl.extensions.soap.SOAPBinding;
050: import javax.wsdl.extensions.soap12.SOAP12Binding;
051: import javax.xml.namespace.QName;
052:
053: import org.w3c.dom.Element;
054:
055: import org.apache.cxf.Bus;
056: import org.apache.cxf.BusException;
057: import org.apache.cxf.binding.BindingFactory;
058: import org.apache.cxf.catalog.CatalogXmlSchemaURIResolver;
059: import org.apache.cxf.catalog.OASISCatalogManager;
060: import org.apache.cxf.helpers.CastUtils;
061: import org.apache.cxf.service.model.AbstractMessageContainer;
062: import org.apache.cxf.service.model.AbstractPropertiesHolder;
063: import org.apache.cxf.service.model.BindingFaultInfo;
064: import org.apache.cxf.service.model.BindingInfo;
065: import org.apache.cxf.service.model.BindingMessageInfo;
066: import org.apache.cxf.service.model.BindingOperationInfo;
067: import org.apache.cxf.service.model.DescriptionInfo;
068: import org.apache.cxf.service.model.EndpointInfo;
069: import org.apache.cxf.service.model.FaultInfo;
070: import org.apache.cxf.service.model.InterfaceInfo;
071: import org.apache.cxf.service.model.MessageInfo;
072: import org.apache.cxf.service.model.MessagePartInfo;
073: import org.apache.cxf.service.model.OperationInfo;
074: import org.apache.cxf.service.model.SchemaInfo;
075: import org.apache.cxf.service.model.ServiceInfo;
076: import org.apache.cxf.service.model.UnwrappedOperationInfo;
077: import org.apache.cxf.transport.DestinationFactory;
078: import org.apache.cxf.transport.DestinationFactoryManager;
079: import org.apache.ws.commons.schema.XmlSchema;
080: import org.apache.ws.commons.schema.XmlSchemaCollection;
081: import org.apache.ws.commons.schema.XmlSchemaComplexType;
082: import org.apache.ws.commons.schema.XmlSchemaElement;
083: import org.apache.ws.commons.schema.XmlSchemaObject;
084: import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
085: import org.apache.ws.commons.schema.XmlSchemaSequence;
086:
087: import static org.apache.cxf.helpers.CastUtils.cast;
088:
089: public class WSDLServiceBuilder {
090:
091: public static final String WSDL_SCHEMA_LIST = WSDLServiceBuilder.class
092: .getName()
093: + ".SCHEMA";
094: public static final String WSDL_DEFINITION = WSDLServiceBuilder.class
095: .getName()
096: + ".DEFINITION";
097: public static final String WSDL_SERVICE = WSDLServiceBuilder.class
098: .getName()
099: + ".SERVICE";
100: public static final String WSDL_PORTTYPE = WSDLServiceBuilder.class
101: .getName()
102: + ".WSDL_PORTTYPE";
103: public static final String WSDL_PORT = WSDLServiceBuilder.class
104: .getName()
105: + ".PORT";
106: public static final String WSDL_BINDING = WSDLServiceBuilder.class
107: .getName()
108: + ".BINDING";
109: public static final String WSDL_SCHEMA_ELEMENT_LIST = WSDLServiceBuilder.class
110: .getName()
111: + ".SCHEMA_ELEMENTS";
112: public static final String WSDL_OPERATION = WSDLServiceBuilder.class
113: .getName()
114: + ".OPERATION";
115: public static final String WSDL_BINDING_OPERATION = WSDLServiceBuilder.class
116: .getName()
117: + ".BINDING_OPERATION";
118:
119: private static final Logger LOG = Logger
120: .getLogger(WSDLServiceBuilder.class.getName());
121: private Bus bus;
122: private Map<String, Element> schemaList = new HashMap<String, Element>();
123:
124: public WSDLServiceBuilder(Bus bus) {
125: this .bus = bus;
126: }
127:
128: private void copyExtensors(AbstractPropertiesHolder info,
129: List<?> extList) {
130: if (info != null) {
131: for (ExtensibilityElement ext : cast(extList,
132: ExtensibilityElement.class)) {
133: info.addExtensor(ext);
134: }
135: }
136: }
137:
138: private void copyExtensionAttributes(AbstractPropertiesHolder info,
139: javax.wsdl.extensions.AttributeExtensible ae) {
140: Map<QName, Object> attrs = CastUtils.cast(ae
141: .getExtensionAttributes());
142: if (!attrs.isEmpty()) {
143: info.setExtensionAttributes(attrs);
144: }
145: }
146:
147: public List<ServiceInfo> buildServices(Definition d) {
148: DescriptionInfo description = new DescriptionInfo();
149: description.setProperty(WSDL_DEFINITION, d);
150: description.setName(d.getQName());
151: description.setBaseURI(d.getDocumentBaseURI());
152: copyExtensors(description, d.getExtensibilityElements());
153: copyExtensionAttributes(description, d);
154:
155: List<ServiceInfo> serviceList = new ArrayList<ServiceInfo>();
156: for (java.util.Iterator<QName> ite = CastUtils.cast(d
157: .getServices().keySet().iterator()); ite.hasNext();) {
158: QName qn = ite.next();
159: serviceList.addAll(buildServices(d, qn, description));
160: }
161: return serviceList;
162: }
163:
164: public List<ServiceInfo> buildServices(Definition d, QName name) {
165: return buildServices(d, name, null);
166: }
167:
168: private List<ServiceInfo> buildServices(Definition d, QName name,
169: DescriptionInfo description) {
170: Service service = d.getService(name);
171: return buildServices(d, service, description);
172: }
173:
174: public List<ServiceInfo> buildServices(Definition def, Service serv) {
175: return buildServices(def, serv, null);
176: }
177:
178: public List<ServiceInfo> buildMockServices(Definition d) {
179: List<ServiceInfo> serviceList = new ArrayList<ServiceInfo>();
180: List<Definition> defList = new ArrayList<Definition>();
181: defList.add(d);
182: parseImports(d, defList);
183: for (Definition def : defList) {
184:
185: for (Iterator ite = def.getPortTypes().entrySet()
186: .iterator(); ite.hasNext();) {
187: Entry entry = (Entry) ite.next();
188: PortType portType = def.getPortType((QName) entry
189: .getKey());
190: ServiceInfo serviceInfo = this .buildMockService(def,
191: portType);
192: serviceList.add(serviceInfo);
193: }
194:
195: if (def.getPortTypes().size() == 0) {
196:
197: DescriptionInfo description = new DescriptionInfo();
198: description.setProperty(WSDL_DEFINITION, def);
199: description.setName(def.getQName());
200: description.setBaseURI(def.getDocumentBaseURI());
201: copyExtensors(description, def
202: .getExtensibilityElements());
203: copyExtensionAttributes(description, def);
204:
205: ServiceInfo service = new ServiceInfo();
206: service.setDescription(description);
207: service.setProperty(WSDL_DEFINITION, def);
208: XmlSchemaCollection schemas = getSchemas(def, service);
209:
210: service.setProperty(WSDL_SCHEMA_ELEMENT_LIST,
211: this .schemaList);
212: service.setProperty(WSDL_SCHEMA_LIST, schemas);
213: serviceList.add(service);
214: }
215: }
216: return serviceList;
217: }
218:
219: public ServiceInfo buildMockService(Definition def, PortType p) {
220: DescriptionInfo description = new DescriptionInfo();
221: description.setProperty(WSDL_DEFINITION, def);
222: description.setName(def.getQName());
223: description.setBaseURI(def.getDocumentBaseURI());
224: copyExtensors(description, def.getExtensibilityElements());
225: copyExtensionAttributes(description, def);
226:
227: ServiceInfo service = new ServiceInfo();
228: service.setDescription(description);
229: service.setProperty(WSDL_DEFINITION, def);
230: XmlSchemaCollection schemas = getSchemas(def, service);
231:
232: service.setProperty(WSDL_SCHEMA_ELEMENT_LIST, this .schemaList);
233:
234: service.setProperty(WSDL_SCHEMA_LIST, schemas);
235:
236: buildInterface(service, p);
237:
238: return service;
239: }
240:
241: private List<ServiceInfo> buildServices(Definition def,
242: Service serv, DescriptionInfo d) {
243: Map<QName, ServiceInfo> services = new LinkedHashMap<QName, ServiceInfo>();
244:
245: DescriptionInfo description = d;
246: if (null == description) {
247: description = new DescriptionInfo();
248: description.setProperty(WSDL_DEFINITION, def);
249: description.setName(def.getQName());
250: description.setBaseURI(def.getDocumentBaseURI());
251: copyExtensors(description, def.getExtensibilityElements());
252: copyExtensionAttributes(description, def);
253: }
254:
255: for (Port port : cast(serv.getPorts().values(), Port.class)) {
256: Binding binding = port.getBinding();
257: PortType bindingPt = binding.getPortType();
258: //TODO: wsdl4j's bug. if there is recursive import,
259: //wsdl4j can not get operation input message
260: PortType pt = def.getPortType(bindingPt.getQName());
261: if (pt == null) {
262: pt = bindingPt;
263: }
264: ServiceInfo service = services.get(pt.getQName());
265: if (service == null) {
266: service = new ServiceInfo();
267: service.setDescription(description);
268: description.getDescribed().add(service);
269: service.setProperty(WSDL_DEFINITION, def);
270: service.setProperty(WSDL_SERVICE, serv);
271:
272: XmlSchemaCollection schemas = getSchemas(def, service);
273: service.setProperty(WSDL_SCHEMA_ELEMENT_LIST,
274: this .schemaList);
275: service.setProperty(WSDL_SCHEMA_LIST, schemas);
276: service.setTargetNamespace(def.getTargetNamespace());
277: service.setName(serv.getQName());
278: copyExtensors(service, serv.getExtensibilityElements());
279: copyExtensionAttributes(service, serv);
280:
281: buildInterface(service, pt);
282:
283: services.put(pt.getQName(), service);
284: }
285:
286: BindingInfo bi = service.getBinding(binding.getQName());
287: if (bi == null) {
288: bi = buildBinding(service, binding);
289: }
290: buildEndpoint(service, bi, port);
291: }
292:
293: return new ArrayList<ServiceInfo>(services.values());
294: }
295:
296: private XmlSchemaCollection getSchemas(Definition def,
297: ServiceInfo serviceInfo) {
298: XmlSchemaCollection schemaCol = new XmlSchemaCollection();
299: serviceInfo.setXmlSchemaCollection(schemaCol);
300:
301: List<Definition> defList = new ArrayList<Definition>();
302: parseImports(def, defList);
303: extractSchema(def, schemaCol, serviceInfo);
304: // added
305: getSchemaList(def);
306: for (Definition def2 : defList) {
307: extractSchema(def2, schemaCol, serviceInfo);
308: // added
309: getSchemaList(def2);
310: }
311:
312: return schemaCol;
313: }
314:
315: private void parseImports(Definition def, List<Definition> defList) {
316: List<Import> importList = new ArrayList<Import>();
317:
318: Collection<List<Import>> ilist = cast(def.getImports().values());
319: for (List<Import> list : ilist) {
320: importList.addAll(list);
321: }
322: for (Import impt : importList) {
323: if (!defList.contains(impt.getDefinition())) {
324: defList.add(impt.getDefinition());
325: parseImports(impt.getDefinition(), defList);
326: }
327: }
328: }
329:
330: private void extractSchema(Definition def,
331: XmlSchemaCollection schemaCol, ServiceInfo serviceInfo) {
332: Types typesElement = def.getTypes();
333: if (typesElement != null) {
334: int schemaCount = 1;
335: for (Object obj : typesElement.getExtensibilityElements()) {
336: org.w3c.dom.Element schemaElem = null;
337: if (obj instanceof Schema) {
338: Schema schema = (Schema) obj;
339: schemaElem = schema.getElement();
340: } else if (obj instanceof UnknownExtensibilityElement) {
341: org.w3c.dom.Element elem = ((UnknownExtensibilityElement) obj)
342: .getElement();
343: if (elem.getLocalName().equals("schema")) {
344: schemaElem = elem;
345: }
346: }
347: if (schemaElem != null) {
348: for (Object prefix : def.getNamespaces().keySet()) {
349: String ns = (String) def.getNamespaces().get(
350: prefix);
351: if (!"".equals(prefix)
352: && !schemaElem.hasAttribute("xmlns:"
353: + prefix)) {
354: schemaElem
355: .setAttributeNS(
356: javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
357: "xmlns:" + prefix, ns);
358: }
359: }
360: String systemId = def.getDocumentBaseURI()
361: + "#types" + schemaCount;
362:
363: schemaCol.setBaseUri(def.getDocumentBaseURI());
364: CatalogXmlSchemaURIResolver schemaResolver = new CatalogXmlSchemaURIResolver(
365: OASISCatalogManager.getCatalogManager(bus));
366: schemaCol.setSchemaResolver(schemaResolver);
367: XmlSchema xmlSchema = schemaCol.read(schemaElem,
368: systemId);
369:
370: SchemaInfo schemaInfo = new SchemaInfo(serviceInfo,
371: xmlSchema.getTargetNamespace());
372: schemaInfo.setElement(schemaElem);
373: schemaInfo.setSchema(xmlSchema);
374: schemaInfo.setSystemId(systemId);
375: serviceInfo.addSchema(schemaInfo);
376: schemaCount++;
377: }
378: }
379: }
380: }
381:
382: // Workaround for getting the elements
383: private void getSchemaList(Definition def) {
384: Types typesElement = def.getTypes();
385: if (typesElement != null) {
386: Iterator ite = typesElement.getExtensibilityElements()
387: .iterator();
388: while (ite.hasNext()) {
389: Object obj = ite.next();
390: if (obj instanceof Schema) {
391: Schema schema = (Schema) obj;
392: addSchema(schema);
393: }
394: }
395: }
396: }
397:
398: private void addSchema(Schema schema) {
399: String docBaseURI = schema.getDocumentBaseURI();
400: Element schemaEle = schema.getElement();
401: if (schemaList.get(docBaseURI) == null) {
402: schemaList.put(docBaseURI, schemaEle);
403: } else if (schemaList.get(docBaseURI) != null
404: && schemaList.containsValue(schemaEle)) {
405: // do nothing
406: } else {
407: String tns = schema.getDocumentBaseURI()
408: + "#"
409: + schema.getElement().getAttribute(
410: "targetNamespace");
411: if (schemaList.get(tns) == null) {
412: schemaList.put(tns, schema.getElement());
413: }
414: }
415:
416: Map<String, List> imports = CastUtils.cast(schema.getImports());
417: if (imports != null && imports.size() > 0) {
418: Collection<String> importKeys = imports.keySet();
419: for (String importNamespace : importKeys) {
420:
421: List<SchemaImport> schemaImports = CastUtils
422: .cast(imports.get(importNamespace));
423:
424: for (SchemaImport schemaImport : schemaImports) {
425: Schema tempImport = schemaImport
426: .getReferencedSchema();
427: if (importNamespace == null) {
428: importNamespace = tempImport
429: .getDocumentBaseURI();
430: }
431: if (tempImport != null
432: && !isSchemaParsed(tempImport
433: .getDocumentBaseURI(),
434: importNamespace)
435: && !schemaList.containsValue(tempImport
436: .getElement())) {
437: addSchema(tempImport);
438: }
439: }
440:
441: }
442: }
443:
444: }
445:
446: private boolean isSchemaParsed(String baseUri, String ns) {
447: if (schemaList.get(baseUri) != null) {
448: Element ele = schemaList.get(baseUri);
449: String tns = ele.getAttribute("targetNamespace");
450: if (ns.equals(tns)) {
451: return true;
452: }
453: }
454: return false;
455: }
456:
457: public EndpointInfo buildEndpoint(ServiceInfo service,
458: BindingInfo bi, Port port) {
459: List elements = port.getExtensibilityElements();
460: String ns = null;
461:
462: DestinationFactory factory = null;
463: EndpointInfo ei = null;
464:
465: if (null != elements && elements.size() > 0) {
466: for (ExtensibilityElement el : CastUtils.cast(elements,
467: ExtensibilityElement.class)) {
468: ns = el.getElementType().getNamespaceURI();
469: try {
470: factory = bus.getExtension(
471: DestinationFactoryManager.class)
472: .getDestinationFactory(ns);
473: } catch (BusException e) {
474: // do nothing
475: }
476: if (factory != null) {
477: break;
478: }
479: }
480: if (factory == null) {
481: ns = ((ExtensibilityElement) elements.get(0))
482: .getElementType().getNamespaceURI();
483: }
484: }
485:
486: if (factory == null) { // get the transport id from bindingInfo
487: elements = port.getBinding().getExtensibilityElements();
488: if (null != elements && elements.size() > 0) {
489: for (ExtensibilityElement el : CastUtils.cast(elements,
490: ExtensibilityElement.class)) {
491: if (el instanceof SOAPBinding) {
492: ns = (String) ((SOAPBinding) el)
493: .getTransportURI();
494: break;
495: } else if (el instanceof SOAP12Binding) {
496: ns = (String) ((SOAP12Binding) el)
497: .getTransportURI();
498: break;
499: // TODO: this is really ugly, but how to link between
500: // this binding and this transport ?
501: } else if ("http://cxf.apache.org/bindings/jbi"
502: .equals(el.getElementType()
503: .getNamespaceURI())) {
504: ns = "http://cxf.apache.org/transports/jbi";
505: break;
506: }
507: }
508: }
509: try {
510: factory = bus.getExtension(
511: DestinationFactoryManager.class)
512: .getDestinationFactory(ns);
513: } catch (BusException e) {
514: // do nothing
515: }
516: }
517: if (factory instanceof WSDLEndpointFactory) {
518: WSDLEndpointFactory wFactory = (WSDLEndpointFactory) factory;
519: ei = wFactory.createEndpointInfo(service, bi, port);
520: }
521:
522: if (ei == null) {
523: ei = new EndpointInfo(service, ns);
524: }
525:
526: ei.setName(new QName(service.getName().getNamespaceURI(), port
527: .getName()));
528: ei.setBinding(bi);
529: copyExtensors(ei, port.getExtensibilityElements());
530: copyExtensionAttributes(ei, port);
531:
532: service.addEndpoint(ei);
533: DescriptionInfo d = service.getDescription();
534: if (null != d) {
535: ei.setDescription(d);
536: d.getDescribed().add(ei);
537: }
538: return ei;
539: }
540:
541: public BindingInfo buildBinding(ServiceInfo service, Binding binding) {
542: BindingInfo bi = null;
543: StringBuffer ns = new StringBuffer(100);
544: BindingFactory factory = WSDLServiceUtils.getBindingFactory(
545: binding, bus, ns);
546: if (factory instanceof WSDLBindingFactory) {
547: WSDLBindingFactory wFactory = (WSDLBindingFactory) factory;
548: bi = wFactory.createBindingInfo(service, binding, ns
549: .toString());
550: copyExtensors(bi, binding.getExtensibilityElements());
551: copyExtensionAttributes(bi, binding);
552: }
553: if (bi == null) {
554: bi = new BindingInfo(service, ns.toString());
555: bi.setName(binding.getQName());
556: copyExtensors(bi, binding.getExtensibilityElements());
557: copyExtensionAttributes(bi, binding);
558:
559: for (BindingOperation bop : cast(binding
560: .getBindingOperations(), BindingOperation.class)) {
561: LOG.fine("binding operation name is " + bop.getName());
562: String inName = null;
563: String outName = null;
564: if (bop.getBindingInput() != null) {
565: inName = bop.getBindingInput().getName();
566: }
567: if (bop.getBindingOutput() != null) {
568: outName = bop.getBindingOutput().getName();
569: }
570: BindingOperationInfo bop2 = bi.buildOperation(
571: new QName(service.getName().getNamespaceURI(),
572: bop.getName()), inName, outName);
573: if (bop2 != null) {
574:
575: copyExtensors(bop2, bop.getExtensibilityElements());
576: copyExtensionAttributes(bop2, bop);
577: bi.addOperation(bop2);
578: if (bop.getBindingInput() != null) {
579: copyExtensors(bop2.getInput(), bop
580: .getBindingInput()
581: .getExtensibilityElements());
582: copyExtensionAttributes(bop2.getInput(), bop
583: .getBindingInput());
584: handleHeader(bop2.getInput());
585: }
586: if (bop.getBindingOutput() != null) {
587: copyExtensors(bop2.getOutput(), bop
588: .getBindingOutput()
589: .getExtensibilityElements());
590: copyExtensionAttributes(bop2.getOutput(), bop
591: .getBindingOutput());
592: handleHeader(bop2.getOutput());
593: }
594: for (BindingFault f : cast(bop.getBindingFaults()
595: .values(), BindingFault.class)) {
596: BindingFaultInfo bif = bop2.getFault(new QName(
597: service.getTargetNamespace(), f
598: .getName()));
599: copyExtensors(bif, bop.getBindingFault(
600: f.getName()).getExtensibilityElements());
601: copyExtensionAttributes(bif, bop
602: .getBindingFault(f.getName()));
603: }
604: }
605:
606: }
607: }
608:
609: service.addBinding(bi);
610: DescriptionInfo d = service.getDescription();
611: if (null != d) {
612: bi.setDescription(d);
613: d.getDescribed().add(bi);
614: }
615: return bi;
616: }
617:
618: private void handleHeader(BindingMessageInfo bindingMessageInfo) {
619: // mark all message part which should be in header
620: List<ExtensibilityElement> extensiblilityElement = bindingMessageInfo
621: .getExtensors(ExtensibilityElement.class);
622: // for non-soap binding, the extensiblilityElement could be null
623: if (extensiblilityElement == null) {
624: return;
625: }
626: // for (ExtensibilityElement element : extensiblilityElement) {
627: // LOG.info("the extensibility is " + element.getClass().getName());
628: // if (element instanceof SOAPHeader) {
629: // LOG.info("the header is " + ((SOAPHeader)element).getPart());
630: // }
631: // }
632: }
633:
634: public void buildInterface(ServiceInfo si, PortType p) {
635: InterfaceInfo inf = si.createInterface(p.getQName());
636: DescriptionInfo d = si.getDescription();
637: if (null != d) {
638: inf.setDescription(si.getDescription());
639: d.getDescribed().add(inf);
640: }
641: this .copyExtensors(inf, p.getExtensibilityElements());
642: this .copyExtensionAttributes(inf, p);
643: inf.setProperty(WSDL_PORTTYPE, p);
644: for (Operation op : cast(p.getOperations(), Operation.class)) {
645: buildInterfaceOperation(inf, op);
646: }
647:
648: }
649:
650: private void buildInterfaceOperation(InterfaceInfo inf, Operation op) {
651: OperationInfo opInfo = inf.addOperation(new QName(inf.getName()
652: .getNamespaceURI(), op.getName()));
653: opInfo.setProperty(WSDL_OPERATION, op);
654: List<String> porderList = CastUtils.cast((List) op
655: .getParameterOrdering());
656: opInfo.setParameterOrdering(porderList);
657: this .copyExtensors(opInfo, op.getExtensibilityElements());
658: this .copyExtensionAttributes(opInfo, op);
659: Input input = op.getInput();
660: if (input != null) {
661: MessageInfo minfo = opInfo.createMessage(input.getMessage()
662: .getQName());
663: opInfo.setInput(input.getName(), minfo);
664: buildMessage(minfo, input.getMessage());
665: copyExtensors(minfo, input.getExtensibilityElements());
666: copyExtensionAttributes(minfo, input);
667: }
668: Output output = op.getOutput();
669: if (output != null) {
670: MessageInfo minfo = opInfo.createMessage(output
671: .getMessage().getQName());
672: opInfo.setOutput(output.getName(), minfo);
673: buildMessage(minfo, output.getMessage());
674: copyExtensors(minfo, output.getExtensibilityElements());
675: copyExtensionAttributes(minfo, output);
676: }
677: Map<?, ?> m = op.getFaults();
678: for (Map.Entry<?, ?> rawentry : m.entrySet()) {
679: Map.Entry<String, Fault> entry = cast(rawentry,
680: String.class, Fault.class);
681: FaultInfo finfo = opInfo.addFault(new QName(inf.getName()
682: .getNamespaceURI(), entry.getKey()), entry
683: .getValue().getMessage().getQName());
684: buildMessage(finfo, entry.getValue().getMessage());
685: copyExtensors(finfo, entry.getValue()
686: .getExtensibilityElements());
687: copyExtensionAttributes(finfo, entry.getValue());
688: }
689: checkForWrapped(opInfo, false);
690: }
691:
692: public static void checkForWrapped(OperationInfo opInfo,
693: boolean allowRefs) {
694: MessageInfo inputMessage = opInfo.getInput();
695: MessageInfo outputMessage = opInfo.getOutput();
696: boolean passedRule = true;
697: // RULE No.1:
698: // The operation's input and output message (if present) each contain
699: // only a single part
700: // input message must exist
701: if (inputMessage == null || inputMessage.size() != 1
702: || (outputMessage != null && outputMessage.size() > 1)) {
703: passedRule = false;
704: }
705:
706: if (!passedRule) {
707: return;
708: }
709: XmlSchemaCollection schemas = (XmlSchemaCollection) opInfo
710: .getInterface().getService().getProperty(
711: WSDL_SCHEMA_LIST);
712: XmlSchemaElement inputEl = null;
713: XmlSchemaElement outputEl = null;
714:
715: // RULE No.2:
716: // The input message part refers to a global element decalration whose
717: // localname
718: // is equal to the operation name
719: MessagePartInfo inputPart = inputMessage
720: .getMessagePartByIndex(0);
721: if (!inputPart.isElement()) {
722: passedRule = false;
723: } else {
724: QName inputElementName = inputPart.getElementQName();
725: inputEl = schemas.getElementByQName(inputElementName);
726: if (inputEl == null
727: || !opInfo.getName().getLocalPart().equals(
728: inputElementName.getLocalPart())) {
729: passedRule = false;
730: }
731: }
732:
733: if (!passedRule) {
734: return;
735: }
736: // RULE No.3:
737: // The output message part refers to a global element declaration
738: MessagePartInfo outputPart = null;
739: if (outputMessage != null && outputMessage.size() == 1) {
740: outputPart = outputMessage.getMessagePartByIndex(0);
741: if (outputPart != null) {
742: if (!outputPart.isElement()
743: || schemas.getElementByQName(outputPart
744: .getElementQName()) == null) {
745: passedRule = false;
746: } else {
747: outputEl = schemas.getElementByQName(outputPart
748: .getElementQName());
749: }
750: }
751: }
752:
753: if (!passedRule) {
754: return;
755: }
756: // RULE No.4 and No5:
757: // wrapper element should be pure complex type
758:
759: // Now lets see if we have any attributes...
760: // This should probably look at the restricted and substitute types too.
761: OperationInfo unwrapped = new UnwrappedOperationInfo(opInfo);
762: MessageInfo unwrappedInput = new MessageInfo(unwrapped,
763: inputMessage.getName());
764: MessageInfo unwrappedOutput = null;
765:
766: XmlSchemaComplexType xsct = null;
767: if (inputEl.getSchemaType() instanceof XmlSchemaComplexType) {
768: xsct = (XmlSchemaComplexType) inputEl.getSchemaType();
769: if (hasAttributes(xsct)
770: || !isWrappableSequence(xsct, inputEl.getQName()
771: .getNamespaceURI(), unwrappedInput,
772: allowRefs)) {
773: passedRule = false;
774: }
775: } else {
776: passedRule = false;
777: }
778:
779: if (!passedRule) {
780: return;
781: }
782:
783: if (outputMessage != null) {
784: unwrappedOutput = new MessageInfo(unwrapped, outputMessage
785: .getName());
786:
787: if (outputEl != null
788: && outputEl.getSchemaType() instanceof XmlSchemaComplexType) {
789: xsct = (XmlSchemaComplexType) outputEl.getSchemaType();
790: if (hasAttributes(xsct)
791: || !isWrappableSequence(xsct, outputEl
792: .getQName().getNamespaceURI(),
793: unwrappedOutput, allowRefs)) {
794: passedRule = false;
795: }
796: } else {
797: passedRule = false;
798: }
799: }
800:
801: if (!passedRule) {
802: return;
803: }
804: // we are wrappable!!
805: opInfo.setUnwrappedOperation(unwrapped);
806: unwrapped.setInput(opInfo.getInputName(), unwrappedInput);
807: if (outputMessage != null) {
808: unwrapped
809: .setOutput(opInfo.getOutputName(), unwrappedOutput);
810: }
811: }
812:
813: private static boolean hasAttributes(
814: XmlSchemaComplexType complexType) {
815: // Now lets see if we have any attributes...
816: // This should probably look at the restricted and substitute types too.
817: if (complexType.getAnyAttribute() != null
818: || complexType.getAttributes().getCount() > 0) {
819: return true;
820: }
821: return false;
822: }
823:
824: private static boolean isWrappableSequence(
825: XmlSchemaComplexType type, String namespaceURI,
826: MessageInfo wrapper, boolean allowRefs) {
827: if (type.getParticle() instanceof XmlSchemaSequence) {
828: XmlSchemaSequence seq = (XmlSchemaSequence) type
829: .getParticle();
830: XmlSchemaObjectCollection items = seq.getItems();
831: boolean ret = true;
832: for (int x = 0; x < items.getCount(); x++) {
833: XmlSchemaObject o = items.getItem(x);
834: if (!(o instanceof XmlSchemaElement)) {
835: return false;
836: }
837: XmlSchemaElement el = (XmlSchemaElement) o;
838:
839: if (el.getSchemaTypeName() != null) {
840: MessagePartInfo mpi = wrapper
841: .addMessagePart(new QName(namespaceURI, el
842: .getName()));
843: mpi.setTypeQName(el.getSchemaTypeName());
844: mpi.setConcreteName(el.getQName());
845: mpi.setXmlSchema(el);
846: } else if (el.getRefName() != null) {
847: MessagePartInfo mpi = wrapper.addMessagePart(el
848: .getRefName());
849: mpi.setTypeQName(el.getRefName());
850: mpi.setXmlSchema(el);
851: // element reference is not permitted for wrapper element
852: if (!allowRefs) {
853: ret = false;
854: }
855: } else {
856: // anonymous type
857: MessagePartInfo mpi = wrapper
858: .addMessagePart(new QName(namespaceURI, el
859: .getName()));
860: mpi.setElementQName(mpi.getName());
861: mpi.setElement(true);
862: mpi.setXmlSchema(el);
863: }
864: }
865:
866: return ret;
867: } else if (type.getParticle() == null) {
868: return true;
869: }
870: return false;
871: }
872:
873: private void buildMessage(AbstractMessageContainer minfo,
874: Message msg) {
875: XmlSchemaCollection schemas = (XmlSchemaCollection) minfo
876: .getOperation().getInterface().getService()
877: .getProperty(WSDL_SCHEMA_LIST);
878: List orderedParam = msg.getOrderedParts(null);
879: for (Part part : cast(orderedParam, Part.class)) {
880: MessagePartInfo pi = minfo.addMessagePart(new QName(minfo
881: .getName().getNamespaceURI(), part.getName()));
882: if (part.getTypeName() != null) {
883: pi.setTypeQName(part.getTypeName());
884: pi.setElement(false);
885: pi.setXmlSchema(schemas.getTypeByQName(part
886: .getTypeName()));
887: } else {
888: pi.setElementQName(part.getElementName());
889: pi.setElement(true);
890: pi.setXmlSchema(schemas.getElementByQName(part
891: .getElementName()));
892: }
893: }
894: }
895:
896: }
|