Java 소스 파일을 생성하는 Java API
자바 소스 파일을 생성할 프레임워크를 찾고 있습니다.
다음과 같은 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 소스 파일을 찾을 수 있습니다.
그런 틀을 아는 사람이 있나요?
편집:
- 소스 파일이 정말 필요해요.
- 그 방법의 코드도 기입하고 싶습니다.
- 저는 직접적인 바이트 코드 조작/생성이 아닌 높은 수준의 추상화를 찾고 있습니다.
- 또, 오브젝트 트리의 「클래스의 구조」도 필요합니다.
- 문제 영역은 일반적입니다. "공통 구조" 없이 매우 다른 많은 양의 클래스를 생성하는 것입니다.
★★★★★★★
저는 당신의 답변을 바탕으로 2개의 답변을 올렸습니다.CodeModel 및 Eclipse JDT를 사용합니다.
솔루션에서 Code Model을 사용한 적이 있습니다. : - )
Sun은 API를 사용하여 Java 소스 파일을 생성하기 위한 CodeModel이라는 API를 제공합니다.정보를 얻는 것이 가장 쉬운 것은 아니지만, 그것은 거기에 있고 매우 잘 작동한다.
이를 입수하는 가장 쉬운 방법은 JAXB 2 RI의 일부로서 XJC 스키마-to-java 제너레이터는 Java 소스를 생성하기 위해 CodeModel을 사용합니다.XJC jars의 일부입니다.Code Model에만 사용할 수 있습니다.
http://codemodel.java.net/ 에서 입수할 수 있습니다.
Model Code Model에서 발견된 솔루션
고마워, 스카프만
예를 들어, 이 코드의 경우:
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;
}
}
ASTEClipse JDT에서 찾은
고마워, 자일스
예를 들어, 이 코드의 경우:
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();
}
}
Roaster(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 소스 코드를 다시 작성해야 할 경우에 적합합니다.(일식과는 별도로 사용할 수 있다고 생각합니다).
Eclipse JET 프로젝트를 사용하여 소스 생성을 수행할 수 있습니다.당신이 설명한 API와 완전히 다르다고는 생각하지 않지만, 자바 소스 생성 프로젝트를 들을 때마다 JET 또는 자체 개발 툴을 사용하고 있습니다.
라이브러리는 모르지만 범용 템플릿 엔진만 있으면 됩니다.여러 가지가 있습니다. 저는 개인적으로 FreeMarker와 좋은 경험을 했습니다.
당신의 이론 DSL과 매우 흡사한 "sourcegen"이라고 불리는 것을 만들었지만, 엄밀히 말하면 제가 쓴 ORM의 실용 프로젝트는 아닙니다.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을 "Auto-organize imports", 이 코드젠 실행에서 터치되지 않은 오래된 파일을 자동 플루닝, 내부 클래스를 올바르게 식별하는 등의 간단한 작업도 수행합니다.
생성된 코드는 다른 코드와 마찬가지로 경고(미사용 Import 등) 없이 보기에도 예쁘다는 것입니다.너무 많이 생성된 코드는 읽기 흉하고 끔찍해
어쨌든 많은 문서는 없지만 API는 매우 단순하고 직관적이라고 생각합니다.관심있는 사람이 있으면 메이븐 레포도 와 있어요.
정말 그 원천이 필요하다면, 난 그 원천을 만들어낼만한 어떤 것도 몰라.단, ASM 또는 CGLIB를 사용하여 .class 파일을 직접 작성할 수 있습니다.
소스 생성은 가능하지만 바이트 코드 생성에만 사용해 왔습니다.
내가 직접 모의 발전기 도구를 만들고 있었어.Sun 포맷 가이드라인을 따라야 하는 경우에도 매우 간단한 작업입니다.인터넷에서 당신의 목표에 맞는 것을 찾는 것보다 더 빨리 코드를 완성할 수 있을 거라고 장담합니다.
API의 개요는 본인이 직접 작성했습니다.지금 바로 실제 코드로 채우세요!
StringTemplate도 있습니다.이것은 ANTLR의 저자에 의해 작성되었으며 매우 강력합니다.
한 번 쓰면 되는 새로운 Write-It-Once.템플릿 기반 코드 생성기.Groovy를 사용하여 커스텀 템플릿을 작성하고 Java 리플렉션에 따라 파일을 생성합니다.모든 파일을 생성하는 가장 간단한 방법입니다.AspectJ 파일, JPA 주석을 기반으로 한 SQL, Enum을 기반으로 한 삽입/업데이트 등을 생성하여 getters/setest/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;
}
}
그것은 정말 당신이 무엇을 하려고 하는가에 달려있다.코드 생성은 그 자체로 하나의 주제입니다.구체적인 사용 사례 없이 속도 코드 생성/템플릿 라이브러리를 검토할 것을 권장합니다.또한 오프라인에서 코드 생성을 하는 경우, UML 다이어그램/오브젝트 모델에서 Java 코드로 이동하기 위해 ArgoUML과 같은 것을 사용하는 것이 좋습니다.
예: 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.jsonschema2pojo.org/
언급URL : https://stackoverflow.com/questions/121324/a-java-api-to-generate-java-source-files
'programing' 카테고리의 다른 글
원칙 2에서 마지막 삽입 ID를 얻으시겠습니까? (0) | 2022.11.19 |
---|---|
MySQL에서 FULL OUTER JOIN 구문 오류가 보고되는 이유는 무엇입니까? (0) | 2022.11.19 |
Java 유형 삭제의 이점은 무엇입니까? (0) | 2022.11.10 |
PHP에서 추상 클래스는 무엇입니까? (0) | 2022.11.10 |
Python 3의 sys.maxint란 무엇입니까? (0) | 2022.11.10 |