Author: henning
Date: Thu May 3 07:05:18 2007
New Revision: 534869
URL: http://svn.apache.org/viewvc?view=rev&rev=534869
Log:
Factor out the actual Anakia engine, making it embeddable in programs.
Added:
velocity/anakia/trunk/src/java/org/apache/anakia/Anakia.java (with props)
Modified:
velocity/anakia/trunk/src/java/org/apache/anakia/AnakiaTask.java
Added: velocity/anakia/trunk/src/java/org/apache/anakia/Anakia.java
URL:
http://svn.apache.org/viewvc/velocity/anakia/trunk/src/java/org/apache/anakia/Anakia.java?view=auto&rev=534869
==============================================================================
--- velocity/anakia/trunk/src/java/org/apache/anakia/Anakia.java (added)
+++ velocity/anakia/trunk/src/java/org/apache/anakia/Anakia.java Thu May 3
07:05:18 2007
@@ -0,0 +1,569 @@
+package org.apache.anakia;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.commons.collections.ExtendedProperties;
+import org.apache.commons.lang.StringUtils;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.jdom.Document;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+import org.jdom.output.Format;
+import org.xml.sax.SAXParseException;
+
+/**
+ * This is the Anakia processor whicih allows you to do XML
+ * transformations using Velocity style sheets.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">The Velocity developers
community</a>
+ * @version $Id$
+ */
+public class Anakia
+{
+ private File baseDir = null;
+
+ private File destDir = null;
+
+ private String styleTemplate = null;
+
+ private File propertiesFile = null;
+
+ private File projectFile = null;
+
+ private File templatePath = null;
+
+ private String extension = null;
+
+ private List files = null;
+
+ private boolean checkLastModified = false;
+
+ private AnakiaLog log = null;
+
+ /** the Velocity subcontexts */
+ private List contexts = Collections.EMPTY_LIST;
+
+ private long styleSheetLastModified = 0;
+
+ private long projectFileLastModified = 0;
+
+ /** the VelocityEngine instance to use */
+ private final VelocityEngine ve;
+
+ /** <code>[EMAIL PROTECTED] SAXBuilder}</code> instance to use */
+ private final SAXBuilder builder;
+
+ public Anakia()
+ {
+ ve = new VelocityEngine();
+ builder = new SAXBuilder();
+ builder.setFactory(new AnakiaJDOMFactory());
+ }
+
+ protected File getBaseDir()
+ {
+ return baseDir;
+ }
+
+ public void setBaseDir(final File baseDir)
+ {
+ this.baseDir = baseDir;
+ }
+
+ protected File getDestDir()
+ {
+ return destDir;
+ }
+
+
+
+ public void setDestDir(final File destDir)
+ {
+ this.destDir = destDir;
+ }
+
+
+
+ protected List getFiles()
+ {
+ return files;
+ }
+
+
+
+ public void setFiles(final List files)
+ {
+ this.files = files;
+ }
+
+ protected File getProjectFile()
+ {
+ return projectFile;
+ }
+
+ public void setProjectFile(final File projectFile)
+ {
+ this.projectFile = projectFile;
+ }
+
+ protected File getPropertiesFile()
+ {
+ return propertiesFile;
+ }
+
+ public void setPropertiesFile(final File propertiesFile)
+ {
+ this.propertiesFile = propertiesFile;
+ }
+
+ protected String getStyleTemplate()
+ {
+ return styleTemplate;
+ }
+
+ public void setStyleTemplate(final String styleTemplate)
+ {
+ this.styleTemplate = styleTemplate;
+ }
+
+ protected File getTemplatePath()
+ {
+ return templatePath;
+ }
+
+ public void setTemplatePath(final File templatePath)
+ {
+ this.templatePath = templatePath;
+ }
+
+ protected boolean isCheckLastModified()
+ {
+ return checkLastModified;
+ }
+
+ public void setCheckLastModified(final boolean checkLastChanged)
+ {
+ this.checkLastModified = checkLastChanged;
+ }
+
+ protected String getExtension()
+ {
+ return extension;
+ }
+
+ public void setExtension(final String extension)
+ {
+ this.extension = extension;
+ }
+
+ protected AnakiaLog getLog()
+ {
+ return log;
+ }
+
+ public void setLog(final AnakiaLog log)
+ {
+ this.log = log;
+ }
+
+ protected List getContexts()
+ {
+ return contexts;
+ }
+
+ public void setContexts(final List contexts)
+ {
+ this.contexts = contexts;
+ }
+
+ protected SAXBuilder getBuilder()
+ {
+ return builder;
+ }
+
+ public void execute()
+ throws Exception
+ {
+ if (getPropertiesFile() != null && getPropertiesFile().exists())
+ {
+ String file = getPropertiesFile().getAbsolutePath();
+ ExtendedProperties config = new ExtendedProperties(file);
+ ve.setExtendedProperties(config);
+ }
+
+ // override the templatePath if it exists
+ if (getTemplatePath() != null)
+ {
+ ve.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH,
getTemplatePath().getCanonicalPath());
+ }
+
+ ve.init();
+
+ // get the last modification of the VSL stylesheet
+ styleSheetLastModified =
ve.getTemplate(getStyleTemplate()).getLastModified();
+ projectFileLastModified = getProjectFile().lastModified();
+
+ // Build the Project file document
+ Document projectDocument = builder.build(getProjectFile());
+
+ for (Iterator it = getFiles().iterator(); it.hasNext(); )
+ {
+ String xmlFile = (String) it.next();
+ process(xmlFile, projectDocument);
+ }
+ }
+
+ /**
+ * Process an XML file using Velocity
+ */
+ private void process(final String xmlFile, final Document projectDocument)
+ throws AnakiaException
+ {
+ File outFile = null;
+ File inFile = null;
+ Writer writer = null;
+
+ try
+ {
+ // the current input file relative to the baseDir
+ inFile = new File(getBaseDir(),xmlFile);
+ // the output file relative to basedir
+ outFile = new File(getDestDir(),
+ xmlFile.substring(0,
+ xmlFile.lastIndexOf('.')) + getExtension());
+
+ // only process files that have changed
+ if (isCheckLastModified() == false ||
+ (inFile.lastModified() > outFile.lastModified() ||
+ styleSheetLastModified > outFile.lastModified() ||
+ projectFileLastModified > outFile.lastModified() ||
+ userContextsModifed(outFile.lastModified())))
+ {
+ ensureDirectoryFor(outFile);
+
+ //-- command line status
+ getLog().info("Input: " + xmlFile);
+
+ // Build the JDOM Document
+ Document root = builder.build(inFile);
+
+ // Shove things into the Context
+ VelocityContext context = new VelocityContext();
+
+ /*
+ * get the property TEMPLATE_ENCODING
+ * we know it's a string...
+ */
+ String encoding = (String)
ve.getProperty(RuntimeConstants.OUTPUT_ENCODING);
+ if (encoding == null || encoding.length() == 0
+ || encoding.equals("8859-1") || encoding.equals("8859_1"))
+ {
+ encoding = "ISO-8859-1";
+ }
+
+ Format f = Format.getRawFormat();
+ f.setEncoding(encoding);
+
+ OutputWrapper ow = new OutputWrapper(f);
+
+ context.put ("root", root.getRootElement());
+ context.put ("xmlout", ow);
+ context.put ("relativePath", getRelativePath(xmlFile));
+ context.put ("treeWalk", new TreeWalker());
+ context.put ("xpath", new XPathTool());
+ context.put ("escape", new Escape());
+ context.put ("date", new java.util.Date());
+
+ /**
+ * only put this into the context if it exists.
+ */
+ if (projectDocument != null)
+ {
+ context.put ("project", projectDocument.getRootElement());
+ }
+
+ /**
+ * Add the user subcontexts to the to context
+ */
+ for (Iterator iter = contexts.iterator(); iter.hasNext(); )
+ {
+ Context subContext = (Anakia.Context) iter.next();
+
+ if (subContext == null)
+ {
+ throw new AnakiaException("Found an undefined
SubContext!");
+ }
+
+ if (subContext.getContextDocument() == null)
+ {
+ throw new AnakiaException("Could not build a
subContext for " + subContext.getName());
+ }
+
+ context.put(subContext.getName(), subContext
+ .getContextDocument().getRootElement());
+ }
+
+ /**
+ * Process the VSL template with the context and write out
+ * the result as the outFile.
+ */
+ writer = new BufferedWriter(new OutputStreamWriter(
+ new FileOutputStream(outFile),
+ encoding));
+
+ /**
+ * get the template to process
+ */
+ Template template = ve.getTemplate(getStyleTemplate());
+ template.merge(context, writer);
+
+ getLog().info("Output: " + outFile);
+ }
+ }
+ catch (JDOMException e)
+ {
+ outFile.delete();
+
+ if (e.getCause() != null)
+ {
+ Throwable rootCause = e.getCause();
+ if (rootCause instanceof SAXParseException)
+ {
+ System.out.println("");
+ System.out.println("Error: " + rootCause.getMessage());
+ System.out.println(
+ " Line: " +
+ ((SAXParseException)rootCause).getLineNumber() +
+ " Column: " +
+ ((SAXParseException)rootCause).getColumnNumber());
+ System.out.println("");
+ }
+ else
+ {
+ rootCause.printStackTrace();
+ }
+ }
+ else
+ {
+ e.printStackTrace();
+ }
+ }
+ catch (Throwable e)
+ {
+ if (outFile != null)
+ {
+ outFile.delete();
+ }
+ e.printStackTrace();
+ }
+ finally
+ {
+ if (writer != null)
+ {
+ try
+ {
+ writer.flush();
+ }
+ catch (IOException e)
+ {
+ // Do nothing
+ }
+
+ try
+ {
+ writer.close();
+ }
+ catch (IOException e)
+ {
+ // Do nothing
+ }
+ }
+ }
+ }
+
+ /**
+ * Hacky method to figure out the relative path
+ * that we are currently in. This is good for getting
+ * the relative path for images and anchor's.
+ */
+ private String getRelativePath(String file)
+ {
+ if (file == null || file.length()==0)
+ return "";
+ StringTokenizer st = new StringTokenizer(file, "/\\");
+ // needs to be -1 cause ST returns 1 even if there are no matches. huh?
+ int slashCount = st.countTokens() - 1;
+ StringBuffer sb = new StringBuffer();
+ for (int i=0;i<slashCount ;i++)
+ {
+ sb.append ("../");
+ }
+
+ if (sb.toString().length() > 0)
+ {
+ return StringUtils.chomp(sb.toString(), "/");
+ }
+
+ return ".";
+ }
+
+ /**
+ * create directories as needed
+ */
+ private void ensureDirectoryFor(File targetFile) throws AnakiaException
+ {
+ File directory = new File(targetFile.getParent());
+ if (!directory.exists())
+ {
+ if (!directory.mkdirs())
+ {
+ throw new AnakiaException("Unable to create directory: "
+ + directory.getAbsolutePath());
+ }
+ }
+ }
+
+
+ /**
+ * Check to see if user context is modified.
+ */
+ private boolean userContextsModifed(long lastModified)
+ {
+ for (Iterator iter = contexts.iterator(); iter.hasNext();)
+ {
+ Anakia.Context ctx = (Anakia.Context) iter.next();
+ if(ctx.getLastModified() > lastModified)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * A context implementation that loads all values from an XML file.
+ */
+ public class Context
+ {
+ private String name;
+ private Document contextDoc = null;
+ private String file;
+
+ /**
+ * Public constructor.
+ */
+ public Context()
+ {
+ }
+
+ /**
+ * Get the name of the context.
+ * @return The name of the context.
+ */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * Set the name of the context.
+ * @param name
+ *
+ * @throws AnakiaException if a reserved word is used as a
+ * name, specifically any of "relativePath", "treeWalk", "xpath",
+ * "escape", "date", or "project"
+ */
+ public void setName(String name)
+ {
+ if (name.equals("relativePath") ||
+ name.equals("treeWalk") ||
+ name.equals("xpath") ||
+ name.equals("escape") ||
+ name.equals("date") ||
+ name.equals("project"))
+ {
+
+ throw new AnakiaException("Context name '" + name + "' is
reserved by Anakia");
+ }
+
+ this.name = name;
+ }
+
+ /**
+ * Build the context based on a file path.
+ * @param file
+ */
+ public void setFile(String file)
+ {
+ this.file = file;
+ }
+
+ /**
+ * Retrieve the time the source file was last modified.
+ * @return The time the source file was last modified.
+ */
+ public long getLastModified()
+ {
+ return new File(getBaseDir(), file).lastModified();
+ }
+
+ /**
+ * Retrieve the context document object.
+ * @return The context document object.
+ */
+ public Document getContextDocument()
+ {
+ if (contextDoc == null)
+ {
+ File contextFile = new File(getBaseDir(), file);
+
+ try
+ {
+ contextDoc = getBuilder().build(contextFile);
+ }
+ catch (RuntimeException re)
+ {
+ throw re;
+ }
+ catch (Exception e)
+ {
+ throw new AnakiaException(e);
+ }
+ }
+ return contextDoc;
+ }
+ }
+
+}
+
Propchange: velocity/anakia/trunk/src/java/org/apache/anakia/Anakia.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: velocity/anakia/trunk/src/java/org/apache/anakia/Anakia.java
------------------------------------------------------------------------------
svn:keywords = Id Author Date Revision
Modified: velocity/anakia/trunk/src/java/org/apache/anakia/AnakiaTask.java
URL:
http://svn.apache.org/viewvc/velocity/anakia/trunk/src/java/org/apache/anakia/AnakiaTask.java?view=diff&rev=534869&r1=534868&r2=534869
==============================================================================
--- velocity/anakia/trunk/src/java/org/apache/anakia/AnakiaTask.java (original)
+++ velocity/anakia/trunk/src/java/org/apache/anakia/AnakiaTask.java Thu May 3
07:05:18 2007
@@ -16,36 +16,19 @@
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
- * under the License.
+ * under the License.
*/
-import java.io.BufferedWriter;
import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.util.Iterator;
+import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
-import java.util.StringTokenizer;
-import org.apache.commons.collections.ExtendedProperties;
+import org.apache.commons.lang.StringUtils;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.MatchingTask;
-import org.apache.velocity.Template;
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.app.VelocityEngine;
-import org.apache.velocity.runtime.RuntimeConstants;
-import org.apache.velocity.util.StringUtils;
-
-import org.jdom.Document;
-import org.jdom.JDOMException;
-import org.jdom.input.SAXBuilder;
-import org.jdom.output.Format;
-import org.xml.sax.SAXParseException;
/**
* The purpose of this Ant Task is to allow you to use
@@ -63,10 +46,8 @@
* @version $Id$
*/
public class AnakiaTask extends MatchingTask
+ implements AnakiaLog
{
- /** <code>[EMAIL PROTECTED] SAXBuilder}</code> instance to use */
- SAXBuilder builder;
-
/** the destination directory */
private File destDir = null;
@@ -76,17 +57,8 @@
/** the style= attribute */
private String style = null;
- /** last modified of the style sheet */
- private long styleSheetLastModified = 0;
-
/** the projectFile= attribute */
- private String projectAttribute = null;
-
- /** the File for the project.xml file */
- private File projectFile = null;
-
- /** last modified of the project file if it exists */
- private long projectFileLastModified = 0;
+ private String projectFile = null;
/** check the last modified date on files. defaults to true */
private boolean lastModifiedCheck = true;
@@ -94,34 +66,32 @@
/** the default output extension is .html */
private String extension = ".html";
+ /** the Velocity subcontexts */
+ private List contexts = new LinkedList();
+
/** the template path */
- private String templatePath = null;
+ private File templatePath = null;
/** the file to get the velocity properties file */
- private File velocityPropertiesFile = null;
+ private File propertiesFile = null;
- /** the VelocityEngine instance to use */
- private VelocityEngine ve = new VelocityEngine();
-
- /** the Velocity subcontexts */
- private List contexts = new LinkedList();
+ private final Anakia anakia;
/**
* Constructor creates the SAXBuilder.
*/
public AnakiaTask()
{
- builder = new SAXBuilder();
- builder.setFactory(new AnakiaJDOMFactory());
+ this.anakia = new Anakia();
}
/**
* Set the base directory.
* @param dir
*/
- public void setBasedir(File dir)
+ public void setBasedir(final File baseDir)
{
- baseDir = dir;
+ this.baseDir = baseDir;
}
/**
@@ -129,16 +99,16 @@
* files should be copied to
* @param dir the name of the destination directory
*/
- public void setDestdir(File dir)
+ public void setDestdir(final File destDir)
{
- destDir = dir;
+ this.destDir = destDir;
}
/**
* Allow people to set the default output file extension
* @param extension
*/
- public void setExtension(String extension)
+ public void setExtension(final String extension)
{
this.extension = extension;
}
@@ -147,18 +117,18 @@
* Allow people to set the path to the .vsl file
* @param style
*/
- public void setStyle(String style)
+ public void setStyle(final String style)
{
this.style = style;
}
/**
* Allow people to set the path to the project.xml file
- * @param projectAttribute
+ * @param projectFile
*/
- public void setProjectFile(String projectAttribute)
+ public void setProjectFile(final String projectFile)
{
- this.projectAttribute = projectAttribute;
+ this.projectFile = projectFile;
}
/**
@@ -172,17 +142,10 @@
* @param templatePath
*/
- public void setTemplatePath(File templatePath)
- {
- try
- {
- this.templatePath = templatePath.getCanonicalPath();
- }
- catch (java.io.IOException ioe)
- {
- throw new BuildException(ioe);
- }
- }
+ public void setTemplatePath(final File templatePath)
+ {
+ this.templatePath = templatePath;
+ }
/**
* Allow people to set the path to the velocity.properties file
@@ -190,18 +153,18 @@
* For example, if build.sh was executed in the ./build directory,
* then the path would be relative to this directory.
* This is optional based on the setting of setTemplatePath().
- * @param velocityPropertiesFile
+ * @param propertiesFile
*/
- public void setVelocityPropertiesFile(File velocityPropertiesFile)
+ public void setVelocityPropertiesFile(final File propertiesFile)
{
- this.velocityPropertiesFile = velocityPropertiesFile;
+ this.propertiesFile = propertiesFile;
}
/**
* Turn on/off last modified checking. by default, it is on.
* @param lastmod
*/
- public void setLastModifiedCheck(String lastmod)
+ public void setLastModifiedCheck(final String lastmod)
{
if (lastmod.equalsIgnoreCase("false") || lastmod.equalsIgnoreCase("no")
|| lastmod.equalsIgnoreCase("off"))
@@ -210,436 +173,106 @@
}
}
+ public void info(final String message)
+ {
+ log(message, Project.MSG_INFO);
+ }
+
+ public void error(final String message)
+ {
+ log(message, Project.MSG_ERR);
+ }
+
/**
* Main body of the application
* @throws BuildException
*/
- public void execute () throws BuildException
+ public void execute() throws BuildException
{
- DirectoryScanner scanner;
- String[] list;
-
- if (baseDir == null)
+ if (baseDir == null || !baseDir.exists())
{
- baseDir = project.resolveFile(".");
+ baseDir = getProject().resolveFile(".");
}
- if (destDir == null )
+
+ anakia.setBaseDir(baseDir);
+
+ if (destDir == null)
{
- String msg = "destdir attribute must be set!";
- throw new BuildException(msg);
+ throw new BuildException("destdir attribute must be set!");
}
- if (style == null)
+
+ anakia.setDestDir(destDir);
+
+ if (StringUtils.isEmpty(style))
{
throw new BuildException("style attribute must be set!");
}
- if (velocityPropertiesFile == null)
+ anakia.setStyleTemplate(style);
+
+ if (propertiesFile == null)
{
- velocityPropertiesFile = new File("velocity.properties");
+ propertiesFile = new File(baseDir, "velocity.properties");
}
/*
* If the props file doesn't exist AND a templatePath hasn't
* been defined, then throw the exception.
*/
- if ( !velocityPropertiesFile.exists() && templatePath == null )
+ if (!propertiesFile.exists() && (templatePath == null ||
!templatePath.exists()))
{
- throw new BuildException ("No template path and could not " +
- "locate velocity.properties file: " +
- velocityPropertiesFile.getAbsolutePath());
+ throw new BuildException ("No template path set and properties
file '" +
+ propertiesFile.getAbsolutePath() + "' does not exist!");
}
- log("Transforming into: " + destDir.getAbsolutePath(),
Project.MSG_INFO);
+ anakia.setTemplatePath(templatePath);
+ anakia.setPropertiesFile(propertiesFile);
- // projectFile relative to baseDir
- if (projectAttribute != null && projectAttribute.length() > 0)
- {
- projectFile = new File(baseDir, projectAttribute);
- if (projectFile.exists())
- {
- projectFileLastModified = projectFile.lastModified();
- }
- else
- {
- log ("Project file is defined, but could not be located: " +
- projectFile.getAbsolutePath(), Project.MSG_INFO );
- projectFile = null;
- }
- }
+ log("Transforming into: " + destDir.getAbsolutePath(),
Project.MSG_INFO);
- Document projectDocument = null;
- try
+ if (StringUtils.isNotEmpty(projectFile))
{
- if ( velocityPropertiesFile.exists() )
+ File file = new File(baseDir, projectFile);
+ if (!file.exists())
{
- String file = velocityPropertiesFile.getAbsolutePath();
- ExtendedProperties config = new ExtendedProperties(file);
- ve.setExtendedProperties(config);
+ throw new BuildException("Project file '" +
file.getAbsolutePath() + "' does not exist!");
}
- // override the templatePath if it exists
- if (templatePath != null && templatePath.length() > 0)
- {
- ve.setProperty( RuntimeConstants.FILE_RESOURCE_LOADER_PATH,
- templatePath);
- }
-
- ve.init();
-
- // get the last modification of the VSL stylesheet
- styleSheetLastModified = ve.getTemplate( style ).getLastModified();
-
- // Build the Project file document
- if (projectFile != null)
- {
- projectDocument = builder.build(projectFile);
- }
- }
- catch (Exception e)
- {
- log("Error: " + e.toString(), Project.MSG_INFO);
- throw new BuildException(e);
+ anakia.setProjectFile(file);
}
- // find the files/directories
- scanner = getDirectoryScanner(baseDir);
-
- // get a list of files to work on
- list = scanner.getIncludedFiles();
- for (int i = 0;i < list.length; ++i)
- {
- process(list[i], projectDocument );
- }
-
- }
-
- /**
- * Process an XML file using Velocity
- */
- private void process(String xmlFile, Document projectDocument)
- throws BuildException
- {
- File outFile=null;
- File inFile=null;
- Writer writer = null;
- try
- {
- // the current input file relative to the baseDir
- inFile = new File(baseDir,xmlFile);
- // the output file relative to basedir
- outFile = new File(destDir,
- xmlFile.substring(0,
- xmlFile.lastIndexOf('.')) + extension);
-
- // only process files that have changed
- if (lastModifiedCheck == false ||
- (inFile.lastModified() > outFile.lastModified() ||
- styleSheetLastModified > outFile.lastModified() ||
- projectFileLastModified > outFile.lastModified() ||
- userContextsModifed(outFile.lastModified())))
- {
- ensureDirectoryFor( outFile );
-
- //-- command line status
- log("Input: " + xmlFile, Project.MSG_INFO );
- // Build the JDOM Document
- Document root = builder.build(inFile);
+ DirectoryScanner scanner = getDirectoryScanner(baseDir);
+ anakia.setFiles(Arrays.asList(scanner.getIncludedFiles()));
- // Shove things into the Context
- VelocityContext context = new VelocityContext();
-
- /*
- * get the property TEMPLATE_ENCODING
- * we know it's a string...
- */
- String encoding = (String) ve.getProperty(
RuntimeConstants.OUTPUT_ENCODING );
- if (encoding == null || encoding.length() == 0
- || encoding.equals("8859-1") || encoding.equals("8859_1"))
- {
- encoding = "ISO-8859-1";
- }
-
- Format f = Format.getRawFormat();
- f.setEncoding(encoding);
-
- OutputWrapper ow = new OutputWrapper(f);
-
- context.put ("root", root.getRootElement());
- context.put ("xmlout", ow );
- context.put ("relativePath", getRelativePath(xmlFile));
- context.put ("treeWalk", new TreeWalker());
- context.put ("xpath", new XPathTool() );
- context.put ("escape", new Escape() );
- context.put ("date", new java.util.Date() );
-
- /**
- * only put this into the context if it exists.
- */
- if (projectDocument != null)
- {
- context.put ("project", projectDocument.getRootElement());
- }
-
- /**
- * Add the user subcontexts to the to context
- */
- for (Iterator iter = contexts.iterator(); iter.hasNext();)
- {
- Context subContext = (Context) iter.next();
- if (subContext == null)
- {
- throw new BuildException("Found an undefined
SubContext!");
- }
-
- if (subContext.getContextDocument() == null)
- {
- throw new BuildException("Could not build a subContext
for " + subContext.getName());
- }
-
- context.put(subContext.getName(), subContext
- .getContextDocument().getRootElement());
- }
-
- /**
- * Process the VSL template with the context and write out
- * the result as the outFile.
- */
- writer = new BufferedWriter(new OutputStreamWriter(
- new FileOutputStream(outFile),
- encoding));
-
- /**
- * get the template to process
- */
- Template template = ve.getTemplate(style);
- template.merge(context, writer);
+ anakia.setCheckLastModified(lastModifiedCheck);
+ anakia.setExtension(extension);
- log("Output: " + outFile, Project.MSG_INFO );
- }
- }
- catch (JDOMException e)
- {
- outFile.delete();
+ anakia.setLog(this);
+ anakia.setContexts(contexts);
- if (e.getCause() != null)
- {
- Throwable rootCause = e.getCause();
- if (rootCause instanceof SAXParseException)
- {
- System.out.println("");
- System.out.println("Error: " + rootCause.getMessage());
- System.out.println(
- " Line: " +
- ((SAXParseException)rootCause).getLineNumber() +
- " Column: " +
- ((SAXParseException)rootCause).getColumnNumber());
- System.out.println("");
- }
- else
- {
- rootCause.printStackTrace();
- }
- }
- else
- {
- e.printStackTrace();
- }
- }
- catch (Throwable e)
- {
- if (outFile != null)
- {
- outFile.delete();
- }
- e.printStackTrace();
- }
- finally
- {
- if (writer != null)
- {
- try
- {
- writer.flush();
- }
- catch (IOException e)
- {
- // Do nothing
- }
-
- try
- {
- writer.close();
- }
- catch (IOException e)
- {
- // Do nothing
- }
- }
- }
- }
-
- /**
- * Hacky method to figure out the relative path
- * that we are currently in. This is good for getting
- * the relative path for images and anchor's.
- */
- private String getRelativePath(String file)
- {
- if (file == null || file.length()==0)
- return "";
- StringTokenizer st = new StringTokenizer(file, "/\\");
- // needs to be -1 cause ST returns 1 even if there are no matches. huh?
- int slashCount = st.countTokens() - 1;
- StringBuffer sb = new StringBuffer();
- for (int i=0;i<slashCount ;i++ )
- {
- sb.append ("../");
- }
-
- if (sb.toString().length() > 0)
+ try
{
- return StringUtils.chop(sb.toString(), 1);
+ anakia.execute();
}
-
- return ".";
- }
-
- /**
- * create directories as needed
- */
- private void ensureDirectoryFor( File targetFile ) throws BuildException
- {
- File directory = new File( targetFile.getParent() );
- if (!directory.exists())
+ catch (RuntimeException re)
{
- if (!directory.mkdirs())
- {
- throw new BuildException("Unable to create directory: "
- + directory.getAbsolutePath() );
- }
+ throw re;
}
- }
-
-
- /**
- * Check to see if user context is modified.
- */
- private boolean userContextsModifed(long lastModified)
- {
- for (Iterator iter = contexts.iterator(); iter.hasNext();)
+ catch (Exception e)
{
- AnakiaTask.Context ctx = (AnakiaTask.Context) iter.next();
- if(ctx.getLastModified() > lastModified)
- {
- return true;
- }
+ throw new BuildException(e);
}
- return false;
}
/**
* Create a new context.
* @return A new context.
*/
- public Context createContext()
+ public Anakia.Context createContext()
{
- Context context = new Context();
+ Anakia.Context context = anakia.new Context(); // Always wanted to use
that... :-)
contexts.add(context);
return context;
}
-
-
- /**
- * A context implementation that loads all values from an XML file.
- */
- public class Context
- {
-
- private String name;
- private Document contextDoc = null;
- private String file;
-
- /**
- * Public constructor.
- */
- public Context()
- {
- }
-
- /**
- * Get the name of the context.
- * @return The name of the context.
- */
- public String getName()
- {
- return name;
- }
-
- /**
- * Set the name of the context.
- * @param name
- *
- * @throws IllegalArgumentException if a reserved word is used as a
- * name, specifically any of "relativePath", "treeWalk", "xpath",
- * "escape", "date", or "project"
- */
- public void setName(String name)
- {
- if (name.equals("relativePath") ||
- name.equals("treeWalk") ||
- name.equals("xpath") ||
- name.equals("escape") ||
- name.equals("date") ||
- name.equals("project"))
- {
-
- throw new IllegalArgumentException("Context name '" + name
- + "' is reserved by Anakia");
- }
-
- this.name = name;
- }
-
- /**
- * Build the context based on a file path.
- * @param file
- */
- public void setFile(String file)
- {
- this.file = file;
- }
-
- /**
- * Retrieve the time the source file was last modified.
- * @return The time the source file was last modified.
- */
- public long getLastModified()
- {
- return new File(baseDir, file).lastModified();
- }
-
- /**
- * Retrieve the context document object.
- * @return The context document object.
- */
- public Document getContextDocument()
- {
- if (contextDoc == null)
- {
- File contextFile = new File(baseDir, file);
-
- try
- {
- contextDoc = builder.build(contextFile);
- }
- catch (Exception e)
- {
- throw new BuildException(e);
- }
- }
- return contextDoc;
- }
- }
-
}