You are viewing a plain text version of this content. The canonical link for it is here.
Posted to torque-dev@db.apache.org by tf...@apache.org on 2007/10/12 22:18:07 UTC
svn commit: r584257 - in /db/torque:
generator/trunk/src/java/org/apache/torque/task/TorqueDataModelTask.java
site/trunk/xdocs/changes.xml
Author: tfischer
Date: Fri Oct 12 13:18:01 2007
New Revision: 584257
URL: http://svn.apache.org/viewvc?rev=584257&view=rev
Log:
Create nicely trimmed output in the generator.
Resolves TORQUE-71.
Thanks to Thoralf Rickert for the patch.
Modified:
db/torque/generator/trunk/src/java/org/apache/torque/task/TorqueDataModelTask.java
db/torque/site/trunk/xdocs/changes.xml
Modified: db/torque/generator/trunk/src/java/org/apache/torque/task/TorqueDataModelTask.java
URL: http://svn.apache.org/viewvc/db/torque/generator/trunk/src/java/org/apache/torque/task/TorqueDataModelTask.java?rev=584257&r1=584256&r2=584257&view=diff
==============================================================================
--- db/torque/generator/trunk/src/java/org/apache/torque/task/TorqueDataModelTask.java (original)
+++ db/torque/generator/trunk/src/java/org/apache/torque/task/TorqueDataModelTask.java Fri Oct 12 13:18:01 2007
@@ -19,7 +19,16 @@
* under the License.
*/
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.LineNumberReader;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
@@ -28,6 +37,8 @@
import java.util.Map;
import org.apache.commons.lang.StringUtils;
+import org.apache.texen.Generator;
+import org.apache.texen.ant.TexenTask;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.FileSet;
@@ -35,8 +46,13 @@
import org.apache.torque.engine.database.model.Database;
import org.apache.torque.engine.database.transform.XmlToAppData;
import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
-import org.apache.texen.ant.TexenTask;
+import org.apache.velocity.exception.MethodInvocationException;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
+import org.apache.velocity.runtime.resource.loader.FileResourceLoader;
/**
* A base torque task that uses either a single XML schema
@@ -372,4 +388,390 @@
}
}
}
+ /**
+ * This message fragment (telling users to consult the log or
+ * invoke ant with the -debug flag) is appended to rethrown
+ * exception messages.
+ */
+ private final static String ERR_MSG_FRAGMENT =
+ ". For more information consult the velocity log, or invoke ant " +
+ "with the -debug flag.";
+
+ /**
+ * This method creates an VelocityEngine instance, parses
+ * every template and creates the corresponding output.
+ *
+ * Unfortunately the TextenTask.execute() method makes
+ * everything for us but we just want to set our own
+ * VelocityTemplateLoader.
+ * TODO: change once TEXEN-14 is resolved and out.
+ *
+ * @see org.apache.texen.ant.TexenTask#execute()
+ */
+ public void execute() throws BuildException
+ {
+ // Make sure the template path is set.
+ if (templatePath == null && useClasspath == false)
+ {
+ throw new BuildException(
+ "The template path needs to be defined if you are not using "
+ + "the classpath for locating templates!");
+ }
+
+ // Make sure the control template is set.
+ if (controlTemplate == null)
+ {
+ throw new BuildException(
+ "The control template needs to be defined!");
+ }
+
+ // Make sure the output directory is set.
+ if (outputDirectory == null)
+ {
+ throw new BuildException(
+ "The output directory needs to be defined!");
+ }
+
+ // Make sure there is an output file.
+ if (outputFile == null)
+ {
+ throw new BuildException("The output file needs to be defined!");
+ }
+
+ VelocityEngine ve = new VelocityEngine();
+
+ try
+ {
+ // Setup the Velocity Runtime.
+ if (templatePath != null)
+ {
+ log("Using templatePath: " + templatePath, project.MSG_VERBOSE);
+ ve.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH,
+ templatePath);
+
+ // TR: We need our own FileResourceLoader
+ ve.addProperty(VelocityEngine.RESOURCE_LOADER, "torquefile");
+ ve.setProperty("torquefile." + VelocityEngine.RESOURCE_LOADER
+ + ".instance", new TorqueFileResourceLoader(this));
+ }
+
+ if (useClasspath)
+ {
+ log("Using classpath");
+ // TR: We need our own ClasspathResourceLoader
+ ve.addProperty(VelocityEngine.RESOURCE_LOADER, "classpath");
+
+ ve.setProperty("classpath." + VelocityEngine.RESOURCE_LOADER
+ + ".instance", new TorqueClasspathResourceLoader(this));
+
+ ve.setProperty("classpath." + VelocityEngine.RESOURCE_LOADER
+ + ".cache", "false");
+
+ ve.setProperty("classpath." + VelocityEngine.RESOURCE_LOADER
+ + ".modificationCheckInterval", "2");
+ }
+
+ ve.init();
+
+ // Create the text generator.
+ Generator generator = Generator.getInstance();
+ generator.setVelocityEngine(ve);
+ generator.setOutputPath(outputDirectory);
+ generator.setInputEncoding(inputEncoding);
+ generator.setOutputEncoding(outputEncoding);
+
+ if (templatePath != null)
+ {
+ generator.setTemplatePath(templatePath);
+ }
+
+ // Make sure the output directory exists, if it doesn't
+ // then create it.
+ File file = new File(outputDirectory);
+ if (!file.exists())
+ {
+ file.mkdirs();
+ }
+
+ String path = outputDirectory + File.separator + outputFile;
+ log("Generating to file " + path, project.MSG_INFO);
+ Writer writer = generator.getWriter(path, outputEncoding);
+
+ // The generator and the output path should
+ // be placed in the init context here and
+ // not in the generator class itself.
+ Context c = initControlContext();
+
+ // Everything in the generator class should be
+ // pulled out and placed in here. What the generator
+ // class does can probably be added to the Velocity
+ // class and the generator class can probably
+ // be removed all together.
+ populateInitialContext(c);
+
+ // Feed all the options into the initial
+ // control context so they are available
+ // in the control/worker templates.
+ if (contextProperties != null)
+ {
+ Iterator i = contextProperties.getKeys();
+
+ while (i.hasNext())
+ {
+ String property = (String) i.next();
+ String value = contextProperties.getString(property);
+
+ // Now lets quickly check to see if what
+ // we have is numeric and try to put it
+ // into the context as an Integer.
+ try
+ {
+ c.put(property, new Integer(value));
+ } catch (NumberFormatException nfe)
+ {
+ // Now we will try to place the value into
+ // the context as a boolean value if it
+ // maps to a valid boolean value.
+ String booleanString = contextProperties
+ .testBoolean(value);
+
+ if (booleanString != null)
+ {
+ c.put(property, new Boolean(booleanString));
+ } else
+ {
+ // We are going to do something special
+ // for properties that have a "file.contents"
+ // suffix: for these properties will pull
+ // in the contents of the file and make
+ // them available in the context. So for
+ // a line like the following in a properties file:
+ //
+ // license.file.contents = license.txt
+ //
+ // We will pull in the contents of license.txt
+ // and make it available in the context as
+ // $license. This should make texen a little
+ // more flexible.
+ if (property.endsWith("file.contents"))
+ {
+ // We need to turn the license file from
+ // relative to
+ // absolute, and let Ant help :)
+ value = org.apache.velocity.util.StringUtils
+ .fileContentsToString(project
+ .resolveFile(value)
+ .getCanonicalPath());
+
+ property = property.substring(0, property
+ .indexOf("file.contents") - 1);
+ }
+
+ c.put(property, value);
+ }
+ }
+ }
+ }
+
+ writer.write(generator.parse(controlTemplate, c));
+ writer.flush();
+ writer.close();
+ generator.shutdown();
+ cleanup();
+ }
+ catch (BuildException e)
+ {
+ throw e;
+ }
+ catch (MethodInvocationException e)
+ {
+ throw new BuildException("Exception thrown by '"
+ + e.getReferenceName() + "." + e.getMethodName() + "'"
+ + ERR_MSG_FRAGMENT, e.getWrappedThrowable());
+ }
+ catch (ParseErrorException e)
+ {
+ throw new BuildException(
+ "Velocity syntax error" + ERR_MSG_FRAGMENT, e);
+ }
+ catch (ResourceNotFoundException e)
+ {
+ throw new BuildException(
+ "Resource not found" + ERR_MSG_FRAGMENT,
+ e);
+ }
+ catch (Exception e)
+ {
+ throw new BuildException(
+ "Generation failed" + ERR_MSG_FRAGMENT,
+ e);
+ }
+ }
+
+ /**
+ * This method filters the template and replaces some
+ * unwanted characters. For example it removes leading
+ * spaces in front of velocity commands and replaces
+ * tabs with spaces to prevent bounces in different
+ * code editors with different tab-width-setting.
+ *
+ * @param resource the input stream to filter
+ *
+ * @return the filtered input stream.
+ *
+ * @throws IOException if creating, reading or writing to a stream fails.
+ */
+ protected InputStream filter(InputStream resource) throws IOException
+ {
+ InputStreamReader streamReader;
+ if (inputEncoding != null)
+ {
+ streamReader = new InputStreamReader(resource, inputEncoding);
+ }
+ else
+ {
+ streamReader = new InputStreamReader(resource);
+ }
+ LineNumberReader lineNumberReader = new LineNumberReader(streamReader);
+ String line = null;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ PrintStream ps = null;
+ if (inputEncoding != null)
+ {
+ ps = new PrintStream(baos, true, inputEncoding);
+ }
+ else
+ {
+ ps = new PrintStream(baos, true);
+ }
+
+ while ((line = lineNumberReader.readLine()) != null)
+ {
+ // remove leading spaces in front of velocity commands and comments
+ line = line.replaceAll("^\\s*#", "#");
+ // replace tabs with spaces to prevent bounces in editors
+ line = line.replaceAll("\t", " ");
+ ps.println(line);
+ }
+ ps.flush();
+ ps.close();
+
+ return new ByteArrayInputStream(baos.toByteArray());
+ }
+
+
+ /**
+ * A custom classpath resource loader which filters tabs and removes spaces
+ * from lines with velocity commands.
+ */
+ public static class TorqueClasspathResourceLoader
+ extends ClasspathResourceLoader
+ {
+ /**
+ * The task in which this resource loader is used.
+ */
+ private TorqueDataModelTask task;
+
+ /**
+ * Constructor.
+ *
+ * @param task the task in which this resource loader is used.
+ */
+ public TorqueClasspathResourceLoader(TorqueDataModelTask task)
+ {
+ this.task = task;
+ }
+
+ /**
+ * @see org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader#getResourceStream(java.lang.String)
+ */
+ public synchronized InputStream getResourceStream(String name)
+ throws ResourceNotFoundException
+ {
+ InputStream source = null;
+ try
+ {
+ source = super.getResourceStream(name);
+ return task.filter(source);
+ }
+ catch (IOException uee)
+ {
+ task.log(uee.getMessage());
+ throw new ResourceNotFoundException(uee.getMessage());
+ }
+ finally
+ {
+ if (source != null)
+ {
+ try
+ {
+ source.close();
+ }
+ catch (IOException e)
+ {
+ task.log(e.getMessage());
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * A custom file resource loader which filters tabs and removes spaces
+ * from lines with velocity commands.
+ */
+ public static class TorqueFileResourceLoader
+ extends FileResourceLoader
+ {
+ /**
+ * The task in which this resource loader is used.
+ */
+ private TorqueDataModelTask task;
+
+ /**
+ * Constructor.
+ *
+ * @param task the task in which this resource loader is used.
+ */
+ public TorqueFileResourceLoader(TorqueDataModelTask task)
+ {
+ this.task = task;
+ }
+
+ /**
+ * @see org.apache.velocity.runtime.resource.loader.FileResourceLoader#getResourceStream(java.lang.String)
+ */
+ public synchronized InputStream getResourceStream(
+ String name)
+ throws ResourceNotFoundException
+ {
+ InputStream source = null;
+ try
+ {
+ source = super.getResourceStream(name);
+ return task.filter(source);
+ }
+ catch (IOException uee)
+ {
+ task.log(uee.getMessage());
+ throw new ResourceNotFoundException(uee.getMessage());
+ }
+ finally
+ {
+ if (source != null)
+ {
+ try
+ {
+ source.close();
+ }
+ catch (IOException e)
+ {
+ task.log(e.getMessage());
+ }
+ }
+ }
+ }
+ }
}
+
+
Modified: db/torque/site/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/db/torque/site/trunk/xdocs/changes.xml?rev=584257&r1=584256&r2=584257&view=diff
==============================================================================
--- db/torque/site/trunk/xdocs/changes.xml (original)
+++ db/torque/site/trunk/xdocs/changes.xml Fri Oct 12 13:18:01 2007
@@ -31,6 +31,9 @@
<body>
<release version="3.3-RC3" date="in SVN">
+ <action type="change" dev="tfischer" issue="TORQUE-71" due-to="Thoralf Rickert">
+ Create nicely trimmed output in the generator.
+ </action>
<action type="add" dev="tfischer" issue="TORQUE-101" due-to="Marc Kannegiesser">
Implemented the goal id-broker-init-sql in the Maven2 plugin.
</action>
---------------------------------------------------------------------
To unsubscribe, e-mail: torque-dev-unsubscribe@db.apache.org
For additional commands, e-mail: torque-dev-help@db.apache.org