View Javadoc
1   package net.sourceforge.jenesis4java.example;
2   
3   /*
4    * #%L
5    * Jenesis 4 Java Code Generator
6    * %%
7    * Copyright (C) 2000 - 2015 jenesis4java
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation, either version 3 of the
12   * License, or (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Lesser Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Lesser Public
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22   * #L%
23   */
24  
25  /**
26   * Copyright (C) 2008 Richard van Nieuwenhoven - ritchie [at] gmx [dot] at
27   * Copyright (C) 2000, 2001 Paul Cody Johnston - pcj@inxar.org This program is
28   * free software; you can redistribute it and/or modify it under the terms of
29   * the GNU Lesser General Public License as published by the Free Software
30   * Foundation; either version 2 of the License, or (at your option) any later
31   * version. This program is distributed in the hope that it will be useful, but
32   * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
33   * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
34   * for more details. You should have received a copy of the GNU Lesser General
35   * Public License along with this program; if not, write to the Free Software
36   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
37   */
38  
39  import net.sourceforge.jenesis4java.*;
40  
41  import java.io.ByteArrayOutputStream;
42  import java.io.File;
43  import java.io.IOException;
44  import java.io.InputStream;
45  
46  /**
47   * Example which generates a class which prints "Hello World!" to standard
48   * output.
49   */
50  class HelloWorldExample {
51  
52      public static void main(String[] argv) throws Exception {
53          long start = System.currentTimeMillis(), time;
54  
55          File temp = new File("target/testgenerate");
56          temp.mkdirs();
57  
58          if (!temp.isDirectory()) {
59              System.out.println("Error creating temp directories!");
60              return;
61          }
62  
63          final String pathToGeneratedFile = temp.getCanonicalPath() + "/com/example/jenesis/HelloWorld.java";
64          File generatedFile = new File(temp, "/com/example/jenesis/HelloWorld.java");
65  
66          // delete the file if it already exists from a previous run
67          if (generatedFile.exists()) {
68              generatedFile.delete();
69          }
70  
71          // Get the VirtualMachine implementation.
72          VirtualMachine vm = VirtualMachine.getVirtualMachine();
73  
74          // Instantiate a new CompilationUnit. The argument to the
75          // compilation unit is the "codebase" or directory where the
76          // compilation unit should be written.
77          //
78          // Make a new compilation unit rooted to the given sourcepath.
79          CompilationUnit unit = vm.newCompilationUnit(temp.getCanonicalPath());
80  
81          // Set the package namespace.
82          unit.setNamespace("com.example.jenesis");
83  
84          // Add an import statement for fun.
85          unit.addImport("java.io.Serializable");
86  
87          // Comment the package with a javadoc (DocumentationComment).
88          unit.setComment(Comment.DOCUMENTATION, "Auto-Generated using the Jenesis Syntax API");
89  
90          // Make a new class.
91          PackageClass cls = unit.newClass("HelloWorld");
92          // Make it a public class.
93          cls.setAccess(Access.PUBLIC);
94          // Extend Object just for fun.
95          cls.setExtends("Object");
96          // Implement serializable just for fun.
97          cls.addImplements("Serializable");
98          // Comment the class with a javadoc (DocumentationComment).
99          unit.setComment(Comment.DOCUMENTATION, "The HelloWorld example class.");
100 
101         // Make a new Method in the Class having type VOID and name "main".
102         ClassMethod method = cls.newMethod(vm.newType(Type.VOID), "main");
103         // Make it a public method.
104         method.setAccess(Access.PUBLIC);
105         // Make it a static method
106         method.isStatic(true);
107         // Add the "String[] argv" formal parameter.
108         method.addParameter(vm.newArray("String", 1), "argv");
109 
110         // Create a new Method Invocation expression.
111         Invoke println = vm.newInvoke("System.out", "println");
112         // Add the Hello World string literal as the sole argument.
113         println.addArg(vm.newString("Hello World!"));
114         // Add this expression to the method in a statement.
115         method.newStmt(println);
116 
117         time = System.currentTimeMillis() - start;
118         System.out.println("constructed in " + time + " ms");
119 
120         // Encode the file, compile it, and load the class
121         unit.encode();
122 
123         Process exec = Runtime.getRuntime().exec(new String[]{
124             "javac",
125             "-d",
126             "target/classes",
127             generatedFile.getCanonicalPath()
128         });
129         exec.waitFor();
130         if (exec.exitValue() != 0) {
131             String streambuffer1 = readStream(exec.getErrorStream());
132             String streambuffer2 = readStream(exec.getInputStream());
133 
134             throw new RuntimeException(streambuffer1 + "\n" + streambuffer2);
135         }
136         Class<?> hello = Thread.currentThread().getContextClassLoader().loadClass("com.example.jenesis.HelloWorld");
137 
138         time = System.currentTimeMillis() - start;
139         System.out.println("loaded in " + time + " ms");
140         // Get the main method
141         java.lang.reflect.Method main = hello.getMethod("main", String[].class);
142 
143         // Invoke it
144         main.invoke(hello.newInstance(), new Object[]{
145             new String[]{}
146         });
147 
148         time = System.currentTimeMillis() - start;
149         System.out.println("done in " + time + " ms");
150     }
151 
152     private static String readStream(InputStream error) throws IOException {
153         ByteArrayOutputStream errorBytes = new ByteArrayOutputStream();
154         int count;
155         byte[] buffer = new byte[4096];
156         while ((count = error.read(buffer)) >= 0) {
157             errorBytes.write(buffer, 0, count);
158         }
159         return new String(buffer);
160     }
161 }