001: package org.objectweb.celtix.tools.processors.java2.internal;
002:
003: import java.lang.reflect.Method;
004: import java.lang.reflect.Modifier;
005: import java.util.HashMap;
006: import java.util.Map;
007: import java.util.logging.Logger;
008:
009: import javax.jws.Oneway;
010: import javax.jws.WebMethod;
011: import javax.jws.WebService;
012: import javax.jws.soap.SOAPBinding;
013: import javax.wsdl.OperationType;
014:
015: import org.objectweb.celtix.common.i18n.Message;
016: import org.objectweb.celtix.common.logging.LogUtils;
017: import org.objectweb.celtix.tools.common.ProcessorEnvironment;
018: import org.objectweb.celtix.tools.common.ToolConstants;
019: import org.objectweb.celtix.tools.common.ToolException;
020: import org.objectweb.celtix.tools.common.WSDLConstants;
021: import org.objectweb.celtix.tools.common.model.JavaMethod;
022: import org.objectweb.celtix.tools.common.model.WSDLModel;
023: import org.objectweb.celtix.tools.processors.java2.JavaToWSDLProcessor;
024: import org.objectweb.celtix.tools.utils.AnnotationUtil;
025: import org.objectweb.celtix.tools.utils.URIParserUtil;
026:
027: public class ClassProcessor {
028: private static final Logger LOG = LogUtils
029: .getL7dLogger(JavaToWSDLProcessor.class);
030:
031: Class seiClass;
032:
033: WSDLModel model;
034:
035: Map<Class, Boolean> useWebMethodClasses = new HashMap<Class, Boolean>();
036:
037: private final ProcessorEnvironment env;
038:
039: public ClassProcessor(Class clz, ProcessorEnvironment penv) {
040: seiClass = clz;
041: env = penv;
042: }
043:
044: public void process(WSDLModel wmodel) {
045: model = wmodel;
046: populateWSDLInfo(seiClass);
047: checkWebMethodUseClass(seiClass);
048: for (Method method : seiClass.getMethods()) {
049: if (method.getDeclaringClass().equals(Object.class)
050: || !isOperationToGen(method, seiClass)) {
051: continue;
052: }
053: processMethod(wmodel, method);
054: }
055: }
056:
057: private void processMethod(WSDLModel wmodel, Method method) {
058: if (!Modifier.isPublic(method.getModifiers())) {
059: return;
060: }
061:
062: WebMethod webMethod = AnnotationUtil.getPrivMethodAnnotation(
063: method, WebMethod.class);
064: if (webMethod == null
065: || (webMethod != null && webMethod.exclude())) {
066: return;
067: }
068:
069: JavaMethod javaMethod = new JavaMethod();
070:
071: // rule 3.5
072:
073: String operationName = method.getName();
074:
075: if (!method.getDeclaringClass().equals(seiClass)) {
076: try {
077: Method tmp = seiClass.getMethod(method.getName(),
078: (Class[]) method.getParameterTypes());
079: operationName = tmp.getName();
080: } catch (NoSuchMethodException e) {
081: throw new ToolException(e.getMessage(), e);
082: }
083: }
084:
085: if (webMethod != null) {
086: operationName = webMethod.operationName().length() > 0 ? webMethod
087: .operationName()
088: : operationName;
089: }
090:
091: javaMethod.setName(operationName);
092: javaMethod.setSoapAction(webMethod.action());
093:
094: if (isAsynMethod(method)) {
095: return;
096: }
097:
098: if (isOneWayMethod(method)) {
099: javaMethod.setStyle(OperationType.ONE_WAY);
100: } else {
101: javaMethod.setStyle(OperationType.REQUEST_RESPONSE);
102: }
103:
104: switch (getMethodType(method)) {
105: case WSDLConstants.DOC_BARE:
106: DocBareMethodProcessor docBareProcessor = new DocBareMethodProcessor(
107: model);
108: docBareProcessor.processDocBare(javaMethod, method);
109: break;
110: case WSDLConstants.DOC_WRAPPED:
111: DocWrapperMethodProcessor docWrapperProcessor = new DocWrapperMethodProcessor(
112: model);
113: docWrapperProcessor.process(javaMethod, method);
114: break;
115: case WSDLConstants.RPC_WRAPPED:
116: RPCMethodProcessor rpcMethodProcessor = new RPCMethodProcessor(
117: model);
118: rpcMethodProcessor.process(javaMethod, method);
119: break;
120: default:
121: Message message = new Message(
122: "SOAPUSESTYLE_PARAMETERSTYLE_ERROR", LOG, method
123: .getName());
124: throw new ToolException(message);
125: }
126: wmodel.addJavaMethod(javaMethod);
127: }
128:
129: private int getMethodType(Method method) {
130: SOAPBinding binding = method.getAnnotation(SOAPBinding.class);
131: int result = WSDLConstants.ERORR_STYLE_USE;
132: if (binding != null) {
133: if (binding.style() == SOAPBinding.Style.RPC) {
134: result = WSDLConstants.RPC_WRAPPED;
135: }
136: if (binding.style() == SOAPBinding.Style.DOCUMENT
137: && binding.parameterStyle() == SOAPBinding.ParameterStyle.WRAPPED) {
138: result = WSDLConstants.DOC_WRAPPED;
139: }
140: if (binding.style() == SOAPBinding.Style.DOCUMENT
141: && binding.parameterStyle() == SOAPBinding.ParameterStyle.BARE) {
142: result = WSDLConstants.DOC_BARE;
143: }
144:
145: } else {
146: if (model.isRPC() && model.isWrapped()) {
147: result = WSDLConstants.RPC_WRAPPED;
148: }
149: if (model.isDocLit() && model.isWrapped()) {
150: result = WSDLConstants.DOC_WRAPPED;
151: }
152: if (model.isDocLit() && !model.isWrapped()) {
153: result = WSDLConstants.DOC_BARE;
154: }
155: }
156: return result;
157: }
158:
159: private boolean isOperationToGen(Method method, Class clazz) {
160: if (clazz.isInterface()) {
161: return true;
162: }
163: Class declareClass = method.getDeclaringClass();
164: WebMethod webMethod = AnnotationUtil.getPrivMethodAnnotation(
165: method, WebMethod.class);
166: if (webMethod != null && !webMethod.exclude()) {
167: return true;
168: }
169: if (AnnotationUtil.getPrivClassAnnotation(declareClass,
170: WebService.class) != null
171: && !useWebMethodClasses.get(declareClass)) {
172: return true;
173: }
174: return false;
175:
176: }
177:
178: // for rule 3.3
179: private void checkWebMethodUseClass(Class clz) {
180: if (clz == null) {
181: return;
182: }
183: if (clz.isInterface()) {
184: useWebMethodClasses.put(clz, false);
185: } else {
186: WebMethod webMethod;
187: boolean existWebMethod = false;
188: for (Method method : clz.getMethods()) {
189: if (!method.getDeclaringClass().equals(seiClass)) {
190: continue;
191: }
192: webMethod = AnnotationUtil.getPrivMethodAnnotation(
193: method, WebMethod.class);
194: if (webMethod != null && !webMethod.exclude()) {
195: existWebMethod = true;
196: break;
197: }
198: }
199: useWebMethodClasses.put(clz, existWebMethod);
200: }
201: checkWebMethodUseClass(clz.getSuperclass());
202: }
203:
204: private void populateWSDLInfo(Class clazz) {
205: WebService webService = AnnotationUtil.getPrivClassAnnotation(
206: clazz, WebService.class);
207: if (webService == null) {
208: Message message = new Message(
209: "SEI_CLASS_NO_WEBSERVICE_ANNOTATED", LOG);
210: throw new ToolException(message);
211:
212: }
213: if (webService.endpointInterface().length() > 0) {
214: clazz = AnnotationUtil.loadClass(webService
215: .endpointInterface(), clazz.getClassLoader());
216: webService = AnnotationUtil.getPrivClassAnnotation(clazz,
217: WebService.class);
218: if (webService == null) {
219: Message message = new Message(
220: "SEI_INTERFACE_NO_WEBSERVICE_ANNOTATED", LOG);
221: throw new ToolException(message);
222: }
223: }
224:
225: String portTypeName = clazz.getSimpleName() + "PortType";
226: if (webService.name().length() > 0) {
227: portTypeName = webService.name();
228: }
229:
230: model.setPortTypeName(portTypeName);
231:
232: String portName = clazz.getSimpleName() + "Port";
233:
234: if (webService.portName().length() > 0) {
235: portName = webService.portName();
236: } else if (webService.name().length() > 0) {
237: portName = webService.name() + "Port";
238:
239: }
240: model.setPortName(portName);
241:
242: String serviceName = clazz.getSimpleName() + "Service";
243: if (env.optionSet(ToolConstants.CFG_SERVICENAME)) {
244: serviceName = (String) env
245: .get(ToolConstants.CFG_SERVICENAME);
246: } else {
247: if (webService.serviceName().length() > 0) {
248: serviceName = webService.serviceName();
249: }
250: }
251: model.setServiceName(serviceName);
252:
253: String packageName = "";
254: if (clazz.getPackage() != null) {
255: packageName = clazz.getPackage().getName();
256: }
257: model.setPackageName(packageName);
258:
259: String targetNamespace = URIParserUtil
260: .getNamespace(packageName);
261: if (env.optionSet(ToolConstants.CFG_TNS)) {
262: targetNamespace = (String) env.get(ToolConstants.CFG_TNS);
263: } else if (webService.targetNamespace().length() > 0) {
264: targetNamespace = webService.targetNamespace();
265: } else if (targetNamespace == null) {
266: Message message = new Message("SEI_CLASS_HASNO_PACKAGE",
267: LOG);
268: throw new ToolException(message);
269: }
270:
271: model.setTargetNameSpace(targetNamespace);
272: String wsdlLocation = webService.wsdlLocation();
273: model.setWsdllocation(wsdlLocation);
274:
275: javax.jws.soap.SOAPBinding soapBinding = AnnotationUtil
276: .getPrivClassAnnotation(clazz,
277: javax.jws.soap.SOAPBinding.class);
278: if (soapBinding != null) {
279: model.setStyle(soapBinding.style());
280: model.setUse(soapBinding.use());
281: model.setPrameterStyle(soapBinding.parameterStyle());
282: }
283:
284: }
285:
286: private boolean isAsynMethod(Method method) {
287: return method.getReturnType().equals(
288: java.util.concurrent.Future.class)
289: && method.getName().endsWith("Async")
290: || method.getReturnType().equals(
291: javax.xml.ws.Response.class)
292: && method.getName().endsWith("Async");
293:
294: }
295:
296: private boolean isOneWayMethod(Method method) {
297: return method.isAnnotationPresent(Oneway.class);
298: }
299:
300: }
|