use of freemarker.template.TemplateModel in project freemarker by apache.
the class ClassBasedModelFactory method getInternal.
private TemplateModel getInternal(String key) throws TemplateModelException, ClassNotFoundException {
{
TemplateModel model = (TemplateModel) cache.get(key);
if (model != null)
return model;
}
final ClassIntrospector classIntrospector;
int classIntrospectorClearingCounter;
final Object sharedLock = wrapper.getSharedIntrospectionLock();
synchronized (sharedLock) {
TemplateModel model = (TemplateModel) cache.get(key);
if (model != null)
return model;
while (model == null && classIntrospectionsInProgress.contains(key)) {
// waiting for its result.
try {
sharedLock.wait();
model = (TemplateModel) cache.get(key);
} catch (InterruptedException e) {
throw new RuntimeException("Class inrospection data lookup aborded: " + e);
}
}
if (model != null)
return model;
// This will be the thread that introspects this class.
classIntrospectionsInProgress.add(key);
// While the classIntrospector should not be changed from another thread, badly written apps can do that,
// and it's cheap to get the classIntrospector from inside the lock here:
classIntrospector = wrapper.getClassIntrospector();
classIntrospectorClearingCounter = classIntrospector.getClearingCounter();
}
try {
final Class clazz = ClassUtil.forName(key);
// This is called so that we trigger the
// class-reloading detector. If clazz is a reloaded class,
// the wrapper will in turn call our clearCache method.
// TODO: Why do we check it now and only now?
classIntrospector.get(clazz);
TemplateModel model = createModel(clazz);
if (model != null) {
synchronized (sharedLock) {
// Save it into the cache, but only if nothing relevant has changed while we were outside the lock:
if (classIntrospector == wrapper.getClassIntrospector() && classIntrospectorClearingCounter == classIntrospector.getClearingCounter()) {
cache.put(key, model);
}
}
}
return model;
} finally {
synchronized (sharedLock) {
classIntrospectionsInProgress.remove(key);
sharedLock.notifyAll();
}
}
}
use of freemarker.template.TemplateModel in project freemarker by apache.
the class ResourceBundleModel method exec.
/**
* Takes first argument as a resource key, looks up a string in resource bundle
* with this key, then applies a MessageFormat.format on the string with the
* rest of the arguments. The created MessageFormats are cached for later reuse.
*/
public Object exec(List arguments) throws TemplateModelException {
// Must have at least one argument - the key
if (arguments.size() < 1)
throw new TemplateModelException("No message key was specified");
// Read it
Iterator it = arguments.iterator();
String key = unwrap((TemplateModel) it.next()).toString();
try {
if (!it.hasNext()) {
return wrap(((ResourceBundle) object).getObject(key));
}
// Copy remaining arguments into an Object[]
int args = arguments.size() - 1;
Object[] params = new Object[args];
for (int i = 0; i < args; ++i) params[i] = unwrap((TemplateModel) it.next());
// Invoke format
return new StringModel(format(key, params), wrapper);
} catch (MissingResourceException e) {
throw new TemplateModelException("No such key: " + key);
} catch (Exception e) {
throw new TemplateModelException(e.getMessage());
}
}
use of freemarker.template.TemplateModel in project freemarker by apache.
the class _ObjectBuilderSettingEvaluator method setJavaBeanProperties.
private void setJavaBeanProperties(Object bean, List namedParamNames, List namedParamValues) throws _ObjectBuilderSettingEvaluationException {
if (namedParamNames.isEmpty()) {
return;
}
final Class cl = bean.getClass();
Map /*<String,Method>*/
beanPropSetters;
try {
PropertyDescriptor[] propDescs = Introspector.getBeanInfo(cl).getPropertyDescriptors();
beanPropSetters = new HashMap(propDescs.length * 4 / 3, 1.0f);
for (int i = 0; i < propDescs.length; i++) {
PropertyDescriptor propDesc = propDescs[i];
final Method writeMethod = propDesc.getWriteMethod();
if (writeMethod != null) {
beanPropSetters.put(propDesc.getName(), writeMethod);
}
}
} catch (Exception e) {
throw new _ObjectBuilderSettingEvaluationException("Failed to inspect " + cl.getName() + " class", e);
}
TemplateHashModel beanTM = null;
for (int i = 0; i < namedParamNames.size(); i++) {
String name = (String) namedParamNames.get(i);
if (!beanPropSetters.containsKey(name)) {
throw new _ObjectBuilderSettingEvaluationException("The " + cl.getName() + " class has no writeable JavaBeans property called " + StringUtil.jQuote(name) + ".");
}
Method beanPropSetter = (Method) beanPropSetters.put(name, null);
if (beanPropSetter == null) {
throw new _ObjectBuilderSettingEvaluationException("JavaBeans property " + StringUtil.jQuote(name) + " is set twice.");
}
try {
if (beanTM == null) {
TemplateModel wrappedObj = env.getObjectWrapper().wrap(bean);
if (!(wrappedObj instanceof TemplateHashModel)) {
throw new _ObjectBuilderSettingEvaluationException("The " + cl.getName() + " class is not a wrapped as TemplateHashModel.");
}
beanTM = (TemplateHashModel) wrappedObj;
}
TemplateModel m = beanTM.get(beanPropSetter.getName());
if (m == null) {
throw new _ObjectBuilderSettingEvaluationException("Can't find " + beanPropSetter + " as FreeMarker method.");
}
if (!(m instanceof TemplateMethodModelEx)) {
throw new _ObjectBuilderSettingEvaluationException(StringUtil.jQuote(beanPropSetter.getName()) + " wasn't a TemplateMethodModelEx.");
}
List /*TemplateModel*/
args = new ArrayList();
args.add(env.getObjectWrapper().wrap(namedParamValues.get(i)));
((TemplateMethodModelEx) m).exec(args);
} catch (Exception e) {
throw new _ObjectBuilderSettingEvaluationException("Failed to set " + StringUtil.jQuote(name), e);
}
}
}
use of freemarker.template.TemplateModel in project freemarker by apache.
the class DeepUnwrapTest method testHashEx2Unwrapping.
@SuppressWarnings("rawtypes")
@Test
public void testHashEx2Unwrapping() throws Exception {
Map<Object, Object> map = new LinkedHashMap<Object, Object>();
map.put("k1", "v1");
map.put("k2", null);
map.put(3, "v3");
map.put(null, "v4");
DefaultObjectWrapper dow = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_27).build();
TemplateModel model = dow.wrap(map);
assertSame(map, DeepUnwrap.unwrap(model));
Object unwrapped = DeepUnwrap.unwrap(new PurelyTemplateHashModelEx2((TemplateHashModelEx2) model));
assertNotSame(map, unwrapped);
assertEquals(map, unwrapped);
// Order is kept:
assertArrayEquals(new Object[] { "k1", "k2", 3, null }, ((Map) unwrapped).keySet().toArray());
}
use of freemarker.template.TemplateModel in project freemarker by apache.
the class DOMNodeModel method get.
public TemplateModel get(String key) throws TemplateModelException {
TemplateModel result = null;
if (equivalenceTable.containsKey(key)) {
key = (String) equivalenceTable.get(key);
}
if (cache.containsKey(key)) {
result = (TemplateModel) cache.get(key);
}
if (result == null) {
if ("attributes".equals(key)) {
NamedNodeMap attributes = node.getAttributes();
if (attributes != null) {
SimpleHash hash = new SimpleHash();
for (int i = 0; i < attributes.getLength(); i++) {
Attr att = (Attr) attributes.item(i);
hash.put(att.getName(), att.getValue());
}
result = hash;
}
} else if (key.charAt(0) == '@') {
if (node instanceof Element) {
String attValue = ((Element) node).getAttribute(key.substring(1));
result = new SimpleScalar(attValue);
} else {
throw new TemplateModelException("Trying to get an attribute value for a non-element node");
}
} else if ("is_element".equals(key)) {
result = (node instanceof Element) ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
} else if ("is_text".equals(key)) {
result = (node instanceof Text) ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
} else if ("name".equals(key)) {
result = new SimpleScalar(node.getNodeName());
} else if ("children".equals(key)) {
result = new NodeListTM(node.getChildNodes());
} else if ("parent".equals(key)) {
Node parent = node.getParentNode();
result = (parent == null) ? null : new DOMNodeModel(parent);
} else if ("ancestorByName".equals(key)) {
result = new AncestorByName();
} else if ("nextSibling".equals(key)) {
Node next = node.getNextSibling();
result = (next == null) ? null : new DOMNodeModel(next);
} else if ("previousSibling".equals(key)) {
Node previous = node.getPreviousSibling();
result = (previous == null) ? null : new DOMNodeModel(previous);
} else if ("nextSiblingElement".equals(key)) {
Node next = nextSiblingElement(node);
result = (next == null) ? null : new DOMNodeModel(next);
} else if ("previousSiblingElement".equals(key)) {
Node previous = previousSiblingElement(node);
result = (previous == null) ? null : new DOMNodeModel(previous);
} else if ("nextElement".equals(key)) {
Node next = nextElement(node);
result = (next == null) ? null : new DOMNodeModel(next);
} else if ("previousElement".equals(key)) {
Node previous = previousElement(node);
result = (previous == null) ? null : new DOMNodeModel(previous);
} else if ("text".equals(key)) {
result = new SimpleScalar(getText(node));
}
cache.put(key, result);
}
return result;
}
Aggregations