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.addressing.wsdl;
020:
021: import org.apache.commons.logging.Log;
022: import org.apache.commons.logging.LogFactory;
023:
024: import javax.wsdl.Definition;
025: import javax.wsdl.Fault;
026: import javax.wsdl.Input;
027: import javax.wsdl.Operation;
028: import javax.wsdl.OperationType;
029: import javax.wsdl.Output;
030: import javax.wsdl.PortType;
031:
032: /**
033: * Generates a wsa:Action value using the Default Action Pattern defined at
034: * http://www.w3.org/TR/2006/WD-ws-addr-wsdl-20060216/#defactionwsdl11
035: */
036: public class WSDL11DefaultActionPatternHelper {
037:
038: private static final Log log = LogFactory
039: .getLog(WSDL11DefaultActionPatternHelper.class);
040:
041: // String constants used extensively in this class
042: private static final String URN = "urn";
043: private static final String SLASH = "/";
044: private static final String COLON = ":";
045: private static final String REQUEST = "Request";
046: private static final String RESPONSE = "Response";
047: private static final String SOLICIT = "Solicit";
048: private static final String FAULT = "Fault";
049:
050: /**
051: * Generate the Action for an Input using the Default Action Pattern
052: * <p/>
053: * Pattern is defined as [target namespace][delimiter][port type name][delimiter][input name]
054: *
055: * @param def is required to obtain the targetNamespace
056: * @param wsdl4jPortType is required to obtain the portType name
057: * @param op is required to generate the input name if not explicitly specified
058: * @param input is required for its name if specified
059: * @return a wsa:Action value based on the Default Action Pattern and the provided objects
060: */
061: public static String generateActionFromInputElement(Definition def,
062: PortType wsdl4jPortType, Operation op, Input input) {
063: // Get the targetNamespace of the wsdl:definitions
064: String targetNamespace = def.getTargetNamespace();
065:
066: // Determine the delimiter. Per the spec: 'is ":" when the [target namespace] is a URN, otherwise "/".
067: // Note that for IRI schemes other than URNs which aren't path-based (i.e. those that outlaw the "/"
068: // character), the default action value may not conform to the rules of the IRI scheme. Authors
069: // are advised to specify explicit values in the WSDL in this case.'
070: String delimiter = SLASH;
071: if (targetNamespace.toLowerCase().startsWith(URN)) {
072: delimiter = COLON;
073: }
074:
075: // Get the portType name (as a string to be included in the action)
076: String portTypeName = wsdl4jPortType.getQName().getLocalPart();
077: // Get the name of the input element (and generate one if none explicitly specified)
078: String inputName = getNameFromInputElement(op, input);
079:
080: // Append the bits together
081: StringBuffer sb = new StringBuffer();
082: sb.append(targetNamespace);
083: // Deal with the problem that the targetNamespace may or may not have a trailing delimiter
084: if (!targetNamespace.endsWith(delimiter)) {
085: sb.append(delimiter);
086: }
087: sb.append(portTypeName);
088: sb.append(delimiter);
089: sb.append(inputName);
090:
091: // Resolve the action from the StringBuffer
092: String result = sb.toString();
093:
094: if (log.isTraceEnabled()) {
095: log.trace("generateActionFromInputElement result: "
096: + result);
097: }
098:
099: return result;
100: }
101:
102: /**
103: * Get the name of the specified Input element using the rules defined in WSDL 1.1
104: * Section 2.4.5 http://www.w3.org/TR/wsdl#_names
105: */
106: private static String getNameFromInputElement(Operation op,
107: Input input) {
108: // Get the name from the input element if specified.
109: String result = input.getName();
110:
111: // If not we'll have to generate it.
112: if (result == null) {
113: // If Request-Response or Solicit-Response do something special per
114: // WSDL 1.1 Section 2.4.5
115: OperationType operationType = op.getStyle();
116: if (null != operationType) {
117: if (operationType
118: .equals(OperationType.REQUEST_RESPONSE)) {
119: result = op.getName() + REQUEST;
120: } else if (operationType
121: .equals(OperationType.SOLICIT_RESPONSE)) {
122: result = op.getName() + RESPONSE;
123: }
124: }
125: // If the OperationType was not available for some reason, assume on-way or notification
126: if (result == null) {
127: result = op.getName();
128: }
129: }
130: return result;
131: }
132:
133: protected static String getInputActionFromStringInformation(
134: String messageExchangePattern, String targetNamespace,
135: String portTypeName, String operationName, String inputName) {
136: if (messageExchangePattern == null && inputName == null) {
137: throw new IllegalArgumentException(
138: "One of messageExchangePattern or inputName must the non-null to generate an action.");
139: }
140:
141: // Determine the delimiter. Per the spec: 'is ":" when the [target namespace] is a URN, otherwise "/".
142: // Note that for IRI schemes other than URNs which aren't path-based (i.e. those that outlaw the "/"
143: // character), the default action value may not conform to the rules of the IRI scheme. Authors
144: // are advised to specify explicit values in the WSDL in this case.'
145: String delimiter = SLASH;
146: if (targetNamespace.toLowerCase().startsWith(URN)) {
147: delimiter = COLON;
148: }
149:
150: if (inputName == null) {
151: inputName = operationName;
152: if (messageExchangePattern.indexOf("in-out") >= 0) {
153: inputName += REQUEST;
154: }
155: }
156:
157: // Append the bits together
158: StringBuffer sb = new StringBuffer();
159: sb.append(targetNamespace);
160: // Deal with the problem that the targetNamespace may or may not have a trailing delimiter
161: if (!targetNamespace.endsWith(delimiter)) {
162: sb.append(delimiter);
163: }
164: sb.append(portTypeName);
165: sb.append(delimiter);
166: sb.append(inputName);
167:
168: // Resolve the action from the StringBuffer
169: String result = sb.toString();
170:
171: if (log.isTraceEnabled()) {
172: log.trace("getInputActionFromStringInformation result: "
173: + result);
174: }
175:
176: return result;
177: }
178:
179: /**
180: * Generate the Action for an Output using the Default Action Pattern
181: * <p/>
182: * Pattern is defined as [target namespace][delimiter][port type name][delimiter][output name]
183: *
184: * @param def is required to obtain the targetNamespace
185: * @param wsdl4jPortType is required to obtain the portType name
186: * @param op is required to generate the output name if not explicitly specified
187: * @param output is required for its name if specified
188: * @return a wsa:Action value based on the Default Action Pattern and the provided objects
189: */
190: public static String generateActionFromOutputElement(
191: Definition def, PortType wsdl4jPortType, Operation op,
192: Output output) {
193: // Get the targetNamespace of the wsdl:definition
194: String targetNamespace = def.getTargetNamespace();
195:
196: // Determine the delimiter. Per the spec: 'is ":" when the [target namespace] is a URN, otherwise "/".
197: // Note that for IRI schemes other than URNs which aren't path-based (i.e. those that outlaw the "/"
198: // character), the default action value may not conform to the rules of the IRI scheme. Authors
199: // are advised to specify explicit values in the WSDL in this case.'
200: String delimiter = SLASH;
201: if (targetNamespace.toLowerCase().startsWith(URN)) {
202: delimiter = COLON;
203: }
204:
205: // Get the portType name (as a string to be included in the action)
206: String portTypeName = wsdl4jPortType.getQName().getLocalPart();
207: // Get the name of the output element (and generate one if none explicitly specified)
208: String outputName = getNameFromOutputElement(op, output);
209:
210: // Append the bits together
211: StringBuffer sb = new StringBuffer();
212: sb.append(targetNamespace);
213: // Deal with the problem that the targetNamespace may or may not have a trailing delimiter
214: if (!targetNamespace.endsWith(delimiter)) {
215: sb.append(delimiter);
216: }
217: sb.append(portTypeName);
218: sb.append(delimiter);
219: sb.append(outputName);
220:
221: // Resolve the action from the StringBuffer
222: String result = sb.toString();
223:
224: if (log.isTraceEnabled()) {
225: log.trace("generateActionFromOutputElement result: "
226: + result);
227: }
228:
229: return result;
230: }
231:
232: /**
233: * Get the name of the specified Output element using the rules defined in WSDL 1.1
234: * Section 2.4.5 http://www.w3.org/TR/wsdl#_names
235: */
236: private static String getNameFromOutputElement(Operation op,
237: Output output) {
238: // Get the name from the output element if specified.
239: String result = output.getName();
240:
241: // If not we'll have to generate it.
242: if (result == null) {
243: // If Request-Response or Solicit-Response do something special per
244: // WSDL 1.1 Section 2.4.5
245: OperationType operationType = op.getStyle();
246: if (null != operationType) {
247: if (operationType
248: .equals(OperationType.REQUEST_RESPONSE)) {
249: return op.getName() + RESPONSE;
250: } else if (operationType
251: .equals(OperationType.SOLICIT_RESPONSE)) {
252: return op.getName() + SOLICIT;
253: }
254: }
255: // If the OperationType was not available for some reason, assume on-way or notification
256: if (result == null) {
257: result = op.getName();
258: }
259: }
260: return result;
261: }
262:
263: protected static String getOutputActionFromStringInformation(
264: String messageExchangePattern, String targetNamespace,
265: String portTypeName, String operationName, String outputName) {
266: if (messageExchangePattern == null && outputName == null) {
267: throw new IllegalArgumentException(
268: "One of messageExchangePattern or outputName must the non-null to generate an action.");
269: }
270:
271: // Determine the delimiter. Per the spec: 'is ":" when the [target namespace] is a URN, otherwise "/".
272: // Note that for IRI schemes other than URNs which aren't path-based (i.e. those that outlaw the "/"
273: // character), the default action value may not conform to the rules of the IRI scheme. Authors
274: // are advised to specify explicit values in the WSDL in this case.'
275: String delimiter = SLASH;
276: if (targetNamespace.toLowerCase().startsWith(URN)) {
277: delimiter = COLON;
278: }
279:
280: if (outputName == null) {
281: outputName = operationName;
282: if (messageExchangePattern.indexOf("in-out") >= 0) {
283: outputName += RESPONSE;
284: }
285: }
286:
287: // Append the bits together
288: StringBuffer sb = new StringBuffer();
289: sb.append(targetNamespace);
290: // Deal with the problem that the targetNamespace may or may not have a trailing delimiter
291: if (!targetNamespace.endsWith(delimiter)) {
292: sb.append(delimiter);
293: }
294: sb.append(portTypeName);
295: sb.append(delimiter);
296: sb.append(outputName);
297:
298: // Resolve the action from the StringBuffer
299: String result = sb.toString();
300:
301: if (log.isTraceEnabled()) {
302: log.trace("getOutputActionFromStringInformation result: "
303: + result);
304: }
305:
306: return result;
307: }
308:
309: /**
310: * Generate the Action for a Fault using the Default Action Pattern
311: * <p/>
312: * Pattern is defined as [target namespace][delimiter][port type name][delimiter][operation name][delimiter]Fault[delimiter][fault name]
313: *
314: * @param def is required to obtain the targetNamespace
315: * @param wsdl4jPortType is required to obtain the portType name
316: * @param op is required to obtain the operation name
317: * @param fault is required to obtain the fault name
318: * @return a wsa:Action value based on the Default Action Pattern and the provided objects
319: */
320: public static String generateActionFromFaultElement(Definition def,
321: PortType wsdl4jPortType, Operation op, Fault fault) {
322: // Get the targetNamespace of the wsdl:definition
323: String targetNamespace = def.getTargetNamespace();
324:
325: // Determine the delimiter. Per the spec: 'is ":" when the [target namespace] is a URN, otherwise "/".
326: // Note that for IRI schemes other than URNs which aren't path-based (i.e. those that outlaw the "/"
327: // character), the default action value may not conform to the rules of the IRI scheme. Authors
328: // are advised to specify explicit values in the WSDL in this case.'
329: String delimiter = SLASH;
330: if (targetNamespace.toLowerCase().startsWith(URN)) {
331: delimiter = COLON;
332: }
333:
334: // Get the portType name (as a string to be included in the action)
335: String portTypeName = wsdl4jPortType.getQName().getLocalPart();
336: // Get the operation name (as a string to be included in the action)
337: String operationName = op.getName();
338:
339: // Get the name of the fault element (name is mandatory on fault elements)
340: String faultName = fault.getName();
341:
342: // Append the bits together
343: StringBuffer sb = new StringBuffer();
344: sb.append(targetNamespace);
345: // Deal with the problem that the targetNamespace may or may not have a trailing delimiter
346: if (!targetNamespace.endsWith(delimiter)) {
347: sb.append(delimiter);
348: }
349: sb.append(portTypeName);
350: sb.append(delimiter);
351: sb.append(operationName);
352: sb.append(delimiter);
353: sb.append(FAULT);
354: sb.append(delimiter);
355: sb.append(faultName);
356:
357: // Resolve the action from the StringBuffer
358: String result = sb.toString();
359:
360: if (log.isTraceEnabled()) {
361: log.trace("generateActionFromFaultElement result: "
362: + result);
363: }
364:
365: return result;
366: }
367:
368: protected static String getFaultActionFromStringInformation(
369: String targetNamespace, String portTypeName,
370: String operationName, String faultName) {
371: // Determine the delimiter. Per the spec: 'is ":" when the [target namespace] is a URN, otherwise "/".
372: // Note that for IRI schemes other than URNs which aren't path-based (i.e. those that outlaw the "/"
373: // character), the default action value may not conform to the rules of the IRI scheme. Authors
374: // are advised to specify explicit values in the WSDL in this case.'
375: String delimiter = SLASH;
376: if (targetNamespace.toLowerCase().startsWith(URN)) {
377: delimiter = COLON;
378: }
379:
380: // Append the bits together
381: StringBuffer sb = new StringBuffer();
382: sb.append(targetNamespace);
383: // Deal with the problem that the targetNamespace may or may not have a trailing delimiter
384: if (!targetNamespace.endsWith(delimiter)) {
385: sb.append(delimiter);
386: }
387: sb.append(portTypeName);
388: sb.append(delimiter);
389: sb.append(operationName);
390: sb.append(delimiter);
391: sb.append(FAULT);
392: sb.append(delimiter);
393: sb.append(faultName);
394:
395: // Resolve the action from the StringBuffer
396: String result = sb.toString();
397:
398: if (log.isTraceEnabled()) {
399: log.trace("getFaultActionFromStringInformation result: "
400: + result);
401: }
402:
403: return result;
404: }
405: }
|