001    package nl.tudelft.tbm.eeni.owl2java.generator;
002    
003    import nl.tudelft.tbm.eeni.owl2java.formatter.CodeFormattingWriter;
004    import nl.tudelft.tbm.eeni.owl2java.model.jmodel.JClass;
005    import nl.tudelft.tbm.eeni.owl2java.model.jmodel.JModel;
006    import nl.tudelft.tbm.eeni.owl2java.model.jmodel.JPackage;
007    import nl.tudelft.tbm.eeni.owl2java.model.jmodel.utils.NamingUtils;
008    import nl.tudelft.tbm.eeni.owl2java.model.xsd.XsdMapTestData;
009    import nl.tudelft.tbm.eeni.owl2java.utils.JavaUtils;
010    import org.apache.commons.logging.Log;
011    import org.apache.commons.logging.LogFactory;
012    import org.apache.velocity.Template;
013    import org.apache.velocity.VelocityContext;
014    import org.apache.velocity.app.VelocityEngine;
015    import org.apache.velocity.exception.ParseErrorException;
016    import org.apache.velocity.exception.ResourceNotFoundException;
017    
018    import java.io.File;
019    import java.io.FileWriter;
020    import java.io.IOException;
021    import java.io.Writer;
022    import java.text.DateFormat;
023    import java.util.Calendar;
024    import java.util.Iterator;
025    import java.util.Properties;
026    
027    
028    public class JavaWriter {
029        private static final String TEMPLATE_ROOT = JavaWriter.class.getResource("") + "templates/";
030    
031        private static final String TEMPLATE_CLASS = "class.vm";
032        private static final String TEMPLATE_FACTORY = "factory.vm";
033        private static final String TEMPLATE_INTERFACE = "interface.vm";
034        private static final String TEMPLATE_TEST = "test.vm";
035        private static final String TEMPLATE_VOCABULARY = "vocabulary.vm";
036    
037        static Log log = LogFactory.getLog(JavaWriter.class);
038    
039        private String baseDir;
040        private String basePackage;
041        private Properties codeFormatterOptions;
042        private boolean enableCodeFormatting;
043        private String factoryName;
044        private boolean generateTestClass;
045        private JModel jmodel;
046        private String testClassName;
047        private String toolsPackage;
048        private VelocityEngine vEngine;
049        private String vocabularyName;
050    
051        public void generate(JModel model, String baseDir, String basePackage) {
052            this.baseDir = baseDir;
053            jmodel = model;
054            this.basePackage = basePackage;
055    
056            log.info("");
057            log.info("Writing JModel to java");
058    
059            // create the package structure
060            createPackageDirectories();
061    
062            // init the templating engine
063            initVelocityEngine();
064    
065            // write interfaces
066            createInterfaces();
067    
068            // write classes
069            createClasses();
070    
071            // write vocabulary
072            createVocabulary();
073    
074            // write factory
075            createFactory();
076    
077            // write testclass
078            if (generateTestClass) {
079                createTestClass();
080            }
081    
082        }
083    
084        public void setCodeFormatterOptions(Properties codeFormatterOptions) {
085            this.codeFormatterOptions = codeFormatterOptions;
086        }
087    
088        public void setCreateTestClass(boolean createTestClass) {
089            generateTestClass = createTestClass;
090        }
091    
092        public void setEnableCodeFormatting(boolean enableCodeFormatting) {
093            this.enableCodeFormatting = enableCodeFormatting;
094        }
095    
096        public void setFactoryName(String factoryName) {
097            this.factoryName = factoryName;
098        }
099    
100        public void setTestClassName(String testClassName) {
101            this.testClassName = testClassName;
102        }
103    
104        public void setToolsPackage(String toolsPackage) {
105            this.toolsPackage = toolsPackage;
106        }
107    
108        public void setVocabularyName(String vocabularyName) {
109            this.vocabularyName = vocabularyName;
110        }
111    
112        private void createClasses() {
113            log.info("Creating java classes");
114            Iterator<JClass> clsIt = jmodel.listJClasses().iterator();
115            while (clsIt.hasNext()) {
116                JClass cls = clsIt.next();
117                String outDir = JavaUtils.toDirectoryFromPackage(cls.getJavaPackageName(), baseDir);
118                String outName = cls.getJavaClassName();
119                String outPath = outDir + "/" + outName + ".java";
120                log.info("Creating class " + outName);
121                log.debug("Creating class as " + outPath);
122    
123                Template template;
124                try {
125                    template = vEngine.getTemplate(TEMPLATE_CLASS);
126                } catch (ResourceNotFoundException e) {
127                    throw new RuntimeException();
128                } catch (ParseErrorException e) {
129                    throw new RuntimeException();
130                } catch (Exception e) {
131                    throw new RuntimeException();
132                }
133    
134                VelocityContext vContext = getBaseVelocityContext();
135                vContext.put("cls", cls);
136    
137                try {
138                    Writer writer = getCodeWriter(outPath);
139                    template.merge(vContext, writer);
140                    writer.close();
141                } catch (Exception e) {
142                    throw new RuntimeException(e);
143                }
144            }
145        }
146    
147        private void createFactory() {
148            String pkgName = NamingUtils.getJavaPackageName(basePackage, toolsPackage);
149            String outDir = JavaUtils.toDirectoryFromPackage(pkgName, baseDir);
150            String outName = factoryName;
151            String outPath = outDir + "/" + outName + ".java";
152            log.debug("Creating factory " + outPath);
153    
154            Template template;
155            try {
156                template = vEngine.getTemplate(TEMPLATE_FACTORY);
157            } catch (ResourceNotFoundException e) {
158                throw new RuntimeException();
159            } catch (ParseErrorException e) {
160                throw new RuntimeException();
161            } catch (Exception e) {
162                throw new RuntimeException();
163            }
164    
165            try {
166                Writer writer = getCodeWriter(outPath);
167                template.merge(getBaseVelocityContext(), writer);
168                writer.close();
169            } catch (Exception e) {
170                throw new RuntimeException(e);
171            }
172        }
173    
174        private void createInterfaces() {
175            log.info("Creating java interfaces");
176    
177            Iterator<JClass> clsIt = jmodel.listJClasses().iterator();
178            while (clsIt.hasNext()) {
179                JClass cls = clsIt.next();
180                String outDir = JavaUtils.toDirectoryFromPackage(cls.getJavaPackageName(), baseDir);
181                String outName = cls.getJavaInterfaceName();
182                String outPath = outDir + "/" + outName + ".java";
183                log.info("Creating interface " + outName);
184                log.debug("Creating interface as " + outPath);
185    
186                Template template;
187                try {
188                    template = vEngine.getTemplate(TEMPLATE_INTERFACE);
189                } catch (ResourceNotFoundException e) {
190                    throw new RuntimeException(e);
191                } catch (ParseErrorException e) {
192                    throw new RuntimeException();
193                } catch (Exception e) {
194                    throw new RuntimeException();
195                }
196    
197                VelocityContext vContext = getBaseVelocityContext();
198                vContext.put("cls", cls);
199    
200                try {
201                    Writer writer = getCodeWriter(outPath);
202                    template.merge(vContext, writer);
203                    writer.close();
204                } catch (Exception e) {
205                    throw new RuntimeException(e);
206                }
207            }
208        }
209    
210        private void createPackageDirectories() {
211            boolean success = true;
212    
213            log.info("Creating directory structure");
214            // create base directory
215            log.debug("Creating base directory " + baseDir);
216            success &= new File(baseDir).mkdirs();
217    
218            // dito for all package directories
219            Iterator<JPackage> pkgIt = jmodel.listPackages().iterator();
220            while (pkgIt.hasNext()) {
221                JPackage pkg = pkgIt.next();
222                if (pkg.listJClasses().size() > 0) {
223                    String pkgName = pkg.getPackageName();
224                    String pkgDir = JavaUtils.toDirectoryFromPackage(pkgName, baseDir);
225                    log.debug("Creating directory for package " + pkgName);
226                    success &= new File(pkgDir).mkdirs();
227                }
228            }
229            // finally for the tools package
230            String pkgName = NamingUtils.getJavaPackageName(basePackage, toolsPackage);
231            String pkgDir = JavaUtils.toDirectoryFromPackage(pkgName, baseDir);
232            log.debug("Creating tools directory for package " + pkgName);
233            success &= new File(pkgDir).mkdirs();
234        }
235    
236        private void createTestClass() {
237            String pkgName = NamingUtils.getJavaPackageName(basePackage, toolsPackage);
238            String outDir = JavaUtils.toDirectoryFromPackage(pkgName, baseDir);
239            String outName = testClassName;
240            String outPath = outDir + "/" + outName + ".java";
241            log.debug("Creating test cases " + outPath);
242    
243            Template template;
244            try {
245                template = vEngine.getTemplate(TEMPLATE_TEST);
246            } catch (ResourceNotFoundException e) {
247                throw new RuntimeException();
248            } catch (ParseErrorException e) {
249                throw new RuntimeException();
250            } catch (Exception e) {
251                throw new RuntimeException();
252            }
253    
254            try {
255                Writer writer = getCodeWriter(outPath);
256                template.merge(getBaseVelocityContext(), writer);
257                writer.close();
258            } catch (Exception e) {
259                throw new RuntimeException(e);
260            }
261        }
262    
263        private void createVocabulary() {
264            String pkgName = NamingUtils.getJavaPackageName(basePackage, toolsPackage);
265            String outDir = JavaUtils.toDirectoryFromPackage(pkgName, baseDir);
266            String outName = vocabularyName;
267            String outPath = outDir + "/" + outName + ".java";
268            log.debug("Creating vocabulary " + outPath);
269    
270            Template template;
271            try {
272                template = vEngine.getTemplate(TEMPLATE_VOCABULARY);
273            } catch (ResourceNotFoundException e) {
274                throw new RuntimeException();
275            } catch (ParseErrorException e) {
276                throw new RuntimeException();
277            } catch (Exception e) {
278                throw new RuntimeException();
279            }
280    
281            try {
282                Writer writer = getCodeWriter(outPath);
283                template.merge(getBaseVelocityContext(), writer);
284                writer.close();
285            } catch (Exception e) {
286                throw new RuntimeException(e);
287            }
288        }
289    
290        private VelocityContext getBaseVelocityContext() {
291            // add some default stuff to our context. These are reused over all
292            // writers
293            VelocityContext vContext = new VelocityContext();
294            Calendar c = Calendar.getInstance();
295            vContext.put("now", DateFormat.getInstance().format(c.getTime()));
296            vContext.put("pkgBase", basePackage);
297            vContext.put("pkgTools", toolsPackage);
298            vContext.put("jmodel", jmodel);
299            vContext.put("factoryName", factoryName);
300            vContext.put("factoryPkg", NamingUtils.getJavaPackageName(basePackage, toolsPackage));
301            vContext.put("vocabName", vocabularyName);
302            vContext.put("vocabPkg", NamingUtils.getJavaPackageName(basePackage, toolsPackage));
303            vContext.put("testcaseName", testClassName);
304            vContext.put("testcasePkg", NamingUtils.getJavaPackageName(basePackage, toolsPackage));
305            XsdMapTestData xsdMap = new XsdMapTestData();
306            vContext.put("xsdMap", xsdMap);
307            return vContext;
308        }
309    
310        /**
311         * Creates a factory for stream writers that write source code to a
312         * specified file
313         *
314         * @throws IOException
315         */
316        private Writer getCodeWriter(String fileName) throws IOException {
317            Writer writer = new FileWriter(fileName);
318            if (enableCodeFormatting) {
319                writer = new CodeFormattingWriter(writer, codeFormatterOptions);
320            }
321            return writer;
322        }
323    
324        private void initVelocityEngine() {
325            log.info("Init velocity engine");
326            try {
327    
328                vEngine = new VelocityEngine();
329                //System.out.println(JavaWriter.class.getResource(""));
330                //System.exit(0);
331    
332                //vEngine.setProperty("resource.loader", "class");
333                //vEngine.setProperty("class.resource.loader.description", " Velocity Classpath Resource Loader");
334                //vEngine.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
335    
336                //vEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
337                //vEngine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
338    
339                vEngine.setProperty("resource.loader", "url");
340                vEngine.setProperty("url.resource.loader.description", "Velocity URL Resource Loader");
341                vEngine.setProperty("url.resource.loader.class", "org.apache.velocity.runtime.resource.loader.URLResourceLoader");
342                vEngine.setProperty("url.resource.loader.root", TEMPLATE_ROOT);
343    
344                // see http://minaret.biz/tips/tomcatLogging.html
345                vEngine.setProperty("runtime.log.logsystem.class", "org.apache.velocity.runtime.log.Log4JLogSystem");
346                vEngine.setProperty("velocimacro.library", "macros.vm");
347    
348    
349                vEngine.init();
350                /*URL u = this.getClass().getClassLoader().getResource("nl/tudelft/tbm/eeni/owl2java/generator/templates/interface.vm");
351                 u = this.getClass().getClassLoader().getResource("interface.vm");
352                System.out.println(JavaWriter.class.getResource(""));
353                System.out.println(JavaWriter.class.getResource("")+"templates/");
354    
355                System.out.println(u);
356    
357                vEngine.getTemplate(TEMPLATE_ROOT+"inferface.vm");
358                  System.exit(0);
359                                                                  */
360                /* System.out.println(JavaWriter.class.getResource("templates") + "/");
361                 System.out.println(this.getClass().getResource("templates") + "/");
362                 System.out.println(this.getClass().getClassLoader().getResource(""));
363                 System.out.println(this.getClass().getClassLoader().getResource("templates") + "/");
364    
365                vEngine.getTemplate("nl.tudelft.tbm.eeni.owl2java.generator.templates/inferface.vm");
366                //vEngine.getTemplate("nl/tudelft/tbm/eeni/owl2java/generator/templates/inferface.vm");
367                */
368            } catch (Exception e) {
369                log.error("", e);
370                throw new RuntimeException(e);
371            }
372    
373        }
374    
375    }