문제

Java 소스 파일을 생성 할 프레임 워크를 찾고 있습니다.

다음 API와 같은 것 :

X clazz = Something.createClass("package name", "class name");
clazz.addSuperInterface("interface name");
clazz.addMethod("method name", returnType, argumentTypes, ...);

File targetDir = ...;
clazz.generate(targetDir);

그런 다음 Java 소스 파일은 대상 디렉토리의 하위 디렉토리에 있습니다.

누구든지 그런 프레임 워크를 아는 사람이 있습니까?


편집하다:

  1. 소스 파일이 정말 필요합니다.
  2. 또한 메소드 코드를 작성하고 싶습니다.
  3. 직접 바이트 코드 조작/생성이 아닌 높은 수준의 추상화를 찾고 있습니다.
  4. 또한 물체의 나무에 "클래스의 구조"가 필요합니다.
  5. 문제 영역은 일반적입니다. "공통 구조"없이 많은 양의 매우 다른 클래스를 생성하는 것입니다.

솔루션
나는 당신의 답변에 기반한 2 개의 답변을 게시했습니다 ... CodeModel과 함께 그리고 Eclipse Jdt.

나는 사용했다 코드 모델 내 해결책에서 :-)

도움이 되었습니까?

해결책

Sun은 API를 사용하여 Java 소스 파일을 생성하기위한 Codemodel이라는 API를 제공합니다. 정보를 얻는 것이 가장 쉬운 것은 아니지만 거기에 있으며 매우 잘 작동합니다.

가장 쉬운 방법은 JAXB 2 RI의 일부입니다. XJC Schema-to-Java Generator는 Codemodel을 사용하여 Java 소스를 생성하며 XJC Jars의 일부입니다. 코드 모델에만 사용할 수 있습니다.

그것을 잡아 http://codemodel.java.net/

다른 팁

Codemodel과 함께 찾은 솔루션
감사, Skaffman.

예를 들어,이 코드를 사용하면 다음과 같습니다.

JCodeModel cm = new JCodeModel();
JDefinedClass dc = cm._class("foo.Bar");
JMethod m = dc.method(0, int.class, "foo");
m.body()._return(JExpr.lit(5));

File file = new File("./target/classes");
file.mkdirs();
cm.build(file);

이 출력을 얻을 수 있습니다.

package foo;
public class Bar {
    int foo() {
        return  5;
    }
}

Eclipse JDT의 AST에서 찾은 솔루션
감사, Giles.

예를 들어,이 코드를 사용하면 다음과 같습니다.

AST ast = AST.newAST(AST.JLS3);
CompilationUnit cu = ast.newCompilationUnit();

PackageDeclaration p1 = ast.newPackageDeclaration();
p1.setName(ast.newSimpleName("foo"));
cu.setPackage(p1);

ImportDeclaration id = ast.newImportDeclaration();
id.setName(ast.newName(new String[] { "java", "util", "Set" }));
cu.imports().add(id);

TypeDeclaration td = ast.newTypeDeclaration();
td.setName(ast.newSimpleName("Foo"));
TypeParameter tp = ast.newTypeParameter();
tp.setName(ast.newSimpleName("X"));
td.typeParameters().add(tp);
cu.types().add(td);

MethodDeclaration md = ast.newMethodDeclaration();
td.bodyDeclarations().add(md);

Block block = ast.newBlock();
md.setBody(block);

MethodInvocation mi = ast.newMethodInvocation();
mi.setName(ast.newSimpleName("x"));

ExpressionStatement e = ast.newExpressionStatement(mi);
block.statements().add(e);

System.out.println(cu);

이 출력을 얻을 수 있습니다.

package foo;
import java.util.Set;
class Foo<X> {
  void MISSING(){
    x();
  }
}

