/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 *******************************************************************************/ package org.ebayopensource.turmeric.tools.codegen.builders; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.List; import java.util.logging.Logger; import javax.xml.ws.AsyncHandler; import org.ebayopensource.turmeric.runtime.common.impl.utils.LogManager; import org.ebayopensource.turmeric.tools.codegen.CodeGenContext; import org.ebayopensource.turmeric.tools.codegen.JTypeTable; import org.ebayopensource.turmeric.tools.codegen.SourceGenerator; import org.ebayopensource.turmeric.tools.codegen.exception.CodeGenFailedException; import org.ebayopensource.turmeric.tools.codegen.util.CodeGenConstants; import org.ebayopensource.turmeric.tools.codegen.util.CodeGenUtil; import org.ebayopensource.turmeric.tools.codegen.util.CodeModelUtil; import org.ebayopensource.turmeric.tools.codegen.util.IntrospectUtil; import com.sun.codemodel.JClass; import com.sun.codemodel.JClassAlreadyExistsException; import com.sun.codemodel.JCodeModel; import com.sun.codemodel.JDefinedClass; import com.sun.codemodel.JMethod; import com.sun.codemodel.JMod; public class AsyncServiceInterfaceGenerator extends BaseCodeGenerator implements SourceGenerator { private static final String ASYNC_METHOD_SUFFIX = "Async"; private static final String RESPONSE_FQN = "javax.xml.ws.Response"; private static final String FUTURE_FQN = "java.util.concurrent.Future"; private static Logger s_logger = LogManager.getInstance(AsyncServiceInterfaceGenerator.class); private static AsyncServiceInterfaceGenerator s_extentedServiceInterfaceGenerator = new AsyncServiceInterfaceGenerator(); private AsyncServiceInterfaceGenerator() {} public static AsyncServiceInterfaceGenerator getInstance() { return s_extentedServiceInterfaceGenerator; } @SuppressWarnings("unused") private Logger getLogger() { return s_logger; } public boolean continueOnError() { return true; } /** * @param args */ public void generate(CodeGenContext codeGenCtx) throws CodeGenFailedException { JTypeTable jTypeTable = codeGenCtx.getJTypeTable(); JCodeModel jCodeModel = new JCodeModel(); Class<?> serviceInterfaceClass = jTypeTable.getClazz(); if(serviceInterfaceClass == null) return; String qualifiedInterfaceName = codeGenCtx.getServiceInterfaceClassName(); String asyncInterfaceClassName = getAsyncInterfaceClassName(qualifiedInterfaceName); String asyncInterfacePackage = CodeGenUtil.getPackageName(asyncInterfaceClassName); String asyncInterfaceName = CodeGenUtil.getJavaClassName(asyncInterfaceClassName); JDefinedClass asyncInterface = null; try { asyncInterface = jCodeModel._package(asyncInterfacePackage)._interface(JMod.PUBLIC,asyncInterfaceName); // interface extends another interface JDefinedClass proxyClass = asyncInterface._implements(serviceInterfaceClass); implementMethods(proxyClass,serviceInterfaceClass, jCodeModel,codeGenCtx); //generateAsyncInterfaceJavaFile(codeGenCtx, asyncInterface, codeGenCtx.getAsyncJavaSrcDestLocation()); generateJavaFile(codeGenCtx, proxyClass, CodeGenConstants.CLIENT_GEN_FOLDER); //if (codeGenCtx.getInputOptions().isNoCompile() == false) { compileJavaFilesNoException( codeGenCtx.getGeneratedJavaFiles(), codeGenCtx.getBinLocation()); //} codeGenCtx.setServiceAsyncInterfaceClassName(asyncInterfaceClassName); } catch (JClassAlreadyExistsException e) { // e.printStackTrace(); } } private void implementMethods(JDefinedClass proxyClass, Class<?> serviceInterfaceClass, JCodeModel jCodeModel, CodeGenContext codeGenCtx){ List<Method> methods = IntrospectUtil.getMethods(serviceInterfaceClass); for (Method method : methods) { //ArrayList parameters = new ArrayList(); String methodName = method.getName(); String asyncMethodName = methodName.concat(ASYNC_METHOD_SUFFIX); Type returnType = method.getGenericReturnType(); if(!returnType.toString().equals("void")){ generateAsyncMethodsWithReturnType(asyncMethodName, method, proxyClass, jCodeModel); } else { generateAsyncMethodsNoReturnType(asyncMethodName, method, proxyClass, jCodeModel); } } CodeModelUtil codeModelUtil = CodeModelUtil.getInstance(); if(codeGenCtx.isGeneratePollMethod()) codeModelUtil.generatePollMethod(jCodeModel, proxyClass); } public void generateAsyncMethodsWithReturnType(String asyncMethodName, Method method, JDefinedClass proxyClass, JCodeModel jCodeModel){ generateAsyncOperationReturnTypeWithHandler(asyncMethodName, method, proxyClass, jCodeModel); generateAsyncOperationReturnTypeNoHandler(asyncMethodName, method, proxyClass, jCodeModel); } public void generateAsyncMethodsNoReturnType(String asyncMethodName, Method method, JDefinedClass proxyClass, JCodeModel jCodeModel){ generateAsyncOperationNoReturnTypeWithHandler(asyncMethodName, method, proxyClass, jCodeModel); generateAsyncOperationNoReturnTypeNoHandler(asyncMethodName, method, proxyClass, jCodeModel); } public void generateAsyncOperationNoReturnTypeWithHandler(String asyncMethodName, Method method, JDefinedClass proxyClass, JCodeModel jCodeModel){ //Class returnType = method.getReturnType(); JClass jClass = getResponseClass(jCodeModel,FUTURE_FQN); JMethod asyncMethod = addMethodAsync(proxyClass, asyncMethodName, JMod.PUBLIC, jClass, jCodeModel); addParameterValues(method, asyncMethod,jCodeModel);; JClass asyncClass = jCodeModel.ref(AsyncHandler.class).narrow(jCodeModel.wildcard()); asyncMethod.param(asyncClass, "handler"); } public void generateAsyncOperationNoReturnTypeNoHandler(String asyncMethodName, Method method, JDefinedClass proxyClass, JCodeModel jCodeModel){ //Class returnType = method.getReturnType(); JClass jClass = getResponseClass(jCodeModel,RESPONSE_FQN); JMethod asyncMethod = addMethodAsync(proxyClass, asyncMethodName, JMod.PUBLIC, jClass, jCodeModel); addParameterValues(method, asyncMethod, jCodeModel); } public void generateAsyncOperationReturnTypeWithHandler(String asyncMethodName, Method method, JDefinedClass proxyClass, JCodeModel jCodeModel){ Class<?> returnType = method.getReturnType(); JClass jClass = getResponseClass(jCodeModel,FUTURE_FQN); JMethod asyncMethod = addMethodAsync(proxyClass, asyncMethodName, JMod.PUBLIC, jClass, jCodeModel); addParameterValues(method, asyncMethod, jCodeModel); //JClass asyncHandler = jCodeModel.ref(AsyncHandler.class).narrow(returnType); JClass asyncHandler = jCodeModel.ref(AsyncHandler.class).narrow(getJClass(returnType, jCodeModel)); asyncMethod.param(asyncHandler, "handler"); } public void generateAsyncOperationReturnTypeNoHandler(String asyncMethodName, Method method, JDefinedClass proxyClass, JCodeModel jCodeModel){ Class<?> returnType = method.getReturnType(); //JClass jClass = jCodeModel.ref(RESPONSE_FQN).narrow(returnType); JClass jClass = jCodeModel.ref(RESPONSE_FQN).narrow(getJClass(returnType, jCodeModel)); //jCodeModel.ref(RESPONSE_FQN).narrow(returnType); JMethod asyncMethod = addMethodAsync(proxyClass, asyncMethodName, JMod.PUBLIC, jClass, jCodeModel); addParameterValues(method, asyncMethod, jCodeModel); } /* * Add the paramter values */ public void addParameterValues(Method method, JMethod jMethod, JCodeModel jCodeModel){ Class<?> paramValues[] = method.getParameterTypes(); if (paramValues != null && paramValues.length > 0) { for(int i=0; i<paramValues.length; i++){ String className = paramValues[i].getName(); // String paramClass = className.concat(".class"); JClass jClassParam = jCodeModel.ref(className); jMethod.param(jClassParam, "param"+i); } } } /* * Generates the type object with unknown * Foe example, the following method constructs like Response<?> */ private JClass getResponseClass(JCodeModel jCodeModel, String fullyQualifiedClassName){ return jCodeModel.ref(fullyQualifiedClassName).narrow(jCodeModel.wildcard()); } public String getFilePath(String serviceAdminName, String interfaceName) { return null; } protected JMethod addMethodAsync( JDefinedClass jDefinedClass, String methodName, int methodModifiers, JClass classReturnType, JCodeModel jCodeModel) { JMethod jCodeGenMethod = jDefinedClass.method(methodModifiers, classReturnType, methodName); return jCodeGenMethod; } @SuppressWarnings("unused") private void inheritFromBaseClasses( JDefinedClass serviceProxyClass, Class<?> serviceInterfaceClass, JCodeModel jCodeModel) throws CodeGenFailedException { JClass serviceInterfaceJClazz = getJClass(serviceInterfaceClass, jCodeModel); extend(serviceProxyClass, serviceInterfaceJClazz); } }