有没有可能通过编程方式将java代码添加到现有java文件中?

有没有可能通过编程方式将java代码添加到现有java文件中?,java,code-generation,maven-plugin,codegen,inria-spoon,Java,Code Generation,Maven Plugin,Codegen,Inria Spoon,我有一个使用我创建的自定义maven插件自动生成的接口和类文件。该插件将从JSON文件中读取必要的数据,并使用Jenesis4Java(下面提供的Mojo代码)创建Java文件 要求-我必须遍历已生成的文件,并在该文件中添加新方法或代码。有没有办法从魔咒中实现这一点?看看下面生成的代码,所以我必须添加一个新的抽象方法 我只能从头重新生成相同的文件,但无法添加到现有代码中 生成了以下代码- /** * Customer360 interface. */ import java.io.S

我有一个使用我创建的自定义maven插件自动生成的接口和类文件。该插件将从JSON文件中读取必要的数据,并使用Jenesis4Java(下面提供的Mojo代码)创建Java文件

要求-我必须遍历已生成的文件,并在该文件中添加新方法或代码。有没有办法从魔咒中实现这一点?看看下面生成的代码,所以我必须添加一个新的抽象方法

我只能从头重新生成相同的文件,但无法添加到现有代码中

生成了以下代码-

   /**
 * Customer360 interface.
 */

import java.io.Serializable;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import javax.ws.rs.core.*;

import reactor.core.publisher.Mono;


@Path(value = "/")
public interface Customer360 {
    @GET
    @Path(value = "")
    @Produces(value = "application/json")
    Mono<Response> casecreation(@Context
    HttpHeaders httpHeaders, @Context
    UriInfo uriInfo);

    @GET
    @Path(value = "")
    @Produces(value = "application/json")
    Mono<Response> getCustomerDetails(@Context
    HttpHeaders httpHeaders, @Context
    UriInfo uriInfo);

    @GET
    @Path(value = "")
    @Produces(value = "application/json")
    Mono<Response> prefetch(@Context
    HttpHeaders httpHeaders, @Context
    UriInfo uriInfo);
}
/**
*Customer360界面。
*/
导入java.io.Serializable;
导入javax.ws.rs.GET;
导入javax.ws.rs.Path;
导入javax.ws.rs.products;
导入javax.ws.rs.core.*;
导入reactor.core.publisher.Mono;
@路径(value=“/”)
公共界面Customer360{
@得到
@路径(值=“”)
@产生(value=“application/json”)
单案例创建(@Context)
HttpHeaders HttpHeaders,@Context
UriInfo-UriInfo);
@得到
@路径(值=“”)
@产生(value=“application/json”)
Mono getCustomerDetails(@Context
HttpHeaders HttpHeaders,@Context
UriInfo-UriInfo);
@得到
@路径(值=“”)
@产生(value=“application/json”)
单声道预取(@Context
HttpHeaders HttpHeaders,@Context
UriInfo-UriInfo);
}
在mojo文件中,我编写了生成这个类文件和另一个类文件的逻辑。(Mojo指maven插件创建过程中的java文件)

供参考的Mojo文件-

import net.sf.json.JSONSerializer;
import net.sourceforge.jenesis4java.*;
import net.sourceforge.jenesis4java.impl.MCodeWriter;
import net.sourceforge.jenesis4java.jaloppy.JenesisJalopyEncoder;
import org.apache.commons.io.IOUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import java.awt.*;
import java.io.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

//import reactor.core.publisher.Mono;


import java.util.Iterator;
import java.util.Map;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.*;

@Mojo(name = "generate-code", defaultPhase = LifecyclePhase.COMPILE)
public class GenerateApiResource extends AbstractMojo {

    @Parameter(defaultValue = "${project}", required = true, readonly = true)
    MavenProject project;

    @Parameter(defaultValue = "src/main/java", required = true)
    protected File outputJavaDirectory;

    @Parameter(defaultValue = "src/main/java", required = true)
    protected File outputJavaDirectory2;

    @Parameter
    protected String[] endpoints;

    private String apiName;


