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.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.common.i18n.Message;
023: import org.objectweb.celtix.common.logging.LogUtils;
024: import org.objectweb.celtix.tools.common.ToolException;
025: import org.objectweb.celtix.tools.common.model.JavaMethod;
026: import org.objectweb.celtix.tools.common.model.JavaParameter;
027: import org.objectweb.celtix.tools.common.model.JavaType;
028: import org.objectweb.celtix.tools.common.model.WSDLException;
029: import org.objectweb.celtix.tools.common.model.WSDLModel;
030: import org.objectweb.celtix.tools.common.model.WSDLParameter;
031: import org.objectweb.celtix.tools.processors.java2.JavaToWSDLProcessor;
032: import org.objectweb.celtix.tools.utils.AnnotationUtil;
033:
034: public class DocBareMethodProcessor {
035: private static final Logger LOG = LogUtils
036: .getL7dLogger(JavaToWSDLProcessor.class);
037: private WSDLModel model;
038:
039: public DocBareMethodProcessor(WSDLModel wmodel) {
040: model = wmodel;
041: }
042:
043: public void processDocBare(JavaMethod javaMethod, Method method) {
044: boolean isHolder = false;
045: javaMethod.setSoapStyle(SOAPBinding.Style.DOCUMENT);
046: javaMethod.setWrapperStyle(false);
047: setMethodUse(javaMethod, method);
048:
049: // process webresult annotation
050: String resultName = method.getName() + "Response";
051: String resultTNS = model.getTargetNameSpace();
052: String resultPartName = null;
053:
054: WebResult webResult = method.getAnnotation(WebResult.class);
055: boolean webResultHeader = false;
056: if (webResult != null) {
057: resultName = webResult.name().length() > 0 ? webResult
058: .name() : resultName;
059: webResultHeader = webResult.header();
060: resultTNS = webResult.targetNamespace().length() > 0 ? webResult
061: .targetNamespace()
062: : resultTNS;
063: resultPartName = webResult.partName().length() > 0 ? webResult
064: .partName()
065: : resultName;
066: }
067:
068: // get return type class
069:
070: WSDLParameter response = new WSDLParameter();
071: // process return
072: Class returnType = method.getReturnType();
073: if (returnType != null && !"void".equals(returnType.getName())) {
074: QName resQN = new QName(resultTNS, resultName);
075: TypeReference typeRef = new TypeReference(resQN,
076: returnType, new Annotation[0]);
077: response.setName(method.getName() + "Response");
078: response.setStyle(JavaType.Style.OUT);
079: response.setTargetNamespace(resultTNS);
080: JavaParameter jp = new JavaParameter(resultName, typeRef,
081: JavaType.Style.OUT);
082: jp.setPartName(resultPartName);
083: jp.setTargetNamespace(resultTNS);
084: jp.setName(resultName);
085: jp.setHeader(webResultHeader);
086: response.addChildren(jp);
087: javaMethod.addResponse(response);
088: }
089:
090: // processWebparam
091: WSDLParameter request = new WSDLParameter();
092: request.setName(method.getName());
093: request.setStyle(JavaType.Style.IN);
094: javaMethod.addRequest(request);
095: List<JavaParameter> paras = processWebPara(method);
096: for (JavaParameter jp : paras) {
097: // requestWrapper.addWrapperChild(jp);
098: if (jp.getStyle() == JavaType.Style.IN) {
099: request.addChildren(jp);
100: }
101: if (jp.getStyle() == JavaType.Style.INOUT) {
102: request.addChildren(jp);
103: response.addChildren(jp);
104: isHolder = true;
105: }
106: if (jp.getStyle() == JavaType.Style.OUT) {
107: isHolder = true;
108: response.addChildren(jp);
109: }
110: }
111:
112: if ((returnType == null || "void".equals(returnType.getName()))
113: && isHolder) {
114: response.setName(method.getName() + "Response");
115: response.setStyle(JavaType.Style.OUT);
116: response.setTargetNamespace(resultTNS);
117: javaMethod.addResponse(response);
118: }
119: processExceptions(javaMethod, method);
120: }
121:
122: private void setMethodUse(JavaMethod javaMethod, Method method) {
123: SOAPBinding binding = method.getAnnotation(SOAPBinding.class);
124: if (binding != null) {
125: javaMethod.setSoapUse(binding.use());
126: } else {
127: javaMethod.setSoapUse(this .model.getUse());
128: }
129: }
130:
131: private List<JavaParameter> processWebPara(Method method) {
132: // processWebparam
133: Class<?>[] parameterTypes = method.getParameterTypes();
134: Type[] parameterGenTypes = method.getGenericParameterTypes();
135: Annotation[][] paraAnns = AnnotationUtil
136: .getPrivParameterAnnotations(method);
137: List<JavaParameter> paras = new ArrayList<JavaParameter>();
138: // DocumentBare_criteria defined jaxws spec 3.6.2.2
139: // criteria 1 - it must have at most one in or in/out non_header
140: boolean criteria1 = false;
141: // criteria 2 - if it has a return type other than void
142: // it must have no in/out or out non-header parameters
143: boolean criteria2 = true;
144: // criteria 3 - if it has a return type of void
145: // it must have at most one in/out or out-header parameter
146: boolean criteria3 = false;
147: // for doc_bare criteria3
148: int nonHeaderParamCount = 0;
149:
150: int i = 0;
151: for (Class clazzType : parameterTypes) {
152: String paraName = "arg" + i;
153: String partName;
154: String paraTNS = model.getTargetNameSpace();
155: Class clazz = clazzType;
156: boolean holder = isHolder(clazzType);
157: if (holder) {
158: clazz = getHoldedClass(clazzType, parameterGenTypes[i]);
159: }
160: for (Annotation anno : paraAnns[i]) {
161: if (anno.annotationType() == WebParam.class) {
162: WebParam webParam = (WebParam) anno;
163:
164: if (!webParam.header()
165: && (webParam.mode() == WebParam.Mode.IN || webParam
166: .mode() == WebParam.Mode.INOUT)) {
167: criteria1 = true;
168: }
169:
170: if (!method.getReturnType().getName()
171: .equalsIgnoreCase("void")
172: && !webParam.header()
173: && (webParam.mode() == WebParam.Mode.OUT || webParam
174: .mode() == WebParam.Mode.INOUT)) {
175: criteria2 = false;
176:
177: }
178:
179: if (method.getReturnType().getName()
180: .equalsIgnoreCase("void")
181: && !webParam.header()
182: && (webParam.mode() == WebParam.Mode.OUT || webParam
183: .mode() == WebParam.Mode.INOUT)) {
184: nonHeaderParamCount++;
185: }
186:
187: paraName = webParam.name().length() > 0 ? webParam
188: .name() : paraName;
189: partName = webParam.partName().length() > 0 ? webParam
190: .partName()
191: : paraName;
192: paraTNS = webParam.targetNamespace().length() > 0 ? webParam
193: .targetNamespace()
194: : paraTNS;
195:
196: QName requestQN = new QName(paraTNS, paraName);
197: TypeReference typeref = new TypeReference(
198: requestQN, clazz, paraAnns[i]);
199: JavaParameter jp;
200: if (holder) {
201: if (webParam.mode() == WebParam.Mode.INOUT) {
202: jp = new JavaParameter(typeref.tagName
203: .getLocalPart(), typeref,
204: JavaType.Style.INOUT);
205: } else {
206: jp = new JavaParameter(typeref.tagName
207: .getLocalPart(), typeref,
208: JavaType.Style.OUT);
209: }
210: } else {
211: jp = new JavaParameter(typeref.tagName
212: .getLocalPart(), typeref,
213: JavaType.Style.IN);
214: }
215: jp.setName(paraName);
216: jp.setPartName(partName);
217: jp.setHeader(webParam.header());
218: jp.setTargetNamespace(paraTNS);
219: paras.add(jp);
220: }
221: }
222: i++;
223: }
224: if (!criteria1) {
225: Message message = new Message("DOC_BARE_METHOD_CRITERIA1",
226: LOG);
227: throw new ToolException(message);
228: }
229: if (!criteria2) {
230: Message message = new Message("DOC_BARE_METHOD_CRITERIA2",
231: LOG);
232: throw new ToolException(message);
233: }
234: criteria3 = nonHeaderParamCount <= 1 ? true : false;
235: if (!criteria3) {
236: Message message = new Message("DOC_BARE_METHOD_CRITERIA3",
237: LOG);
238: throw new ToolException(message);
239: }
240: return paras;
241: }
242:
243: private void processExceptions(JavaMethod jmethod, Method method) {
244: for (Type exception : method.getGenericExceptionTypes()) {
245: if (RemoteException.class
246: .isAssignableFrom((Class) exception)) {
247: continue;
248: }
249: Annotation[] anns = null;
250: Class<?> exClass = (Class<?>) exception;
251: String exNameSpace = model.getTargetNameSpace();
252: String exName = exClass.getSimpleName();
253: Class exReturnType = null;
254: Method faultInfo = null;
255: try {
256: faultInfo = exClass.getMethod("getFaultInfo",
257: new Class[0]);
258: } catch (SecurityException e) {
259: throw new ToolException(e.getMessage(), e);
260: } catch (NoSuchMethodException e) {
261: throw new ToolException(e.getMessage(), e);
262: }
263:
264: if (faultInfo != null) {
265: WebFault wf = exClass.getAnnotation(WebFault.class);
266: exReturnType = faultInfo.getReturnType();
267: anns = faultInfo.getAnnotations();
268: if (wf.targetNamespace().length() > 0) {
269: exNameSpace = wf.targetNamespace();
270: }
271: exName = wf.name();
272: }
273:
274: QName exQName = new QName(exNameSpace, exName);
275: TypeReference tf = new TypeReference(exQName, exReturnType,
276: anns);
277: WSDLException wsdlEx = new WSDLException(exClass, tf);
278:
279: jmethod.addWSDLException(wsdlEx);
280:
281: }
282: }
283:
284: private boolean isHolder(Class cType) {
285: return Holder.class.isAssignableFrom(cType);
286: // set the actual type argument of Holder in the TypeReference
287: }
288:
289: private Class getHoldedClass(Class holderClazz, Type type) {
290: ParameterizedType pt = (ParameterizedType) type;
291: return getClass(pt.getActualTypeArguments()[0]);
292: }
293:
294: private Class getClass(Type type) {
295: if (type instanceof Class) {
296: return (Class) type;
297: } else if (type instanceof GenericArrayType) {
298: GenericArrayType gt = (GenericArrayType) type;
299: Class compType = getClass(gt.getGenericComponentType());
300: return java.lang.reflect.Array.newInstance(compType, 0)
301: .getClass();
302: }
303: return Object.class;
304: }
305:
306: }
|