/*******************************************************************************
* 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;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.wsdl.Definition;
import org.ebayopensource.turmeric.runtime.codegen.common.ImplClassDefType;
import org.ebayopensource.turmeric.runtime.codegen.common.InterfaceClassDefType;
import org.ebayopensource.turmeric.runtime.codegen.common.InterfaceDefType;
import org.ebayopensource.turmeric.runtime.codegen.common.InterfaceType;
import org.ebayopensource.turmeric.runtime.codegen.common.OpNameCemcMappingType;
import org.ebayopensource.turmeric.runtime.codegen.common.OpNameToCemcMappingList;
import org.ebayopensource.turmeric.runtime.codegen.common.ServiceCodeGenDefType;
import org.ebayopensource.turmeric.runtime.common.impl.utils.LogManager;
import org.ebayopensource.turmeric.tools.codegen.InputOptions.CodeGenType;
import org.ebayopensource.turmeric.tools.codegen.InputOptions.InputType;
import org.ebayopensource.turmeric.tools.codegen.builders.BaseCodeGenerator;
import org.ebayopensource.turmeric.tools.codegen.builders.ServiceInterfaceGenerator;
import org.ebayopensource.turmeric.tools.codegen.exception.BadInputValueException;
import org.ebayopensource.turmeric.tools.codegen.exception.CodeGenFailedException;
import org.ebayopensource.turmeric.tools.codegen.exception.PreProcessFailedException;
import org.ebayopensource.turmeric.tools.codegen.exception.PreValidationFailedException;
import org.ebayopensource.turmeric.tools.codegen.external.JavaWSDLGenerator;
import org.ebayopensource.turmeric.tools.codegen.external.JavaWSDLGeneratorFactory;
import org.ebayopensource.turmeric.tools.codegen.external.JavaXmlBinder;
import org.ebayopensource.turmeric.tools.codegen.external.JavaXmlBindingFactory;
import org.ebayopensource.turmeric.tools.codegen.external.WSDLUtil;
import org.ebayopensource.turmeric.tools.codegen.handler.UserResponseHandler;
import org.ebayopensource.turmeric.tools.codegen.util.CodeGenConstants;
import org.ebayopensource.turmeric.tools.codegen.util.CodeGenUtil;
import org.ebayopensource.turmeric.tools.codegen.util.IntrospectUtil;
import org.ebayopensource.turmeric.tools.codegen.validator.MessageObject;
import org.ebayopensource.turmeric.tools.codegen.validator.SourceValidator;
public class CodeGenPreProcessor {
private static Logger s_logger = LogManager.getInstance(CodeGenPreProcessor.class);
private static final String GEN_INTERFACE_SUFFIX = "Gen";
public static ServiceCodeGenDefType parseCodeGenXml(String filePath)
throws BadInputValueException {
ServiceCodeGenDefType svcCodeGenDefType = null;
try {
File xmlFile = new File(filePath);
JavaXmlBinder javaXmlBinder = JavaXmlBindingFactory.getInstance();
svcCodeGenDefType = (ServiceCodeGenDefType) javaXmlBinder
.unmarshal(xmlFile, ServiceCodeGenDefType.class);
} catch (Exception ex) {
String errMsg = "Failed to parse input xml : " + filePath;
s_logger.log(Level.SEVERE, errMsg, ex);
throw new BadInputValueException(errMsg, ex);
}
return svcCodeGenDefType;
}
public static int preProcess(CodeGenContext codeGenCtx)
throws PreProcessFailedException, CodeGenFailedException {
int exitCode = 0;
InputOptions inputOptions = codeGenCtx.getInputOptions();
if (inputOptions.getInputType() == InputType.INTERFACE) {
exitCode = processInterface(codeGenCtx);
}
else if (inputOptions.getInputType() == InputType.WSDL) {
preProcessWSDL(codeGenCtx);
inputOptions.setInputType(InputType.INTERFACE);
exitCode = processInterface(codeGenCtx);
}
else if (inputOptions.getInputType() == InputType.CLASS) {
preProcessImplClass(
inputOptions.getInputFile(),
inputOptions.getGenInterfaceName(),
inputOptions.getGenInterfacePackage(),
null,
codeGenCtx);
inputOptions.setInputType(InputType.INTERFACE);
exitCode = processInterface(codeGenCtx);
}
else if (inputOptions.getInputType() == InputType.XML) {
ServiceCodeGenDefType svcCodeGenDefType = inputOptions.getSvcCodeGenDefType();
InterfaceType interfaceType = svcCodeGenDefType.getInterfaceInfo();
if (interfaceType.getInterfaceClassDef() != null) {
InterfaceClassDefType interfaceDef = interfaceType.getInterfaceClassDef();
inputOptions.setInputFile(interfaceDef.getInterfaceClassName());
inputOptions.setInputType(InputType.INTERFACE);
exitCode = processInterface(codeGenCtx);
}
else if (interfaceType.getInterfaceDef() != null) {
InterfaceDefType interfaceDef = interfaceType.getInterfaceDef();
preProcessInterfaceDef(interfaceDef, codeGenCtx);
inputOptions.setInputType(InputType.INTERFACE);
exitCode = processInterface(codeGenCtx);
}
else if (interfaceType.getImplClassDef() != null) {
ImplClassDefType implClassDef = interfaceType.getImplClassDef();
preProcessImplClassDef(implClassDef, codeGenCtx);
inputOptions.setInputType(InputType.INTERFACE);
exitCode = processInterface(codeGenCtx);
}
else if (interfaceType.getWsdlDef() != null) {
inputOptions.setInputFile(
interfaceType.getWsdlDef().getWsdlFile());
preProcessWSDL(codeGenCtx);
inputOptions.setInputType(InputType.INTERFACE);
exitCode = processInterface(codeGenCtx);
}
}
cleanTemporaryFiles(codeGenCtx);
return exitCode;
}
/**
* This method is used for cleaning temporary files created for wsdl2java
* @param ctx
*/
private static void cleanTemporaryFiles(CodeGenContext ctx)
{
if(ctx.getInputOptions().getIsWsdlTobeDeleted())
{
s_logger.log(Level.INFO, "Deleting temporary file : " + ctx.getInputOptions().getInputFile());
File inputFile = new File(ctx.getInputOptions().getInputFile());
try {
CodeGenUtil.deleteFile(inputFile);
} catch (IOException e) {
s_logger.log(Level.WARNING, "Could not delete temporary file :" + ctx.getInputOptions().getInputFile());
}
}
}
private static int processInterface(CodeGenContext codeGenCtx)
throws PreProcessFailedException, CodeGenFailedException {
s_logger.log(Level.FINE, "BEGIN: Processing interface...");
InputOptions inputOptions = codeGenCtx.getInputOptions();
int exitCode = 0;
if (!codeGenCtx.getGeneratedJavaFiles().isEmpty()) {
exitCode = 1;
}
else {
compileInterface(codeGenCtx);
// Validate interface
exitCode = preProcessInterface(codeGenCtx.getServiceInterfaceClassName(), codeGenCtx);
// Initialize
String qualifiedInterfaceName =
CodeGenUtil.toQualifiedClassName(codeGenCtx.getServiceInterfaceClassName());
codeGenCtx.setServiceInterfaceClassName(qualifiedInterfaceName);
JTypeTable jTypeTable = IntrospectUtil.initializeJType(qualifiedInterfaceName);
addCemClasses(jTypeTable, inputOptions);
codeGenCtx.setJTypeTable(jTypeTable);
}
s_logger.log(Level.FINE, "END: Processing interface, exitCode :" + exitCode);
return exitCode;
}
private static void addCemClasses(
JTypeTable jTypeTable,
InputOptions inputOptions) throws CodeGenFailedException {
OpNameToCemcMappingList opNameToCemcMappings = inputOptions.getOpNameToCemcMappings();
if (opNameToCemcMappings != null &&
opNameToCemcMappings.getOpNameCemcMap().size() > 0) {
for (OpNameCemcMappingType opNameCemcMapEntry : opNameToCemcMappings.getOpNameCemcMap()) {
String cemClassName = opNameCemcMapEntry.getCustomErrMsgClass();
try {
Class customErrMsgClass = IntrospectUtil.loadClass(cemClassName);
jTypeTable.getTypesReferred().add(customErrMsgClass);
}
catch (ClassNotFoundException clsNotFoundEx) {
throw new CodeGenFailedException(
"Failed to load custom error message class : " + cemClassName, clsNotFoundEx);
}
}
}
}
private static int preProcessInterface(
String interfaceClassName,
CodeGenContext codeGenCtx)
throws PreProcessFailedException, CodeGenFailedException {
int exitCode = 0;
InputOptions inputOptions = codeGenCtx.getInputOptions();
//ServiceFromWSDLImpl is used by plugin for impl project build
//DispatcherForBuild is used by v3 build for impl project build
//DispatcherForMaven is used by maven build for impl project build
if(inputOptions.getCodeGenType().equals(CodeGenType.ServiceFromWSDLImpl)
|| inputOptions.getCodeGenType().equals(CodeGenType.DispatcherForBuild)
|| inputOptions.getCodeGenType().equals(CodeGenType.DispatcherForMaven) ){
populateCodegenContextWithWSDLFromClassPath(codeGenCtx);
}
String qualifiedInterfaceName = CodeGenUtil.toQualifiedClassName(interfaceClassName);
Class interfaceClass = null;
try {
interfaceClass = IntrospectUtil.loadClass(qualifiedInterfaceName);
} catch (ClassNotFoundException clsNotFound) {
throw new PreProcessFailedException(clsNotFound.getMessage(), clsNotFound);
}
List<MessageObject> errorList =
SourceValidator.validateServiceInterface(interfaceClass);
processFatalErros(errorList);
if (!errorList.isEmpty()) {
UserResponseHandler usrRespHandler = codeGenCtx.getUserResponseHandler();
boolean autoRefineInterface = isAutoRefineInput(usrRespHandler, getPromptMsg());
if (!autoRefineInterface) {
exitCode = 1;
}
else {
List<String> generatedJavaSrcFiles = null;
ServiceInterfaceGenerator svcInterfaceGenerator =
ServiceInterfaceGenerator.getInstance();
try {
String interfaceName = inputOptions.getGenInterfaceName();
String interfacePackage = inputOptions.getGenInterfacePackage();
if(CodeGenUtil.isEmptyString(interfaceName))
interfaceName = interfaceClass.getSimpleName() + GEN_INTERFACE_SUFFIX ;
if(CodeGenUtil.isEmptyString(interfacePackage))
interfacePackage = interfaceClass.getPackage().getName();
generatedJavaSrcFiles =
svcInterfaceGenerator.internalGenerateJavaInterface(
interfaceClass,
interfaceName,
interfacePackage,
codeGenCtx.getSrcLocation(),
codeGenCtx.getJavaSrcDestLocation());
codeGenCtx.addGeneratedJavaSrcFiles(generatedJavaSrcFiles);
BaseCodeGenerator.compileJavaFiles(
generatedJavaSrcFiles,
codeGenCtx.getBinLocation());
String svcInterfaceClassName =
CodeGenUtil.getQualifiedClassName(
generatedJavaSrcFiles.get(0),
codeGenCtx.getJavaSrcDestLocation());
codeGenCtx.setServiceInterfaceClassName(svcInterfaceClassName);
s_logger.log(Level.FINE, "preProcessInterface() - generated interface : " + svcInterfaceClassName);
} catch (PreProcessFailedException preProcessFailedEx) {
throw preProcessFailedEx;
} catch (CodeGenFailedException codeGenFailedEx) {
throw codeGenFailedEx;
} catch (Exception ex) {
s_logger.log(Level.SEVERE, ex.getMessage(), ex);
throw new CodeGenFailedException(ex.getMessage(), ex);
}
}
}
return exitCode;
}
private static void populateCodegenContextWithWSDLFromClassPath(CodeGenContext codeGenCtx) {
InputOptions inputOptions = codeGenCtx.getInputOptions();
String serviceName = inputOptions.getServiceAdminName();
String wsdlRelativeLocation = "META-INF/soa/services/wsdl/" + serviceName + "/" + serviceName + ".wsdl";
File wsdlFile = null;
InputStream inputStream= null;
try {
inputStream = CodeGenUtil.getInputStreamForAFileFromClasspath(wsdlRelativeLocation, CodeGenPreProcessor.class.getClassLoader());
if(inputStream == null) {
s_logger.log(Level.WARNING, "The WSDL file could not be found in the classpath");
return;
} else {
wsdlFile = CodeGenUtil.getFileFromInputStream(inputStream, ".wsdl");
}
} finally {
CodeGenUtil.closeQuietly(inputStream);
}
if(wsdlFile == null){
s_logger.log(Level.WARNING, "The WSDL file could not be be created from the input stream");
return;
}
try {
WSDLUtil.populateCodegenCtxWithWSDLDetails(wsdlFile.getAbsolutePath(), codeGenCtx);
//After CodegenCtx has been populated with wsdlDetails, temp file should be deleted.
CodeGenUtil.deleteFile(wsdlFile);
} catch (PreProcessFailedException e) {
s_logger.log(Level.WARNING, "" + e.getMessage());
} catch (IOException e) {
s_logger.log(Level.WARNING, "The temprary WSDL file could not be be deleted at location :"+ wsdlFile.getAbsolutePath());
}
}
private static void preProcessInterfaceDef(
InterfaceDefType interfaceDef,
CodeGenContext codeGenCtx)
throws PreProcessFailedException, CodeGenFailedException {
List<MessageObject> errorList =
SourceValidator.validateInterfaceDef(interfaceDef);
processFatalErros(errorList);
if (!errorList.isEmpty()) {
throw new PreProcessFailedException(
"Interface definition is not valid", errorList);
}
ServiceInterfaceGenerator svcInterfaceGenerator =
ServiceInterfaceGenerator.getInstance();
String generatedJavaInterface = null;
try {
generatedJavaInterface =
svcInterfaceGenerator.generateJavaInterface(
interfaceDef,
codeGenCtx.getJavaSrcDestLocation());
codeGenCtx.addGeneratedJavaSrcFile(generatedJavaInterface);
BaseCodeGenerator.compileJavaFile(
generatedJavaInterface,
codeGenCtx.getBinLocation());
String svcInterfaceClassName =
CodeGenUtil.getQualifiedClassName(
generatedJavaInterface,
codeGenCtx.getJavaSrcDestLocation());
codeGenCtx.setServiceInterfaceClassName(svcInterfaceClassName);
s_logger.log(Level.FINE, "preProcessInterfaceDef() - generated interface : " + svcInterfaceClassName);
} catch (PreProcessFailedException preProcessFailedEx) {
throw preProcessFailedEx;
} catch (CodeGenFailedException codeGenFailedEx) {
throw codeGenFailedEx;
} catch (Exception ex) {
s_logger.log(Level.SEVERE, ex.getMessage(), ex);
throw new CodeGenFailedException(ex.getMessage(), ex);
}
}
private static void preProcessImplClass(
String className,
String newInterfaceName,
String newInterfacePkgName,
List<String> exposedMethodNames,
CodeGenContext codeGenCtx)
throws PreProcessFailedException, CodeGenFailedException {
String qualifiedClassName = CodeGenUtil.toQualifiedClassName(className);
List<MessageObject> errorList =
SourceValidator.validateClassForService(
qualifiedClassName,
exposedMethodNames);
processFatalErros(errorList);
if (!errorList.isEmpty()) {
UserResponseHandler usrRespHandler = codeGenCtx.getUserResponseHandler();
boolean autoRefineInterface = isAutoRefineInput(usrRespHandler, getPromptMsg());
if (!autoRefineInterface) {
throw new PreProcessFailedException("Code generation stopped.");
}
else {
ServiceInterfaceGenerator svcInterfaceGenerator =
ServiceInterfaceGenerator.getInstance();
try {
List<String> generatedJavaSrcFiles =
svcInterfaceGenerator.generateJavaInterface(
qualifiedClassName,
newInterfaceName,
newInterfacePkgName,
exposedMethodNames,
codeGenCtx.getSrcLocation(),
codeGenCtx.getJavaSrcDestLocation());
codeGenCtx.addGeneratedJavaSrcFiles(generatedJavaSrcFiles);
BaseCodeGenerator.compileJavaFiles(
generatedJavaSrcFiles,
codeGenCtx.getBinLocation());
String svcInterfaceClassName =
CodeGenUtil.getQualifiedClassName(
generatedJavaSrcFiles.get(0),
codeGenCtx.getJavaSrcDestLocation());
codeGenCtx.setServiceInterfaceClassName(svcInterfaceClassName);
s_logger.log(Level.FINE, "preProcessImplClass() - generated interface : " + svcInterfaceClassName);
} catch (PreProcessFailedException preProcessFailedEx) {
throw preProcessFailedEx;
} catch (CodeGenFailedException codeGenFailedEx) {
throw codeGenFailedEx;
} catch (Exception ex) {
s_logger.log(Level.SEVERE, ex.getMessage(), ex);
throw new CodeGenFailedException(ex.getMessage(), ex);
}
}
}
}
private static void preProcessImplClassDef(
ImplClassDefType implClassDef,
CodeGenContext codeGenCtx)
throws PreProcessFailedException, CodeGenFailedException {
List<String> exposedMethodNames = null;
if (implClassDef.getExposedMethods() != null) {
exposedMethodNames = implClassDef.getExposedMethods().getMethodName();
}
preProcessImplClass(
implClassDef.getImplClassName(),
implClassDef.getInterfaceName(),
implClassDef.getInterfacePackage(),
exposedMethodNames,
codeGenCtx);
}
private static void preProcessWSDL(CodeGenContext codeGenCtx)
throws PreProcessFailedException, CodeGenFailedException {
InputOptions inputOptions = codeGenCtx.getInputOptions();
try {
// Attempt to use as set Java Src Dest Location
// If user specifies a Java Src Dest Location, use it.
// Do not tack on arbitrary extra paths, as this will
// break the classloader lookup at loadClass and introspection
// in later codegen tasks, especially when running in Eclipse
// and Maven Plugin.
String javaSrcDestLoc = codeGenCtx.getJavaSrcDestLocation(false);
// Use [LEGACY] behavior if javaSrcDestLoc is unset.
if(javaSrcDestLoc == null) {
// [LEGACY] the interface generated from WSDL or XML should always be generated under the "client" folder.
javaSrcDestLoc = codeGenCtx.getJavaSrcDestLocation(true);
javaSrcDestLoc = CodeGenUtil.toOSFilePath(javaSrcDestLoc) + CodeGenConstants.CLIENT_GEN_FOLDER;
}
String wsdlFileLoc = inputOptions.getInputFile();
if(codeGenCtx.getWsdlDefinition() == null){
Definition definition = WSDLUtil.getWSDLDefinition(wsdlFileLoc);
codeGenCtx.setWsdlDefinition(definition);
}
JavaWSDLGenerator wsdlGen = JavaWSDLGeneratorFactory.getInstance();
wsdlGen.wsdl2Java(codeGenCtx, javaSrcDestLoc);
String interfacePkgName = inputOptions.getGenInterfacePackage();
WSDLUtil.populateCodegenCtxWithWSDLDetails(wsdlFileLoc, codeGenCtx);
String qualifiedIntfName = inputOptions.getGenInterfaceName();
qualifiedIntfName = interfacePkgName + "." + qualifiedIntfName;
qualifiedIntfName = CodeGenUtil.toQualifiedClassName(qualifiedIntfName);
String wsdl2JavaSrcLoc = wsdlGen.wsdl2JavaGenSrcLoc(javaSrcDestLoc);
moveFiles(wsdl2JavaSrcLoc, javaSrcDestLoc);
codeGenCtx.setSchemaTypesJavaFileLocation(javaSrcDestLoc);
codeGenCtx.setServiceInterfaceClassName(qualifiedIntfName);
codeGenCtx.setWSDLURI(wsdlFileLoc);
codeGenCtx.setAsyncInputType((inputOptions.getInputType() == InputType.WSDL));
codeGenCtx.setAsyncJavaSrcDestLocation(javaSrcDestLoc);
BaseCodeGenerator.compileJavaFile(
qualifiedIntfName,
javaSrcDestLoc,
codeGenCtx.getBinLocation());
} catch (PreProcessFailedException preProcessFailedEx) {
throw preProcessFailedEx;
} catch (CodeGenFailedException codegenFailedEx) {
throw codegenFailedEx;
} catch (Exception ex) {
s_logger.log(Level.SEVERE, ex.getMessage(), ex);
throw new CodeGenFailedException(ex.getMessage(), ex);
}
}
private static void processFatalErros(List<MessageObject> errorList)
throws PreValidationFailedException {
if (errorList.isEmpty()) {
return;
}
List<MessageObject> fatalErrors = new ArrayList<MessageObject>();
for (MessageObject errMsgObj : errorList) {
if (errMsgObj.isFatalError()) {
fatalErrors.add(errMsgObj);
}
}
if (!fatalErrors.isEmpty()) {
throw new PreValidationFailedException(fatalErrors.toString());
}
}
private static void compileInterface(CodeGenContext codeGenCtx)
throws CodeGenFailedException {
// 1. Load interface class
// 2. If step 1 fails, then try to compile interface source file
// 3. Try to load class again to make sure that compiled class is in the
// classpath
String interfaceName = codeGenCtx.getServiceInterfaceClassName();
String qualifiedIntfName = CodeGenUtil.toQualifiedClassName(interfaceName);
try {
IntrospectUtil.loadClass(qualifiedIntfName);
} catch (ClassNotFoundException clsNotFoundEx) {
try {
//If the original InputType is WSDL then we should look for the generated Interface java file under gen-src\client
InputOptions inputOptions = codeGenCtx.getInputOptions();
String interfaceSourceLocation = codeGenCtx.getSrcLocation();
if(inputOptions.getOriginalInputType() == InputType.WSDL) {
// If user specifies a Java Src Dest Location, use it.
// Do not tack on arbitrary extra paths, as this will
// break the classloader lookup at the loadClass later
// when running in Eclipse and Maven Plugin.
String javaSrcDestLoc = codeGenCtx.getJavaSrcDestLocation(false);
// Use [LEGACY] behavior if javaSrcDestLoc is unset.
if(javaSrcDestLoc == null) {
// [LEGACY] the interface generated from WSDL or XML should always be generated under the "client" folder.
javaSrcDestLoc = codeGenCtx.getJavaSrcDestLocation(true);
javaSrcDestLoc = CodeGenUtil.toOSFilePath(javaSrcDestLoc) + CodeGenConstants.CLIENT_GEN_FOLDER;
}
interfaceSourceLocation = javaSrcDestLoc;
}
BaseCodeGenerator.compileJavaFile(
interfaceName,
interfaceSourceLocation,
codeGenCtx.getBinLocation());
}
catch (Exception ex) {
throw new CodeGenFailedException(
"Failed to compile java source file : " + interfaceName , ex);
}
try {
IntrospectUtil.loadClass(qualifiedIntfName);
}
catch (ClassNotFoundException clsNotFoundEx2) {
throw new CodeGenFailedException("Failed to load java class : "
+ qualifiedIntfName + "\n Cause: " + clsNotFoundEx2.getCause(), clsNotFoundEx2);
}
}
}
private static void moveFiles(String srcLoc, String destLoc) throws IOException {
File srcDir = new File(srcLoc);
String srcPath = srcDir.getAbsolutePath();
File destDir = new File(destLoc);
String destPath = destDir.getAbsolutePath();
String normalizedDestLoc = CodeGenUtil.toOSFilePath(destPath);
List<String> allFiles = new ArrayList<String>();
CodeGenUtil.addAllFiles(srcDir, allFiles);
if (allFiles.size() > 0) {
for (String filePath : allFiles) {
int pos = filePath.indexOf(srcPath);
String relativeFilePath = filePath.substring(pos + srcPath.length() + 1);
// Strip-off file name
String relativeFileLoc = relativeFilePath.substring(0,relativeFilePath.lastIndexOf(File.separator));
String destFileLoc = normalizedDestLoc + relativeFileLoc;
CodeGenUtil.move(filePath, destFileLoc, true);
}
}
CodeGenUtil.deleteDir(srcDir);
}
private static boolean isAutoRefineInput(
UserResponseHandler userRespHandler,
String promptMsg) {
boolean isAutoRefineInput =
userRespHandler.getBooleanResponse(promptMsg);
return isAutoRefineInput;
}
private static String getPromptMsg() {
StringBuffer strBuffer = new StringBuffer();
strBuffer.append("One or more of the following must be corrected : \n");
strBuffer.append("1. Service methods should take only one parameter.\n");
strBuffer.append("2. Service method parameter types / return type should be non-collection types.\n\n");
strBuffer.append("Do you want CodeGen tool to create a new interface based on your input interface / class?\n");
return strBuffer.toString();
}
}