KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > finalist > jag > util > VelocityTemplateEngine


1 /* Copyright (C) 2003 Finalist IT Group
2  *
3  * This file is part of JAG - the Java J2EE Application Generator
4  *
5  * JAG is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * JAG is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  * You should have received a copy of the GNU General Public License
14  * along with JAG; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  */

17
18 package com.finalist.jag.util;
19
20 import com.finalist.util.Diff;
21 import com.finalist.jaggenerator.HtmlContentPopUp;
22 import com.finalist.jaggenerator.JagGenerator;
23 import com.finalist.jaggenerator.modules.*;
24 import com.finalist.jag.JApplicationGen;
25
26 import javax.swing.*;
27 import java.io.File JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.StringWriter JavaDoc;
30 import java.util.Properties JavaDoc;
31 import java.util.Collection JavaDoc;
32 import java.util.Iterator JavaDoc;
33
34 import org.apache.velocity.app.Velocity;
35 import org.apache.velocity.app.VelocityEngine;
36 import org.apache.velocity.VelocityContext;
37 import org.apache.velocity.Template;
38 import org.apache.velocity.exception.ResourceNotFoundException;
39 import org.apache.velocity.exception.ParseErrorException;
40 import org.apache.log4j.lf5.LogLevel;
41
42 /**
43  * A TemplateEngine implementation for Apache's "Velocity" open-source templating engine.
44  * <p>
45  *
46  *
47  * @author Michael O'Connor
48  */

49 public class VelocityTemplateEngine implements TemplateEngine {
50    /**
51     * The templates should output a line beginning with FILE_HEADER to mark
52     * the boundary between output files. In this way, the output of one template
53     * can result in the creation of multiple files.
54     */

55    private static final String JavaDoc FILE_HEADER = "////File:";
56    private Boolean JavaDoc overwrite;
57    VelocityEngine ve = new VelocityEngine();
58
59
60    public int process(Collection JavaDoc documents, String JavaDoc outputDir) throws InterruptedException JavaDoc {
61       overwrite = null;
62       int totalNumberOfNewFiles = 0;
63       String JavaDoc templateDir = JagGenerator.jagGenerator.root.config.selectedTemplate.getTemplateDir().getAbsolutePath();
64       try {
65          //Initialise Velocity:
66
Properties JavaDoc props = new Properties JavaDoc();
67           //file.resource.loader.path
68
props.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, templateDir + "/templates");
69          props.setProperty(Velocity.FILE_RESOURCE_LOADER_CACHE, "false");
70          ve.init(props);
71       } catch (Exception JavaDoc e) {
72          JApplicationGen.log("FATAL: Can't initialise the Velocity template engine. Aborting! :" + e);
73          //this app runs in its own thread - so just quit!
74
System.exit(1);
75       }
76
77       VelocityContext context = initialiseContext();
78
79       JApplicationGen.createOutputStructure(templateDir);
80       JApplicationGen.log("Number of template files found : " + documents.size() + "\n");
81       Iterator JavaDoc iterator = documents.iterator();
82       while (iterator.hasNext()) {
83          File JavaDoc templateFile = (File JavaDoc) iterator.next();
84          String JavaDoc relativePath = templateFile.getPath().substring((templateDir + "/templates/").length());
85          Template template = null;
86          try {
87
88             template = ve.getTemplate(relativePath);
89          } catch (ResourceNotFoundException rnfe) {
90             JApplicationGen.log("Velocity template error: cannot find template " + relativePath + ":" + rnfe, LogLevel.ERROR);
91          } catch (ParseErrorException pee) {
92             JApplicationGen.log("Velocity template error: Syntax error in template " + relativePath + ":" + pee, LogLevel.ERROR);
93          } catch (Exception JavaDoc e) {
94             JApplicationGen.log("Velocity template error: template " + relativePath + ":" + e, LogLevel.ERROR);
95          }
96          if (template == null) continue;
97
98          StringWriter JavaDoc writer = new StringWriter JavaDoc();
99          try {
100             JApplicationGen.log("[Processing " + relativePath + "]");
101             template.merge(context, writer);
102             writer.flush();
103             if (writer.toString().indexOf(FILE_HEADER) != -1) {
104                FileCreationResult result = createOutputFiles(outputDir, writer.toString());
105
106                if (result.created == 0 && result.skipped == 0) {
107                   JApplicationGen.log("No files generated by : "
108                                       + relativePath);
109                }
110                if (result.skipped > 0) {
111                   JApplicationGen.log("Skipped generation of " + result.skipped +
112                                       (result.skipped == 1 ? " file." : " files."));
113                }
114                if (result.created > 0) {
115                   JApplicationGen.log("Created " + result.created + " new " +
116                                       (result.created == 1 ? "file" : "files") +
117                                       " from template " + relativePath);
118                }
119                totalNumberOfNewFiles += result.created;
120             }
121
122          } catch (Exception JavaDoc e) {
123             JApplicationGen.log("Velocity parser error: template " + templateFile.getName() + ":" + e, LogLevel.ERROR);
124             e.printStackTrace();
125          } finally {
126             try {
127                writer.close();
128             } catch (IOException JavaDoc e) {
129             }
130          }
131       }
132
133       return totalNumberOfNewFiles;
134    }
135
136    public void setOverwrite(Boolean JavaDoc overwrite) {
137       this.overwrite = overwrite;
138    }
139
140    /**
141     * Sets up the Velocity context: where objects are placed that will be needed by the templates.
142     *
143     * @return the context.
144     */

