use of freemarker.template.TemplateModel in project freemarker by apache.
the class FreemarkerXmlTask method process.
/**
* Process an XML file using FreeMarker
*/
private void process(File baseDir, String xmlFile, File destDir) throws BuildException {
File outFile = null;
File inFile = 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 (!incremental || (inFile.lastModified() > outFile.lastModified() || templateFileLastModified > outFile.lastModified() || projectFileLastModified > outFile.lastModified())) {
ensureDirectoryFor(outFile);
// -- command line status
log("Input: " + xmlFile, Project.MSG_INFO);
if (projectTemplate == null && projectFile != null) {
Document doc = builder.parse(projectFile);
projectTemplate = new NodeListModel(builder.parse(projectFile));
projectNode = NodeModel.wrap(doc);
}
// Build the file DOM
Document docNode = builder.parse(inFile);
TemplateModel document = new NodeListModel(docNode);
TemplateNodeModel docNodeModel = NodeModel.wrap(docNode);
HashMap root = new HashMap();
root.put("document", document);
insertDefaults(root);
// Process the template and write out
// the result as the outFile.
Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), encoding));
try {
if (parsedTemplate == null) {
throw new BuildException("No template file specified in build script or in XML file");
}
if (prepareModel != null) {
Map vars = new HashMap();
vars.put("model", root);
vars.put("doc", docNode);
if (projectNode != null) {
vars.put("project", ((NodeModel) projectNode).getNode());
}
prepareModel.execute(vars);
}
freemarker.core.Environment env = parsedTemplate.createProcessingEnvironment(root, writer);
env.setCurrentVisitorNode(docNodeModel);
if (prepareEnvironment != null) {
Map vars = new HashMap();
vars.put("env", env);
vars.put("doc", docNode);
if (projectNode != null) {
vars.put("project", ((NodeModel) projectNode).getNode());
}
prepareEnvironment.execute(vars);
}
env.process();
writer.flush();
} finally {
writer.close();
}
log("Output: " + outFile, Project.MSG_INFO);
}
} catch (SAXParseException spe) {
Throwable rootCause = spe;
if (spe.getException() != null)
rootCause = spe.getException();
log("XML parsing error in " + inFile.getAbsolutePath(), Project.MSG_ERR);
log("Line number " + spe.getLineNumber());
log("Column number " + spe.getColumnNumber());
throw new BuildException(rootCause, getLocation());
} catch (Throwable e) {
if (outFile != null) {
if (!outFile.delete() && outFile.exists()) {
log("Failed to delete " + outFile, Project.MSG_WARN);
}
}
e.printStackTrace();
throw new BuildException(e, getLocation());
}
}
use of freemarker.template.TemplateModel in project freemarker by apache.
the class BeanModel method get.
/**
* Uses Beans introspection to locate a property or method with name
* matching the key name. If a method or property is found, it's wrapped
* into {@link freemarker.template.TemplateMethodModelEx} (for a method or
* indexed property), or evaluated on-the-fly and the return value wrapped
* into appropriate model (for a non-indexed property) Models for various
* properties and methods are cached on a per-class basis, so the costly
* introspection is performed only once per property or method of a class.
* (Side-note: this also implies that any class whose method has been called
* will be strongly referred to by the framework and will not become
* unloadable until this class has been unloaded first. Normally this is not
* an issue, but can be in a rare scenario where you create many classes on-
* the-fly. Also, as the cache grows with new classes and methods introduced
* to the framework, it may appear as if it were leaking memory. The
* framework does, however detect class reloads (if you happen to be in an
* environment that does this kind of things--servlet containers do it when
* they reload a web application) and flushes the cache. If no method or
* property matching the key is found, the framework will try to invoke
* methods with signature
* <tt>non-void-return-type get(java.lang.String)</tt>,
* then <tt>non-void-return-type get(java.lang.Object)</tt>, or
* alternatively (if the wrapped object is a resource bundle)
* <tt>Object getObject(java.lang.String)</tt>.
* @throws TemplateModelException if there was no property nor method nor
* a generic <tt>get</tt> method to invoke.
*/
public TemplateModel get(String key) throws TemplateModelException {
Class<?> clazz = object.getClass();
Map<Object, Object> classInfo = wrapper.getClassIntrospector().get(clazz);
TemplateModel retval = null;
try {
if (wrapper.isMethodsShadowItems()) {
Object fd = classInfo.get(key);
if (fd != null) {
retval = invokeThroughDescriptor(fd, classInfo);
} else {
retval = invokeGenericGet(classInfo, clazz, key);
}
} else {
TemplateModel model = invokeGenericGet(classInfo, clazz, key);
final TemplateModel nullModel = wrapper.wrap(null);
if (model != nullModel && model != UNKNOWN) {
return model;
}
Object fd = classInfo.get(key);
if (fd != null) {
retval = invokeThroughDescriptor(fd, classInfo);
if (retval == UNKNOWN && model == nullModel) {
// This is the (somewhat subtle) case where the generic get() returns null
// and we have no bean info, so we respect the fact that
// the generic get() returns null and return null. (JR)
retval = nullModel;
}
}
}
if (retval == UNKNOWN) {
if (wrapper.isStrict()) {
throw new InvalidPropertyException("No such bean property: " + key);
} else if (LOG.isDebugEnabled()) {
logNoSuchKey(key, classInfo);
}
retval = wrapper.wrap(null);
}
return retval;
} catch (TemplateModelException e) {
throw e;
} catch (Exception e) {
throw new _TemplateModelException(e, "An error has occurred when reading existing sub-variable ", new _DelayedJQuote(key), "; see cause exception! The type of the containing value was: ", new _DelayedFTLTypeDescription(this));
}
}
use of freemarker.template.TemplateModel in project freemarker by apache.
the class BeansWrapper method unwrapSequenceToArray.
/**
* @param tryOnly
* If {@code true}, if the conversion of an item to the component type isn't possible, the method returns
* {@link ObjectWrapperAndUnwrapper#CANT_UNWRAP_TO_TARGET_CLASS} instead of throwing a
* {@link TemplateModelException}.
*/
Object unwrapSequenceToArray(TemplateSequenceModel seq, Class<?> arrayClass, boolean tryOnly, Map<Object, Object> recursionStops) throws TemplateModelException {
if (recursionStops != null) {
Object retval = recursionStops.get(seq);
if (retval != null) {
return retval;
}
} else {
recursionStops = new IdentityHashMap<Object, Object>();
}
Class<?> componentType = arrayClass.getComponentType();
final int size = seq.size();
Object array = Array.newInstance(componentType, size);
recursionStops.put(seq, array);
try {
for (int i = 0; i < size; i++) {
final TemplateModel seqItem = seq.get(i);
Object val = tryUnwrapTo(seqItem, componentType, 0, recursionStops);
if (val == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
if (tryOnly) {
return ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
} else {
throw new _TemplateModelException("Failed to convert ", new _DelayedFTLTypeDescription(seq), " object to ", new _DelayedShortClassName(array.getClass()), ": Problematic sequence item at index ", Integer.valueOf(i), " with value type: ", new _DelayedFTLTypeDescription(seqItem));
}
}
Array.set(array, i, val);
}
} finally {
recursionStops.remove(seq);
}
return array;
}
use of freemarker.template.TemplateModel in project freemarker by apache.
the class SimpleMethod method unwrapArguments.
private Object[] unwrapArguments(List args, Class[] argTypes, boolean isVarargs, BeansWrapper w) throws TemplateModelException {
if (args == null)
return null;
int typesLen = argTypes.length;
int argsLen = args.size();
Object[] unwrappedArgs = new Object[typesLen];
// Unwrap arguments:
Iterator it = args.iterator();
int normalArgCnt = isVarargs ? typesLen - 1 : typesLen;
int argIdx = 0;
while (argIdx < normalArgCnt) {
Class argType = argTypes[argIdx];
TemplateModel argVal = (TemplateModel) it.next();
Object unwrappedArgVal = w.tryUnwrapTo(argVal, argType);
if (unwrappedArgVal == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
throw createArgumentTypeMismarchException(argIdx, argVal, argType);
}
if (unwrappedArgVal == null && argType.isPrimitive()) {
throw createNullToPrimitiveArgumentException(argIdx, argType);
}
unwrappedArgs[argIdx++] = unwrappedArgVal;
}
if (isVarargs) {
// The last argType, which is the vararg type, wasn't processed yet.
Class varargType = argTypes[typesLen - 1];
Class varargItemType = varargType.getComponentType();
if (!it.hasNext()) {
unwrappedArgs[argIdx++] = Array.newInstance(varargItemType, 0);
} else {
TemplateModel argVal = (TemplateModel) it.next();
Object unwrappedArgVal;
// This is consistent to what OverloadedVarArgMethod does.
if (argsLen - argIdx == 1 && (unwrappedArgVal = w.tryUnwrapTo(argVal, varargType)) != ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
// It was a vararg array.
unwrappedArgs[argIdx++] = unwrappedArgVal;
} else {
// It wasn't a vararg array, so we assume it's a vararg
// array *item*, possibly followed by further ones.
int varargArrayLen = argsLen - argIdx;
Object varargArray = Array.newInstance(varargItemType, varargArrayLen);
for (int varargIdx = 0; varargIdx < varargArrayLen; varargIdx++) {
TemplateModel varargVal = (TemplateModel) (varargIdx == 0 ? argVal : it.next());
Object unwrappedVarargVal = w.tryUnwrapTo(varargVal, varargItemType);
if (unwrappedVarargVal == ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS) {
throw createArgumentTypeMismarchException(argIdx + varargIdx, varargVal, varargItemType);
}
if (unwrappedVarargVal == null && varargItemType.isPrimitive()) {
throw createNullToPrimitiveArgumentException(argIdx + varargIdx, varargItemType);
}
Array.set(varargArray, varargIdx, unwrappedVarargVal);
}
unwrappedArgs[argIdx++] = varargArray;
}
}
}
return unwrappedArgs;
}
use of freemarker.template.TemplateModel in project freemarker by apache.
the class RmiDebuggedEnvironmentImpl method getCachedWrapperFor.
static synchronized Object getCachedWrapperFor(Object key) throws RemoteException {
Object value = storage.get(key);
if (value == null) {
if (key instanceof TemplateModel) {
int extraTypes;
if (key instanceof DebugConfigurationModel) {
extraTypes = DebugModel.TYPE_CONFIGURATION;
} else if (key instanceof DebugTemplateModel) {
extraTypes = DebugModel.TYPE_TEMPLATE;
} else {
extraTypes = 0;
}
value = new RmiDebugModelImpl((TemplateModel) key, extraTypes);
} else if (key instanceof Environment) {
value = new RmiDebuggedEnvironmentImpl((Environment) key);
} else if (key instanceof Template) {
value = new DebugTemplateModel((Template) key);
} else if (key instanceof Configuration) {
value = new DebugConfigurationModel((Configuration) key);
}
}
if (value != null) {
storage.put(key, value);
}
if (value instanceof Remote) {
remotes.add(value);
}
return value;
}
Aggregations