জাভা উত্স ফাইলগুলি তৈরি করার জন্য একটি জাভা এপিআই [বন্ধ]


127

আমি জাভা উত্স ফাইল উত্পন্ন করার জন্য একটি কাঠামো খুঁজছি।

নিম্নলিখিত API এর মতো কিছু:

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

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

তারপরে, কোনও জাভা উত্স ফাইলটি লক্ষ্য ডিরেক্টরিটির একটি উপ ডিরেক্টরিতে খুঁজে পাওয়া উচিত।

কেউ কি এমন কাঠামো জানেন?


সম্পাদনা :

  1. আমার সত্যিকারের উত্স ফাইলগুলি দরকার।
  2. আমি পদ্ধতিগুলির কোডটি পূরণ করতে চাই।
  3. আমি একটি উচ্চ-স্তরের বিমূর্ততা খুঁজছি, সরাসরি বাইটকোড ম্যানিপুলেশন / জেনারেশন নয়।
  4. আমার বস্তুর গাছে "শ্রেণির কাঠামো" দরকার।
  5. সমস্যা ডোমেনটি সাধারণ: "সাধারণ কাঠামো" ছাড়াই প্রচুর পরিমাণে বিভিন্ন শ্রেণি তৈরি করতে।

সমাধান
আমি আপনার উত্তরগুলির ভিত্তিতে 2 টি উত্তর পোস্ট করেছি ... কোডমোডেল সহ এবং গ্রহণ জেডিটি সহ

আমি আমার দ্রবণে কোডমোডেল ব্যবহার করেছি, :-)


আপনার প্রশ্নটি খুব সাধারণ, আপনার সমস্যার ডোমেনটি কি এই সাধারণ? আপনি কি আপনার সমস্যা ডোমেন সম্পর্কে আরও নির্দিষ্ট হতে পারেন? উদাহরণস্বরূপ, আমি নির্দিষ্ট সমস্যার জন্য কোড তৈরি করার জন্য কোড উত্পন্নকরণের কোডগুলি লিখেছি যেমন সদৃশ ব্যতিক্রম শ্রেণি কোডটি বাদ দেওয়া, বা এনগ্রামগুলিতে সদৃশকে বাদ দেওয়া।
গ্রেগ ম্যাটস

@ ভিভওয়ার্ড: আপনি যে উত্তরগুলি প্রশ্নের মধ্যে রেখেছেন তা নীচের 2 টি পৃথক উত্তর হিসাবে সরিয়ে নিতে পারেন। তারপরে প্রশ্ন থেকে প্রতিটিটিতে একটি লিঙ্ক যুক্ত করুন।
অ্যান্ডি টার্নার

@ বানেনগাস্ক: জিজ্ঞাসা করার জন্য ধন্যবাদ, আমাকে ইন্টারনেটের অন্ধকারতম অংশগুলিতে অনুসন্ধানের সময়গুলি বাঁচিয়েছে। @ স্কাফম্যান: দুর্দান্ত সন্ধান - আপনি তার আসন্ন কাজটি সহ আরও একটি বিকাশকারীকে আরও স্বাচ্ছন্দ্যে তৈরি করেছেন :)
রান বায়ারন

এই এই উত্তরটি জাভা পরিবর্তে সি ++ এর জন্য প্রশ্নের উত্তর দেয়, তবে উত্তরটি জাভাতেও কাজ করে। stackoverflow.com/a/28103779/120163
ইরা

উত্তর:


70

সান একটি এপিআই ব্যবহার করে জাভা উত্স ফাইল উত্পন্ন করার জন্য কোডমোডেল নামে একটি এপিআই সরবরাহ করে। এটি তথ্য পাওয়া সবচেয়ে সহজ জিনিস নয়, তবে এটি রয়েছে এবং এটি অত্যন্ত ভালভাবে কাজ করে।

এটি ধরে রাখার সবচেয়ে সহজ উপায় জ্যাকএক্সবি 2 আরআইয়ের অংশ হিসাবে - এক্সজেসি স্কিমা-থেকে-জাভা জেনারেটর কোডভাডেলটিকে তার জাভা উত্স তৈরি করতে ব্যবহার করে এবং এটি এক্সজেসি জারগুলির অংশ। আপনি এটি কেবল কোডমোডেলের জন্য ব্যবহার করতে পারেন।

এটি http://codemodel.java.net/ থেকে ধরুন


2
আমার যা দরকার তা-ই! সহজ এবং সম্পূর্ণরূপে কার্যকর। ধন্যবাদ, স্কাফম্যান!
ড্যানিয়েল ফানজুল

