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:
012: import javax.jws.Oneway;
013: import javax.jws.WebParam;
014: import javax.jws.WebResult;
015: import javax.jws.soap.SOAPBinding;
016: import javax.xml.namespace.QName;
017: import javax.xml.ws.Holder;
018: import javax.xml.ws.WebFault;
019:
020: import com.sun.xml.bind.api.TypeReference;
021:
022: import org.objectweb.celtix.tools.common.ToolException;
023: import org.objectweb.celtix.tools.common.model.JavaMethod;
024: import org.objectweb.celtix.tools.common.model.JavaParameter;
025: import org.objectweb.celtix.tools.common.model.JavaType;
026: import org.objectweb.celtix.tools.common.model.WSDLException;
027: import org.objectweb.celtix.tools.common.model.WSDLModel;
028: import org.objectweb.celtix.tools.common.model.WSDLParameter;
029: import org.objectweb.celtix.tools.utils.AnnotationUtil;
030:
031: public class RPCMethodProcessor {
032:
033: private WSDLModel model;
034:
035: public RPCMethodProcessor(WSDLModel wmodel) {
036: model = wmodel;
037: }
038:
039: public void process(JavaMethod javaMethod, Method method) {
040: javaMethod.setSoapStyle(SOAPBinding.Style.RPC);
041: javaMethod.setWrapperStyle(true);
042: setMethodUse(javaMethod, method);
043:
044: String targetNS = model.getTargetNameSpace();
045: WSDLParameter request = new WSDLParameter();
046: request.setName(method.getName());
047: request.setStyle(JavaType.Style.IN);
048:
049: request.setTargetNamespace(targetNS);
050: javaMethod.addRequest(request);
051:
052: boolean isOneway = method.isAnnotationPresent(Oneway.class);
053: if (!isOneway) {
054: QName resQN = new QName(targetNS, method.getName()
055: + "Response");
056: TypeReference typeRef = new TypeReference(resQN, this
057: .getClass(), new Annotation[0]);
058: WSDLParameter response = new WSDLParameter();
059: response.setName(method.getName() + "Response");
060: response.setStyle(JavaType.Style.OUT);
061: javaMethod.addResponse(response);
062:
063: Class returnType = method.getReturnType();
064: String resultName = method.getName() + "Response";
065: String resultTNS = targetNS;
066: String resultPartName = null;
067: WebResult webResult = method.getAnnotation(WebResult.class);
068: boolean webResultHeader = false;
069: if (webResult != null) {
070: resultName = webResult.name().length() > 0 ? webResult
071: .name() : resultName;
072: resultPartName = webResult.partName().length() > 0 ? webResult
073: .partName()
074: : resultName;
075: resultTNS = webResult.targetNamespace().length() > 0 ? webResult
076: .targetNamespace()
077: : resultTNS;
078: webResultHeader = webResult.header();
079: }
080: QName resultQName = new QName(resultTNS, resultName);
081: if (returnType != null
082: && (!"void".equals(returnType.getName()))) {
083: // Annotation[] rann = method.getAnnotations();
084: Annotation[] rann = new Annotation[0];
085: typeRef = new TypeReference(resultQName, returnType,
086: rann);
087: JavaParameter returnParameter = new JavaParameter(
088: resultName, typeRef, JavaType.Style.OUT);
089: returnParameter.setPartName(resultPartName);
090: returnParameter.setTargetNamespace(resultTNS);
091: returnParameter.setHeader(webResultHeader);
092: response.addChildren(returnParameter);
093: }
094: }
095: // get WebParam
096: List<JavaParameter> paras = processWebPara(method);
097: for (JavaParameter jp : paras) {
098: request.addChildren(jp);
099: }
100: processExceptions(javaMethod, method);
101: }
102:
103: private void setMethodUse(JavaMethod javaMethod, Method method) {
104: SOAPBinding binding = method.getAnnotation(SOAPBinding.class);
105: if (binding != null) {
106: javaMethod.setSoapUse(binding.use());
107: } else {
108: javaMethod.setSoapUse(this .model.getUse());
109: }
110: }
111:
112: private List<JavaParameter> processWebPara(Method method) {
113: // processWebparam
114: Class<?>[] parameterTypes = method.getParameterTypes();
115: Type[] parameterGenTypes = method.getGenericParameterTypes();
116: Annotation[][] paraAnns = AnnotationUtil
117: .getPrivParameterAnnotations(method);
118: List<JavaParameter> paras = new ArrayList<JavaParameter>();
119: int i = 0;
120: for (Class clazzType : parameterTypes) {
121: String paraName = "arg" + i;
122: String partName;
123: String paraTNS = model.getTargetNameSpace();
124: Class clazz = clazzType;
125: boolean holder = isHolder(clazzType);
126: if (holder) {
127: clazz = getHoldedClass(clazzType, parameterGenTypes[i]);
128: }
129: for (Annotation anno : paraAnns[i]) {
130: if (anno.annotationType() == WebParam.class) {
131: WebParam webParam = (WebParam) anno;
132: paraName = webParam.name().length() > 0 ? webParam
133: .name() : paraName;
134: partName = webParam.partName().length() > 0 ? webParam
135: .partName()
136: : paraName;
137: paraTNS = webParam.targetNamespace().length() > 0 ? webParam
138: .targetNamespace()
139: : paraTNS;
140:
141: QName requestQN = new QName(paraTNS, paraName);
142: TypeReference typeref = new TypeReference(
143: requestQN, clazz, paraAnns[i]);
144: JavaParameter jp;
145: if (holder) {
146: if (webParam.mode() == WebParam.Mode.INOUT) {
147: jp = new JavaParameter(typeref.tagName
148: .getLocalPart(), typeref,
149: JavaType.Style.INOUT);
150: } else {
151: jp = new JavaParameter(typeref.tagName
152: .getLocalPart(), typeref,
153: JavaType.Style.OUT);
154: }
155: } else {
156: jp = new JavaParameter(typeref.tagName
157: .getLocalPart(), typeref,
158: JavaType.Style.IN);
159: }
160: jp.setName(paraName);
161: jp.setPartName(partName);
162: jp.setHeader(webParam.header());
163: jp.setTargetNamespace(paraTNS);
164: paras.add(jp);
165: }
166: }
167: i++;
168: }
169:
170: return paras;
171: }
172:
173: private void processExceptions(JavaMethod jmethod, Method method) {
174: for (Type exception : method.getGenericExceptionTypes()) {
175: if (RemoteException.class
176: .isAssignableFrom((Class) exception)) {
177: continue;
178: }
179: Annotation[] anns = null;
180: Class<?> exClass = (Class<?>) exception;
181: String exNameSpace = model.getTargetNameSpace();
182: String exName = exClass.getSimpleName();
183: Class exReturnType = null;
184: Method faultInfo = null;
185: try {
186: faultInfo = exClass.getMethod("getFaultInfo",
187: new Class[0]);
188: } catch (SecurityException e) {
189: throw new ToolException(e.getMessage(), e);
190: } catch (NoSuchMethodException e) {
191: throw new ToolException(e.getMessage(), e);
192: }
193:
194: if (faultInfo != null) {
195: WebFault wf = exClass.getAnnotation(WebFault.class);
196: exReturnType = faultInfo.getReturnType();
197: anns = faultInfo.getAnnotations();
198: if (wf.targetNamespace().length() > 0) {
199: exNameSpace = wf.targetNamespace();
200: }
201: exName = wf.name();
202: }
203:
204: QName exQName = new QName(exNameSpace, exName);
205: TypeReference tf = new TypeReference(exQName, exReturnType,
206: anns);
207: WSDLException wsdlEx = new WSDLException(exClass, tf);
208: jmethod.addWSDLException(wsdlEx);
209:
210: }
211: }
212:
213: private boolean isHolder(Class cType) {
214: return Holder.class.isAssignableFrom(cType);
215: // set the actual type argument of Holder in the TypeReference
216: }
217:
218: private Class getHoldedClass(Class holderClazz, Type type) {
219: ParameterizedType pt = (ParameterizedType) type;
220: return getClass(pt.getActualTypeArguments()[0]);
221: }
222:
223: private Class getClass(Type type) {
224: if (type instanceof Class) {
225: return (Class) type;
226: } else if (type instanceof GenericArrayType) {
227: GenericArrayType gt = (GenericArrayType) type;
228: Class compType = getClass(gt.getGenericComponentType());
229: return java.lang.reflect.Array.newInstance(compType, 0)
230: .getClass();
231: }
232: return Object.class;
233: }
234:
235: }
|