
com.soulgalore.velocity.MergeXMLWithVelocity Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xml-velocity Show documentation
Show all versions of xml-velocity Show documentation
Merge a XML file with a Velocity template
/******************************************************
* Merge XML with a Velocity template
*
*
* Copyright (C) 2012 by Peter Hedenskog (http://peterhedenskog.com)
*
******************************************************
*
* Licensed 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.
*
*******************************************************
*/
package com.soulgalore.velocity;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.input.sax.XMLReaderSAX2Factory;
/**
* Merge a XML file with a Velocity template.
* java -jar xml-velocity-1.0-full.jar test.xml test.vm test.properties newfile.xml
*
*
*
* The parameters:
*
* - the xml file
* - the Velocity template file
* - the properties file, key/vale will be added to the Velocity context, used
* when merged
* - the output file name, if excluded the merge will be printed to system.out
*
*
*
*
* The document is added to the context with {@link #CONTEXT_DOCUMENT} as key.
*
* You can also add objects to the velocity context by configuration, in the properties file, add:
*
velocity.context.object.1=CLASSNAME:KEYNAME
* And make sure the class exists in the classpath and have a constructor without arguments. See this example:
*
* velocity.context.object.1=org.apache.velocity.tools.generic.MathTool:math
* velocity.context.object.2=org.apache.velocity.tools.generic.EscapeTool:esc
* velocity.context.object.3=org.apache.commons.math3.stat.descriptive.DescriptiveStatistics:stats
* velocity.context.object.4=com.soulgalore.velocity.HostTool:host
*
*
*
*/
public class MergeXMLWithVelocity {
/**
* The name of the xml document, added to the context.
*/
public static final String CONTEXT_DOCUMENT = "document";
public static final String CONTEXT_PROPERTY_OBJECT = "velocity.context.object";
private final VelocityContext context = new VelocityContext();
private final VelocityEngine ve;
MergeXMLWithVelocity(Properties properties) {
ve = new VelocityEngine(properties);
ve.init();
Map keyAndClasses = getClasses(properties);
for (Entry value : keyAndClasses.entrySet()) {
try {
Class clazz = Class.forName(value.getValue());
context.put(value.getKey(), clazz.newInstance());
} catch (Exception e) {
System.err.println("Couldn't instantiate class:"
+ value.getValue() + " with key:" + value.getKey()
+ " and put it in Velocity context:" + e.toString());
}
}
final Enumeration> e = properties.propertyNames();
while (e.hasMoreElements()) {
final String key = (String) e.nextElement();
context.put(key, properties.getProperty(key));
}
}
/**
* Merge a xml file with Velocity template. The third parameter is the
* properties file, where the key/value is added to the velocity context.
* The fourth parameter is the output file. If not included, the result is
* printed to system.out.
*
* @param args
* are file.xml template.vm properties.prop [output.file]
* @throws JDOMException
* if the xml file couldn't be parsed
* @throws IOException
* couldn't find one of the files
*/
public static void main(String[] args) throws JDOMException, IOException {
if (args.length < 3) {
System.out
.println("Missing input files. XMLToVelocity file.xml template.vm prop.properties [output.file]");
return;
}
final Properties properties = new Properties();
final File prop = new File(args[2]);
if (prop.exists())
properties.load(new FileReader(prop));
else
throw new IOException("Couldn't find the property file:"
+ prop.getAbsolutePath());
final MergeXMLWithVelocity xtv = new MergeXMLWithVelocity(properties);
xtv.create(args);
}
void create(String[] args) throws JDOMException, IOException {
final String result = merge(args[0], args[1]);
if (args.length < 4)
System.out.println(result);
else {
final PrintWriter out = new PrintWriter(new FileOutputStream(
args[3]));
out.write(result);
out.close();
}
}
String merge(String xml, String template) throws JDOMException, IOException {
final File xmlFile = new File(xml);
final SAXBuilder b = new SAXBuilder(new XMLReaderSAX2Factory(false));
final Document doc = b.build(xmlFile);
context.put(CONTEXT_DOCUMENT, doc);
final StringWriter writer = new StringWriter();
final Template fromTemplate = ve.getTemplate(template);
fromTemplate.merge(context, writer);
return writer.toString();
}
private Map getClasses(Properties properties) {
Map keyAndClass = new HashMap();
Set keys = properties.stringPropertyNames();
for (String key : keys) {
if (key.startsWith(CONTEXT_PROPERTY_OBJECT)) {
String value = properties.getProperty(key);
String className = value.substring(0, value.indexOf(":"));
String contextKey = value.substring(value.indexOf(":") + 1,
value.length());
keyAndClass.put(contextKey, className);
}
}
return keyAndClass;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy