1 /*
2 * Copyright 2006 the original author or authors.
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
17 package org.springframework.ws.wsdl.wsdl11.builder;
18
19 import java.util.Iterator;
20 import javax.wsdl.Binding;
21 import javax.wsdl.BindingFault;
22 import javax.wsdl.BindingInput;
23 import javax.wsdl.BindingOperation;
24 import javax.wsdl.BindingOutput;
25 import javax.wsdl.Definition;
26 import javax.wsdl.Fault;
27 import javax.wsdl.Input;
28 import javax.wsdl.Operation;
29 import javax.wsdl.OperationType;
30 import javax.wsdl.Output;
31 import javax.wsdl.Port;
32 import javax.wsdl.PortType;
33 import javax.wsdl.Service;
34 import javax.wsdl.WSDLException;
35 import javax.xml.namespace.QName;
36
37 /**
38 * Abstract base class for <code>Wsdl11DefinitionBuilder</code> implementations that use WSDL4J and contain a concrete
39 * part. Creates a <code>binding</code> that matches any present <code>portType</code>, and a service containing
40 * <code>port</code>s that match the <code>binding</code>s. Lets subclasses populate these through template methods.
41 *
42 * @author Arjen Poutsma
43 * @since 1.0.0
44 * @deprecated as of Spring Web Services 1.5: superseded by {@link org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition}
45 * and the {@link org.springframework.ws.wsdl.wsdl11.provider} package
46 */
47 public abstract class AbstractBindingWsdl4jDefinitionBuilder extends AbstractWsdl4jDefinitionBuilder {
48
49 /** The suffix used to create a binding name from a port type name. */
50 private static final String BINDING_SUFFIX = "Binding";
51
52 /** The suffix used to create a binding name from a port type name. */
53 private static final String PORT_SUFFIX = "Port";
54
55 /**
56 * Creates a {@link Binding} for each {@link PortType} in the definition, and calls {@link #populateBinding(Binding,
57 * PortType)} with it. Creates a {@link BindingOperation} for each {@link Operation} in the port type, a {@link
58 * BindingInput} for each {@link Input} in the operation, etc.
59 * <p/>
60 * Calls the various <code>populate</code> methods with the created WSDL4J objects.
61 *
62 * @param definition the WSDL4J <code>Definition</code>
63 * @throws WSDLException in case of errors
64 * @see #populateBinding(Binding, PortType)
65 * @see #populateBindingOperation(BindingOperation, Operation)
66 * @see #populateBindingInput(BindingInput, Input)
67 * @see #populateBindingOutput(BindingOutput, Output)
68 * @see #populateBindingFault(BindingFault, Fault)
69 */
70 public void buildBindings(Definition definition) throws WSDLException {
71 for (Iterator iterator = definition.getPortTypes().values().iterator(); iterator.hasNext();) {
72 PortType portType = (PortType) iterator.next();
73 Binding binding = definition.createBinding();
74 binding.setPortType(portType);
75 populateBinding(binding, portType);
76 createBindingOperations(definition, binding, portType);
77 binding.setUndefined(false);
78 definition.addBinding(binding);
79 }
80 }
81
82 /**
83 * Called after the {@link Binding} has been created, but before any sub-elements are added. Subclasses can
84 * implement this method to define the binding name, or add extensions to it.
85 * <p/>
86 * Default implementation sets the binding name to the port type name with the suffix {@link Binding} appended to
87 * it.
88 *
89 * @param binding the WSDL4J <code>Binding</code>
90 * @param portType the corresponding <code>PortType</code>
91 * @throws WSDLException in case of errors
92 */
93 protected void populateBinding(Binding binding, PortType portType) throws WSDLException {
94 QName portTypeName = portType.getQName();
95 if (portTypeName != null) {
96 binding.setQName(new QName(portTypeName.getNamespaceURI(), portTypeName.getLocalPart() + BINDING_SUFFIX));
97 }
98 }
99
100 private void createBindingOperations(Definition definition, Binding binding, PortType portType)
101 throws WSDLException {
102 for (Iterator operationIterator = portType.getOperations().iterator(); operationIterator.hasNext();) {
103 Operation operation = (Operation) operationIterator.next();
104 BindingOperation bindingOperation = definition.createBindingOperation();
105 bindingOperation.setOperation(operation);
106 populateBindingOperation(bindingOperation, operation);
107 if (operation.getStyle() == null || operation.getStyle().equals(OperationType.REQUEST_RESPONSE)) {
108 createBindingInput(definition, operation, bindingOperation);
109 createBindingOutput(definition, operation, bindingOperation);
110 }
111 else if (operation.getStyle().equals(OperationType.ONE_WAY)) {
112 createBindingInput(definition, operation, bindingOperation);
113 }
114 else if (operation.getStyle().equals(OperationType.NOTIFICATION)) {
115 createBindingOutput(definition, operation, bindingOperation);
116 }
117 else if (operation.getStyle().equals(OperationType.SOLICIT_RESPONSE)) {
118 createBindingOutput(definition, operation, bindingOperation);
119 createBindingInput(definition, operation, bindingOperation);
120 }
121 for (Iterator faultIterator = operation.getFaults().values().iterator(); faultIterator.hasNext();) {
122 Fault fault = (Fault) faultIterator.next();
123 BindingFault bindingFault = definition.createBindingFault();
124 populateBindingFault(bindingFault, fault);
125 bindingOperation.addBindingFault(bindingFault);
126 }
127 binding.addBindingOperation(bindingOperation);
128 }
129 }
130
131 private void createBindingOutput(Definition definition, Operation operation, BindingOperation bindingOperation)
132 throws WSDLException {
133 BindingOutput bindingOutput = definition.createBindingOutput();
134 populateBindingOutput(bindingOutput, operation.getOutput());
135 bindingOperation.setBindingOutput(bindingOutput);
136 }
137
138 private void createBindingInput(Definition definition, Operation operation, BindingOperation bindingOperation)
139 throws WSDLException {
140 BindingInput bindingInput = definition.createBindingInput();
141 populateBindingInput(bindingInput, operation.getInput());
142 bindingOperation.setBindingInput(bindingInput);
143 }
144
145 /**
146 * Called after the {@link BindingOperation} has been created, but before any sub-elements are added. Subclasses can
147 * implement this method to define the binding name, or add extensions to it.
148 * <p/>
149 * Default implementation sets the name of the binding operation to the name of the operation.
150 *
151 * @param bindingOperation the WSDL4J <code>BindingOperation</code>
152 * @param operation the corresponding WSDL4J <code>Operation</code>
153 * @throws WSDLException in case of errors
154 */
155 protected void populateBindingOperation(BindingOperation bindingOperation, Operation operation)
156 throws WSDLException {
157 bindingOperation.setName(operation.getName());
158 }
159
160 /**
161 * Called after the {@link BindingInput} has been created. Subclasses can implement this method to define the name,
162 * or add extensions to it.
163 * <p/>
164 * Default implementation set the name of the binding input to the name of the input.
165 *
166 * @param bindingInput the WSDL4J <code>BindingInput</code>
167 * @param input the corresponding WSDL4J <code>Input</code>
168 * @throws WSDLException in case of errors
169 */
170 protected void populateBindingInput(BindingInput bindingInput, Input input) throws WSDLException {
171 bindingInput.setName(input.getName());
172 }
173
174 /**
175 * Called after the {@link BindingOutput} has been created. Subclasses can implement this method to define the name,
176 * or add extensions to it.
177 * <p/>
178 * Default implementation set the name of the binding output to the name of the output.
179 *
180 * @param bindingOutput the WSDL4J <code>BindingOutput</code>
181 * @param output the corresponding WSDL4J <code>Output</code>
182 * @throws WSDLException in case of errors
183 */
184 protected void populateBindingOutput(BindingOutput bindingOutput, Output output) throws WSDLException {
185 bindingOutput.setName(output.getName());
186 }
187
188 /**
189 * Called after the {@link BindingFault} has been created. Subclasses can implement this method to define the name,
190 * or add extensions to it.
191 * <p/>
192 * Default implementation set the name of the binding fault to the name of the fault.
193 *
194 * @param bindingFault the WSDL4J <code>BindingFault</code>
195 * @param fault the corresponding WSDL4J <code>Fault</code>
196 * @throws WSDLException in case of errors
197 */
198 protected void populateBindingFault(BindingFault bindingFault, Fault fault) throws WSDLException {
199 bindingFault.setName(fault.getName());
200 }
201
202 /**
203 * Creates a single {@link Service}, and calls {@link #populateService(Service)} with it. Creates a corresponding
204 * {@link Port} for each {@link Binding}, which is passed to {@link #populatePort(Port, Binding)}.
205 *
206 * @param definition the WSDL4J <code>Definition</code>
207 * @throws WSDLException in case of errors
208 * @see #populatePort(Port, Binding)
209 */
210 public void buildServices(Definition definition) throws WSDLException {
211 Service service = definition.createService();
212 populateService(service);
213 createPorts(definition, service);
214 definition.addService(service);
215 }
216
217 /**
218 * Called after the {@link Binding} has been created, but before any sub-elements are added. Subclasses can
219 * implement this method to define the binding name, or add extensions to it.
220 * <p/>
221 * Default implementation is empty.
222 *
223 * @param service the WSDL4J <code>Service</code>
224 * @throws WSDLException in case of errors
225 */
226 protected void populateService(Service service) throws WSDLException {
227 }
228
229 private void createPorts(Definition definition, Service service) throws WSDLException {
230 for (Iterator iterator = definition.getBindings().values().iterator(); iterator.hasNext();) {
231 Binding binding = (Binding) iterator.next();
232 Port port = definition.createPort();
233 port.setBinding(binding);
234 populatePort(port, binding);
235 service.addPort(port);
236 }
237 }
238
239 /**
240 * Called after the {@link Port} has been created, but before any sub-elements are added. Subclasses can implement
241 * this method to define the port name, or add extensions to it.
242 * <p/>
243 * Default implementation sets the port name to the port type name with the suffix {@link Port} appended to it.
244 *
245 * @param port the WSDL4J <code>Port</code>
246 * @param binding the corresponding WSDL4J <code>Binding</code>
247 * @throws WSDLException in case of errors
248 */
249 protected void populatePort(Port port, Binding binding) throws WSDLException {
250 if (binding.getPortType() != null && binding.getPortType().getQName() != null) {
251 port.setName(binding.getPortType().getQName().getLocalPart() + PORT_SUFFIX);
252 }
253 }
254
255 }