001: package org.objectweb.celtix.tools.processors.wsdl2.internal;
002:
003: import java.util.ArrayList;
004: import java.util.Collection;
005: import java.util.Iterator;
006: import java.util.List;
007: import java.util.Map;
008:
009: import javax.jws.soap.SOAPBinding;
010: import javax.wsdl.Message;
011: import javax.wsdl.Part;
012: import javax.xml.namespace.QName;
013:
014: import com.sun.codemodel.JType;
015: import com.sun.tools.xjc.api.Property;
016:
017: import org.objectweb.celtix.tools.common.ProcessorEnvironment;
018: import org.objectweb.celtix.tools.common.ToolException;
019: import org.objectweb.celtix.tools.common.model.JavaAnnotation;
020: import org.objectweb.celtix.tools.common.model.JavaMethod;
021: import org.objectweb.celtix.tools.common.model.JavaParameter;
022: import org.objectweb.celtix.tools.common.model.JavaReturn;
023: import org.objectweb.celtix.tools.common.model.JavaType;
024: import org.objectweb.celtix.tools.utils.ProcessorUtil;
025:
026: public class ParameterProcessor extends AbstractProcessor {
027:
028: public ParameterProcessor(ProcessorEnvironment penv) {
029: super (penv);
030: }
031:
032: public void process(JavaMethod method, Message inputMessage,
033: Message outputMessage, boolean isRequestResponse,
034: List<String> parameterOrder) throws ToolException {
035:
036: boolean parameterOrderPresent = false;
037:
038: if (parameterOrder != null && !parameterOrder.isEmpty()) {
039: parameterOrderPresent = true;
040: }
041:
042: if (parameterOrderPresent
043: && isValidOrdering(parameterOrder, inputMessage,
044: outputMessage) && !method.isWrapperStyle()) {
045: buildParamModelsWithOrdering(method, inputMessage,
046: outputMessage, isRequestResponse, parameterOrder);
047: } else {
048: buildParamModelsWithoutOrdering(method, inputMessage,
049: outputMessage, isRequestResponse);
050: }
051: }
052:
053: /**
054: * This method will be used by binding processor to change existing
055: * generated java method of porttype
056: *
057: * @param method
058: * @param part
059: * @param style
060: * @throws ToolException
061: */
062: public JavaParameter addParameterFromBinding(JavaMethod method,
063: Part part, JavaType.Style style) throws ToolException {
064: return addParameter(method, getParameterFromPart(method, part,
065: style));
066: }
067:
068: private JavaParameter getParameterFromPart(JavaMethod method,
069: Part part, JavaType.Style style) {
070: String name = ProcessorUtil.resolvePartName(part);
071: String namespace = ProcessorUtil.resolvePartNamespace(part);
072: String type = ProcessorUtil.resolvePartType(part, this .env);
073:
074: JavaParameter parameter = new JavaParameter(name, type,
075: namespace);
076: parameter.setPartName(part.getName());
077: parameter.setQName(ProcessorUtil.getElementName(part));
078:
079: parameter.setClassName(ProcessorUtil.getFullClzName(part, env,
080: this .collector));
081:
082: if (style == JavaType.Style.INOUT
083: || style == JavaType.Style.OUT) {
084: parameter.setHolder(true);
085: parameter
086: .setHolderName(javax.xml.ws.Holder.class.getName());
087: parameter.setHolderClass(ProcessorUtil.getFullClzName(part,
088: env, true, this .collector));
089: }
090: parameter.setStyle(style);
091: return parameter;
092: }
093:
094: private JavaParameter addParameter(JavaMethod method,
095: JavaParameter parameter) throws ToolException {
096: JavaAnnotation webParamAnnotation = new JavaAnnotation(
097: "WebParam");
098: String name = parameter.getName();
099: String targetNamespace = method.getInterface().getNamespace();
100: String partName = null;
101:
102: if (method.getSoapStyle() == SOAPBinding.Style.DOCUMENT) {
103: targetNamespace = parameter.getTargetNamespace();
104: if (parameter.getQName() != null) {
105: name = parameter.getQName().getLocalPart();
106: }
107: if (!method.isWrapperStyle()) {
108: partName = parameter.getPartName();
109: }
110: }
111:
112: if (method.getSoapStyle() == SOAPBinding.Style.RPC) {
113: name = parameter.getPartName();
114: partName = parameter.getPartName();
115: }
116:
117: if (partName != null) {
118: webParamAnnotation.addArgument("partName", partName);
119: }
120: if (parameter.getStyle() == JavaType.Style.OUT
121: || parameter.getStyle() == JavaType.Style.INOUT) {
122: webParamAnnotation.addArgument("mode", "Mode."
123: + parameter.getStyle().toString(), "");
124: }
125: webParamAnnotation.addArgument("name", name);
126: if (method.getSoapStyle() == SOAPBinding.Style.DOCUMENT) {
127: webParamAnnotation.addArgument("targetNamespace",
128: targetNamespace);
129: }
130:
131: parameter.setAnnotation(webParamAnnotation);
132:
133: method.addParameter(parameter);
134:
135: return parameter;
136: }
137:
138: private void processReturn(JavaMethod method, Part part) {
139: String name = part == null ? "return" : part.getName();
140: String type = part == null ? "void" : ProcessorUtil
141: .resolvePartType(part, this .env);
142: String namespace = part == null ? null : ProcessorUtil
143: .resolvePartNamespace(part);
144:
145: JavaReturn returnType = new JavaReturn(name, type, namespace);
146: returnType.setQName(ProcessorUtil.getElementName(part));
147: returnType.setStyle(JavaType.Style.OUT);
148: if (namespace != null && type != null && !"void".equals(type)) {
149: returnType.setClassName(ProcessorUtil.getFullClzName(part,
150: env, this .collector));
151: }
152: method.setReturn(returnType);
153: }
154:
155: @SuppressWarnings("unchecked")
156: private void processInput(JavaMethod method, Message inputMessage)
157: throws ToolException {
158: Map<String, Part> inputPartsMap = inputMessage.getParts();
159: Collection<Part> inputParts = inputPartsMap.values();
160: for (Part part : inputParts) {
161: addParameter(method, getParameterFromPart(method, part,
162: JavaType.Style.IN));
163: }
164: }
165:
166: @SuppressWarnings("unchecked")
167: private void processWrappedInput(JavaMethod method,
168: Message inputMessage) throws ToolException {
169: Map<String, Part> inputPartsMap = inputMessage.getParts();
170: Collection<Part> inputParts = inputPartsMap.values();
171: if (inputParts.size() > 1) {
172: processInput(method, inputMessage);
173: return;
174: } else if (inputParts.isEmpty()) {
175: return;
176: }
177: Part part = inputParts.iterator().next();
178:
179: List<? extends Property> block = ProcessorUtil.getBlock(part,
180: env);
181: if (block != null) {
182: if (block.size() == 0) {
183: // complete
184: }
185: for (Property item : block) {
186: addParameter(method, getParameterFromProperty(item,
187: JavaType.Style.IN, part));
188: }
189: }
190: }
191:
192: @SuppressWarnings("unchecked")
193: private void processOutput(JavaMethod method, Message inputMessage,
194: Message outputMessage, boolean isRequestResponse)
195: throws ToolException {
196: Map<String, Part> inputPartsMap = inputMessage.getParts();
197: Map<String, Part> outputPartsMap = outputMessage.getParts();
198: Collection<Part> outputParts = outputPartsMap.values();
199: // figure out output parts that are not present in input parts
200: List<Part> outParts = new ArrayList<Part>();
201: if (isRequestResponse) {
202:
203: for (Part outpart : outputParts) {
204: Part inpart = inputPartsMap.get(outpart.getName());
205: if (inpart == null) {
206: outParts.add(outpart);
207: continue;
208: } else if (isSamePart(inpart, outpart)) {
209: addParameter(method, getParameterFromPart(method,
210: outpart, JavaType.Style.INOUT));
211: continue;
212: } else if (!isSamePart(inpart, outpart)) {
213: outParts.add(outpart);
214: continue;
215: }
216: // outParts.add(outpart);
217: }
218: }
219:
220: if (isRequestResponse && outParts.size() == 1) {
221: processReturn(method, outputParts.iterator().next());
222: return;
223: } else {
224: processReturn(method, null);
225: }
226: if (isRequestResponse) {
227: for (Part part : outParts) {
228: addParameter(method, getParameterFromPart(method, part,
229: JavaType.Style.OUT));
230: }
231: }
232: }
233:
234: @SuppressWarnings("unchecked")
235: private void processWrappedOutput(JavaMethod method,
236: Message inputMessage, Message outputMessage,
237: boolean isRequestResponse) throws ToolException {
238: Map<String, Part> inputPartsMap = inputMessage.getParts();
239: Map<String, Part> outputPartsMap = outputMessage.getParts();
240: Collection<Part> outputParts = outputPartsMap.values();
241: Collection<Part> inputParts = inputPartsMap.values();
242:
243: if (inputPartsMap.size() > 1 || outputPartsMap.size() > 1) {
244: processOutput(method, inputMessage, outputMessage,
245: isRequestResponse);
246: return;
247: }
248:
249: Part inputPart = inputParts.iterator().next();
250: Part outputPart = outputParts.iterator().next();
251: List<? extends Property> inputBlock = ProcessorUtil.getBlock(
252: inputPart, env);
253: List<? extends Property> outputBlock = ProcessorUtil.getBlock(
254: outputPart, env);
255:
256: if (outputBlock == null || outputBlock.size() == 0) {
257: addVoidReturn(method);
258: return;
259: }
260: method.setReturn(null);
261: if (outputBlock.size() == 1) {
262: Property outElement = outputBlock.iterator().next();
263: boolean sameWrapperChild = false;
264: for (Property inElement : inputBlock) {
265: if (isSameWrapperChild(inElement, outElement)) {
266: addParameter(method, getParameterFromProperty(
267: outElement, JavaType.Style.INOUT,
268: outputPart));
269: sameWrapperChild = true;
270: if (method.getReturn() == null) {
271: addVoidReturn(method);
272: }
273: break;
274: }
275: }
276: if (!sameWrapperChild) {
277: method.setReturn(getReturnFromProperty(outElement,
278: outputPart));
279: }
280: return;
281: }
282: method.setReturn(null);
283: for (Property outElement : outputBlock) {
284: if ("return"
285: .equals(outElement.elementName().getLocalPart())) {
286: if (method.getReturn() != null) {
287: org.objectweb.celtix.common.i18n.Message msg = new org.objectweb.celtix.common.i18n.Message(
288: "WRAPPER_STYLE_TWO_RETURN_TYPES", LOG);
289: throw new ToolException(msg);
290: }
291: method.setReturn(getReturnFromProperty(outElement,
292: outputPart));
293: continue;
294: }
295: boolean sameWrapperChild = false;
296: for (Property inElement : inputBlock) {
297: if (isSameWrapperChild(inElement, outElement)) {
298: addParameter(method, getParameterFromProperty(
299: outElement, JavaType.Style.INOUT,
300: outputPart));
301: sameWrapperChild = true;
302: break;
303: }
304: }
305: if (!sameWrapperChild) {
306: addParameter(method, getParameterFromProperty(
307: outElement, JavaType.Style.OUT, outputPart));
308: }
309: }
310: if (method.getReturn() == null) {
311: addVoidReturn(method);
312: }
313: }
314:
315: private void addVoidReturn(JavaMethod method) {
316: JavaReturn returnType = new JavaReturn("return", "void", null);
317: method.setReturn(returnType);
318: }
319:
320: private boolean isSameWrapperChild(Property in, Property out) {
321: if (!in.name().equals(out.name())) {
322: return false;
323: }
324: if (!in.type().fullName().equals(out.type().fullName())) {
325: return false;
326: }
327: if (!in.elementName().getNamespaceURI().equals(
328: out.elementName().getNamespaceURI())) {
329: return false;
330: }
331: return true;
332: }
333:
334: private JavaParameter getParameterFromProperty(Property property,
335: JavaType.Style style, Part part) {
336: JType t = property.type();
337: String targetNamespace = ProcessorUtil
338: .resolvePartNamespace(part);
339: if (targetNamespace == null) {
340: targetNamespace = property.elementName().getNamespaceURI();
341: }
342: JavaParameter parameter = new JavaParameter(property.name(), t
343: .fullName(), targetNamespace);
344: parameter.setStyle(style);
345: parameter.setQName(property.elementName());
346: if (style == JavaType.Style.OUT
347: || style == JavaType.Style.INOUT) {
348: parameter.setHolder(true);
349: parameter
350: .setHolderName(javax.xml.ws.Holder.class.getName());
351: parameter.setHolderClass(t.boxify().fullName());
352: }
353: return parameter;
354: }
355:
356: private JavaReturn getReturnFromProperty(Property property,
357: Part part) {
358: JType t = property.type();
359: String targetNamespace = ProcessorUtil
360: .resolvePartNamespace(part);
361: if (targetNamespace == null) {
362: targetNamespace = property.elementName().getNamespaceURI();
363: }
364: JavaReturn returnType = new JavaReturn(property.name(), t
365: .fullName(), targetNamespace);
366: returnType.setQName(property.elementName());
367: returnType.setStyle(JavaType.Style.OUT);
368: return returnType;
369: }
370:
371: private void buildParamModelsWithoutOrdering(JavaMethod method,
372: Message inputMessage, Message outputMessage,
373: boolean isRequestResponse) throws ToolException {
374: if (inputMessage != null) {
375: if (method.isWrapperStyle()) {
376: processWrappedInput(method, inputMessage);
377: } else {
378: processInput(method, inputMessage);
379: }
380: }
381: if (outputMessage == null) {
382: processReturn(method, null);
383: } else {
384: if (method.isWrapperStyle()) {
385: processWrappedOutput(method, inputMessage,
386: outputMessage, isRequestResponse);
387: } else {
388: processOutput(method, inputMessage, outputMessage,
389: isRequestResponse);
390: }
391: }
392: }
393:
394: @SuppressWarnings("unchecked")
395: private void buildParamModelsWithOrdering(JavaMethod method,
396: Message inputMessage, Message outputMessage,
397: boolean isRequestResponse, List<String> parameterList)
398: throws ToolException {
399: Map<String, Part> inputPartsMap = inputMessage.getParts();
400: Map<String, Part> outputPartsMap = outputMessage.getParts();
401:
402: Collection<Part> inputParts = inputPartsMap.values();
403: Collection<Part> outputParts = outputPartsMap.values();
404:
405: List<Part> inputUnlistedParts = new ArrayList<Part>();
406: List<Part> outputUnlistedParts = new ArrayList<Part>();
407:
408: for (Part part : inputParts) {
409: if (!parameterList.contains(part.getName())) {
410: inputUnlistedParts.add(part);
411: }
412: }
413:
414: if (isRequestResponse) {
415: for (Part part : outputParts) {
416: if (!parameterList.contains(part.getName())) {
417: Part inpart = inputMessage.getPart(part.getName());
418: if (inpart == null
419: || (inpart != null && !isSamePart(inpart,
420: part))) {
421: outputUnlistedParts.add(part);
422: }
423: }
424: }
425:
426: if (outputUnlistedParts.size() == 1) {
427: processReturn(method, outputUnlistedParts.get(0));
428: outputPartsMap.remove(outputUnlistedParts.get(0));
429: outputUnlistedParts.clear();
430: } else {
431: processReturn(method, null);
432: }
433: }
434:
435: // now create list of paramModel with parts
436: // first for the ordered list
437: int index = 0;
438: int size = parameterList.size();
439: while (index < size) {
440: String partName = parameterList.get(index);
441: Part part = inputPartsMap.get(partName);
442: JavaType.Style style = JavaType.Style.IN;
443: if (part == null) {
444: part = outputPartsMap.get(partName);
445: style = JavaType.Style.OUT;
446: } else if (outputPartsMap.get(partName) != null
447: && isSamePart(part, outputPartsMap.get(partName))) {
448: style = JavaType.Style.INOUT;
449: }
450: if (part != null) {
451: addParameter(method, getParameterFromPart(method, part,
452: style));
453: }
454: index++;
455: }
456: // now from unlisted input parts
457: for (Part part : inputUnlistedParts) {
458: addParameter(method, getParameterFromPart(method, part,
459: JavaType.Style.IN));
460: }
461: // now from unlisted output parts
462: for (Part part : outputUnlistedParts) {
463: addParameter(method, getParameterFromPart(method, part,
464: JavaType.Style.INOUT));
465: }
466: }
467:
468: private boolean isSamePart(Part part1, Part part2) {
469: QName qname1 = part1.getElementName();
470: QName qname2 = part2.getElementName();
471: if (qname1 != null && qname2 != null) {
472: return qname1.equals(qname2);
473: }
474: qname1 = part1.getTypeName();
475: qname2 = part2.getTypeName();
476: if (qname1 != null && qname2 != null) {
477: return qname1.equals(qname2);
478: }
479: return false;
480: }
481:
482: @SuppressWarnings("unchecked")
483: private boolean isValidOrdering(List<String> parameterOrder,
484: Message inputMessage, Message outputMessage) {
485: Iterator<String> params = parameterOrder.iterator();
486:
487: Collection<Part> inputParts = inputMessage.getParts().values();
488: Collection<Part> outputParts = outputMessage.getParts()
489: .values();
490:
491: boolean partFound = false;
492:
493: while (params.hasNext()) {
494: String param = params.next();
495: partFound = false;
496: for (Part part : inputParts) {
497: if (param.equals(part.getName())) {
498: partFound = true;
499: break;
500: }
501: }
502: // if not found, check output parts
503: if (!partFound) {
504: for (Part part : outputParts) {
505: if (param.equals(part.getName())) {
506: partFound = true;
507: break;
508: }
509: }
510: }
511: if (!partFound) {
512: break;
513: }
514: }
515: return partFound;
516: }
517: }
|