-
Notifications
You must be signed in to change notification settings - Fork 34
How Tos
Philip Helger edited this page Dec 21, 2020
·
5 revisions
This page contains code snippets and the created outcome, mainly based on the test cases available.
- The most relevant object is
JCodeModel
- it contains all the data structures files etc for a single generation run. Sofinal JCodeModel cm = new JCodeModel ();
is always a good starting point. - Afterwards you can create classes, interfaces and enumerations but you can also add resource files (like XML or SQL files) as part of your generated code. The example code snippet (see below for more)
cm._package ("org.example")._class ("MyFirstClass");
would create the directory structureorg/example
and create a fileMyFirstClass.java
in that new directory. - Once all of the code is generated, you need to serialize it to disk. The relevant class to do this is
JCMWriter
. It takes an instance ofJCodeModel
as a constructor argument, lets you customize the output a bit and via thebuild
method the results are written to a directory on disk (via theFile
-based methods) or onto a genericWriter
of your choice. Different base directory for Java-classes and resources can be provided to accomodate e.g. the requirements of the Maven folder structure.
- You can create invalid Java code - there is no syntax or consistency checker build-in
Create a class with one field and one getter and one setter
final JCodeModel cm = new JCodeModel ();
final JDefinedClass jClass = cm._package ("org.example")._class ("MyFirstClass");
final JFieldVar jField = jClass.field (JMod.PRIVATE, String.class, "text");
// getter
final JMethod jGet = jClass.method (JMod.PUBLIC, String.class, "getText");
jGet.body ()._return (jField);
// setter
final JMethod jSet = jClass.method (JMod.PUBLIC, cm.VOID, "setText");
final JVar jParam = jSet.param (String.class, "text");
jSet.body ().assign (JExpr._this ().ref (jField), jParam);
Created Java code:
package org.example;
public class MyFirstClass {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
The second class enhances the first class with two constructor - one that has no argument and one that has a constructor parameter. Additionally Javadoc comments are created to make the code more explaining.
Note: for the rest of the examples no Javadocs are emitted for the sake of improved readability
final JCodeModel cm = new JCodeModel ();
final JDefinedClass jClass = cm._package ("org.example")._class ("MySecondClass");
jClass.javadoc ().add ("This is my second class comment");
jClass.javadoc ().addAuthor ().add ("JCodeModel authors");
final JFieldVar jField = jClass.field (JMod.PRIVATE, String.class, "text");
// Empty constructor
JMethod jCtor = jClass.constructor (JMod.PUBLIC);
jCtor.javadoc ().add ("This is a no-argument constructor");
// Constructor with Parameter
jCtor = jClass.constructor (JMod.PUBLIC);
JVar jParam = jCtor.param (String.class, "text");
jCtor.body ().assign (JExpr._this ().ref (jField), jParam);
jCtor.javadoc ().add ("This is the constructor with a parameter");
jCtor.javadoc ().addParam (jParam).add ("The new text to be set");
// getter
final JMethod jGet = jClass.method (JMod.PUBLIC, String.class, "getText");
jGet.body ()._return (jField);
jGet.javadoc ().add ("This is a getter");
jGet.javadoc ().addReturn ().add ("The text value");
// setter
final JMethod jSet = jClass.method (JMod.PUBLIC, cm.VOID, "setText");
jParam = jSet.param (String.class, "text");
jSet.body ().assign (JExpr._this ().ref (jField), jParam);
jSet.javadoc ().add ("This is a setter");
jSet.javadoc ().addParam (jParam).add ("The new text to be set");
Created Java code:
package org.example;
/**
* This is my second class comment
*
* @author JCodeModel authors
*/
public class MySecondClass {
private String text;
/**
* This is a no-argument constructor
*/
public MySecondClass() {
}
/**
* This is the constructor with a parameter
*
* @param text
* The new text to be set
*/
public MySecondClass(String text) {
this.text = text;
}
/**
* This is a getter
*
* @return
* The text value
*/
public String getText() {
return text;
}
/**
* This is a setter
*
* @param text
* The new text to be set
*/
public void setText(String text) {
this.text = text;
}
}
final JCodeModel cm = JCodeModel.createUnified ();
final JDefinedClass jClass = cm._package ("org.example")._class ("SwitchTest");
final JDefinedClass jEnumClass = jClass._enum ("MyEnum");
final JEnumConstant ca = jEnumClass.enumConstant ("A");
final JEnumConstant cb = jEnumClass.enumConstant ("B");
jEnumClass.enumConstant ("C");
final JMethod m = jClass.method (JMod.PUBLIC, cm.VOID, "dummy");
final JVar p = m.param (JMod.FINAL, jEnumClass, "enumParam");
final JSwitch s = m.body ()._switch (p);
s._case (ca).body ()._break ();
s._case (cb).body ()._break ();
s._default ().body ()._break ();
Create Java code:
package org.example;
public class SwitchTest {
public void dummy(final SwitchTest.MyEnum enumParam) {
switch (enumParam) {
case A:
{
break;
}
case B:
{
break;
}
default:
{
break;
}
}
}
public enum MyEnum {
A,
B,
C;
}
}
Creating a simple for-each loop in a static method.
final JCodeModel cm = JCodeModel.createUnified ();
final JDefinedClass cls = cm._package ("org.example")._class ("TestForEach");
final JMethod m = cls.method (JMod.PUBLIC | JMod.STATIC, cm.VOID, "foo");
final AbstractJClass jClassList = cm.ref (List.class).narrow (Integer.class);
final JVar jVarList = m.body ().decl (JMod.FINAL, jClassList, "alist", cm.ref (ArrayList.class).narrowEmpty ()._new ());
m.body ().add (jVarList.invoke ("add").arg (1));
m.body ().add (jVarList.invoke ("add").arg (2));
// The main for-each
final JForEach foreach = m.body ().forEach (JMod.FINAL, cm.ref (Integer.class), "count", jVarList);
// printing out the variable
foreach.body ().add (cm.ref (System.class).staticRef ("out").invoke ("println").arg (foreach.var ()));
Create Java code:
package org.example;
import java.util.ArrayList;
import java.util.List;
public class TestForEach {
public static void foo() {
final List<Integer> alist = new ArrayList<>();
alist.add(1);
alist.add(2);
for (final Integer count: alist) {
System.out.println(count);
}
}
}
final JCodeModel cm = JCodeModel.createUnified ();
final JDefinedClass aClass = cm._class ("org.test.DaTestClass");
final JDefinedClass daInner1 = aClass._class ("Inner");
final JDefinedClass daInnerInner = daInner1._class ("InnerInner");
final JDefinedClass daInner2 = aClass._class ("DaTestClassInner");
final JDefinedClass daInner2Inner = daInner2._class ("Inner2");
aClass.method (JMod.PUBLIC, daInner1, "getInner");
aClass.method (JMod.PUBLIC, daInnerInner, "getInnerInner");
aClass.method (JMod.PUBLIC, daInner2, "getInner2");
aClass.method (JMod.PUBLIC, daInner2Inner, "getInner2Inner");
final JDefinedClass otherClass = cm._class ("org.test.OtherClass");
otherClass.method (JMod.PUBLIC, daInner1, "getInner");
otherClass.method (JMod.PUBLIC, daInnerInner, "getInnerInner");
otherClass.method (JMod.PUBLIC, daInner2Inner, "getInner2Inner");
otherClass.method (JMod.PUBLIC, aClass, "getOuter");
Created Java code org/test/DaTestClass.java
:
package org.test;
public class DaTestClass {
public DaTestClass.Inner getInner() {
}
public DaTestClass.Inner.InnerInner getInnerInner() {
}
public DaTestClassInner getInner2() {
}
public DaTestClassInner.Inner2 getInner2Inner() {
}
public class DaTestClassInner {
public class Inner2 {
}
}
public class Inner {
public class InnerInner {
}
}
}
Created Java code org/test/OtherClass.java
:
package org.test;
import org.test.DaTestClass.DaTestClassInner;
public class OtherClass {
public DaTestClass.Inner getInner() {
}
public DaTestClass.Inner.InnerInner getInnerInner() {
}
public DaTestClassInner.Inner2 getInner2Inner() {
}
public DaTestClass getOuter() {
}
}
To create a method foo
with variable arguments:
final JCodeModel cm = new JCodeModel ();
final JDefinedClass cls = cm._package ("org.example")._class ("TestVarArgs");
final JMethod m = cls.method (JMod.PUBLIC, cm.VOID, "foo");
m.param (String.class, "param1");
m.param (Integer.class, "param2");
// That is the VarArg param
final JVar jParam3 = m.varParam (String.class, "param3");
final JForLoop forloop = m.body ()._for ();
final JVar jcount = forloop.init (cm.INT, "count", JExpr.lit (0));
forloop.test (jcount.lt (jParam3.ref ("length")));
forloop.update (jcount.incr ());
forloop.body ().add (cm.ref (System.class).staticRef ("out").invoke ("println").arg (jParam3.component (jcount)));
final JMethod main = cls.method (JMod.PUBLIC | JMod.STATIC, cm.VOID, "main");
main.param (String [].class, "args");
main.body ().add (cls._new ().invoke (m)
.arg ("Param1")
.arg (cm.ref (Integer.class).staticInvoke ("valueOf").arg (5))
.arg ("Param 3a")
.arg ("Param 3b"));
Create Java code:
package org.example;
public class TestVarArgs {
public void foo(String param1, Integer param2, String... param3) {
for (int count = 0; (count<param3 .length); count ++) {
System.out.println(param3 [count]);
}
}
public static void main(String[] args) {
new TestVarArgs().foo("Param1", Integer.valueOf(5), "Param 3a", "Param 3b");
}
}
TODO