    private AbstractMethod mtr;
    private PackageClass cls ;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {

        this.apiName = endpoints[0];
        System.out.println("API TO USE  1= >> "+apiName);
        this.apiName = endpoints[1];
        System.out.println("API TO USE  2= >> "+apiName);

        this.apiName = "Customer360";
        if (this.project != null) {
            this.project.addCompileSourceRoot(this.outputJavaDirectory.getAbsolutePath());
            this.project.addCompileSourceRoot(this.outputJavaDirectory2.getAbsolutePath());
        }

        /*if (!this.outputJavaDirectory.mkdirs()) {
            getLog().error("Could not create source directory!");
        } else {

        }*/
        try {
            generateJavaCode();
        } catch (IOException e) {
            throw new MojoExecutionException("Could not generate Java source code!", e);
        }

        /*if (!this.outputJavaDirectory2.mkdirs()) {
            getLog().error("Could not create source directory!");
        } else {

        } */

        try {
            generateJavaCode2();
        } catch (IOException e) {
            throw new MojoExecutionException("Could not generate Java source code!", e);
        }


    }

    private void generateJavaCode2() throws IOException {
        System.setProperty("jenesis.encoder", JenesisJalopyEncoder.class.getName());
        // Get the VirtualMachine implementation.
        VirtualMachine vm = VirtualMachine.getVirtualMachine();

        // Instantiate a new CompilationUnit. The argument to the
        // compilation unit is the "codebase" or directory where the
        // compilation unit should be written.

        // Make a new compilation unit rooted to the given sourcepath.
        CompilationUnit unit = vm.newCompilationUnit(this.outputJavaDirectory2.getAbsolutePath());

        // Set the package namespace.
        unit.setNamespace("com.cs.frontline.apiimplementations");

        unit.addImport("javax.inject.Inject");
        unit.addImport("javax.ws.rs.core.Context");
        unit.addImport("javax.ws.rs.core.HttpHeaders");
        unit.addImport("javax.ws.rs.core.Response");
        unit.addImport("javax.ws.rs.core.UriInfo");
        unit.addImport("org.springframework.context.annotation.Scope");
        unit.addImport("org.springframework.stereotype.Component");
        unit.addImport(String.format("com.cs.frontoffice.api.%s",apiName));
        unit.addImport("com.cs.frontoffice.dataorchestrationengine.EndPointHandler");
        unit.addImport("reactor.core.publisher.Mono");

        PackageClass cls = unit.newPublicClass(String.format("%sImpl",apiName));
        cls.addImplements(String.format("%s",apiName));
        unit.setComment(Comment.D, "The API Implementation class.");
        cls.newField(vm.newType("EndPointHandler"),"endPointHandler").addAnnotation("Inject");

        //READ FROM JSON FILE
        JSONParser parser = new JSONParser();
        JSONObject jsonObject;
        JSONArray jsonArray;
        try{
            // parsing file
            File file = new File(String.format("src/main/resources/%s.json",apiName));
            jsonArray = (JSONArray) parser.parse(new FileReader(file));

            for(Object obj: jsonArray){
                JSONObject apiObj = (JSONObject) obj;

                String operationId = (String) apiObj.get("operationId");
                String method = (String) apiObj.get("method");
                String endPointFunction = (String) apiObj.get("endPointFunction");

                ClassMethod mtr = cls.newMethod(vm.newType("Mono<Response>"),operationId);
                mtr.setAccess(Access.PUBLIC);

                if(method == "POST" || method == "PUT"){
                    mtr.addParameter(vm.newType("String"),"requestBodyStr");
                }

                ClassType clsType = vm.newType("@Context HttpHeaders");
                ClassType clsType2 = vm.newType("@Context UriInfo");

                mtr.addParameter(clsType,"httpHeaders");
                mtr.addParameter(clsType2,"uriInfo");

                mtr.addAnnotation("Override");

                Try tr = mtr.newTry();
                tr.newCatch(vm.newType("Exception"),"e");

                Let letx = tr.newLet(vm.newType("Mono<Response>"));

                if(method.equals("GET")){
                    letx.addAssign("responseMap",vm.newInvoke("endPointHandler",String.format("%s",endPointFunction))
                            .addArg(vm.newVar("new Object() {}.getClass().getEnclosingMethod().getName()"))
                            .addArg(vm.newNull())
                            .addVarriableArg("uriInfo")
                            .addVarriableArg("httpHeaders"));

                } else {

                    letx.addAssign("responseMap",vm.newInvoke("endPointHandler","getEndpointResponse")
                            .addArg(vm.newVar("new Object() {}.getClass().getEnclosingMethod().getName()"))
                            .addArg(vm.newVar("new JSONObject(requestBodyStr)"))
                            .addVarriableArg("uriInfo")
                            .addVarriableArg("httpHeaders"));

                }

                tr.newReturn().setExpression(vm.newVar("responseMap"));

                mtr.newReturn().setExpression(vm.newNull());



            }
        } catch (Exception e){
            System.out.println("File FAILED ======");
            System.out.println(e);
        }



        unit.encode();



    }

