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.tools.misc.processor;
019:
020: import java.io.IOException;
021: import java.io.Writer;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Map;
025:
026: import javax.wsdl.Binding;
027: import javax.wsdl.BindingFault;
028: import javax.wsdl.BindingInput;
029: import javax.wsdl.BindingOperation;
030: import javax.wsdl.BindingOutput;
031: import javax.wsdl.Fault;
032: import javax.wsdl.Input;
033: import javax.wsdl.Operation;
034: import javax.wsdl.Output;
035: import javax.wsdl.Part;
036: import javax.wsdl.PortType;
037: import javax.wsdl.WSDLException;
038: import javax.wsdl.extensions.ExtensionRegistry;
039: import javax.wsdl.xml.WSDLWriter;
040: import javax.xml.namespace.QName;
041:
042: import org.apache.cxf.common.i18n.Message;
043: import org.apache.cxf.tools.common.ToolConstants;
044: import org.apache.cxf.tools.common.ToolException;
045: import org.apache.cxf.tools.common.extensions.soap.SoapBinding;
046: import org.apache.cxf.tools.common.extensions.soap.SoapBody;
047: import org.apache.cxf.tools.common.extensions.soap.SoapFault;
048: import org.apache.cxf.tools.common.extensions.soap.SoapOperation;
049: import org.apache.cxf.tools.util.SOAPBindingUtil;
050: import org.apache.cxf.wsdl.WSDLConstants;
051:
052: public class WSDLToSoapProcessor extends AbstractWSDLToProcessor {
053:
054: private static final String NEW_FILE_NAME_MODIFIER = "-soapbinding";
055:
056: private ExtensionRegistry extReg;
057:
058: private Map portTypes;
059: private PortType portType;
060: private Binding binding;
061:
062: public void process() throws ToolException {
063: init();
064: validate();
065: extReg = this .wsdlReader.getExtensionRegistry();
066: doAppendBinding();
067: }
068:
069: private boolean isSOAP12() {
070: return env.optionSet(ToolConstants.CFG_SOAP12);
071: }
072:
073: private void validate() throws ToolException {
074: if (isBindingExisted()) {
075: Message msg = new Message("BINDING_ALREADY_EXIST", LOG);
076: throw new ToolException(msg);
077: }
078: if (!isPortTypeExisted()) {
079: Message msg = new Message("PORTTYPE_NOT_EXIST", LOG);
080: throw new ToolException(msg);
081: }
082: if (!nameSpaceCheck()) {
083: Message msg = new Message("SOAPBINDING_STYLE_NOT_PROVIDED",
084: LOG);
085: throw new ToolException(msg);
086: }
087: if (WSDLConstants.RPC.equalsIgnoreCase((String) env
088: .get(ToolConstants.CFG_STYLE))) {
089: Iterator it = portType.getOperations().iterator();
090: while (it.hasNext()) {
091: Operation op = (Operation) it.next();
092: Input input = op.getInput();
093: if (input != null && input.getMessage() != null) {
094: Iterator itParts = input.getMessage().getParts()
095: .values().iterator();
096: while (itParts.hasNext()) {
097: Part part = (Part) itParts.next();
098: if (part.getTypeName() == null
099: || "".equals(part.getTypeName()
100: .toString())) {
101: Message msg = new Message(
102: "RPC_PART_ILLEGAL", LOG,
103: new Object[] { part.getName() });
104: throw new ToolException(msg);
105: }
106: }
107: }
108: Output output = op.getOutput();
109: if (output != null && output.getMessage() != null) {
110: Iterator itParts = output.getMessage().getParts()
111: .values().iterator();
112: while (itParts.hasNext()) {
113: Part part = (Part) itParts.next();
114: if (part.getTypeName() == null
115: || "".equals(part.getTypeName()
116: .toString())) {
117: Message msg = new Message(
118: "RPC_PART_ILLEGAL", LOG,
119: new Object[] { part.getName() });
120: throw new ToolException(msg);
121: }
122: }
123: }
124: }
125: }
126: }
127:
128: private boolean isPortTypeExisted() {
129: portTypes = wsdlDefinition.getPortTypes();
130: if (portTypes == null) {
131: return false;
132: }
133: Iterator it = portTypes.keySet().iterator();
134: while (it.hasNext()) {
135: QName existPortQName = (QName) it.next();
136: String existPortName = existPortQName.getLocalPart();
137: if (existPortName.equals(env
138: .get(ToolConstants.CFG_PORTTYPE))) {
139: portType = (PortType) portTypes.get(existPortQName);
140: break;
141: }
142: }
143: return (portType == null) ? false : true;
144: }
145:
146: private boolean isBindingExisted() {
147: Map bindings = wsdlDefinition.getBindings();
148: if (bindings == null) {
149: return false;
150: }
151: Iterator it = bindings.keySet().iterator();
152: while (it.hasNext()) {
153: QName existBindingQName = (QName) it.next();
154: String existBindingName = existBindingQName.getLocalPart();
155: String bindingName = (String) env
156: .get(ToolConstants.CFG_BINDING);
157: if (bindingName.equals(existBindingName)) {
158: binding = (Binding) bindings.get(existBindingQName);
159: }
160: }
161: return (binding == null) ? false : true;
162: }
163:
164: private boolean nameSpaceCheck() {
165: if (WSDLConstants.RPC.equalsIgnoreCase((String) env
166: .get(ToolConstants.CFG_STYLE))
167: && !env.optionSet(ToolConstants.CFG_NAMESPACE)) {
168: return false;
169: }
170: return true;
171: }
172:
173: protected void init() throws ToolException {
174: parseWSDL((String) env.get(ToolConstants.CFG_WSDLURL));
175: }
176:
177: private void doAppendBinding() throws ToolException {
178: if (binding == null) {
179: binding = wsdlDefinition.createBinding();
180: binding.setQName(new QName(wsdlDefinition
181: .getTargetNamespace(), (String) env
182: .get(ToolConstants.CFG_BINDING)));
183: binding.setUndefined(false);
184: binding.setPortType(portType);
185: }
186: setSoapBindingExtElement();
187: addBindingOperation();
188: wsdlDefinition.addBinding(binding);
189:
190: WSDLWriter wsdlWriter = wsdlFactory.newWSDLWriter();
191: Writer outputWriter = getOutputWriter(NEW_FILE_NAME_MODIFIER);
192: try {
193: wsdlWriter.writeWSDL(wsdlDefinition, outputWriter);
194: } catch (WSDLException wse) {
195: Message msg = new Message("FAIL_TO_WRITE_WSDL", LOG, wse
196: .getMessage());
197: throw new ToolException(msg);
198: }
199: try {
200: outputWriter.close();
201: } catch (IOException ioe) {
202: Message msg = new Message("PORTTYPE_NOT_EXIST", LOG);
203: throw new ToolException(msg);
204: }
205: }
206:
207: private void setSoapBindingExtElement() throws ToolException {
208: if (extReg == null) {
209: extReg = wsdlFactory.newPopulatedExtensionRegistry();
210: }
211:
212: SOAPBindingUtil.addSOAPNamespace(wsdlDefinition, isSOAP12());
213:
214: SoapBinding soapBinding = null;
215: try {
216: soapBinding = SOAPBindingUtil.createSoapBinding(extReg,
217: isSOAP12());
218: } catch (WSDLException wse) {
219: Message msg = new Message("FAIL_TO_CREATE_SOAPBINDING", LOG);
220: throw new ToolException(msg, wse);
221: }
222: soapBinding.setStyle((String) env.get(ToolConstants.CFG_STYLE));
223: binding.addExtensibilityElement(soapBinding);
224: }
225:
226: @SuppressWarnings("unchecked")
227: private void addBindingOperation() throws ToolException {
228: /**
229: * This method won't do unique operation name checking on portType The
230: * WS-I Basic Profile[17] R2304 requires that operations within a
231: * wsdl:portType have unique values for their name attribute so mapping
232: * of WS-I compliant WSDLdescriptions will not generate Java interfaces
233: * with overloaded methods. However, for backwards compatibility, JAX-WS
234: * supports operation name overloading provided the overloading does not
235: * cause conflicts (as specified in the Java Language Specification[25])
236: * in the mapped Java service endpoint interface declaration.
237: */
238: List<Operation> ops = portType.getOperations();
239: for (Operation op : ops) {
240: BindingOperation bindingOperation = wsdlDefinition
241: .createBindingOperation();
242: setSoapOperationExtElement(bindingOperation);
243: bindingOperation.setName(op.getName());
244: if (op.getInput() != null) {
245: bindingOperation.setBindingInput(getBindingInput(op
246: .getInput()));
247: }
248: if (op.getOutput() != null) {
249: bindingOperation.setBindingOutput(getBindingOutput(op
250: .getOutput()));
251: }
252: if (op.getFaults() != null && op.getFaults().size() > 0) {
253: addSoapFaults(op, bindingOperation);
254: }
255: bindingOperation.setOperation(op);
256: binding.addBindingOperation(bindingOperation);
257: }
258: }
259:
260: private void setSoapOperationExtElement(BindingOperation bo)
261: throws ToolException {
262: if (extReg == null) {
263: extReg = wsdlFactory.newPopulatedExtensionRegistry();
264: }
265: SoapOperation soapOperation = null;
266:
267: try {
268: soapOperation = SOAPBindingUtil.createSoapOperation(extReg,
269: isSOAP12());
270: } catch (WSDLException wse) {
271: Message msg = new Message("FAIL_TO_CREATE_SOAPBINDING", LOG);
272: throw new ToolException(msg, wse);
273: }
274: soapOperation.setStyle((String) env
275: .get(ToolConstants.CFG_STYLE));
276: soapOperation.setSoapActionURI("");
277: bo.addExtensibilityElement(soapOperation);
278: }
279:
280: private BindingInput getBindingInput(Input input)
281: throws ToolException {
282: BindingInput bi = wsdlDefinition.createBindingInput();
283: bi.setName(input.getName());
284: // As command line won't specify the details of body/header for message
285: // parts
286: // All input message's parts will be added into one soap body element
287: bi.addExtensibilityElement(getSoapBody(BindingInput.class));
288: return bi;
289: }
290:
291: private BindingOutput getBindingOutput(Output output)
292: throws ToolException {
293: BindingOutput bo = wsdlDefinition.createBindingOutput();
294: bo.setName(output.getName());
295: // As command line won't specify the details of body/header for message
296: // parts
297: // All output message's parts will be added into one soap body element
298: bo.addExtensibilityElement(getSoapBody(BindingOutput.class));
299: return bo;
300: }
301:
302: private SoapBody getSoapBody(Class parent) throws ToolException {
303: if (extReg == null) {
304: extReg = wsdlFactory.newPopulatedExtensionRegistry();
305: }
306: SoapBody soapBody = null;
307: try {
308: soapBody = SOAPBindingUtil.createSoapBody(extReg, parent,
309: isSOAP12());
310: } catch (WSDLException wse) {
311: Message msg = new Message("FAIL_TO_CREATE_SOAPBINDING", LOG);
312: throw new ToolException(msg, wse);
313: }
314: soapBody.setUse((String) env.get(ToolConstants.CFG_USE));
315: if (WSDLConstants.RPC.equalsIgnoreCase((String) env
316: .get(ToolConstants.CFG_STYLE))
317: && env.optionSet(ToolConstants.CFG_NAMESPACE)) {
318: soapBody.setNamespaceURI((String) env
319: .get(ToolConstants.CFG_NAMESPACE));
320: }
321: return soapBody;
322: }
323:
324: private void addSoapFaults(Operation op,
325: BindingOperation bindingOperation) throws ToolException {
326: Map faults = op.getFaults();
327: Iterator it = faults.keySet().iterator();
328: while (it.hasNext()) {
329: String key = (String) it.next();
330: Fault fault = (Fault) faults.get(key);
331: BindingFault bf = wsdlDefinition.createBindingFault();
332: bf.setName(fault.getName());
333: setSoapFaultExtElement(bf);
334: bindingOperation.addBindingFault(bf);
335: }
336: }
337:
338: private void setSoapFaultExtElement(BindingFault bf)
339: throws ToolException {
340: if (extReg == null) {
341: extReg = wsdlFactory.newPopulatedExtensionRegistry();
342: }
343: SoapFault soapFault = null;
344: try {
345: soapFault = SOAPBindingUtil.createSoapFault(extReg,
346: isSOAP12());
347: } catch (WSDLException wse) {
348: Message msg = new Message("FAIL_TO_CREATE_SOAPBINDING", LOG);
349: throw new ToolException(msg, wse);
350: }
351: soapFault.setName(bf.getName());
352: soapFault.setUse((String) env.get(ToolConstants.CFG_USE));
353: if (WSDLConstants.RPC.equalsIgnoreCase((String) env
354: .get(ToolConstants.CFG_STYLE))
355: && env.optionSet(ToolConstants.CFG_NAMESPACE)) {
356: soapFault.setNamespaceURI((String) env
357: .get(ToolConstants.CFG_NAMESPACE));
358: }
359: bf.addExtensibilityElement(soapFault);
360: }
361:
362: }
|