/** * Gets map keys, either as collection or Set. * <p> * WARN: auto-escaping is bypassed on all keys, caller handles. * (e.g. the object wrapper used to rewrap the result). * DEV NOTE: we MUST manually bypass auto-escaping for all on this one. */ public static Object getMapKeys(TemplateModel object) throws TemplateModelException { if (OfbizFtlObjectType.COMPLEXMAP.isObjectType(object)) { // WARN: bypasses auto-escaping Map<Object, Object> wrappedObject = UtilGenerics.cast(((WrapperTemplateModel) object).getWrappedObject()); return wrappedObject.keySet(); } else if (object instanceof TemplateHashModelEx) { // 2016-04-20: cannot do this because we MUST trigger bypass of auto-escaping, // so just do a deep unwrap, which automatically bypasses the escaping, // and then caller handles the result, which is probably an arraylist //return ((TemplateHashModelEx) object).keys(); return unwrapAlways(((TemplateHashModelEx) object).keys()); } else { throw new TemplateModelException("object is not a map or does not support key iteration"); } }
/** * Adapts a map to a TemplateHashModelEx using an appropriate simple adapter, normally * DefaultMapAdapter (or SimpleMapModel for BeansWrapper compatibility). * <p> * The ObjectWrapper is expected to implement at least ObjectWrapperWithAPISupport. * <p> * WARN: If impossible, it will duplicate the map using SimpleHash; but because this may result * in loss of ordering, a log warning will be printed. */ public static TemplateHashModelEx makeSimpleMapAdapter(Map<?, ?> map, ObjectWrapper objectWrapper, boolean permissive) throws TemplateModelException { // COMPATIBILITY MODE: check if exactly BeansWrapper, or a class that we know extends it WITHOUT extending DefaultObjectWrapper if (objectWrapper instanceof ScipioBeansWrapper || BeansWrapper.class.equals(objectWrapper.getClass())) { return new SimpleMapModel(map, (BeansWrapper) objectWrapper); } else if (objectWrapper instanceof ObjectWrapperWithAPISupport) { return DefaultMapAdapter.adapt(map, (ObjectWrapperWithAPISupport) objectWrapper); } else { if (permissive) { Debug.logWarning("Scipio: adaptSimpleMap: Unsupported Freemarker object wrapper (expected to implement ObjectWrapperWithAPISupport or BeansWrapper); forced to adapt map" + " using SimpleHash; this could cause loss of map insertion ordering; please switch renderer setup to a different ObjectWrapper", module); return new SimpleHash(map, objectWrapper); } else { throw new TemplateModelException("Tried to wrap a Map using an adapter class," + " but our ObjectWrapper does not implement ObjectWrapperWithAPISupport or BeansWrapper" + "; please switch renderer setup to a different ObjectWrapper"); } } }
/** * Combines two maps with the given operator into a new hash. */ public static TemplateHashModelEx combineMaps(TemplateHashModelEx first, TemplateHashModelEx second, SetOperations ops, ObjectWrapper objectWrapper) throws TemplateModelException { SimpleHash res = new SimpleHash(objectWrapper); if (ops == null || ops == SetOperations.UNION) { // this is less efficient than freemarker + operator, but provides the "alternative" implementation, so have choice addToSimpleMap(res, first); addToSimpleMap(res, second); } else if (ops == SetOperations.INTERSECT) { Set<String> intersectKeys = toStringSet(second.keys()); intersectKeys.retainAll(toStringSet(first.keys())); addToSimpleMap(res, second, intersectKeys); } else if (ops == SetOperations.DIFFERENCE) { Set<String> diffKeys = toStringSet(first.keys()); diffKeys.removeAll(toStringSet(second.keys())); addToSimpleMap(res, first, diffKeys); } else { throw new TemplateModelException("Unsupported combineMaps operation"); } return res; }
public Object execTyped(List<TemplateModel> args) throws TemplateModelException { if (args.size() != 2) { throw new TemplateModelException("Invalid number of arguments (expected: 2)"); } Environment env = FreeMarkerWorker.getCurrentEnvironment(); TemplateModel arg1 = args.get(0); if (!(arg1 instanceof TemplateScalarModel)) { throw new TemplateModelException("First argument (type) was not a string"); } String type = LangFtlUtil.getAsStringNonEscaping((TemplateScalarModel) arg1); TemplateModel arg2 = args.get(1); if (!(arg2 instanceof TemplateHashModel)) { throw new TemplateModelException("Second argument (sectionsMap) was not a map"); } TemplateHashModelEx sectionsMapModel = (TemplateHashModelEx) LangFtlUtil.toSimpleMap(arg2, false, env.getObjectWrapper()); if ("ftl".equals(type)) { FtlSectionsRenderer sections = FtlSectionsRenderer.create(sectionsMapModel); return sections; } else if ("screen".equals(type)) { // TODO: "screen": WARN: due to build dependencies we won't be able to invoke widget renderer from here // may be forced to use reflection (dirty)... throw new TemplateModelException("First argument (type) currently only supports: ftl (screen type not yet implemented)"); } else { throw new TemplateModelException("First argument (type) currently only supports: ftl"); } }
@Override protected Object execTyped(List<TemplateModel> args) throws TemplateModelException { TemplateHashModelEx varMapsModel = (TemplateHashModelEx) args.get(0); CommonVarMaps<Map<String, Object>> varMaps = CommonVarMaps.getRawMaps(varMapsModel); Environment env = FreeMarkerWorker.getCurrentEnvironment(); setVars(varMaps, env); return new SimpleScalar(""); }
@Override protected Object execTyped(List<TemplateModel> args) throws TemplateModelException { TemplateHashModelEx varListsModel = (TemplateHashModelEx) args.get(0); CommonVarMaps<Collection<String>> varLists = CommonVarMaps.getRawSequences(varListsModel); Environment env = FreeMarkerWorker.getCurrentEnvironment(); clearVars(varLists, env); return new SimpleScalar(""); }
@SuppressWarnings("unchecked") public static CommonVarMaps<Map<String, Object>> getRawMaps(TemplateHashModelEx varMapsModel) throws TemplateModelException { return new CommonVarMaps<>( (Map<String, Object>) LangFtlUtil.unwrap(varMapsModel.get("ctxVars")), (Map<String, Object>) LangFtlUtil.unwrap(varMapsModel.get("globalCtxVars")), (Map<String, Object>) LangFtlUtil.unwrap(varMapsModel.get("reqAttribs"))); }
public TemplateHashModelEx toMapModel(Environment env) { SimpleHash map = new SimpleHash(env.getObjectWrapper()); map.put("ctxVars", ctxVars); map.put("globalCtxVars", globalCtxVars); map.put("reqAttribs", reqAttribs); return map; }
@SuppressWarnings("unchecked") static Collection<String> getAsRawSequence(TemplateModel elems) throws TemplateModelException { if (elems == null || elems instanceof TemplateBooleanModel) { return Collections.emptyList(); } else if (elems instanceof TemplateCollectionModel || elems instanceof TemplateSequenceModel) { return (Collection<String>) LangFtlUtil.unwrapAlways(elems); } else if (elems instanceof TemplateHashModelEx) { return (Collection<String>) LangFtlUtil.getMapKeys(elems); } else { throw new TemplateModelException("invalid parameter type, can't interpret as sequence: " + elems.getClass()); } }
/** * Shallow-copies map or list. Note: won't preserve order for maps. * * @param object * @param toSimpleType if true, converts to simple FTL type instead of beans, where possible * @return * @throws TemplateModelException */ public static Object copyObject(TemplateModel object, TemplateValueTargetType targetType, ObjectWrapper objectWrapper) throws TemplateModelException { if (targetType == null) { targetType = TemplateValueTargetType.PRESERVE; } if (OfbizFtlObjectType.COMPLEXMAP.isObjectType(object) || (object instanceof TemplateHashModelEx && OfbizFtlObjectType.MAP.isObjectType(object))) { return LangFtlUtil.copyMap(object, null, null, targetType, objectWrapper); } else if (object instanceof TemplateCollectionModel || object instanceof TemplateSequenceModel) { return LangFtlUtil.copyList(object, targetType, objectWrapper); } else { throw new TemplateModelException("object is not cloneable"); } }
/** * Adds to simple hash from source map. * <p> * <em>WARN</em>: This is not BeanModel-aware (complex map). */ public static void addToSimpleMap(SimpleHash dest, TemplateHashModelEx source) throws TemplateModelException { TemplateCollectionModel keysModel = source.keys(); TemplateModelIterator modelIt = keysModel.iterator(); while(modelIt.hasNext()) { String key = getAsStringNonEscaping((TemplateScalarModel) modelIt.next()); dest.put(key, source.get(key)); } }
/** * Adds the still-wrapped TemplateModels in hash to a java Map. * <p> * <em>WARN</em>: This is not BeanModel-aware (complex map). */ public static void addModelsToMap(Map<String, ? super TemplateModel> dest, TemplateHashModelEx source) throws TemplateModelException { TemplateCollectionModel keysModel = source.keys(); TemplateModelIterator modelIt = keysModel.iterator(); while(modelIt.hasNext()) { String key = getAsStringNonEscaping((TemplateScalarModel) modelIt.next()); dest.put(key, source.get(key)); } }
public static FtlSectionsRenderer create(TemplateHashModelEx sectionMapModel) throws TemplateModelException { return new FtlSectionsRenderer(LangFtlUtil.makeModelObjectMap(sectionMapModel), new FtlContextFetcher.FallbackFtlFullFetcher(null, null)); }
public static CommonVarMaps<Collection<String>> getRawSequences(TemplateHashModelEx varListsModel) throws TemplateModelException { return new CommonVarMaps<>( getAsRawSequence(varListsModel.get("ctxVars")), getAsRawSequence(varListsModel.get("globalCtxVars")), getAsRawSequence(varListsModel.get("reqAttribs"))); }
@SuppressWarnings("unchecked") @Override public Object exec(List args) throws TemplateModelException { if (args == null || args.size() < 1 || args.size() > 2 ) { throw new TemplateModelException("Invalid number of arguments (expected: 1-2)"); } ObjectWrapper objectWrapper = CommonFtlUtil.getCurrentEnvironment().getObjectWrapper(); TemplateHashModelEx argsMap = (TemplateHashModelEx) args.get(0); // caller-supplied excludes TemplateModel excludesModel = (args.size() >=2) ? (TemplateModel) args.get(1) : null; Set<String> excludes; if (excludesModel != null) { excludes = LangFtlUtil.getAsStringSet(excludesModel); } else { excludes = new HashSet<>(); } SimpleHash res = null; final Boolean useExclude = Boolean.FALSE; // put attribs from explicit attribs map first, if any TemplateModel attribsModel = argsMap.get("attribs"); if (attribsModel != null && OfbizFtlObjectType.isObjectType(OfbizFtlObjectType.MAP, attribsModel)) { if (OfbizFtlObjectType.isObjectType(OfbizFtlObjectType.COMPLEXMAP, attribsModel)) { attribsModel = LangFtlUtil.toSimpleMap(attribsModel, false, objectWrapper); } res = LangFtlUtil.copyMapToSimple((TemplateHashModel) attribsModel, excludes, useExclude, objectWrapper); } // to get inline attribs, add list of all arg names to excludes as well as the lists themselves TemplateModel allArgNamesModel = argsMap.get("allArgNames"); if (allArgNamesModel != null) { excludes.addAll(LangFtlUtil.getAsStringSet(allArgNamesModel)); } excludes.add("allArgNames"); excludes.add("localArgNames"); // add the inline attribs over the attribs map (if any) if (res == null) { res = LangFtlUtil.copyMapToSimple(argsMap, excludes, useExclude, objectWrapper); } else { LangFtlUtil.putAll(res, argsMap, excludes, useExclude, objectWrapper); } return res; }
public static TemplateHashModelEx makeSimpleMapCopy(Map<?, ?> map, ObjectWrapper objectWrapper) throws TemplateModelException { return new SimpleHash(map, objectWrapper); }
public static Map<String, TemplateModel> makeModelMap(TemplateHashModelEx source) throws TemplateModelException { Map<String, TemplateModel> map = new HashMap<>(); addModelsToMap(map, source); return map; }
public static Map<String, Object> makeModelObjectMap(TemplateHashModelEx source) throws TemplateModelException { Map<String, Object> map = new HashMap<>(); addModelsToMap(map, source); return map; }
public static void varsPutAll(TemplateHashModelEx hashModel, Environment env) throws TemplateModelException { varsPutAll(hashModel, null, null, new CurrentFtlVarHandler(env), env); }
public static void localsPutAll(TemplateHashModelEx hashModel, Environment env) throws TemplateModelException { varsPutAll(hashModel, null, null, new LocalFtlVarHandler(env), env); }
/** * Puts all values in hash into FTL globals (#global). * <p> * @see copyMapToSimple */ public static void globalsPutAll(TemplateHashModelEx hashModel, Environment env) throws TemplateModelException { varsPutAll(hashModel, null, null, new GlobalFtlVarHandler(env), env); }