use of freemarker.template.TemplateModelException in project freemarker by apache.
the class ErrorMessagesTest method getterMessage.
@Test
public void getterMessage() throws TemplateModelException {
BeansWrapper bw = new BeansWrapperBuilder(Configuration.VERSION_2_3_0).build();
TemplateHashModel thm = (TemplateHashModel) bw.wrap(new TestBean());
try {
thm.get("foo");
} catch (TemplateModelException e) {
e.printStackTrace();
final String msg = e.getMessage();
assertThat(msg, containsString("\"foo\""));
assertThat(msg, containsString("existing sub-variable"));
}
assertNull(thm.get("bar"));
}
use of freemarker.template.TemplateModelException 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.TemplateModelException in project freemarker by apache.
the class StaticModel method populate.
private void populate() throws TemplateModelException {
if (!Modifier.isPublic(clazz.getModifiers())) {
throw new TemplateModelException("Can't wrap the non-public class " + clazz.getName());
}
if (wrapper.getExposureLevel() == BeansWrapper.EXPOSE_NOTHING) {
return;
}
Field[] fields = clazz.getFields();
for (int i = 0; i < fields.length; ++i) {
Field field = fields[i];
int mod = field.getModifiers();
if (Modifier.isPublic(mod) && Modifier.isStatic(mod)) {
if (Modifier.isFinal(mod))
try {
// public static final fields are evaluated once and
// stored in the map
map.put(field.getName(), wrapper.getOuterIdentity().wrap(field.get(null)));
} catch (IllegalAccessException e) {
// Intentionally ignored
}
else
// This is a special flagging value: Field in the map means
// that this is a non-final field, and it must be evaluated
// on each get() call.
map.put(field.getName(), field);
}
}
if (wrapper.getExposureLevel() < BeansWrapper.EXPOSE_PROPERTIES_ONLY) {
Method[] methods = clazz.getMethods();
for (int i = 0; i < methods.length; ++i) {
Method method = methods[i];
int mod = method.getModifiers();
if (Modifier.isPublic(mod) && Modifier.isStatic(mod) && wrapper.getClassIntrospector().isAllowedToExpose(method)) {
String name = method.getName();
Object obj = map.get(name);
if (obj instanceof Method) {
OverloadedMethods overloadedMethods = new OverloadedMethods(wrapper.is2321Bugfixed());
overloadedMethods.addMethod((Method) obj);
overloadedMethods.addMethod(method);
map.put(name, overloadedMethods);
} else if (obj instanceof OverloadedMethods) {
OverloadedMethods overloadedMethods = (OverloadedMethods) obj;
overloadedMethods.addMethod(method);
} else {
if (obj != null) {
if (LOG.isInfoEnabled()) {
LOG.info("Overwriting value [" + obj + "] for " + " key '" + name + "' with [" + method + "] in static model for " + clazz.getName());
}
}
map.put(name, method);
}
}
}
for (Iterator entries = map.entrySet().iterator(); entries.hasNext(); ) {
Map.Entry entry = (Map.Entry) entries.next();
Object value = entry.getValue();
if (value instanceof Method) {
Method method = (Method) value;
entry.setValue(new SimpleMethodModel(null, method, method.getParameterTypes(), wrapper));
} else if (value instanceof OverloadedMethods) {
entry.setValue(new OverloadedMethodsModel(null, (OverloadedMethods) value, wrapper));
}
}
}
}
use of freemarker.template.TemplateModelException in project freemarker by apache.
the class JaxenXPathSupport method executeQuery.
public TemplateModel executeQuery(Object context, String xpathQuery) throws TemplateModelException {
try {
BaseXPath xpath;
Map<String, BaseXPath> xpathCache = (Map<String, BaseXPath>) XPATH_CACHE_ATTR.get();
synchronized (xpathCache) {
xpath = xpathCache.get(xpathQuery);
if (xpath == null) {
xpath = new BaseXPath(xpathQuery, FM_DOM_NAVIGATOR);
xpath.setNamespaceContext(customNamespaceContext);
xpath.setFunctionContext(FM_FUNCTION_CONTEXT);
xpath.setVariableContext(FM_VARIABLE_CONTEXT);
xpathCache.put(xpathQuery, xpath);
}
}
List result = xpath.selectNodes(context != null ? context : EMPTY_ARRAYLIST);
if (result.size() == 1) {
// [2.4] Use the proper object wrapper (argument in 2.4)
return ObjectWrapper.DEFAULT_WRAPPER.wrap(result.get(0));
}
NodeListModel nlm = new NodeListModel(result, null);
nlm.xpathSupport = this;
return nlm;
} catch (UndeclaredThrowableException e) {
Throwable t = e.getUndeclaredThrowable();
if (t instanceof TemplateModelException) {
throw (TemplateModelException) t;
}
throw e;
} catch (JaxenException je) {
throw new TemplateModelException(je);
}
}
use of freemarker.template.TemplateModelException in project freemarker by apache.
the class SunInternalXalanXPathSupport method executeQuery.
public synchronized TemplateModel executeQuery(Object context, String xpathQuery) throws TemplateModelException {
if (!(context instanceof Node)) {
if (context != null) {
if (isNodeList(context)) {
int cnt = ((List) context).size();
if (cnt != 0) {
throw new TemplateModelException("Cannot perform an XPath query against a node set of " + cnt + " nodes. Expecting a single node." + ERRMSG_RECOMMEND_JAXEN);
} else {
throw new TemplateModelException(ERRMSG_EMPTY_NODE_SET);
}
} else {
throw new TemplateModelException("Cannot perform an XPath query against a " + context.getClass().getName() + ". Expecting a single org.w3c.dom.Node.");
}
} else {
throw new TemplateModelException(ERRMSG_EMPTY_NODE_SET);
}
}
Node node = (Node) context;
try {
XPath xpath = new XPath(xpathQuery, null, customPrefixResolver, XPath.SELECT, null);
int ctxtNode = xpathContext.getDTMHandleFromNode(node);
XObject xresult = xpath.execute(xpathContext, ctxtNode, customPrefixResolver);
if (xresult instanceof XNodeSet) {
NodeListModel result = new NodeListModel(node);
result.xpathSupport = this;
NodeIterator nodeIterator = xresult.nodeset();
Node n;
do {
n = nodeIterator.nextNode();
if (n != null) {
result.add(n);
}
} while (n != null);
return result.size() == 1 ? result.get(0) : result;
}
if (xresult instanceof XBoolean) {
return ((XBoolean) xresult).bool() ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
}
if (xresult instanceof XNull) {
return null;
}
if (xresult instanceof XString) {
return new SimpleScalar(xresult.toString());
}
if (xresult instanceof XNumber) {
return new SimpleNumber(Double.valueOf(((XNumber) xresult).num()));
}
throw new TemplateModelException("Cannot deal with type: " + xresult.getClass().getName());
} catch (TransformerException te) {
throw new TemplateModelException(te);
}
}
Aggregations