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: */
019: package org.apache.axis2.description;
020:
021: import org.apache.axiom.om.OMAbstractFactory;
022: import org.apache.axiom.om.OMElement;
023: import org.apache.axiom.om.OMFactory;
024: import org.apache.axiom.om.OMNamespace;
025: import org.apache.axiom.om.OMAttribute;
026: import org.apache.axiom.om.OMNode;
027: import org.apache.axiom.om.OMText;
028: import org.apache.axis2.util.XMLUtils;
029: import org.apache.axis2.util.WSDLSerializationUtil;
030: import org.apache.axis2.util.JavaUtils;
031: import org.apache.axis2.AxisFault;
032: import org.apache.axis2.Constants;
033: import org.apache.axis2.addressing.AddressingConstants;
034: import org.apache.axis2.wsdl.WSDLConstants;
035: import org.apache.ws.commons.schema.XmlSchema;
036:
037: import javax.xml.stream.XMLStreamException;
038: import javax.xml.stream.XMLStreamConstants;
039: import javax.xml.namespace.QName;
040: import java.io.ByteArrayInputStream;
041: import java.io.StringWriter;
042: import java.util.ArrayList;
043: import java.util.Iterator;
044: import java.util.Map;
045: import java.util.Set;
046: import java.util.HashSet;
047: import java.net.URI;
048:
049: public class AxisService2WSDL20 implements WSDL2Constants {
050:
051: private AxisService axisService;
052: private String[] eprs = null;
053: private OMNamespace wsaw;
054:
055: public AxisService2WSDL20(AxisService service) {
056: this .axisService = service;
057: }
058:
059: /**
060: * Generates a WSDL 2.0 document for this web service
061: * @return The WSDL2 document element
062: * @throws Exception - Thrown in case an exception occurs
063: */
064: public OMElement generateOM() throws Exception {
065:
066: Map nameSpacesMap = axisService.getNamespaceMap();
067: OMFactory omFactory = OMAbstractFactory.getOMFactory();
068: OMNamespace wsdl;
069:
070: if (nameSpacesMap != null
071: && nameSpacesMap
072: .containsValue(WSDL2Constants.WSDL_NAMESPACE)) {
073: wsdl = omFactory.createOMNamespace(
074: WSDL2Constants.WSDL_NAMESPACE,
075: WSDLSerializationUtil.getPrefix(
076: WSDL2Constants.WSDL_NAMESPACE,
077: nameSpacesMap));
078: } else {
079: wsdl = omFactory.createOMNamespace(
080: WSDL2Constants.WSDL_NAMESPACE,
081: WSDL2Constants.DEFAULT_WSDL_NAMESPACE_PREFIX);
082: }
083:
084: OMElement descriptionElement = omFactory.createOMElement(
085: WSDL2Constants.DESCRIPTION, wsdl);
086:
087: // Declare all the defined namespaces in the document
088: WSDLSerializationUtil.populateNamespaces(descriptionElement,
089: nameSpacesMap);
090:
091: descriptionElement.declareNamespace(axisService
092: .getTargetNamespace(), axisService
093: .getTargetNamespacePrefix());
094: wsaw = descriptionElement.declareNamespace(
095: AddressingConstants.Final.WSAW_NAMESPACE, "wsaw");
096: // Need to add the targetnamespace as an attribute according to the wsdl 2.0 spec
097: OMAttribute targetNamespace = omFactory.createOMAttribute(
098: WSDL2Constants.TARGET_NAMESPACE, null, axisService
099: .getTargetNamespace());
100: descriptionElement.addAttribute(targetNamespace);
101:
102: // Check whether the required namespaces are already in namespaceMap, if they are not
103: // present declare them.
104: OMNamespace wsoap;
105: OMNamespace whttp;
106: OMNamespace wsdlx;
107:
108: OMNamespace tns = omFactory.createOMNamespace(axisService
109: .getTargetNamespace(), axisService
110: .getTargetNamespacePrefix());
111: if (nameSpacesMap != null
112: && !nameSpacesMap
113: .containsValue(WSDL2Constants.WSDL_NAMESPACE)) {
114: descriptionElement
115: .declareDefaultNamespace(WSDL2Constants.WSDL_NAMESPACE);
116: }
117: if (nameSpacesMap != null
118: && nameSpacesMap
119: .containsValue(WSDL2Constants.URI_WSDL2_SOAP)) {
120: wsoap = omFactory.createOMNamespace(
121: WSDL2Constants.URI_WSDL2_SOAP,
122: WSDLSerializationUtil.getPrefix(
123: WSDL2Constants.URI_WSDL2_SOAP,
124: nameSpacesMap));
125: } else {
126: wsoap = descriptionElement.declareNamespace(
127: WSDL2Constants.URI_WSDL2_SOAP,
128: WSDL2Constants.SOAP_PREFIX);
129: }
130: if (nameSpacesMap != null
131: && nameSpacesMap
132: .containsValue(WSDL2Constants.URI_WSDL2_HTTP)) {
133: whttp = omFactory.createOMNamespace(
134: WSDL2Constants.URI_WSDL2_HTTP,
135: WSDLSerializationUtil.getPrefix(
136: WSDL2Constants.URI_WSDL2_HTTP,
137: nameSpacesMap));
138: } else {
139: whttp = descriptionElement.declareNamespace(
140: WSDL2Constants.URI_WSDL2_HTTP,
141: WSDL2Constants.HTTP_PREFIX);
142: }
143: if (nameSpacesMap != null
144: && nameSpacesMap
145: .containsValue(WSDL2Constants.URI_WSDL2_EXTENSIONS)) {
146: wsdlx = omFactory.createOMNamespace(
147: WSDL2Constants.URI_WSDL2_EXTENSIONS,
148: WSDLSerializationUtil.getPrefix(
149: WSDL2Constants.URI_WSDL2_EXTENSIONS,
150: nameSpacesMap));
151: } else {
152: wsdlx = descriptionElement.declareNamespace(
153: WSDL2Constants.URI_WSDL2_EXTENSIONS,
154: WSDL2Constants.WSDL_EXTENTION_PREFIX);
155: }
156:
157: // Add the documentation element
158: String description;
159: OMElement documentationElement = omFactory.createOMElement(
160: WSDL2Constants.DOCUMENTATION, wsdl);
161: if ((description = axisService.getDocumentation()) != null) {
162: OMText omText;
163: if (description.indexOf(WSDLSerializationUtil.CDATA_START) > -1) {
164: description = description.replaceFirst(
165: WSDLSerializationUtil.CDATA_START_REGEX, "");
166: description = description.replaceFirst(
167: WSDLSerializationUtil.CDATA_END_REGEX, "");
168: omText = omFactory.createOMText(description,
169: XMLStreamConstants.CDATA);
170: } else {
171: omText = omFactory.createOMText(description);
172: }
173: documentationElement.addChild(omText);
174: descriptionElement.addChild(documentationElement);
175: }
176:
177: // Add types element
178: OMElement typesElement = omFactory.createOMElement(
179: WSDL2Constants.TYPES_LOCAL_NALE, wsdl);
180: axisService.populateSchemaMappings();
181: ArrayList schemas = axisService.getSchema();
182: for (int i = 0; i < schemas.size(); i++) {
183: StringWriter writer = new StringWriter();
184: XmlSchema schema = axisService.getSchema(i);
185:
186: if (!org.apache.axis2.namespace.Constants.URI_2001_SCHEMA_XSD
187: .equals(schema.getTargetNamespace())) {
188: schema.write(writer);
189: String schemaString = writer.toString();
190:
191: if (!"".equals(schemaString)) {
192: try {
193: typesElement.addChild(XMLUtils
194: .toOM(new ByteArrayInputStream(
195: schemaString.getBytes())));
196: } catch (XMLStreamException e) {
197: throw AxisFault.makeFault(e);
198: }
199: }
200: }
201: }
202: descriptionElement.addChild(typesElement);
203:
204: Parameter parameter = axisService
205: .getParameter(WSDL2Constants.INTERFACE_LOCAL_NAME);
206: String interfaceName;
207: if (parameter != null) {
208: interfaceName = (String) parameter.getValue();
209: } else {
210: interfaceName = WSDL2Constants.DEFAULT_INTERFACE_NAME;
211: }
212:
213: // Add the interface element
214: descriptionElement.addChild(getInterfaceElement(wsdl, tns,
215: wsdlx, omFactory, interfaceName));
216:
217: boolean disableREST = false;
218: Parameter disableRESTParameter = axisService
219: .getParameter(Constants.Configuration.DISABLE_REST);
220: if (disableRESTParameter != null
221: && JavaUtils.isTrueExplicitly(disableRESTParameter
222: .getValue())) {
223: disableREST = true;
224: }
225:
226: // Check whether the axisService has any endpoints. If they exists serialize them else
227: // generate default endpoint elements.
228: Set bindings = new HashSet();
229: Map endpointMap = axisService.getEndpoints();
230: if (endpointMap != null && endpointMap.size() > 0) {
231: String[] eprs = axisService.getEPRs();
232: if (eprs == null) {
233: eprs = new String[] { axisService.getName() };
234: }
235: OMElement serviceElement = getServiceElement(wsdl, tns,
236: omFactory, interfaceName);
237: Iterator iterator = endpointMap.values().iterator();
238: while (iterator.hasNext()) {
239: // With the new binding hierachy in place we need to do some extra checking here.
240: // If a service has both http and https listners up we should show two separate eprs
241: // If the service was deployed with a WSDL and it had two endpoints for http and
242: // https then we have two endpoints populated so we should serialize them instead
243: // of updating the endpoints.
244: AxisEndpoint axisEndpoint = (AxisEndpoint) iterator
245: .next();
246: AxisBinding axisBinding = axisEndpoint.getBinding();
247: String type = axisBinding.getType();
248: if (WSDL2Constants.URI_WSDL2_HTTP.equals(type)) {
249: if (disableREST) {
250: continue;
251: }
252: }
253: bindings.add(axisBinding);
254: for (int i = 0; i < eprs.length; i++) {
255: String epr = eprs[i];
256: OMElement endpointElement = axisEndpoint.toWSDL20(
257: wsdl, tns, whttp, epr);
258: boolean endpointAlreadyAdded = false;
259: Iterator endpointsAdded = serviceElement
260: .getChildren();
261: while (endpointsAdded.hasNext()) {
262: OMElement endpoint = (OMElement) endpointsAdded
263: .next();
264: // Checking whether a endpoint with the same binding and address exists.
265: if (endpoint
266: .getAttribute(
267: new QName(
268: WSDL2Constants.BINDING_LOCAL_NAME))
269: .getAttributeValue()
270: .equals(
271: endpointElement
272: .getAttribute(
273: new QName(
274: WSDL2Constants.BINDING_LOCAL_NAME))
275: .getAttributeValue())
276: && endpoint
277: .getAttribute(
278: new QName(
279: WSDL2Constants.ATTRIBUTE_ADDRESS))
280: .getAttributeValue()
281: .equals(
282: endpointElement
283: .getAttribute(
284: new QName(
285: WSDL2Constants.ATTRIBUTE_ADDRESS))
286: .getAttributeValue())) {
287: endpointAlreadyAdded = true;
288: }
289:
290: }
291: if (!endpointAlreadyAdded) {
292: serviceElement.addChild(endpointElement);
293: }
294: }
295: }
296: Iterator iter = bindings.iterator();
297: while (iter.hasNext()) {
298: AxisBinding binding = (AxisBinding) iter.next();
299: descriptionElement.addChild(binding.toWSDL20(wsdl, tns,
300: wsoap, whttp, interfaceName, axisService
301: .getNamespaceMap(), axisService
302: .getWSAddressingFlag(), axisService
303: .getName(), wsaw));
304: }
305:
306: descriptionElement.addChild(serviceElement);
307: } else {
308:
309: // There are no andpoints defined hence generate default bindings and endpoints
310: descriptionElement.addChild(WSDLSerializationUtil
311: .generateSOAP11Binding(omFactory, axisService,
312: wsdl, wsoap, tns));
313: descriptionElement.addChild(WSDLSerializationUtil
314: .generateSOAP12Binding(omFactory, axisService,
315: wsdl, wsoap, tns));
316: if (!disableREST) {
317: descriptionElement.addChild(WSDLSerializationUtil
318: .generateHTTPBinding(omFactory, axisService,
319: wsdl, whttp, tns));
320: }
321: descriptionElement.addChild(WSDLSerializationUtil
322: .generateServiceElement(omFactory, wsdl, tns,
323: axisService, disableREST, eprs));
324: }
325:
326: return descriptionElement;
327: }
328:
329: /**
330: * Generates the interface element for the service
331: *
332: * @param wsdl The WSDL namespace
333: * @param tns The target namespace
334: * @param wsdlx The WSDL extensions namespace
335: * @param fac The active OMFactory
336: * @param interfaceName The name of the interface
337: * @return The generated interface element
338: */
339: private OMElement getInterfaceElement(OMNamespace wsdl,
340: OMNamespace tns, OMNamespace wsdlx, OMFactory fac,
341: String interfaceName) {
342:
343: OMElement interfaceElement = fac.createOMElement(
344: WSDL2Constants.INTERFACE_LOCAL_NAME, wsdl);
345: interfaceElement.addAttribute(fac.createOMAttribute(
346: WSDL2Constants.ATTRIBUTE_NAME, null, interfaceName));
347: Iterator iterator = axisService.getOperations();
348: ArrayList interfaceOperations = new ArrayList();
349: ArrayList interfaceFaults = new ArrayList();
350: int i = 0;
351: while (iterator.hasNext()) {
352: AxisOperation axisOperation = (AxisOperation) iterator
353: .next();
354: if (axisOperation.isControlOperation()) {
355: continue;
356: }
357: interfaceOperations.add(i,
358: generateInterfaceOperationElement(axisOperation,
359: wsdl, tns, wsdlx));
360: i++;
361: Iterator faultsIterator = axisOperation.getFaultMessages()
362: .iterator();
363: while (faultsIterator.hasNext()) {
364: AxisMessage faultMessage = (AxisMessage) faultsIterator
365: .next();
366: String name = faultMessage.getName();
367: if (!interfaceFaults.contains(name)) {
368: OMElement faultElement = fac.createOMElement(
369: WSDL2Constants.FAULT_LOCAL_NAME, wsdl);
370: faultElement.addAttribute(fac.createOMAttribute(
371: WSDL2Constants.ATTRIBUTE_NAME, null, name));
372: faultElement.addAttribute(fac.createOMAttribute(
373: WSDL2Constants.ATTRIBUTE_ELEMENT, null,
374: WSDLSerializationUtil.getElementName(
375: faultMessage, axisService
376: .getNamespaceMap())));
377: interfaceFaults.add(name);
378: interfaceElement.addChild(faultElement);
379: }
380: }
381:
382: }
383: for (i = 0; i < interfaceOperations.size(); i++) {
384: interfaceElement.addChild((OMNode) interfaceOperations
385: .get(i));
386: }
387: return interfaceElement;
388: }
389:
390: /**
391: * Generates the service element for the service
392: *
393: * @param wsdl the WSDL namespace
394: * @param tns the target namespace
395: * @param omFactory the active OMFactory
396: * @param interfaceName the name of the interface
397: * @return the generated service element
398: */
399: private OMElement getServiceElement(OMNamespace wsdl,
400: OMNamespace tns, OMFactory omFactory, String interfaceName) {
401: OMElement serviceElement = omFactory.createOMElement(
402: WSDL2Constants.SERVICE_LOCAL_NAME, wsdl);
403: serviceElement.addAttribute(omFactory.createOMAttribute(
404: WSDL2Constants.ATTRIBUTE_NAME, null, axisService
405: .getName()));
406: serviceElement.addAttribute(omFactory.createOMAttribute(
407: WSDL2Constants.INTERFACE_LOCAL_NAME, null, tns
408: .getPrefix()
409: + ":" + interfaceName));
410: return serviceElement;
411: }
412:
413: /**
414: * Generates the interface Operation element. As with the binding operations we dont need to
415: * ask AxisMessage to serialize its message cause AxisMessage does not have specific properties
416: * as bindings.
417: *
418: * @param axisOperation the operation to write
419: * @param wsdl the WSDL namespace
420: * @param tns the target namespace
421: * @param wsdlx the WSDL extentions namespace (WSDL 2.0)
422: * @return the generated <operation> element
423: */
424: public OMElement generateInterfaceOperationElement(
425: AxisOperation axisOperation, OMNamespace wsdl,
426: OMNamespace tns, OMNamespace wsdlx) {
427: OMFactory omFactory = OMAbstractFactory.getOMFactory();
428: OMElement axisOperationElement = omFactory.createOMElement(
429: WSDL2Constants.OPERATION_LOCAL_NAME, wsdl);
430: WSDLSerializationUtil.addWSDLDocumentationElement(
431: axisOperation, axisOperationElement, omFactory, wsdl);
432: axisOperationElement.addAttribute(omFactory.createOMAttribute(
433: WSDL2Constants.ATTRIBUTE_NAME, null, axisOperation
434: .getName().getLocalPart()));
435: URI[] opStyle = (URI[]) axisOperation
436: .getParameterValue(WSDL2Constants.OPERATION_STYLE);
437: if (opStyle != null && opStyle.length > 0) {
438: String style = opStyle[0].toString();
439: for (int i = 1; i < opStyle.length; i++) {
440: URI uri = opStyle[i];
441: style = style + " " + uri;
442: }
443: axisOperationElement.addAttribute(omFactory
444: .createOMAttribute(WSDL2Constants.ATTRIBUTE_STYLE,
445: null, style));
446: }
447: axisOperationElement.addAttribute(omFactory.createOMAttribute(
448: WSDL2Constants.ATTRIBUTE_NAME_PATTERN, null,
449: axisOperation.getMessageExchangePattern()));
450: Parameter param = axisOperation
451: .getParameter(WSDL2Constants.ATTR_WSDLX_SAFE);
452: if (param != null) {
453: axisOperationElement.addAttribute(omFactory
454: .createOMAttribute(WSDL2Constants.ATTRIBUTE_SAFE,
455: wsdlx, (param.getValue()).toString()));
456: }
457: AxisService axisService = axisOperation.getAxisService();
458: Map nameSpaceMap = axisService.getNamespaceMap();
459:
460: // Add the input element
461: AxisMessage inMessage = (AxisMessage) axisOperation
462: .getChild(WSDLConstants.WSDL_MESSAGE_IN_MESSAGE);
463: if (inMessage != null) {
464: OMElement inMessageElement = omFactory.createOMElement(
465: WSDL2Constants.IN_PUT_LOCAL_NAME, wsdl);
466: inMessageElement.addAttribute(omFactory.createOMAttribute(
467: WSDL2Constants.ATTRIBUTE_ELEMENT, null,
468: WSDLSerializationUtil.getElementName(inMessage,
469: nameSpaceMap)));
470: WSDLSerializationUtil.addWSAWActionAttribute(
471: inMessageElement, axisOperation.getInputAction(),
472: wsaw);
473: WSDLSerializationUtil.addWSDLDocumentationElement(
474: inMessage, inMessageElement, omFactory, wsdl);
475: axisOperationElement.addChild(inMessageElement);
476: }
477:
478: // Add the output element
479: AxisMessage outMessage = (AxisMessage) axisOperation
480: .getChild(WSDLConstants.WSDL_MESSAGE_OUT_MESSAGE);
481: if (outMessage != null) {
482: OMElement outMessageElement = omFactory.createOMElement(
483: WSDL2Constants.OUT_PUT_LOCAL_NAME, wsdl);
484: outMessageElement.addAttribute(omFactory.createOMAttribute(
485: WSDL2Constants.ATTRIBUTE_ELEMENT, null,
486: WSDLSerializationUtil.getElementName(outMessage,
487: nameSpaceMap)));
488: WSDLSerializationUtil.addWSAWActionAttribute(
489: outMessageElement, axisOperation.getOutputAction(),
490: wsaw);
491: WSDLSerializationUtil.addWSDLDocumentationElement(
492: outMessage, outMessageElement, omFactory, wsdl);
493: axisOperationElement.addChild(outMessageElement);
494: }
495:
496: // Add the fault element
497: ArrayList faults = axisOperation.getFaultMessages();
498: if (faults != null) {
499: Iterator iterator = faults.iterator();
500: while (iterator.hasNext()) {
501: AxisMessage faultMessage = (AxisMessage) iterator
502: .next();
503: OMElement faultElement;
504: if (WSDLConstants.WSDL_MESSAGE_DIRECTION_IN
505: .equals(faultMessage.getDirection())) {
506: faultElement = omFactory.createOMElement(
507: WSDL2Constants.IN_FAULT_LOCAL_NAME, wsdl);
508: } else {
509: faultElement = omFactory.createOMElement(
510: WSDL2Constants.OUT_FAULT_LOCAL_NAME, wsdl);
511: }
512: faultElement.addAttribute(omFactory.createOMAttribute(
513: WSDL2Constants.ATTRIBUTE_REF, null, tns
514: .getPrefix()
515: + ":" + faultMessage.getName()));
516: WSDLSerializationUtil.addWSAWActionAttribute(
517: faultElement,
518: axisOperation.getFaultAction(faultMessage
519: .getName()), wsaw);
520: WSDLSerializationUtil.addWSDLDocumentationElement(
521: faultMessage, faultElement, omFactory, wsdl);
522: axisOperationElement.addChild(faultElement);
523: }
524: }
525: return axisOperationElement;
526: }
527:
528: public void setEPRs(String[] eprs) {
529: this.eprs = eprs;
530: }
531: }
|