View Javadoc

1   /*
2   
3       dsh-codegen  Source code generation suite.
4       Copyright (c) 2004-2013 held jointly by the individual authors.
5   
6       This library is free software; you can redistribute it and/or modify it
7       under the terms of the GNU Lesser General Public License as published
8       by the Free Software Foundation; either version 3 of the License, or (at
9       your option) any later version.
10  
11      This library is distributed in the hope that it will be useful, but WITHOUT
12      ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
13      FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14      License for more details.
15  
16      You should have received a copy of the GNU Lesser General Public License
17      along with this library;  if not, write to the Free Software Foundation,
18      Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
19  
20      > http://www.fsf.org/licensing/licenses/lgpl.html
21      > http://www.opensource.org/licenses/lgpl-license.php
22  
23  */
24  package org.dishevelled.codegen;
25  
26  import java.io.File;
27  import java.io.FileWriter;
28  import java.io.IOException;
29  
30  import java.util.Properties;
31  
32  import org.apache.commons.lang.StringUtils;
33  
34  import org.apache.commons.io.FileUtils;
35  
36  import org.apache.velocity.Template;
37  import org.apache.velocity.VelocityContext;
38  
39  import org.apache.velocity.app.Velocity;
40  
41  /**
42   * Static source code generation methods.
43   *
44   * @author  Michael Heuer
45   */
46  public final class Codegen
47  {
48  
49      /**
50       * Private default constructor.
51       */
52      private Codegen()
53      {
54          // empty
55      }
56  
57  
58      /**
59       * Read license text from the specified file.
60       *
61       * @param license license file to read
62       * @return license text from the specified file or null if the
63       *   specified license file cannot be read
64       */
65      public static String readLicense(final String license)
66      {
67          String text = null;
68          try
69          {
70              text = FileUtils.readFileToString(new File(license));
71          }
72          catch (IOException e)
73          {
74              // ignore
75          }
76          return text;
77      }
78  
79      /**
80       * Generate a java source file for the specified interface
81       * description.
82       *
83       * @param id interface description, must not be null
84       */
85      public static void generateSource(final InterfaceDescription id)
86      {
87          if (id == null)
88          {
89              throw new IllegalArgumentException("id must not be null");
90          }
91  
92          FileWriter fw = null;
93          try
94          {
95              Properties p = new Properties();
96              p.setProperty("resource.loader", "class");
97              p.setProperty("class.resource.loader.class",
98                            "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
99  
100             Velocity.init(p);
101 
102             fw = new FileWriter(id.getUpper() + ".java");
103 
104             VelocityContext context = new VelocityContext();
105             context.put("id", id);
106             context.put("CodegenUtils", new CodegenUtils());
107             context.put("StringUtils", new StringUtils());
108 
109             Template template = Velocity.getTemplate("org/dishevelled/codegen/Interface.wm");
110             template.merge(context, fw);
111         }
112         catch (Exception e)
113         {
114             e.printStackTrace();
115             System.exit(1);
116         }
117         finally
118         {
119             try
120             {
121                 fw.close();
122             }
123             catch (Exception e)
124             {
125                 // empty
126             }
127         }
128     }
129 
130     /**
131      * Generate an abstract unit test java source file for the specified interface
132      * description.
133      *
134      * @param id interface description, must not be null
135      */
136     public static void generateAbstractUnitTest(final InterfaceDescription id)
137     {
138         if (id == null)
139         {
140             throw new IllegalArgumentException("id must not be null");
141         }
142 
143         FileWriter fw = null;
144         try
145         {
146             Properties p = new Properties();
147             p.setProperty("resource.loader", "class");
148             p.setProperty("class.resource.loader.class",
149                           "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
150 
151             Velocity.init(p);
152 
153             fw = new FileWriter("Abstract" + id.getUpper() + "Test.java");
154 
155             VelocityContext context = new VelocityContext();
156             context.put("id", id);
157             context.put("CodegenUtils", new CodegenUtils());
158             context.put("StringUtils", new StringUtils());
159 
160             Template template = Velocity.getTemplate("org/dishevelled/codegen/AbstractInterfaceTest.wm");
161             template.merge(context, fw);
162         }
163         catch (Exception e)
164         {
165             e.printStackTrace();
166             System.exit(1);
167         }
168         finally
169         {
170             try
171             {
172                 fw.close();
173             }
174             catch (Exception e)
175             {
176                 // empty
177             }
178         }
179     }
180 
181     /**
182      * Generate a java source file for the specified class
183      * description and style.
184      *
185      * @param cd class description, must not be null
186      * @param style style, must not be null
187      */
188     public static void generateSource(final ClassDescription cd, final Style style)
189     {
190         if (cd == null)
191         {
192             throw new IllegalArgumentException("cd must not be null");
193         }
194         if (style == null)
195         {
196             throw new IllegalArgumentException("style must not be null");
197         }
198 
199         FileWriter fw = null;
200         try
201         {
202             Properties p = new Properties();
203             p.setProperty("resource.loader", "class");
204             p.setProperty("class.resource.loader.class",
205                           "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
206 
207             Velocity.init(p);
208 
209             fw = new FileWriter(cd.getUpper() + ".java");
210 
211             VelocityContext context = new VelocityContext();
212             context.put("cd", cd);
213             context.put("CodegenUtils", new CodegenUtils());
214             context.put("StringUtils", new StringUtils());
215 
216             Template template = Velocity.getTemplate("org/dishevelled/codegen/" + style + ".wm");
217             template.merge(context, fw);
218         }
219         catch (Exception e)
220         {
221             e.printStackTrace();
222             System.exit(1);
223         }
224         finally
225         {
226             try
227             {
228                 fw.close();
229             }
230             catch (Exception e)
231             {
232                 // empty
233             }
234         }
235     }
236 
237     /**
238      * Generate a java source file for a fluent builder API for the specified class
239      * description and style.
240      *
241      * @param cd class description, must not be null
242      * @param style style, must not be null
243      */
244     public static void generateBuilderSource(final ClassDescription cd, final Style style)
245     {
246         // TODO:  perhaps style doesn't matter here, if all the templates are the same
247         if (cd == null)
248         {
249             throw new IllegalArgumentException("cd must not be null");
250         }
251         if (style == null)
252         {
253             throw new IllegalArgumentException("style must not be null");
254         }
255 
256         FileWriter fw = null;
257         try
258         {
259             Properties p = new Properties();
260             p.setProperty("resource.loader", "class");
261             p.setProperty("class.resource.loader.class",
262                           "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
263 
264             Velocity.init(p);
265 
266             fw = new FileWriter(cd.getUpper() + "Builder.java");
267 
268             VelocityContext context = new VelocityContext();
269             context.put("cd", cd);
270             context.put("CodegenUtils", new CodegenUtils());
271             context.put("StringUtils", new StringUtils());
272 
273             Template template = Velocity.getTemplate("org/dishevelled/codegen/" + style + "Builder.wm");
274             template.merge(context, fw);
275         }
276         catch (Exception e)
277         {
278             e.printStackTrace();
279             System.exit(1);
280         }
281         finally
282         {
283             try
284             {
285                 fw.close();
286             }
287             catch (Exception e)
288             {
289                 // empty
290             }
291         }
292     }
293 
294     /**
295      * Generate a unit test source file for the specified class
296      * description and style.
297      *
298      * @param cd class description, must not be null
299      * @param style style, must not be null
300      */
301     public static void generateUnitTest(final ClassDescription cd, final Style style)
302     {
303         if (cd == null)
304         {
305             throw new IllegalArgumentException("cd must not be null");
306         }
307         if (style == null)
308         {
309             throw new IllegalArgumentException("style must not be null");
310         }
311 
312         FileWriter fw = null;
313         try
314         {
315             Properties p = new Properties();
316             p.setProperty("resource.loader", "class");
317             p.setProperty("class.resource.loader.class",
318                           "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
319 
320             Velocity.init(p);
321 
322             fw = new FileWriter(cd.getUpper() + "Test.java");
323 
324             VelocityContext context = new VelocityContext();
325             context.put("cd", cd);
326             context.put("CodegenUtils", new CodegenUtils());
327             context.put("StringUtils", new StringUtils());
328 
329             Template template = Velocity.getTemplate("org/dishevelled/codegen/" + style + "Test.wm");
330             template.merge(context, fw);
331         }
332         catch (Exception e)
333         {
334             e.printStackTrace();
335             System.exit(1);
336         }
337         finally
338         {
339             try
340             {
341                 fw.close();
342             }
343             catch (Exception e)
344             {
345                 // empty
346             }
347         }
348     }
349 
350     /**
351      * Generate an enum source file for the specified class description.
352      *
353      * @param cd class description, must not be null
354      */
355     public static void generateEnum(final ClassDescription cd)
356     {
357         if (cd == null)
358         {
359             throw new IllegalArgumentException("cd must not be null");
360         }
361 
362         FileWriter fw = null;
363         try
364         {
365             Properties p = new Properties();
366             p.setProperty("resource.loader", "class");
367             p.setProperty("class.resource.loader.class",
368                           "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
369 
370             Velocity.init(p);
371 
372             fw = new FileWriter(cd.getUpper() + ".java");
373 
374             VelocityContext context = new VelocityContext();
375             context.put("cd", cd);
376             context.put("CodegenUtils", new CodegenUtils());
377             context.put("StringUtils", new StringUtils());
378 
379             Template template = Velocity.getTemplate("org/dishevelled/codegen/Enum.wm");
380             template.merge(context, fw);
381         }
382         catch (Exception e)
383         {
384             e.printStackTrace();
385             System.exit(1);
386         }
387         finally
388         {
389             try
390             {
391                 fw.close();
392             }
393             catch (Exception e)
394             {
395                 // empty
396             }
397         }
398     }
399 
400     /**
401      * Generate an enum with lookup source file for the specified class description.
402      *
403      * @param cd class description, must not be null
404      */
405     public static void generateEnumWithLookup(final ClassDescription cd)
406     {
407         if (cd == null)
408         {
409             throw new IllegalArgumentException("cd must not be null");
410         }
411 
412         FileWriter fw = null;
413         try
414         {
415             Properties p = new Properties();
416             p.setProperty("resource.loader", "class");
417             p.setProperty("class.resource.loader.class",
418                           "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
419 
420             Velocity.init(p);
421 
422             fw = new FileWriter(cd.getUpper() + ".java");
423 
424             VelocityContext context = new VelocityContext();
425             context.put("cd", cd);
426             context.put("CodegenUtils", new CodegenUtils());
427             context.put("StringUtils", new StringUtils());
428 
429             Template template = Velocity.getTemplate("org/dishevelled/codegen/EnumWithLookup.wm");
430             template.merge(context, fw);
431         }
432         catch (Exception e)
433         {
434             e.printStackTrace();
435             System.exit(1);
436         }
437         finally
438         {
439             try
440             {
441                 fw.close();
442             }
443             catch (Exception e)
444             {
445                 // empty
446             }
447         }
448     }
449 }