001: package org.ontoware.rdfreactor.generator;
002:
003: import java.io.File;
004: import java.io.FileWriter;
005: import java.io.IOException;
006: import java.text.SimpleDateFormat;
007: import java.util.Calendar;
008:
009: import org.apache.commons.logging.Log;
010: import org.apache.commons.logging.LogFactory;
011: import org.apache.velocity.Template;
012: import org.apache.velocity.VelocityContext;
013: import org.apache.velocity.app.Velocity;
014: import org.apache.velocity.app.VelocityEngine;
015: import org.apache.velocity.exception.MethodInvocationException;
016: import org.apache.velocity.exception.ParseErrorException;
017: import org.apache.velocity.exception.ResourceNotFoundException;
018: import org.ontoware.rdfreactor.generator.java.JClass;
019: import org.ontoware.rdfreactor.generator.java.JModel;
020: import org.ontoware.rdfreactor.generator.java.JPackage;
021:
022: /**
023: * Write the JModel via Velocity templates to Java source code.
024: *
025: * @author $Author: xamde $
026: * @version $Id: SourceCodeWriter.java,v 1.9 2006/07/01 10:35:09 xamde Exp $
027: *
028: */
029: public class SourceCodeWriter {
030:
031: public static final String TEMPLATE_CLASS = "class.vm";
032:
033: private static final Log log = LogFactory
034: .getLog(SourceCodeWriter.class);
035:
036: /**
037: * Writes model 'jm' to 'outdir' creating sub-directories for packages as
038: * needed. Uses the default template. Prefixes all methods with 'prefix', e.g.
039: * with prefix="Sioc" one gets "getSiocName"
040: *
041: * @param jm
042: * @param outdir
043: * @param methodnamePrefix
044: * @throws IOException
045: */
046: public static void write(JModel jm, File outdir,
047: String methodnamePrefix) throws Exception {
048: write(jm, outdir, TEMPLATE_CLASS, methodnamePrefix);
049: }
050:
051: /**
052: * Writes model 'jm' to 'outdir' creating sub-directories for packages as
053: * needed. Uses 'templateName'. Prefixes all methods with 'prefix', e.g.
054: * with prefix="Sioc" one gets "getSiocName"
055: *
056: * @param jm
057: * @param outdir
058: * @param templateName
059: * in resource-syntax, e.g. "com/example/myname.vm"
060: * @param methodnamePrefix
061: * @throws IOException
062: */
063: public static void write(JModel jm, File outdir,
064: String templateName, String methodnamePrefix)
065: throws IOException {
066:
067: log.info("Adding inverse properties");
068: jm.addInverseProperties();
069:
070: assert jm.isConsistent() : "java package is not consistent";
071: // log.info("JModel model: \n" + jm.toString());
072:
073: System.out.println(jm.toString() + "\n>>>>>> written to "
074: + outdir.getAbsolutePath());
075:
076: // //////////////
077: // template
078:
079: log.info("prepare for writing " + jm.getPackages().size()
080: + " packages using template " + templateName);
081:
082: VelocityEngine ve = new VelocityEngine();
083: VelocityContext context = new VelocityContext();
084:
085: // http://jakarta.apache.org/velocity/docs/api/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.html
086: // Properties velocityProperties = new Properties();
087: // velocityProperties.put("resource.loader", "class,classpath");
088: // velocityProperties
089: // .put("class.resource.loader.class",
090: // "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
091:
092: try {
093: ve.setProperty("resource.loader", "class");
094: ve
095: .setProperty("class.resource.loader.class",
096: "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
097:
098: // see http://minaret.biz/tips/tomcatLogging.html
099: ve
100: .setProperty("runtime.log.logsystem.class",
101: "org.apache.velocity.runtime.log.SimpleLog4JLogSystem");
102:
103: ve.init();
104: } catch (Exception e) {
105: throw new RuntimeException(e);
106: }
107: assert templateName != null;
108:
109: if (!ve.templateExists(templateName))
110: throw new RuntimeException("template " + templateName
111: + " does not exist with resource loader "
112: + Velocity.RESOURCE_LOADER);
113:
114: Template template;
115: try {
116: template = ve.getTemplate(templateName);
117: } catch (ResourceNotFoundException e) {
118: throw new RuntimeException(e);
119: } catch (ParseErrorException e) {
120: throw new RuntimeException(e);
121: } catch (Exception e) {
122: throw new RuntimeException(e);
123: }
124: assert template != null;
125:
126: context.put("methodnameprefix", methodnamePrefix);
127: // for debug
128: Calendar c = Calendar.getInstance();
129: context.put("now", SimpleDateFormat.getInstance().format(
130: c.getTime()));
131: context.put("root", jm.getRoot());
132: context
133: .put("generatorVersion",
134: CodeGenerator.GENERATOR_VERSION);
135:
136: for (JPackage jp : jm.getPackages())
137: write(context, jp, outdir, template);
138: }
139:
140: private static void write(VelocityContext context, JPackage jp,
141: File outdir, Template template) throws IOException {
142: log.info("prepare for writing " + jp.getClasses().size()
143: + " classes");
144: File packageOutdir = new File(outdir, jp.getName().replaceAll(
145: "\\.", "\\/"));
146: log.info("Out dir " + packageOutdir.getAbsolutePath());
147: if (!packageOutdir.exists())
148: packageOutdir.mkdirs();
149:
150: // package
151: assert jp.isConsistent();
152: context.put("package", jp);
153: for (JClass jc : jp.getClasses()) {
154: assert jc != null;
155: write(jc, packageOutdir, context, template);
156: }
157: }
158:
159: private static void write(JClass jc, File outdir,
160: VelocityContext context, Template template)
161: throws IOException {
162:
163: assert template != null;
164: assert jc != null;
165: assert jc.getName() != null;
166: assert jc.getSuperclass() != null;
167: context.put("class", jc);
168: String outfile = outdir + "/" + jc.getName() + ".java";
169: log.debug("writing file " + outfile);
170: FileWriter fw = new FileWriter(outfile);
171: try {
172: template.merge(context, fw);
173: } catch (ResourceNotFoundException e) {
174: throw new RuntimeException(e);
175: } catch (ParseErrorException e) {
176: throw new RuntimeException(e);
177: } catch (MethodInvocationException e) {
178: throw new RuntimeException(e);
179: } catch (Exception e) {
180: throw new RuntimeException(e);
181: }
182: fw.close();
183: }
184: }
|