<commit_before>package com.ilscipio.cato.ce.webapp.ftl.lang;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.template.FreeMarkerWorker;

import freemarker.core.Environment;
import freemarker.ext.beans.BeanModel;
import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.SimpleMapModel;
import freemarker.ext.util.WrapperTemplateModel;
import freemarker.template.DefaultArrayAdapter;
import freemarker.template.DefaultListAdapter;
import freemarker.template.ObjectWrapper;
import freemarker.template.ObjectWrapperAndUnwrapper;
import freemarker.template.SimpleHash;
import freemarker.template.SimpleSequence;
import freemarker.template.TemplateCollectionModel;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateHashModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateModelIterator;
import freemarker.template.TemplateScalarModel;
import freemarker.template.TemplateSequenceModel;
import freemarker.template.utility.DeepUnwrap;
import freemarker.template.utility.RichObjectWrapper;

/**
 * Cato: Freemarker language utils.
 * <p>
 * These should generally not include Ofbiz-specific utils, except in the case
 * where the Ofbiz-specific code is merely a configuration of Freemarker (e.g.
 * selected usage of <code>BeansWrapper</code>).
 * <p>
 * <strong>WARN:</strong> All utility methods here (except special wrap methods)
 * using ObjectWrapper should take an ObjectWrapper from caller - let caller decide which - and never
 * call Environment.getObjectWrapper anymore.
 *
 * @see com.ilscipio.cato.ce.webapp.ftl.CommonFtlUtil
 */
public abstract class LangFtlUtil {

    public static final String module = LangFtlUtil.class.getName();
    
    /**
     * Used for TemplateModel <-> unwrapped/raw value conversions.
     */
    public enum TemplateValueTargetType {
        PRESERVE,
        RAW,
        MODEL,
        SIMPLEMODEL,
        COMPLEXMODEL
    }

    public enum SetOperations {
        UNION,
        INTERSECT,
        DIFFERENCE
    }

    public interface FtlVarHandler {
        void setVariable(String name, TemplateModel model) throws TemplateModelException;
        TemplateModel getVariable(String name) throws TemplateModelException;
    }

    public static class GlobalFtlVarHandler implements FtlVarHandler {
        private final Environment env;
    
        public GlobalFtlVarHandler(Environment env) {
            this.env = env;
        }
    
        @Override
        public void setVariable(String name, TemplateModel model) throws TemplateModelException {
            env.setGlobalVariable(name, model);
        }
    
        @Override
        public TemplateModel getVariable(String name) throws TemplateModelException {
            return env.getGlobalVariable(name);
        }
    }

    public static class CurrentFtlVarHandler implements FtlVarHandler {
        private final Environment env;
    
        public CurrentFtlVarHandler(Environment env) {
            this.env = env;
        }
    
        @Override
        public void setVariable(String name, TemplateModel model) throws TemplateModelException {
            env.setVariable(name, model);
        }
    
        @Override
        public TemplateModel getVariable(String name) throws TemplateModelException {
            return env.getVariable(name);
        }
    }

    public static class LocalFtlVarHandler implements FtlVarHandler {
        private final Environment env;
    
        public LocalFtlVarHandler(Environment env) {
            this.env = env;
        }
    
        @Override
        public void setVariable(String name, TemplateModel model) throws TemplateModelException {
            env.setLocalVariable(name, model);
        }
    
        @Override
        public TemplateModel getVariable(String name) throws TemplateModelException {
            return env.getLocalVariable(name);
        }
    }

    protected LangFtlUtil() {
    }

    /**
     * Returns a TemplateModel representing a null value. Will always return
     * a model, even if the bean wrapper does not have a null model set.
     */
    public static TemplateModel getNullModelAlways() {
        return TemplateNullModel.getNullModel();
    }
    
    /**
     * Wraps the object without doing anything special. 
     */
    public static Object wrap(Object object, ObjectWrapper objectWrapper) throws TemplateModelException {
        return objectWrapper.wrap(object);
    }
    
    /**
     * Wraps an object using the standard system wrapper (BeansWrapper), bypassing any special Ofbiz
     * screen wrappers, which the passed objectWrapper may in fact be.
     */
    public static Object wrapNonEscaping(Object object, ObjectWrapper objectWrapper) throws TemplateModelException {
        // FIXME: This is a DIRTY reflection hack to get around build dependency issue!!!
        if ("ExtendedWrapper".equals(objectWrapper.getClass().getSimpleName())) {
            return FreeMarkerWorker.getDefaultOfbizWrapper().wrap(object);
        } else {
            return objectWrapper.wrap(object);
        }
    }
    