로스터를 사용할 수 있습니다 (https://github.com/forge/roaster) 코드 생성을 수행합니다.

예는 다음과 같습니다.

JavaClassSource source = Roaster.create(JavaClassSource.class);
source.setName("MyClass").setPublic();
source.addMethod().setName("testMethod").setPrivate().setBody("return null;")
           .setReturnType(String.class).addAnnotation(MyAnnotation.class);
System.out.println(source);

다음 출력이 표시됩니다.

public class MyClass {
   private String testMethod() {
       return null;
   }
}

또 다른 대안은 Eclipse JDT의 AST입니다. 소스 코드를 생성하기보다는 임의의 Java 소스 코드를 다시 작성 해야하는 경우 좋습니다. (그리고 나는 그것이 일식과 독립적으로 사용할 수 있다고 생각합니다).

그만큼 일식 제트 프로젝트는 소스 생성을 수행하는 데 사용될 수 있습니다. API는 당신이 묘사 한 것과 똑같이 생각하지 않지만 Java 소스 생성을 수행하는 프로젝트를들을 때마다 Jet 또는 Homegrown 도구를 사용했습니다.

라이브러리를 모르지만 일반 템플릿 엔진 만 있으면됩니다. 거기 있습니다 그들 중 많은 것들, 나는 개인적으로 좋은 경험을했습니다 프리 마커

나는 "SourceGen"이라는 이론적 DSL과 매우 유사한 것을 만들었지 만 기술적으로 내가 쓴 ORM을위한 Util 프로젝트 대신 기술적으로는 만들었습니다. DSL은 다음과 같습니다.

@Test
public void testTwoMethods() {
    GClass gc = new GClass("foo.bar.Foo");

    GMethod hello = gc.getMethod("hello");
    hello.arguments("String foo");
    hello.setBody("return 'Hi' + foo;");

    GMethod goodbye = gc.getMethod("goodbye");
    goodbye.arguments("String foo");
    goodbye.setBody("return 'Bye' + foo;");

    Assert.assertEquals(
    Join.lines(new Object[] {
        "package foo.bar;",
        "",
        "public class Foo {",
        "",
        "    public void hello(String foo) {",
        "        return \"Hi\" + foo;",
        "    }",
        "",
        "    public void goodbye(String foo) {",
        "        return \"Bye\" + foo;",
        "    }",
        "",
        "}",
        "" }),
    gc.toCode());
}

https://github.com/stephenh/joist/blob/master/util/src/test/java/joist/sourcegen/gclasstest.java

또한 매개 변수/반환 유형의 FQCN을 "자동 조직 수입",이 CodeGen 실행에서 터치하지 않은 오래된 파일을 자동으로 구축하고 내부 클래스 등을 올바르게 들여 쓰기 등의 깔끔한 작업을 수행합니다.

아이디어는 나머지 코드와 마찬가지로 경고 (미사용 수입 등)없이 생성 된 코드를 보는 것이 예쁘다는 것입니다. 너무 많이 생성 된 코드는 읽기가 못 생겼습니다 ... 끔찍합니다.

어쨌든, 문서는 많지 않지만 API는 매우 간단하고 직관적이라고 생각합니다. Maven Repo입니다 여기 누구든지 관심이 있다면.

당신이 실제로 소스가 필요하다면, 나는 소스를 생성하는 어떤 것도 모른다. 그러나 사용할 수 있습니다 ASM 또는 cglib .class 파일을 직접 작성합니다.

이들로부터 소스를 생성 할 수는 있지만 바이트 코드 만 생성하는 데 소스를 사용했습니다.

나는 모의 발전기 도구를 위해 직접하고있었습니다. Sun 형식 지침을 따라야하더라도 매우 간단한 작업입니다. 나는 당신이 더 빨리 코드를 완성 할 것이라고 확신합니다. 그리고 인터넷에서 당신의 목표에 맞는 것을 발견했습니다.

당신은 기본적으로 API를 직접 설명했습니다. 지금 실제 코드로 채우십시오!

도 있습니다 StringTemplate. 그것은 Antlr의 저자에 의한 것이며 매우 강력합니다.

새로운 프로젝트가 있습니다 쓰기. 템플릿 기반 코드 생성기. 당신은 사용하여 사용자 정의 템플릿을 작성합니다 그루비, Java 반사에 따라 파일을 생성합니다. 파일을 생성하는 가장 간단한 방법입니다. JPA 주석을 기반으로 SQL, 열거를 기반으로 한 삽입/업데이트 등을 생성하여 Getters/Settest/Tostring을 만들 수 있습니다.

템플릿 예 :

package ${cls.package.name};

public class ${cls.shortName}Builder {

    public static ${cls.name}Builder builder() {
        return new ${cls.name}Builder();
    }
<% for(field in cls.fields) {%>
    private ${field.type.name} ${field.name};
<% } %>
<% for(field in cls.fields) {%>
    public ${cls.name}Builder ${field.name}(${field.type.name} ${field.name}) {
        this.${field.name} = ${field.name};
        return this;
    }
<% } %>
    public ${cls.name} build() {
        final ${cls.name} data = new ${cls.name}();
<% for(field in cls.fields) {%>
        data.${field.setter.name}(this.${field.name});
<% } %>
        return data;
    }
}

그것은 실제로 당신이하려는 일에 달려 있습니다. 코드 생성은 그 자체 내에서 주제입니다. 특정 사용 사례가 없으면 속도 코드 생성/템플릿 라이브러리를 살펴 보는 것이 좋습니다. 또한 오프라인 코드 생성을 수행하는 경우 Argouml과 같은 것을 사용하여 UML 다이어그램/객체 모델에서 Java 코드로 이동하는 것이 좋습니다.

예를 들어 : 1/

private JFieldVar generatedField;

2/

String className = "class name";
        /* package name */
        JPackage jp = jCodeModel._package("package name ");
         /*  class name  */
        JDefinedClass jclass = jp._class(className);
        /* add comment */
        JDocComment jDocComment = jclass.javadoc();
        jDocComment.add("By AUTOMAT D.I.T tools : " + new Date() +" => " + className);
        // génération des getter & setter & attribues

            // create attribue 
             this.generatedField = jclass.field(JMod.PRIVATE, Integer.class) 
                     , "attribue name ");
             // getter
             JMethod getter = jclass.method(JMod.PUBLIC, Integer.class) 
                     , "attribue name ");
             getter.body()._return(this.generatedField);
             // setter
             JMethod setter = jclass.method(JMod.PUBLIC, Integer.class) 
                     ,"attribue name ");
             // create setter paramétre 
             JVar setParam = setter.param(getTypeDetailsForCodeModel(Integer.class,"param name");
             // affectation  ( this.param = setParam ) 
             setter.body().assign(JExpr._this().ref(this.generatedField), setParam);

        jCodeModel.build(new File("path c://javaSrc//"));

흥미로운 JSON-to-Pojo 프로젝트는 다음과 같습니다.

http://www.jschema2pojo.org/

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top