Frage

Ich bin auf der Suche nach einem framework zum generieren von Java-source-Dateien.

So etwas wie die folgende API:

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

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

Dann, ein java-source-Datei gefunden werden sollten in einem Unterverzeichnis des Zielverzeichnisses.

Kennt jemand einen solchen Rahmen?


BEARBEITEN:

  1. Ich brauche wirklich die source-Dateien.
  2. Ich möchte auch die zum ausfüllen der code der Methoden.
  3. Ich bin auf der Suche nach einer high-level-Abstraktion, nicht direkt bytecode manipulation/generation.
  4. Ich muss auch die "Struktur der Klasse" im Baum der Objekte.
  5. Die problem-Domäne ist allgemein:generiert eine große Menge von sehr unterschiedlichen Klassen, ohne eine "gemeinsame Struktur".

LÖSUNGEN
Ich habe 2 Antworten in Ihren Antworten... mit CodeModel und mit Eclipse JDT.

Ich habe verwendet CodeModel in meiner Lösung :-)

War es hilfreich?

Lösung

Sun bietet eine API namens CodeModel für die Generierung von Java-Quellcode-Dateien über eine API.Es ist nicht die einfachste Sache, um Informationen zu bekommen, aber es ist da und es funktioniert sehr gut.

Der einfachste Weg, um halt zu bekommen, ist es, als Teil der JAXB 2 RI - das XJC schema-zu-java-generator verwendet CodeModel zum generieren der java-Quelle, und es ist Teil des XJC-Gläser.Sie können es verwenden, nur für den CodeModel.

Schnappen Sie es aus http://codemodel.java.net/

Andere Tipps

Lösung gefunden, mit CodeModel
Vielen Dank, skaffman.

Zum Beispiel mit diesem code:

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);

Ich bekomme diese Ausgabe:

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

Lösung des Problems mit Eclipse-JDT-ist-AST
Vielen Dank, Giles.

Zum Beispiel mit diesem code:

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);

Ich bekomme diese Ausgabe:

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

Sie können Röster (https://github.com/forge/roaster), um die code-Generierung.

Hier ist ein Beispiel:

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);

wird die folgende Ausgabe anzeigen:

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

Eine weitere alternative ist die Eclipse JDT ist AST das ist gut, wenn man neu schreiben müssen, beliebigen Java-Quell-code, anstatt nur generiert Quellcode.(und ich glaube, es kann verwendet werden, unabhängig von eclipse).

Die Eclipse JET Projekt kann verwendet werden, zu tun source generation.Ich glaube nicht, dass es die API ist genau wie die, die Sie beschrieben, aber jedes mal, wenn ich hörte von einem Projekt zu tun Java-Quellcode generation, die Sie verwendet haben JET oder ein hausgemachtes Werkzeug.

Kenne keine Bibliothek, sondern eine generische template-engine könnte alles sein, was Sie brauchen.Es gibt ein paar von Ihnen, Ich persönlich habe gute Erfahrung mit dem FreeMarker

Ich baute etwas, das sieht sehr wie Ihre theoretischen DSL, genannt "sourcegen", aber technisch anstelle einer util-Projekt für ein ORM, das ich schrieb.Die DSL-sieht aus wie:

@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

Es enthält auch einige nette Dinge wie "Auto-Importe verwalten" alle FQCNs in-Parameter/return-Typen, auto-beschneiden alle alten Dateien wurden nicht berührt, in diesem codegen laufen, richtig Einrücken innere Klassen, etc.

Die Idee ist, dass der generierte code sollte ziemlich, um es zu betrachten, ohne Warnungen (nicht verwendete Importe, etc.), genau wie der rest Ihres Codes.So viel erzeugte code ist hässlich zu Lesen...es ist schrecklich.

Trotzdem, es gibt nicht viele Dokumente, aber ich denke, die API ist ziemlich einfach/intuitiv.Die Maven-repo ist hier wenn jemand interessiert ist.

Wenn Sie WIRKLICH brauchen, die Quelle, ich weiß nicht, alles, was Quelle erzeugt.Sie können jedoch ASM oder CGLIB direkt zu erstellen .class-Dateien.

Sie könnten in der Lage zu erzeugen Quelle von diesen, aber ich habe Sie nur benutzt, um generieren von bytecode.

Ich Tat es, mich für ein Modell-generator-tool.Es ist eine sehr einfache Aufgabe, auch wenn Sie benötigen zu Folgen, Sonne Formatierung Richtlinien.Ich Wette, Sie würden finish die code, die macht es schneller, dann haben Sie etwas, das passt zu Ihrem Ziel auf das Internet.

Sie haben im Grunde skizziert die API selbst.Einfach füllen es mit dem tatsächlichen code jetzt!

Es ist auch StringTemplate.Er ist der Autor von ANTLR und ist Recht leistungsfähig.

Es gibt neues Projekt schreiben-es-einmal.Template basierte code-generator.Schreiben Sie benutzerdefinierte Vorlage verwenden Groovy, und generieren Sie die Datei je nach java-Reflektionen.Es ist der einfachste Weg, um erzeugen eine Datei.Sie können Getter/settest/toString durch die Erzeugung von AspectJ-Dateien, SQL-basierend auf JPA-Annotationen, Einfügungen / Aktualisierungen, basierend auf Enumerationen und so auf.

Template Beispiel:

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;
    }
}

Es hängt wirklich davon ab, was Sie versuchen zu tun.Code-Generierung ist ein Thema für sich.Ohne einen konkreten use-case, schlage ich vor, looking at velocity code generation/template-Bibliothek.Auch, wenn Sie dabei sind, die code-Generierung offline, würde ich vorschlagen, etwas wie ArgoUML, um zu gehen von UML-Diagramm-Objekt-Modell Java-code um.

Exemple :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//"));

Hier ist ein JSON zu POJO-Projekt, das interessant aussieht:

http://www.jsonschema2pojo.org/

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top