    /**
     * Checks if the wrapper is a special Ofbiz widget escaping wrapper, and if so,
     * returns a non-escaping one.
     */
    public static ObjectWrapper getNonEscapingObjectWrapper(ObjectWrapper objectWrapper) {
        // FIXME: This is a DIRTY reflection hack to get around build dependency issue!!!
        if ("ExtendedWrapper".equals(objectWrapper.getClass().getSimpleName())) {
            return FreeMarkerWorker.getDefaultOfbizWrapper();
        } else {
            return objectWrapper;
        }
    }
    
    /**
     * Checks if the current env wrapper is a special Ofbiz widget escaping wrapper, and if so,
     * returns a non-escaping one.
     */
    public static ObjectWrapper getNonEscapingObjectWrapper(Environment env) {
        ObjectWrapper objectWrapper = env.getObjectWrapper();
        // FIXME: This is a DIRTY reflection hack to get around build dependency issue!!!
        if ("ExtendedWrapper".equals(objectWrapper.getClass().getSimpleName())) {
            return FreeMarkerWorker.getDefaultOfbizWrapper();
        } else {
            return objectWrapper;
        }
    }    
    
    /**
     * Checks if the curent env wrapper is a special Ofbiz widget escaping wrapper, and if so,
     * returns a non-escaping one.
     */
    public static ObjectWrapper getNonEscapingObjectWrapper() {
        Environment env = FreeMarkerWorker.getCurrentEnvironment();
        ObjectWrapper objectWrapper = env.getObjectWrapper();
        // FIXME: This is a DIRTY reflection hack to get around build dependency issue!!!
        if ("ExtendedWrapper".equals(objectWrapper.getClass().getSimpleName())) {
            return FreeMarkerWorker.getDefaultOfbizWrapper();
        } else {
            return objectWrapper;
        }
    }  
    
