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 }