    private void generateJavaCode() throws IOException {
        System.setProperty("jenesis.encoder", JenesisJalopyEncoder.class.getName());

        // Get the VirtualMachine implementation.
        VirtualMachine vm = VirtualMachine.getVirtualMachine();

        // Instantiate a new CompilationUnit. The argument to the
        // compilation unit is the "codebase" or directory where the
        // compilation unit should be written.
        //
        // Make a new compilation unit rooted to the given sourcepath.
        CompilationUnit unit = vm.newCompilationUnit(this.outputJavaDirectory.getAbsolutePath());

        // Set the package namespace.
        unit.setNamespace("com.cs.frontoffice.api");

        // Add an import statement for fun.
        unit.addImport("java.io.Serializable");
        unit.addImport("javax.ws.rs.GET");
        unit.addImport("javax.ws.rs.Path");
        unit.addImport("javax.ws.rs.Produces");
        unit.addImport("javax.ws.rs.core.*");
        unit.addImport("reactor.core.publisher.Mono");

        // Comment the package with a javadoc (DocumentationComment).
        unit.setComment(Comment.D, "Auto-Generated using the Jenesis Syntax API");


        // Make a new interface.
        Interface itr = unit.newPublicInterface(String.format("%s",apiName));
        itr.addAnnotation("Path").addAnntationAttribute("value").setValue(vm.newString("/"));

        // Comment the class with a javadoc (DocumentationComment).
        unit.setComment(Comment.D, String.format("%s interface.",apiName));
        ClassType t = vm.newType("Mono<Response>");


        //READ FROM JSON FILE
        JSONParser parser = new JSONParser();
        JSONObject jsonObject;
        JSONArray jsonArray;
        try{
            // parsing file
            File file = new File(String.format("src/main/resources/%s.json",apiName));
            jsonArray = (JSONArray) parser.parse(new FileReader(file));

            for(Object obj: jsonArray){
                JSONObject apiObj = (JSONObject) obj;

                String operationId = (String) apiObj.get("operationId");
                String path = (String) apiObj.get("path");
                String method = (String) apiObj.get("method");

                AbstractMethod mtr = itr.newMethod(vm.newType("Mono<Response>"),operationId);
                mtr.addAnnotation(String.format("%s",method));
                mtr.addAnnotation("Path").addAnntationAttribute("value").setValue(vm.newString(String.format("%s",path)));
                mtr.addAnnotation("Produces").addAnntationAttribute("value").setValue(vm.newString("application/json"));

                if(method.equals("POST") || method.equals("PUT")){
                    mtr.addParameter(vm.newType("@RequestBody String"),"requestBodyStr");
                }
                ClassType clsType = vm.newType("@Context HttpHeaders");
                System.out.println(clsType.getName());


                ClassType clsType2 = vm.newType("@Context UriInfo");
                System.out.println(clsType.getName());

                mtr.addParameter(clsType,"httpHeaders");
                mtr.addParameter(clsType2,"uriInfo");

                //Print interface
                System.out.println(mtr);

            }
        } catch (Exception e){
            System.out.println("File FAILED ======");
            System.out.println(e);
        }


        // Write the java file.
        unit.encode();

    }
}
import net.sf.json.JSONSerializer;
导入net.sourceforge.jenesis4java.*;
导入net.sourceforge.jenesis4java.impl.MCodeWriter;
导入net.sourceforge.jenesis4java.jaloppy.JenesisJalopyEncoder;
导入org.apache.commons.io.IOUtils;
导入org.apache.maven.plugin.AbstractMojo;
导入org.apache.maven.plugin.MojoExecutionException;
导入org.apache.maven.plugin.MojoFailureException;
导入org.apache.maven.plugins.annotations.LifecyclePhase;
导入org.apache.maven.plugins.annotations.Mojo;
导入org.apache.maven.plugins.annotations.Parameter;
导入org.apache.maven.project.MavenProject;
导入java.awt.*;
导入java.io.*;
导入javax.ws.rs.core.MediaType;
导入javax.ws.rs.core.Response;
//导入reactor.core.publisher.Mono;
导入java.util.Iterator;
导入java.util.Map;
导入org.json.simple.JSONArray;
导入org.json.simple.JSONObject;
导入org.json.simple.parser.*;
@Mojo(name=“generate code”,defaultPhase=LifecyclePhase.COMPILE)
公共类GenerateFireSource扩展了AbstractMojo{
@参数(defaultValue=“${project}”,必需=true,只读=true)
马文尼项目;
@参数(defaultValue=“src/main/java”,必需=true)
受保护的文件outputJavaDirectory;
@参数(defaultValue=“src/main/java”,必需=true)
受保护的文件outputJavaDirectory2;
@参数
受保护的字符串[]端点;
私有字符串名称;
私人地铁;
专用包装类cls;
@凌驾
public void execute()抛出MojoExecutionException,MojoFailureException{
this.apiName=端点[0];
System.out.println(“API使用1=>>”+apiName);
this.apiName=端点[1];
System.out.println(“API使用2=>>”+apiName);
this.apiName=“Customer360”;
如果(this.project!=null){
this.project.addCompileSourceRoot(this.outputJavaDirectory.getAbsolutePath());
this.project.addCompileSourceRoot(this.outputJavaDirectory2.getAbsolutePath());
}
/*如果(!this.outputJavaDirectory.mkdirs()){
getLog()。错误(“无法创建源目录!”);
}否则{
}*/
试一试{
generateJavaCode();
}捕获(IOE异常){
抛出新的MojoExecutionException(“无法生成Java源代码!”,e);
}
/*如果(!this.outputJavaDirectory2.mkdirs()){
getLog()。错误(“无法创建源目录!”);
}否则{
} */
试一试{
生成代码2();
}捕获(IOE异常){
抛出新的MojoExecutionException(“无法生成Java源代码!”,e);
}
}
私有void generateJavaCode2()引发IOException{
setProperty(“jenesis.encoder”,JenesisJalopyEncoder.class.getName());
//获取VirtualMachine实现。
VirtualMachine vm=VirtualMachine.getVirtualMachine();
//实例化一个新的CompliationUnit
//编译单元是“代码库”或目录,其中
//应编写编译单元。
//使一个新的编译单元以给定的源路径为根。
CompilationUnit=vm.newCompilationUnit(this.outputJavaDirectory2.getAbsolutePath());
//设置包名称空间。
setNamespace(“com.cs.frontline.api实现”);
addImport(“javax.inject.inject”);
addImport(“javax.ws.rs.core.Context”);
addImport(“javax.ws.rs.core.HttpHeaders”);
addImport(“javax.ws.rs.core.Response”);
addImport(“javax.ws.rs.core.UriInfo”);
addImport(“org.springframework.context.annotation.Scope”);
addImport(“org.springframework.stereotype.Component”);
addImport(String.format(“com.cs.frontoffice.api.%s”,apiName));
addImport(“com.cs.frontoffice.dataorchestrationengine.EndPointHandler”);
addImport(“reactor.core.publisher.Mono”);
PackageClass cls=unit.newPublicClass(String.format(“%Siml”,apiName));
cls.addImplements(String.format(“%s”,apiName));
setComment(Comment.D,“API实现类”);
cls.newField(vm.newType(“EndPointHandler”),“EndPointHandler”).addAnnotation(“Inject”);
//从JSON文件读取
// create a Spoon model of the generated code
Launcher launcher = new Launcher();
VirtualFile virtualFile = new VirtualFile(generatedCode);
launcher.addInputResource(virtualFile);
launcher.buildModel();
CtInterface ctInterface = launcher.getModel().getRootPackage().getType("Customer360");

// create an abstract method
String codeWithAbstractMethod = "package pkg; abstract class AbstractClass { abstract void abstractMethod();} ";
CtClass<?> classWithAbstractMethod = Launcher.parseClass(codeWithAbstractMethod);
CtMethod abstractMethod = classWithAbstractMethod.getMethodsByName("abstractMethod").get(0);

// add abstract method to the generated code
ctInterface.addMethod(abstractMethod);
String prettyPrint = ctInterface.toString();