145    private VelocityContext initialiseContext() {
146       VelocityContext context = new VelocityContext();
147
148       context.put("config", JagGenerator.getObjectsFromTree(Config.class).get(0));
149       context.put("app", JagGenerator.getObjectsFromTree(App.class).get(0));
150       context.put("paths", JagGenerator.getObjectsFromTree(Paths.class).get(0));
151       context.put("datasource", JagGenerator.getObjectsFromTree(Datasource.class).get(0));
152       context.put("entities", JagGenerator.getObjectsFromTree(Entity.class));
153       context.put("sessions", JagGenerator.getObjectsFromTree(Session.class));
154
155       return context;
156    }
157
158    private FileCreationResult createOutputFiles(String JavaDoc outputDir, String JavaDoc parseResult) throws InterruptedException JavaDoc {
159       int newFileCounter = 0;
160       int skippedFilesCounter = 0;
161       // In case of windows \r\n will be found. On linux \n will be found.
162
char newline = parseResult.indexOf('\r') != -1 ? '\r' : '\n';
163       int pos = parseResult.indexOf(FILE_HEADER);
164       while (pos != -1) {
165          boolean skipFile = false;
166          int nextPos = parseResult.indexOf(FILE_HEADER, pos + 1);
167          nextPos = nextPos == -1 ? parseResult.length() : nextPos;
168          String JavaDoc fileContent = parseResult.substring(pos, nextPos);
169          int endHeaderPos = fileContent.indexOf(newline);
170          if (endHeaderPos == -1) {
171             JApplicationGen.log("Bad template: expected newline after header.");
172             return new FileCreationResult(0, 0);
173          }
174          String JavaDoc header = fileContent.substring(0, endHeaderPos).trim();
175          fileContent = fileContent.substring(endHeaderPos).trim();
176          if ("".equals(fileContent)) {
177             JApplicationGen.log("Warning! - Empty file - probably a bad template.");
178          }
179
180          int fileNamePos = header.indexOf(':');
181          if (fileNamePos == -1 || fileNamePos == (header.length() - 1)) {
182             JApplicationGen.log("Bad template: header doesn't specify an output file.");
183             return new FileCreationResult(0, 0);
184          }
185          String JavaDoc fileName = header.substring(header.indexOf(':') + 1).trim();
186          File JavaDoc origFile = new File JavaDoc(outputDir + '/' + fileName);
187          File JavaDoc tempFile = new File JavaDoc(outputDir + '/' + fileName + "_temp");
188
189          try {
190             // Add a newline at the end of the file.
191
if (newline == '\r') {
192                 fileContent += "\r\n";
193             } else {
194                 fileContent += "\r";
195             }
196             FileUtils.createFile(tempFile, fileContent);
197
198             if (origFile.exists()) {
199                if (overwrite != Boolean.FALSE) {
200                   String JavaDoc diff = null;
201                   try {
202                      diff = new Diff(origFile, tempFile).performDiff();
203                      int choice = 999;
204                      if (diff != null) {
205                         if (overwrite == null) {
206                            while (choice == 999 || JApplicationGen.DIALOGUE_OPTIONS[choice] == JApplicationGen.OPTION_VIEW_DIFF) {
207                               choice = JOptionPane.showOptionDialog(null,
208                                                                     "The file " + origFile + " differs from the existing copy.\n" +
209                                                                     "Do you want to overwrite this file?",
210                                                                     "File already exists!",
211                                                                     JOptionPane.YES_NO_CANCEL_OPTION,
212                                                                     JOptionPane.QUESTION_MESSAGE,
213                                                                     null,
214                                                                     JApplicationGen.DIALOGUE_OPTIONS,
215                                                                     JApplicationGen.OPTION_VIEW_DIFF);
216                               if (JApplicationGen.DIALOGUE_OPTIONS[choice] == JApplicationGen.OPTION_VIEW_DIFF) {
217                                  new HtmlContentPopUp(null, "Diff report:", true, diff, false).show();
218                               }
219                            }
220                            if (choice == JOptionPane.CLOSED_OPTION ||
221                                JApplicationGen.DIALOGUE_OPTIONS[choice] == JApplicationGen.OPTION_NO) {
222                               skipFile = true;
223                            }
224                            else if (JApplicationGen.DIALOGUE_OPTIONS[choice] == JApplicationGen.OPTION_NO_ALL) {
225                               overwrite = Boolean.FALSE;
226                               skipFile = true;
227                            }
228                            else if (JApplicationGen.DIALOGUE_OPTIONS[choice] == JApplicationGen.OPTION_YES_ALL) {
229                               overwrite = Boolean.TRUE;
230                            }
231                         }
232                      } else {
233                         skipFile = true;
234                      }
235                   } catch (IOException JavaDoc e) {
236                      JApplicationGen.log("Error! Can't perform diff - file '" + origFile.getPath() +
237                                          "' will not be overwritten: " + e);
238                      skipFile = true;
239                   }
240                } else {
241                   skipFile = true;
242                }
243             }
244
245          } catch (IOException JavaDoc e) {
246             JApplicationGen.log("Error! Can't create temp file: " + tempFile.getPath() + " - " + e);
247             tempFile = null;
248          }
249
250          if (skipFile) {
251             JApplicationGen.log("Skipping file " + origFile);
252             FileUtils.deleteFile(tempFile);
253             skippedFilesCounter++;
254          } else if (tempFile != null) {
255             newFileCounter++;
256             if (origFile.exists()) {
257                JApplicationGen.log("Backing up and overwriting " + origFile);
258                File JavaDoc backup = new File JavaDoc(origFile.getPath() + ".backup");
259                FileUtils.deleteFile(backup);
260                origFile.renameTo(backup);
261                FileUtils.deleteFile(origFile);
262             } else {
263                JApplicationGen.log("Creating new file " + origFile);
264             }
265             tempFile.renameTo(origFile);
266          }
267
268          parseResult = parseResult.substring(nextPos);
269          pos = parseResult.indexOf(FILE_HEADER);
270       }
271
272       return new FileCreationResult(newFileCounter, skippedFilesCounter);
273    }
274
275 }
276
Popular Tags