001: package org.objectweb.celtix.tools.processors.java2.internal;
002:
003: import java.lang.annotation.Annotation;
004: import java.lang.reflect.GenericArrayType;
005: import java.lang.reflect.Method;
006: import java.lang.reflect.ParameterizedType;
007: import java.lang.reflect.Type;
008: import java.rmi.RemoteException;
009: import java.util.ArrayList;
010: import java.util.List;
011: import java.util.logging.Logger;
012:
013: import javax.jws.Oneway;
014: import javax.jws.WebParam;
015: import javax.jws.WebResult;
016: import javax.jws.soap.SOAPBinding;
017: import javax.xml.namespace.QName;
018: import javax.xml.ws.Holder;
019: import javax.xml.ws.RequestWrapper;
020: import javax.xml.ws.ResponseWrapper;
021: import javax.xml.ws.WebFault;
022:
023: import com.sun.xml.bind.api.TypeReference;
024:
025: import org.objectweb.celtix.common.i18n.Message;
026: import org.objectweb.celtix.common.logging.LogUtils;
027: import org.objectweb.celtix.tools.common.ToolException;
028: import org.objectweb.celtix.tools.common.model.JavaMethod;
029: import org.objectweb.celtix.tools.common.model.JavaParameter;
030: import org.objectweb.celtix.tools.common.model.JavaType;
031: import org.objectweb.celtix.tools.common.model.WSDLException;
032: import org.objectweb.celtix.tools.common.model.WSDLModel;
033: import org.objectweb.celtix.tools.common.model.WSDLParameter;
034: import org.objectweb.celtix.tools.processors.java2.JavaToWSDLProcessor;
035: import org.objectweb.celtix.tools.utils.AnnotationUtil;
036:
037: public class DocWrapperMethodProcessor {
038: private static final Logger LOG = LogUtils
039: .getL7dLogger(JavaToWSDLProcessor.class);
040: private WSDLModel model;
041:
042: public DocWrapperMethodProcessor(WSDLModel wmodel) {
043: model = wmodel;
044: }
045:
046: public void process(JavaMethod javaMethod, Method method) {
047: javaMethod.setSoapStyle(SOAPBinding.Style.DOCUMENT);
048: javaMethod.setWrapperStyle(true);
049: setMethodUse(javaMethod, method);
050:
051: // process request
052: RequestWrapper reqWrapper = method
053: .getAnnotation(RequestWrapper.class);
054: String reqClassName = "";
055: String reqName = method.getName();
056: String reqNS = model.getTargetNameSpace();
057: if (reqWrapper != null) {
058: reqClassName = reqWrapper.className().length() > 0 ? reqWrapper
059: .className()
060: : reqClassName;
061: reqName = reqWrapper.localName().length() > 0 ? reqWrapper
062: .localName() : reqName;
063: reqNS = reqWrapper.targetNamespace().length() > 0 ? reqWrapper
064: .targetNamespace()
065: : reqNS;
066: } else {
067: reqClassName = model.getPackageName() + ".types."
068: + AnnotationUtil.capitalize(method.getName());
069: }
070:
071: Class reqClass = null;
072: try {
073: reqClass = AnnotationUtil.loadClass(reqClassName, method
074: .getDeclaringClass().getClassLoader());
075: } catch (Exception e) {
076:
077: Message msg = new Message("LOAD_CLASS_ERROR", LOG,
078: reqClassName);
079: throw new ToolException(msg, e);
080: }
081: QName reqQN = new QName(reqNS, reqName);
082: TypeReference typeRef = new TypeReference(reqQN, reqClass,
083: new Annotation[0]);
084: WSDLParameter request = new WSDLParameter(reqName, typeRef,
085: JavaType.Style.IN);
086: request.setTargetNamespace(reqNS);
087: javaMethod.addRequest(request);
088:
089: WSDLParameter response = null;
090: if (!isOneWayMethod(method)) {
091: // process response
092: ResponseWrapper resWrapper = method
093: .getAnnotation(ResponseWrapper.class);
094: String resClassName = "";
095: // rule 3.5 suffix -"Response"
096: String resName = method.getName() + "Response";
097: String resNS = model.getTargetNameSpace();
098: if (resWrapper != null) {
099: resClassName = resWrapper.className();
100: resName = resWrapper.localName().length() > 0 ? resWrapper
101: .localName()
102: : resName;
103: resNS = resWrapper.targetNamespace().length() > 0 ? resWrapper
104: .targetNamespace()
105: : resNS;
106: } else {
107: resClassName = model.getPackageName() + ".types."
108: + AnnotationUtil.capitalize(method.getName())
109: + "Response";
110: }
111: Class resClass = null;
112: QName resQN = new QName(resNS, resName);
113: try {
114: resClass = AnnotationUtil.loadClass(resClassName,
115: method.getDeclaringClass().getClassLoader());
116: } catch (Exception e) {
117: Message msg = new Message("LOAD_CLASS_ERROR", LOG,
118: resClassName);
119: throw new ToolException(msg, e);
120: }
121: typeRef = new TypeReference(resQN, resClass,
122: new Annotation[0]);
123: response = new WSDLParameter(resName, typeRef,
124: JavaType.Style.OUT);
125: response.setTargetNamespace(resNS);
126: javaMethod.addResponse(response);
127: WebResult webResult = method.getAnnotation(WebResult.class);
128: JavaParameter returnParameter = getReturnParameter(
129: webResult, method);
130: if (returnParameter != null) {
131: response.addChildren(returnParameter);
132: }
133: }
134: List<JavaParameter> paras = processWebPara(method);
135: for (JavaParameter jp : paras) {
136: if (jp.getStyle() == JavaType.Style.IN) {
137: request.addChildren(jp);
138: } else {
139: request.addChildren(jp);
140: }
141: }
142:
143: processExceptions(javaMethod, method);
144: }
145:
146: private void setMethodUse(JavaMethod javaMethod, Method method) {
147: SOAPBinding binding = method.getAnnotation(SOAPBinding.class);
148: if (binding != null) {
149: javaMethod.setSoapUse(binding.use());
150: } else {
151: javaMethod.setSoapUse(this .model.getUse());
152: }
153: }
154:
155: private List<JavaParameter> processWebPara(Method method) {
156: // processWebparam
157: Class<?>[] parameterTypes = method.getParameterTypes();
158: Type[] parameterGenTypes = method.getGenericParameterTypes();
159: Annotation[][] paraAnns = AnnotationUtil
160: .getPrivParameterAnnotations(method);
161: List<JavaParameter> paras = new ArrayList<JavaParameter>();
162: int i = 0;
163: for (Class clazzType : parameterTypes) {
164: String paraName = "arg" + i;
165: String partName;
166: String paraTNS = model.getTargetNameSpace();
167: Class clazz = clazzType;
168: boolean holder = isHolder(clazzType);
169: if (holder) {
170: clazz = getHoldedClass(clazzType, parameterGenTypes[i]);
171: }
172: for (Annotation anno : paraAnns[i]) {
173: if (anno.annotationType() == WebParam.class) {
174: WebParam webParam = (WebParam) anno;
175: paraName = webParam.name().length() > 0 ? webParam
176: .name() : paraName;
177: partName = webParam.partName().length() > 0 ? webParam
178: .partName()
179: : paraName;
180: paraTNS = webParam.targetNamespace().length() > 0 ? webParam
181: .targetNamespace()
182: : paraTNS;
183:
184: QName requestQN = new QName(paraTNS, paraName);
185: TypeReference typeref = new TypeReference(
186: requestQN, clazz, paraAnns[i]);
187: JavaParameter jp;
188: if (holder) {
189: if (webParam.mode() == WebParam.Mode.INOUT) {
190: jp = new JavaParameter(typeref.tagName
191: .getLocalPart(), typeref,
192: JavaType.Style.INOUT);
193: } else {
194: jp = new JavaParameter(typeref.tagName
195: .getLocalPart(), typeref,
196: JavaType.Style.OUT);
197: }
198: } else {
199: jp = new JavaParameter(typeref.tagName
200: .getLocalPart(), typeref,
201: JavaType.Style.IN);
202: }
203: jp.setName(paraName);
204: jp.setPartName(partName);
205: jp.setHeader(webParam.header());
206: jp.setTargetNamespace(paraTNS);
207: paras.add(jp);
208: }
209: }
210: i++;
211: }
212:
213: return paras;
214: }
215:
216: private void processExceptions(JavaMethod jmethod, Method method) {
217: for (Type exception : method.getGenericExceptionTypes()) {
218: if (RemoteException.class
219: .isAssignableFrom((Class) exception)) {
220: continue;
221: }
222: Annotation[] anns = null;
223: Class<?> exClass = (Class<?>) exception;
224: String exNameSpace = model.getTargetNameSpace();
225: String exName = exClass.getSimpleName();
226: Class exReturnType = null;
227: Method faultInfo = null;
228: try {
229: faultInfo = exClass.getMethod("getFaultInfo",
230: new Class[0]);
231: } catch (SecurityException e) {
232: throw new ToolException(e.getMessage(), e);
233: } catch (NoSuchMethodException e) {
234: throw new ToolException(e.getMessage(), e);
235: }
236:
237: if (faultInfo != null) {
238: WebFault wf = exClass.getAnnotation(WebFault.class);
239: exReturnType = faultInfo.getReturnType();
240: anns = faultInfo.getAnnotations();
241: if (wf.targetNamespace().length() > 0) {
242: exNameSpace = wf.targetNamespace();
243: }
244: exName = wf.name();
245: }
246:
247: QName exQName = new QName(exNameSpace, exName);
248: TypeReference tf = new TypeReference(exQName, exReturnType,
249: anns);
250: WSDLException wsdlEx = new WSDLException(exClass, tf);
251:
252: jmethod.addWSDLException(wsdlEx);
253:
254: }
255: }
256:
257: private boolean isHolder(Class cType) {
258: return Holder.class.isAssignableFrom(cType);
259: // set the actual type argument of Holder in the TypeReference
260: }
261:
262: private Class getHoldedClass(Class holderClazz, Type type) {
263: ParameterizedType pt = (ParameterizedType) type;
264: return getClass(pt.getActualTypeArguments()[0]);
265: }
266:
267: private Class getClass(Type type) {
268: if (type instanceof Class) {
269: return (Class) type;
270: } else if (type instanceof GenericArrayType) {
271: GenericArrayType gt = (GenericArrayType) type;
272: Class compType = getClass(gt.getGenericComponentType());
273: return java.lang.reflect.Array.newInstance(compType, 0)
274: .getClass();
275: }
276: return Object.class;
277: }
278:
279: private boolean isOneWayMethod(Method method) {
280: return method.isAnnotationPresent(Oneway.class);
281: }
282:
283: private JavaParameter getReturnParameter(WebResult webResult,
284: Method method) {
285: boolean isHeader = false;
286: String resultName = "Return";
287: String resultTNS = model.getTargetNameSpace();
288: JavaParameter jpara = null;
289: QName resultQName = null;
290: if (webResult != null) {
291: resultName = webResult.name().length() > 0
292: && webResult.partName().length() > 0 ? webResult
293: .partName() : resultName;
294: resultName = webResult.name().length() > 0 ? webResult
295: .name() : resultName;
296: resultName = webResult.partName().length() > 0 ? webResult
297: .partName() : resultName;
298: resultTNS = webResult.targetNamespace().length() > 0 ? webResult
299: .targetNamespace()
300: : resultTNS;
301: isHeader = webResult.header();
302: }
303: resultQName = new QName(resultTNS, resultName);
304: Class returnType = method.getReturnType();
305: if (resultQName != null && !isOneWayMethod(method)
306: && (returnType != null)
307: && (!"void".equals(returnType.getName()))) {
308: // Annotation[] annotations = method.getAnnotations();
309: Annotation[] annotations = new Annotation[0];
310: if (resultQName.getLocalPart() != null) {
311: TypeReference rTypeReference = new TypeReference(
312: resultQName, returnType, annotations);
313: jpara = new JavaParameter();
314: jpara.setName(method.getName() + "Response");
315: jpara.setTypeReference(rTypeReference);
316: jpara.setStyle(JavaType.Style.OUT);
317: jpara.setHeader(isHeader);
318: }
319: }
320: return jpara;
321: }
322:
323: }
|