com.soulgalore.velocity.MergeXMLWithVelocity Maven / Gradle / Ivy
/******************************************************
* 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.FilePermission;
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.HashSet;
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.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.FileResourceLoader;
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
* - Optional second XML file (sitespeed.io uses this when parsing the BrowserTime XML)
*
*
*
* 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
*
*
*
* You can also supply System properties that will be merged, the property needs to start with
* {@link #SYSTEM_PROPERTY_START}. It works like this: Set a key
*
*
com.soulgalore.velocity.key.header
* and in the Velocity file you get the value by $header
*
*/
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";
public static final String SYSTEM_PROPERTY_START = "com.soulgalore.velocity.key.";
private final VelocityContext context = new VelocityContext();
private final VelocityEngine ve;
MergeXMLWithVelocity(Properties properties) {
ve = new VelocityEngine(properties);
ve.setProperty("resource.loader", "plainfile");
ve.setProperty("plainfile.resource.loader.instance", new PlainFileResourceLoader());
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));
}
// Add all system properties starting with specific key
Enumeration