1
@BradCupit পম ফাইল অনুযায়ী repo.maven.apache.org/maven2/com/sun/codemodel/codemodel/2.6/... , এটা CDDL + + জিপিএল হয় glassfish.java.net/public/CDDL+GPL_1_1.html
ykaganovich

@ykaganovich ভাল কল। এটি [ repo.maven.apache.org/maven2/com/sun/codemodel/… সিডিডিএল এবং জিপিএল এর অধীন লাইসেন্স প্রাপ্ত)। আমি আমার আগের মন্তব্যটি সরিয়েছি।
ব্র্যাড কাপিট

46

কোডমোডেল
ধন্যবাদ, স্কাফম্যান সহ সমাধান পাওয়া গেল

উদাহরণস্বরূপ, এই কোড সহ:

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

এটি দুর্দান্ত দেখায়। আপনি এমন একটি পদ্ধতি কীভাবে তৈরি করবেন যা কোডডোডেল দিয়ে তৈরি করা হচ্ছে যা অন্য ধরণের ফেরত দেয়?
আন্দ্রে হামার

@ ডিআরএইচ, সরল গুগল অনুসন্ধান: কোডমডেল.জভা.এন.এ.ভা.নাভ
ড্যানিয়েল ফানজুল

@ আন্দ্রে হুমার cm._class(...)রিটার্ন টাইপের আর্গুমেন্ট হিসাবে ফিরে আসা উদাহরণটি ব্যবহার করুন dc.method(...)
হুগো বাশ

28

এক্সিলিপ জেডিটির এএসটি
ধন্যবাদ, গিলস সহ সমাধান পাওয়া গেল found

উদাহরণস্বরূপ, এই কোড সহ:

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

আমি জিজ্ঞাসা করতে পারি - আপনি কোনও জাভা এক্সপ্লাইস প্লাগইনের অংশ হিসাবে এটি করেছেন নাকি আপনি এটি স্ট্যান্ড্যালোন কোড হিসাবে ব্যবহার করতে পরিচালনা করেছেন? আমি বুঝতে পারি এটি বহু বছরের পুরনো।
mtrc

@ এমটিআরসি যদি আমি ভাল করে মনে রাখি তবে এটি ক্লাসপথে যথাযথ জার যোগ করে গ্রহনে একটি স্বতন্ত্র এবং সাধারণ জাভা প্রকল্প ছিল - তবে আমি ফাইলের নাম মনে রাখি না।
ড্যানিয়েল ফানজুল

17

আপনি রোস্টার ( 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;
   }
}

9

আরেকটি বিকল্প হ'ল এক্লিপস জেডিটির এএসটি যা আপনাকে সোর্স কোড উত্পন্ন করার পরিবর্তে স্বেচ্ছাসেবী জাভা উত্স কোডটি পুনরায় লেখার প্রয়োজন হলে তা ভাল। (এবং আমি বিশ্বাস করি এটি গ্রহণ থেকে স্বাধীনভাবে ব্যবহার করা যেতে পারে)।


1
গ্রেট !! একটি বিমূর্ত সিনট্যাক্স ট্রি যা আমি সন্ধান করছি ... এখন আমি এপিআই সম্পর্কে আরও তথ্য সন্ধান করব ... ধন্যবাদ !, :-)
ড্যানিয়েল ফানজুল

এপিআই জটিল, যেমনটি আমি প্রত্যাশা করেছিলাম। তবে এটিতে আমার প্রয়োজনীয় সমস্ত কার্যকারিতা রয়েছে। ধন্যবাদ, গাইলস
ড্যানিয়েল ফানজুল

1
@ গ্যাস্তলডি দ্বারা উল্লিখিত হিসাবে, রোস্টার (জেবস ফোরজ থেকে) গ্রহন জেডিটির জন্য একটি দুর্দান্ত মোড়ক। এটি জেডিটির জটিলতা আড়াল করে এবং জাভা কোডটি বিশ্লেষণ, সংশোধন বা লেখার জন্য একটি দুর্দান্ত এপিআই সরবরাহ করে। github.com/forge/roaster
জিমিণী

4

অন্ধকার JET প্রকল্পের উৎস প্রজন্ম করতে ব্যবহার করা যাবে। আমি মনে করি না যে এটিআইপি আপনার বর্ণিতটির মতোই ঠিক, তবে প্রতিবারই আমি কোনও প্রকল্পের কথা শুনেছি জাভা উত্স উত্পাদন করছে তারা জেট বা হোমগ্রাউন সরঞ্জাম ব্যবহার করেছে।


3

কোনও গ্রন্থাগার সম্পর্কে জানেন না, তবে একটি জেনেরিক টেম্পলেট ইঞ্জিন আপনার প্রয়োজনীয় সমস্ত হতে পারে। তাদের মধ্যে একটি গুচ্ছ রয়েছে , আমি ব্যক্তিগতভাবে ফ্রিমার্কারের সাথে ভাল অভিজ্ঞতা অর্জন করেছি