    /**
     * Unwraps template model; if cannot, returns null.
     */
    public static Object unwrapOrNull(TemplateModel templateModel) throws TemplateModelException {
        if (templateModel != null) {
            Object res = DeepUnwrap.permissiveUnwrap(templateModel);
            if (res != templateModel) {
                return res;
            }<commit_msg>NoRef transforms: ObjectWrapper fix: WIP<commit_after>package com.ilscipio.cato.ce.webapp.ftl.lang;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.template.FreeMarkerWorker;
import org.ofbiz.webapp.ftl.EscapingObjectWrapper;

import freemarker.core.Environment;
import freemarker.ext.beans.BeanModel;
import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.SimpleMapModel;
import freemarker.ext.util.WrapperTemplateModel;
import freemarker.template.DefaultArrayAdapter;
import freemarker.template.DefaultListAdapter;
import freemarker.template.ObjectWrapper;
import freemarker.template.ObjectWrapperAndUnwrapper;
import freemarker.template.SimpleHash;
import freemarker.template.SimpleSequence;
import freemarker.template.TemplateCollectionModel;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateHashModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateModelIterator;
import freemarker.template.TemplateScalarModel;
import freemarker.template.TemplateSequenceModel;
import freemarker.template.utility.DeepUnwrap;
import freemarker.template.utility.RichObjectWrapper;

/**
 * Cato: Freemarker language utils.
 * <p>
 * These should generally not include Ofbiz-specific utils, except in the case
 * where the Ofbiz-specific code is merely a configuration of Freemarker (e.g.
 * selected usage of <code>BeansWrapper</code>).
 * <p>
 * <strong>WARN:</strong> All utility methods here (except special wrap methods)
 * using ObjectWrapper should take an ObjectWrapper from caller - let caller decide which - and never
 * call Environment.getObjectWrapper anymore.
 *
 * @see com.ilscipio.cato.ce.webapp.ftl.CommonFtlUtil
 */
public abstract class LangFtlUtil {

    public static final String module = LangFtlUtil.class.getName();
    
    /**
     * Used for TemplateModel <-> unwrapped/raw value conversions.
     */
    public enum TemplateValueTargetType {
        PRESERVE,
        RAW,
        MODEL,
        SIMPLEMODEL,
        COMPLEXMODEL
    }

    public enum SetOperations {
        UNION,
        INTERSECT,
        DIFFERENCE
    }

    public interface FtlVarHandler {
        void setVariable(String name, TemplateModel model) throws TemplateModelException;
        TemplateModel getVariable(String name) throws TemplateModelException;
    }

    public static class GlobalFtlVarHandler implements FtlVarHandler {
        private final Environment env;
    
        public GlobalFtlVarHandler(Environment env) {
            this.env = env;
        }
    
        @Override
        public void setVariable(String name, TemplateModel model) throws TemplateModelException {
            env.setGlobalVariable(name, model);
        }
    
        @Override
        public TemplateModel getVariable(String name) throws TemplateModelException {
            return env.getGlobalVariable(name);
        }
    }

    public static class CurrentFtlVarHandler implements FtlVarHandler {
        private final Environment env;
    
        public CurrentFtlVarHandler(Environment env) {
            this.env = env;
        }
    
        @Override
        public void setVariable(String name, TemplateModel model) throws TemplateModelException {
            env.setVariable(name, model);
        }
    
        @Override
        public TemplateModel getVariable(String name) throws TemplateModelException {
            return env.getVariable(name);
        }
    }

    public static class LocalFtlVarHandler implements FtlVarHandler {
        private final Environment env;
    
        public LocalFtlVarHandler(Environment env) {
            this.env = env;
        }
    
        @Override
        public void setVariable(String name, TemplateModel model) throws TemplateModelException {
            env.setLocalVariable(name, model);
        }
    
        @Override
        public TemplateModel getVariable(String name) throws TemplateModelException {
            return env.getLocalVariable(name);
        }
    }

    protected LangFtlUtil() {
    }

    /**
     * Returns a TemplateModel representing a null value. Will always return
     * a model, even if the bean wrapper does not have a null model set.
     */
    public static TemplateModel getNullModelAlways() {
        return TemplateNullModel.getNullModel();
    }
    
    /**
     * Wraps the object without doing anything special. 
     */
    public static Object wrap(Object object, ObjectWrapper objectWrapper) throws TemplateModelException {
        return objectWrapper.wrap(object);
    }
    
    /**
     * Wraps an object using the standard system wrapper (BeansWrapper), bypassing any special Ofbiz
     * screen wrappers, which the passed objectWrapper may in fact be.
     */
    public static Object wrapNonEscaping(Object object, ObjectWrapper objectWrapper) throws TemplateModelException {
        if (objectWrapper instanceof EscapingObjectWrapper) {
            return FreeMarkerWorker.getDefaultOfbizWrapper().wrap(object);
        } else {
            return objectWrapper.wrap(object);
        }
    }
    
    /**
     * Checks if the wrapper is a special Ofbiz widget escaping wrapper, and if so,
     * returns a non-escaping one.
     */
    public static ObjectWrapper getNonEscapingObjectWrapper(ObjectWrapper objectWrapper) {
        if (objectWrapper instanceof EscapingObjectWrapper) {
            return FreeMarkerWorker.getDefaultOfbizWrapper();
        } else {
            return objectWrapper;
        }
    }
    
    /**
     * Checks if the current env wrapper is a special Ofbiz widget escaping wrapper, and if so,
     * returns a non-escaping one.
     */
    public static ObjectWrapper getNonEscapingObjectWrapper(Environment env) {
        ObjectWrapper objectWrapper = env.getObjectWrapper();
        if (objectWrapper instanceof EscapingObjectWrapper) {
            return FreeMarkerWorker.getDefaultOfbizWrapper();
        } else {
            return objectWrapper;
        }
    }    
    
    /**
     * Checks if the curent env wrapper is a special Ofbiz widget escaping wrapper, and if so,
     * returns a non-escaping one.
     */
    public static ObjectWrapper getNonEscapingObjectWrapper() {
        Environment env = FreeMarkerWorker.getCurrentEnvironment();
        ObjectWrapper objectWrapper = env.getObjectWrapper();
        if (objectWrapper instanceof EscapingObjectWrapper) {
            return FreeMarkerWorker.getDefaultOfbizWrapper();
        } else {
            return objectWrapper;
        }
    }  
    
    /**
     * Unwraps template model; if cannot, returns null.
     */
    public static Object unwrapOrNull(TemplateModel templateModel) throws TemplateModelException {
        if (templateModel != null) {
            Object res = DeepUnwrap.permissiveUnwrap(templateModel);
            if (res != templateModel) {
                return res;
            }
{'fraction_non_alphanumeric': 0.07167165804519467, 'fraction_numerical': 0.0, 'mean_word_length': 2.9066737569795267, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '141385', 'n_tokens_mistral': 3775, 'n_tokens_neox': 3710, 'n_words': 1048}