use of freemarker.template.TemplateHashModel in project freemarker by apache.
the class ErrorMessagesTest method markupOutputParameter.
@Test
public void markupOutputParameter() throws Exception {
TemplateHTMLOutputModel html = HTMLOutputFormat.INSTANCE.fromMarkup("<p>a");
for (Version ici : new Version[] { Configuration.VERSION_2_3_0, Configuration.VERSION_2_3_24 }) {
BeansWrapper bw = new BeansWrapperBuilder(ici).build();
TemplateHashModel thm = (TemplateHashModel) bw.wrap(new TestBean());
{
TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("m1");
try {
m.exec(Collections.singletonList(html));
fail();
} catch (TemplateModelException e) {
assertThat(e.getMessage(), allOf(containsString("String"), containsString("convert"), containsString("markup_output"), containsString("Tip:"), containsString("?markup_string")));
}
}
{
TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("m2");
try {
m.exec(Collections.singletonList(html));
fail();
} catch (TemplateModelException e) {
assertThat(e.getMessage(), allOf(containsString("Date"), containsString("convert"), containsString("markup_output"), not(containsString("?markup_string"))));
}
}
for (String methodName : new String[] { "mOverloaded", "mOverloaded3" }) {
TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get(methodName);
try {
m.exec(Collections.singletonList(html));
fail();
} catch (TemplateModelException e) {
assertThat(e.getMessage(), allOf(containsString("No compatible overloaded"), containsString("String"), containsString("markup_output"), containsString("Tip:"), containsString("?markup_string")));
}
}
{
TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("mOverloaded2");
try {
m.exec(Collections.singletonList(html));
fail();
} catch (TemplateModelException e) {
assertThat(e.getMessage(), allOf(containsString("No compatible overloaded"), containsString("Integer"), containsString("markup_output"), not(containsString("?markup_string"))));
}
}
{
TemplateMethodModelEx m = (TemplateMethodModelEx) thm.get("mOverloaded4");
Object r = m.exec(Collections.singletonList(html));
if (r instanceof TemplateScalarModel) {
r = ((TemplateScalarModel) r).getAsString();
}
assertEquals("<p>a", r);
}
}
}
use of freemarker.template.TemplateHashModel 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.TemplateHashModel in project freemarker by apache.
the class RecurseNode method accept.
@Override
TemplateElement[] accept(Environment env) throws IOException, TemplateException {
TemplateModel node = targetNode == null ? null : targetNode.eval(env);
if (node != null && !(node instanceof TemplateNodeModel)) {
throw new NonNodeException(targetNode, node, "node", env);
}
TemplateModel nss = namespaces == null ? null : namespaces.eval(env);
if (namespaces instanceof StringLiteral) {
nss = env.importLib(((TemplateScalarModel) nss).getAsString(), null);
} else if (namespaces instanceof ListLiteral) {
nss = ((ListLiteral) namespaces).evaluateStringsToNamespaces(env);
}
if (nss != null) {
if (nss instanceof TemplateHashModel) {
SimpleSequence ss = new SimpleSequence(1);
ss.add(nss);
nss = ss;
} else if (!(nss instanceof TemplateSequenceModel)) {
if (namespaces != null) {
throw new NonSequenceException(namespaces, nss, env);
} else {
// Should not occur
throw new _MiscTemplateException(env, "Expecting a sequence of namespaces after \"using\"");
}
}
}
env.recurse((TemplateNodeModel) node, (TemplateSequenceModel) nss);
return null;
}
use of freemarker.template.TemplateHashModel in project freemarker by apache.
the class BeansWrapper method tryUnwrapTo.
/**
* See {@link #tryUnwrapTo(TemplateModel, Class, int)}.
*/
private Object tryUnwrapTo(final TemplateModel model, Class<?> targetClass, final int typeFlags, final Map<Object, Object> recursionStops) throws TemplateModelException {
if (model == null || model == nullModel) {
return null;
}
final boolean is2321Bugfixed = is2321Bugfixed();
if (is2321Bugfixed && targetClass.isPrimitive()) {
targetClass = ClassUtil.primitiveClassToBoxingClass(targetClass);
}
// passed as an argument to TemplateMethodModelEx etc.
if (model instanceof AdapterTemplateModel) {
Object wrapped = ((AdapterTemplateModel) model).getAdaptedObject(targetClass);
if (targetClass == Object.class || targetClass.isInstance(wrapped)) {
return wrapped;
}
// Attempt numeric conversion:
if (targetClass != Object.class && (wrapped instanceof Number && ClassUtil.isNumerical(targetClass))) {
Number number = forceUnwrappedNumberToType((Number) wrapped, targetClass, is2321Bugfixed);
if (number != null)
return number;
}
}
if (model instanceof WrapperTemplateModel) {
Object wrapped = ((WrapperTemplateModel) model).getWrappedObject();
if (targetClass == Object.class || targetClass.isInstance(wrapped)) {
return wrapped;
}
// Attempt numeric conversion:
if (targetClass != Object.class && (wrapped instanceof Number && ClassUtil.isNumerical(targetClass))) {
Number number = forceUnwrappedNumberToType((Number) wrapped, targetClass, is2321Bugfixed);
if (number != null) {
return number;
}
}
}
// know what is expected as the return type.
if (targetClass != Object.class) {
// [2.4][IcI]: Should also check for CharSequence at the end
if (String.class == targetClass) {
if (model instanceof TemplateScalarModel) {
return ((TemplateScalarModel) model).getAsString();
}
// String is final, so no other conversion will work
return ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
}
// Primitive numeric types & Number.class and its subclasses
if (ClassUtil.isNumerical(targetClass)) {
if (model instanceof TemplateNumberModel) {
Number number = forceUnwrappedNumberToType(((TemplateNumberModel) model).getAsNumber(), targetClass, is2321Bugfixed);
if (number != null) {
return number;
}
}
}
if (boolean.class == targetClass || Boolean.class == targetClass) {
if (model instanceof TemplateBooleanModel) {
return Boolean.valueOf(((TemplateBooleanModel) model).getAsBoolean());
}
// Boolean is final, no other conversion will work
return ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
}
if (Map.class == targetClass) {
if (model instanceof TemplateHashModel) {
return new HashAdapter((TemplateHashModel) model, this);
}
}
if (List.class == targetClass) {
if (model instanceof TemplateSequenceModel) {
return new SequenceAdapter((TemplateSequenceModel) model, this);
}
}
if (Set.class == targetClass) {
if (model instanceof TemplateCollectionModel) {
return new SetAdapter((TemplateCollectionModel) model, this);
}
}
if (Collection.class == targetClass || Iterable.class == targetClass) {
if (model instanceof TemplateCollectionModel) {
return new CollectionAdapter((TemplateCollectionModel) model, this);
}
if (model instanceof TemplateSequenceModel) {
return new SequenceAdapter((TemplateSequenceModel) model, this);
}
}
// TemplateSequenceModels can be converted to arrays
if (targetClass.isArray()) {
if (model instanceof TemplateSequenceModel) {
return unwrapSequenceToArray((TemplateSequenceModel) model, targetClass, true, recursionStops);
}
// array classes are final, no other conversion will work
return ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
}
// Allow one-char strings to be coerced to characters
if (char.class == targetClass || targetClass == Character.class) {
if (model instanceof TemplateScalarModel) {
String s = ((TemplateScalarModel) model).getAsString();
if (s.length() == 1) {
return Character.valueOf(s.charAt(0));
}
}
// Character is final, no other conversion will work
return ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
}
if (Date.class.isAssignableFrom(targetClass) && model instanceof TemplateDateModel) {
Date date = ((TemplateDateModel) model).getAsDate();
if (targetClass.isInstance(date)) {
return date;
}
}
}
// End: if (targetClass != Object.class)
// Since the targetClass was of no help initially, now we use
// a quite arbitrary order in which we walk through the TemplateModel subinterfaces, and unwrapp them to
// their "natural" Java correspondent. We still try exclude unwrappings that won't fit the target parameter
// type(s). This is mostly important because of multi-typed FTL values that could be unwrapped on multiple ways.
// Iteration's Type Flags. Should be always 0 for non-overloaded and when !is2321Bugfixed.
int itf = typeFlags;
// returned, once more with itf == 0. Otherwise we execute this once with itf == 0.
do {
if ((itf == 0 || (itf & TypeFlags.ACCEPTS_NUMBER) != 0) && model instanceof TemplateNumberModel) {
Number number = ((TemplateNumberModel) model).getAsNumber();
if (itf != 0 || targetClass.isInstance(number)) {
return number;
}
}
if ((itf == 0 || (itf & TypeFlags.ACCEPTS_DATE) != 0) && model instanceof TemplateDateModel) {
Date date = ((TemplateDateModel) model).getAsDate();
if (itf != 0 || targetClass.isInstance(date)) {
return date;
}
}
if ((itf == 0 || (itf & (TypeFlags.ACCEPTS_STRING | TypeFlags.CHARACTER)) != 0) && model instanceof TemplateScalarModel && (itf != 0 || targetClass.isAssignableFrom(String.class))) {
String strVal = ((TemplateScalarModel) model).getAsString();
if (itf == 0 || (itf & TypeFlags.CHARACTER) == 0) {
return strVal;
} else {
// TypeFlags.CHAR == 1
if (strVal.length() == 1) {
if ((itf & TypeFlags.ACCEPTS_STRING) != 0) {
return new CharacterOrString(strVal);
} else {
return Character.valueOf(strVal.charAt(0));
}
} else if ((itf & TypeFlags.ACCEPTS_STRING) != 0) {
return strVal;
}
// It had to be unwrapped to Character, but the string length wasn't 1 => Fall through
}
}
// Should be earlier than TemplateScalarModel, but we keep it here until FM 2.4 or such
if ((itf == 0 || (itf & TypeFlags.ACCEPTS_BOOLEAN) != 0) && model instanceof TemplateBooleanModel && (itf != 0 || targetClass.isAssignableFrom(Boolean.class))) {
return Boolean.valueOf(((TemplateBooleanModel) model).getAsBoolean());
}
if ((itf == 0 || (itf & TypeFlags.ACCEPTS_MAP) != 0) && model instanceof TemplateHashModel && (itf != 0 || targetClass.isAssignableFrom(HashAdapter.class))) {
return new HashAdapter((TemplateHashModel) model, this);
}
if ((itf == 0 || (itf & TypeFlags.ACCEPTS_LIST) != 0) && model instanceof TemplateSequenceModel && (itf != 0 || targetClass.isAssignableFrom(SequenceAdapter.class))) {
return new SequenceAdapter((TemplateSequenceModel) model, this);
}
if ((itf == 0 || (itf & TypeFlags.ACCEPTS_SET) != 0) && model instanceof TemplateCollectionModel && (itf != 0 || targetClass.isAssignableFrom(SetAdapter.class))) {
return new SetAdapter((TemplateCollectionModel) model, this);
}
// enough to check if the TypeFlags.ACCEPTS_ARRAY bit is 1:
if ((itf & TypeFlags.ACCEPTS_ARRAY) != 0 && model instanceof TemplateSequenceModel) {
return new SequenceAdapter((TemplateSequenceModel) model, this);
}
if (itf == 0) {
break;
}
// start 2nd iteration
itf = 0;
} while (true);
// Note that this will be always true for Object.class targetClass.
if (targetClass.isInstance(model)) {
return model;
}
return ObjectWrapperAndUnwrapper.CANT_UNWRAP_TO_TARGET_CLASS;
}
use of freemarker.template.TemplateHashModel in project ofbiz-framework by apache.
the class EntitySaxReader method endElement.
public void endElement(String namespaceURI, String localName, String fullNameString) throws SAXException {
if (Debug.verboseOn())
Debug.logVerbose("endElement: localName=" + localName + ", fullName=" + fullNameString + ", numberRead=" + numberRead, module);
if ("entity-engine-xml".equals(fullNameString)) {
return;
}
if ("entity-engine-transform-xml".equals(fullNameString)) {
// transform file & parse it, then return
URL templateUrl = null;
try {
templateUrl = FlexibleLocation.resolveLocation(templatePath.toString());
} catch (MalformedURLException e) {
throw new SAXException("Could not find transform template with resource path [" + templatePath + "]; error was: " + e.toString());
}
if (templateUrl == null) {
throw new SAXException("Could not find transform template with resource path: " + templatePath);
} else {
try {
BufferedReader templateReader = new BufferedReader(new InputStreamReader(templateUrl.openStream(), UtilIO.getUtf8()));
StringWriter outWriter = new StringWriter();
Configuration config = FreeMarkerWorker.newConfiguration();
config.setObjectWrapper(FreeMarkerWorker.getDefaultOfbizWrapper());
config.setSetting("datetime_format", "yyyy-MM-dd HH:mm:ss.SSS");
Template template = new Template("FMImportFilter", templateReader, config);
NodeModel nodeModel = NodeModel.wrap(this.rootNodeForTemplate);
Map<String, Object> context = new HashMap<String, Object>();
TemplateHashModel staticModels = FreeMarkerWorker.getDefaultOfbizWrapper().getStaticModels();
context.put("Static", staticModels);
context.put("doc", nodeModel);
template.process(context, outWriter);
String s = outWriter.toString();
if (Debug.verboseOn())
Debug.logVerbose("transformed xml: " + s, module);
EntitySaxReader reader = new EntitySaxReader(delegator);
reader.setUseTryInsertMethod(this.useTryInsertMethod);
try {
reader.setTransactionTimeout(this.transactionTimeout);
} catch (GenericTransactionException e1) {
Debug.logWarning("couldn't set tx timeout, hopefully shouldn't be a big deal", module);
}
numberRead += reader.parse(s);
} catch (TemplateException | IOException e) {
throw new SAXException("Error storing value", e);
}
}
return;
}
if (isParseForTemplate) {
this.currentNodeForTemplate = this.currentNodeForTemplate.getParentNode();
return;
}
// Test if end action tag, set action to default
if (actionTags.contains(fullNameString)) {
setAction(Action.CREATE_UPDATE);
return;
}
if (currentValue != null) {
if (currentFieldName != null) {
if (UtilValidate.isNotEmpty(currentFieldValue)) {
if (currentValue.getModelEntity().isField(currentFieldName.toString())) {
ModelEntity modelEntity = currentValue.getModelEntity();
ModelField modelField = modelEntity.getField(currentFieldName.toString());
String type = modelField.getType();
if (type != null && "blob".equals(type)) {
byte[] binData = Base64.base64Decode((new String(currentFieldValue)).getBytes());
currentValue.setBytes(currentFieldName.toString(), binData);
} else {
currentValue.setString(currentFieldName.toString(), new String(currentFieldValue));
}
} else {
Debug.logWarning("Ignoring invalid field name [" + currentFieldName + "] found for the entity: " + currentValue.getEntityName() + " with value=" + currentFieldValue, module);
}
currentFieldValue = null;
}
currentFieldName = null;
} else {
// before we write currentValue check to see if PK is there, if not and it is one field, generate it from a sequence using the entity name
if (!currentValue.containsPrimaryKey()) {
if (currentValue.getModelEntity().getPksSize() == 1) {
ModelField modelField = currentValue.getModelEntity().getOnlyPk();
String newSeq = delegator.getNextSeqId(currentValue.getEntityName());
currentValue.setString(modelField.getName(), newSeq);
} else {
throw new SAXException("Cannot store value with incomplete primary key with more than 1 primary key field: " + currentValue);
}
}
try {
boolean exist = true;
boolean skip = false;
// It's necessary to check also for specific action CREATE and DELETE to ensure it's OK
if (Action.CREATE == currentAction || Action.DELETE == currentAction || Debug.verboseOn()) {
GenericHelper helper = delegator.getEntityHelper(currentValue.getEntityName());
if (currentValue.containsPrimaryKey()) {
try {
helper.findByPrimaryKey(currentValue.getPrimaryKey());
} catch (GenericEntityNotFoundException e) {
exist = false;
}
}
if (Action.CREATE == currentAction && exist) {
skip = true;
} else if (Action.DELETE == currentAction && !exist) {
skip = true;
}
}
if (!skip) {
if (this.useTryInsertMethod && !this.checkDataOnly) {
if (Action.DELETE == currentAction) {
currentValue.remove();
} else {
currentValue.create();
}
} else {
if (Action.DELETE == currentAction) {
valuesToDelete.add(currentValue);
if (valuesToDelete.size() >= valuesPerWrite) {
delegator.removeAll(valuesToDelete);
valuesToDelete.clear();
}
} else {
valuesToWrite.add(currentValue);
if (valuesToWrite.size() >= valuesPerWrite) {
writeValues(valuesToWrite);
valuesToWrite.clear();
}
}
}
}
numberRead++;
if (Debug.verboseOn())
countValue(skip, exist);
if ((numberRead % valuesPerMessage) == 0) {
Debug.logImportant("Another " + valuesPerMessage + " values imported: now up to " + numberRead, module);
}
currentValue = null;
} catch (GenericEntityException e) {
String errMsg = "Error performing action " + currentAction;
Debug.logError(e, errMsg, module);
throw new SAXException(errMsg, e);
}
}
}
}
Aggregations