2

আমি এমন কিছু তৈরি করেছি যা আপনার তাত্ত্বিক ডিএসএল এর মতো দেখতে খুব ভাল লাগে, "সোর্সজেন" নামে পরিচিত, তবে প্রযুক্তিগতভাবে আমি যে কোনও ওআরএম লিখেছিলাম তার কোনও ইউজেক্ট প্রকল্পের পরিবর্তে। ডিএসএল দেখে মনে হচ্ছে:

@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

এটি কিছু ঝরঝরে জিনিস যেমন প্যারামিটার / রিটার্নের ধরণের যে কোনও এফকিউসিএনগুলি "স্ব-সংগঠিত আমদানি করে", এই কোডজেন রানটিতে স্পর্শ না করা কোনও পুরানো ফাইলগুলি স্বয়ংক্রিয়ভাবে ছাঁটাই করা, সঠিকভাবে অভ্যন্তরীণ শ্রেণীর প্রবেশদ্বার ইত্যাদি etc.

ধারণাটি হ'ল উত্পন্ন কোডটি আপনার কোডের বাকী কোডগুলির মতো কোনও সতর্কতা (অব্যবহৃত আমদানি ইত্যাদি) ছাড়াই এটি দেখতে খুব সুন্দর হওয়া উচিত। এত উত্পন্ন কোডটি পড়তে কুৎসিত ... এটি ভয়াবহ।

যাইহোক, অনেকগুলি ডক নেই, তবে আমি মনে করি এপিআই বেশ সহজ / স্বজ্ঞাত। কেউ আগ্রহী হলে মাভেন রেপো এখানে


1

আপনার যদি সত্যই উত্সের প্রয়োজন হয় তবে উত্স উত্পন্ন করে এমন কোনও কিছুই আমি জানি না। তবে আপনি এএসএম বা সিজিএলআইবি ব্যবহার করতে পারেন আপনি সরাসরি। ফাইলগুলি তৈরি ।

আপনি এগুলি থেকে উত্স উত্পন্ন করতে সক্ষম হতে পারেন, তবে আমি কেবল এগুলি বাইকোড তৈরি করতে ব্যবহার করেছি।


1

আমি এটি মক জেনারেটরের সরঞ্জামের জন্য নিজেই করছিলাম। এটি খুব সাধারণ কাজ, এমনকি যদি আপনাকে সান ফর্ম্যাটিং গাইডলাইনগুলি অনুসরণ করতে হয় তবে। আমি বাজি ধরছি আপনি কোডটি দ্রুত সম্পন্ন করতে চাইলে আপনি ইন্টারনেটে আপনার লক্ষ্য অনুসারে এমন কিছু খুঁজে পেলেন।

আপনি মূলত এপিআই নিজেই রূপরেখার করেছেন। এখনই এটি আসল কোড দিয়ে পূরণ করুন!


হিহেহে ... যদি কোনও ফ্রেমওয়ার্ক না পাওয়া যায় তবে আমি এটি লিখতে যাচ্ছি। আমি অনেক কার্যকারিতা চাই তাই সকালে এটি পেলাম না ...
ড্যানিয়েল ফানজুল


1

নতুন প্রকল্প আছে এটি একবার লিখুন । টেমপ্লেট ভিত্তিক কোড জেনারেটর। গ্রোভিকে ব্যবহার করে আপনি কাস্টম টেম্পলেটটি লেখেন এবং জাভা প্রতিবিম্বের উপর নির্ভর করে ফাইল তৈরি করেন। এটি কোনও ফাইল উত্পন্ন করার সহজতম উপায়। আপনি AspectJ ফাইল, এসপিএল জেপিএ টীকাভিত্তিক উপর ভিত্তি করে, এনাম এবং অন্যান্য উপর ভিত্তি করে আপডেটগুলি তৈরি করে 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;
    }
}

0

এটি আপনি যা করার চেষ্টা করছেন তার উপর নির্ভর করে। কোড জেনারেশন নিজের মধ্যে একটি বিষয়। কোনও নির্দিষ্ট ব্যবহারের ক্ষেত্রে ছাড়াই, আমি বেগ কোড জেনারেশন / টেম্পলেট লাইব্রেরিটি দেখার পরামর্শ দিই। এছাড়াও, আপনি যদি কোড জেনারেশন অফলাইনে করছেন, আমি ইউএমএল ডায়াগ্রাম / অবজেক্ট মডেল থেকে জাভা কোডে যেতে ArgoUML এর মতো কিছু ব্যবহার করার পরামর্শ দেব।


0

উদাহরণ: 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//"));

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.