Author: cbrisson
Date: Thu Apr 18 14:54:42 2019
New Revision: 1857753

URL: http://svn.apache.org/viewvc?rev=1857753&view=rev
Log:
[tools/model] Initial import: names & values filters

Added:
    
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/
    
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/ColumnMapper.java
    
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Filter.java
    
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/FilterHandler.java
    
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Identifiers.java
    
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Mapper.java
    
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/TableMapper.java
    
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/TypeMapper.java
    
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/ValueFilterHandler.java

Added: 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/ColumnMapper.java
URL: 
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/ColumnMapper.java?rev=1857753&view=auto
==============================================================================
--- 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/ColumnMapper.java
 (added)
+++ 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/ColumnMapper.java
 Thu Apr 18 14:54:42 2019
@@ -0,0 +1,129 @@
+package org.apache.velocity.tools.model.filter;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.velocity.tools.config.ConfigurationException;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class ColumnMapper<T extends Serializable> extends 
TableMapper<T>
+{
+    public ColumnMapper(String configurationPrefix)
+    {
+        super(configurationPrefix);
+    }
+
+    @Override
+    protected void addEntry(String key, T leaf)
+    {
+        int dot = key.indexOf('.');
+        if (dot == -1)
+        {
+            super.addEntry(key, leaf);
+        }
+        else
+        {
+            int otherDot = key.indexOf('.', dot + 1);
+            if (otherDot != -1)
+            {
+                throw new ConfigurationException("invalid mappingEntry key: " 
+ getConfigurationPrefix() + "." + key);
+            }
+            String tablePattern = key.substring(0, dot);
+            String columnPattern = key.substring(dot + 1);
+            MappingEntry mappingEntry = new MappingEntry(columnPattern, leaf);
+            addColumnMapping(tablePattern, columnPattern, mappingEntry);
+        }
+    }
+
+    protected void addColumnMapping(String tablePattern, String columnPattern, 
MappingEntry mappingEntry)
+    {
+        Pair<MappingEntry, Map<String, MappingEntry>> pair = 
columnsMapping.get(tablePattern);
+        if (pair == null)
+        {
+            pair = Pair.of(new MappingEntry(tablePattern), new HashMap<String, 
MappingEntry>());
+            columnsMapping.put(tablePattern, pair);
+        }
+        Map<String, MappingEntry> colsMap = pair.getRight();
+        MappingEntry prevEntry = colsMap.put(columnPattern, mappingEntry);
+        if (prevEntry != null)
+        {
+            getLogger().warn("overriding " + getConfigurationPrefix() + 
".{}.{}", tablePattern, columnPattern);
+        }
+
+        if ("*".equals(columnPattern) && "*".equals(tablePattern))
+        {
+            defaultColumnLeaf = mappingEntry.getLeaf();
+        }
+    }
+
+
+    /* needed ?
+    public List<MappingEntry> getColumnsMapping(String table)
+    {
+        List<MappingEntry> ret = new ArrayList<>();
+        for (Pair<MappingEntry, Map<String, MappingEntry>> pair : 
columnsMapping.values())
+        {
+            if (pair.getLeft().matches(table))
+            {
+                ret.addAll(pair.getRight().values());
+            }
+        }
+        return ret;
+    }
+    */
+
+    public T getColumnEntry(String table, String column)
+    {
+        T ret = null;
+        for (MappingEntry entry : getTablesMapping().values())
+        {
+            if (entry.matches(table))
+            {
+                if (ret == null)
+                {
+                    ret = entry.getLeaf();
+                }
+                else
+                {
+                    ret = composeLeaves(entry.getLeaf(), ret);
+                }
+            }
+        }
+        for (Pair<MappingEntry, Map<String, MappingEntry>> pair : 
columnsMapping.values())
+        {
+            if (pair.getLeft().matches(table))
+            {
+                for (MappingEntry entry : pair.getRight().values())
+                {
+                    if (entry.matches(column))
+                    {
+                        if (ret == null)
+                        {
+                            ret = entry.getLeaf();
+                        }
+                        else
+                        {
+                            ret = composeLeaves(entry.getLeaf(), ret);
+                        }
+                    }
+                }
+            }
+        }
+        return ret;
+    }
+
+    public T getDefaultColumnLeaf()
+    {
+        return defaultColumnLeaf;
+    }
+
+    protected void setDefaultColumnLeaf(T defaultColumnLeaf)
+    {
+        this.defaultColumnLeaf = defaultColumnLeaf;
+    }
+
+    private T defaultColumnLeaf = null;
+
+    private Map<String, Pair<MappingEntry, Map<String, MappingEntry>>> 
columnsMapping = new HashMap<>();
+}

Added: 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Filter.java
URL: 
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Filter.java?rev=1857753&view=auto
==============================================================================
--- 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Filter.java
 (added)
+++ 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Filter.java
 Thu Apr 18 14:54:42 2019
@@ -0,0 +1,20 @@
+package org.apache.velocity.tools.model.filter;
+
+import java.io.Serializable;
+import java.sql.SQLException;
+
+@FunctionalInterface
+public interface Filter<T> extends Serializable
+{
+    T apply(T s) throws SQLException;
+
+    default Filter<T> compose(Filter<T> other)
+    {
+        return x -> apply(other.apply(x));
+    }
+
+    static Filter identity()
+    {
+        return x -> x;
+    }
+}

Added: 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/FilterHandler.java
URL: 
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/FilterHandler.java?rev=1857753&view=auto
==============================================================================
--- 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/FilterHandler.java
 (added)
+++ 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/FilterHandler.java
 Thu Apr 18 14:54:42 2019
@@ -0,0 +1,55 @@
+package org.apache.velocity.tools.model.filter;
+
+import org.apache.velocity.tools.ClassUtils;
+import org.apache.velocity.tools.config.ConfigurationException;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+
+public abstract class FilterHandler <T extends Serializable> extends 
TypeMapper<Filter<T>>
+{
+    public FilterHandler(String configurationPrefix)
+    {
+        super(configurationPrefix);
+        setDefaultColumnLeaf(Filter.identity());
+    }
+
+    @Override
+    protected Filter<T> composeLeaves(Filter<T> left, Filter<T> right)
+    {
+        return left.compose(right);
+    }
+
+    protected Filter<T> newObjectToLeaf(Object obj)
+    {
+        Filter<T> ret = null;
+        if (ret instanceof Filter)
+        {
+            return super.newObjectToLeaf(obj);
+        }
+        else
+        {
+            Method stringGetter = ClassUtils.findMethod(obj.getClass(), "get", 
String.class);
+            final Method getter = stringGetter == null ?
+                ClassUtils.findMethod(obj.getClass(), "get", Object.class) :
+                stringGetter;
+            if (getter == null)
+            {
+                throw new ConfigurationException(getConfigurationPrefix() + ": 
don't know what to do with class " + obj.getClass().getName());
+            }
+            return x ->
+            {
+                try
+                {
+                    return (T)getter.invoke(obj, x);
+                }
+                catch (IllegalAccessException | InvocationTargetException e)
+                {
+                    throw new SQLException("could not apply operator from 
class " + obj.getClass().getName());
+                }
+            };
+        }
+    }
+}

Added: 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Identifiers.java
URL: 
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Identifiers.java?rev=1857753&view=auto
==============================================================================
--- 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Identifiers.java
 (added)
+++ 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Identifiers.java
 Thu Apr 18 14:54:42 2019
@@ -0,0 +1,135 @@
+package org.apache.velocity.tools.model.filter;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.velocity.tools.ClassUtils;
+import org.apache.velocity.tools.config.ConfigurationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+import java.util.Locale;
+import java.util.regex.Pattern;
+
+public class Identifiers extends FilterHandler<String>
+{
+    protected static Logger logger = 
LoggerFactory.getLogger(Identifiers.class);
+
+    public Identifiers()
+    {
+        super("identifiers.mapping");
+        addStockObject("lowercase", x -> x.toLowerCase(Locale.ROOT));
+        addStockObject("uppercase", x -> x.toUpperCase(Locale.ROOT));
+        addStockObject("snake_to_camel", Identifiers::snakeToCamel);
+    }
+
+    private static final String[] prefixes = { "plural", "getPlural" };
+
+    public static String snakeToCamel(String snake)
+    {
+        snake = snake.toLowerCase(Locale.ROOT);
+        String[] parts = snake.split("_");
+        StringBuilder builder = new StringBuilder();
+        boolean first = true;
+        for (String part : parts)
+        {
+            if (part.length() > 0)
+            {
+                builder.append(first ? part : StringUtils.capitalize(part));
+                first = false;
+            }
+        }
+        return builder.length() == 0 ? "_" : builder.toString();
+    }
+
+    public void setInflector(String inflector)
+    {
+        if (inflector == null || inflector.length() == 0 || 
inflector.equals("none"))
+        {
+            this.inflector = Filter.identity();
+        }
+        else
+        {
+            try
+            {
+                Class pluralizerClass = ClassUtils.getClass(inflector);
+                Method method = null;
+                for (String prefix : prefixes)
+                {
+                    try
+                    {
+                        method = ClassUtils.findSetter(prefix, 
pluralizerClass, x -> x == String.class);
+                    }
+                    catch (NoSuchMethodException nsme)
+                    {
+                    }
+                }
+                if (method == null)
+                {
+                    throw new ConfigurationException("invalid inflector: " + 
inflector);
+                }
+                final Method m = method;
+                final Object o = pluralizerClass.newInstance();
+                this.inflector = x ->
+                {
+                    try
+                    {
+                        return (String)m.invoke(o, x);
+                    }
+                    catch (IllegalAccessException | InvocationTargetException 
e)
+                    {
+                        throw new SQLException("could not apply inflector from 
class " + o.getClass().getName());
+                    }
+                };
+            }
+            catch (Exception e)
+            {
+                throw new ConfigurationException("could not instanciate 
inflector", e);
+            }
+        }
+    }
+
+    public String pluralize(String word) throws SQLException
+    {
+        return inflector.apply(word);
+    }
+
+    @Override
+    protected Logger getLogger()
+    {
+        return logger;
+    }
+
+    @Override
+    protected Filter<String> stringToLeaf(String leaf)
+    {
+        Filter<String> ret = null;
+        if (leaf.startsWith("/"))
+        {
+            String[] parts = leaf.substring(1).split("/");
+            if (parts.length != 2)
+            {
+                throw new ConfigurationException("invalid regex replacement 
rule, expecting /search/replace/ :" + leaf);
+            }
+            final Pattern pattern = Pattern.compile(parts[0], 
Pattern.CASE_INSENSITIVE);
+            final String rep = parts[1];
+            return x -> pattern.matcher(x).replaceAll(rep);
+        }
+        return super.stringToLeaf(leaf);
+    }
+
+    public String transformTableName(String sqlTable) throws SQLException
+    {
+        Filter<String> filter = getTableEntry(sqlTable);
+        return filter == null ? sqlTable : filter.apply(sqlTable);
+    }
+
+    public String transformColumnName(String sqlTable, String sqlColumn) 
throws SQLException
+    {
+        Filter<String> filter = getColumnEntry(sqlTable, sqlColumn);
+        return filter == null ? sqlColumn : filter.apply(sqlColumn);
+    }
+
+    private Filter<String> inflector = Filter.identity();
+}

Added: 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Mapper.java
URL: 
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Mapper.java?rev=1857753&view=auto
==============================================================================
--- 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Mapper.java
 (added)
+++ 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/Mapper.java
 Thu Apr 18 14:54:42 2019
@@ -0,0 +1,196 @@
+package org.apache.velocity.tools.model.filter;
+
+import org.apache.velocity.tools.ClassUtils;
+import org.apache.velocity.tools.config.ConfigurationException;
+import org.apache.velocity.tools.model.util.GlobToRegex;
+import org.slf4j.Logger;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+public abstract class Mapper<T extends Serializable>
+{
+    public Mapper(String configurationPrefix)
+    {
+        this.configurationPrefix = configurationPrefix;
+    }
+
+    protected abstract Logger getLogger();
+
+    public void initialize() throws ConfigurationException
+    {
+    }
+
+    protected T valueToLeaf(Object value)
+    {
+        if (value == null)
+        {
+            return null;
+        }
+        if (value instanceof String)
+        {
+            T ret = null;
+            String[] leaves = ((String)value).split(",\\s*");
+            for (String strLeaf : leaves)
+            {
+                T leaf = stringToLeaf(strLeaf);
+                ret = ret == null ? leaf : composeLeaves(leaf, ret);
+            }
+            return ret;
+        }
+        try
+        {
+            return (T)value;
+        }
+        catch (ClassCastException cce)
+        {
+            throw new ConfigurationException("cannot convert mapped value to 
proper type", cce);
+        }
+    }
+
+    protected T stringToLeaf(String value)
+    {
+        T ret = getStockObject(value);
+        if (ret == null)
+        {
+            ret = classnameToLeaf(value);
+        }
+        return ret;
+    }
+
+    protected T classnameToLeaf(String clazz)
+    {
+        try
+        {
+            T ret = null;
+            Class leafClass = ClassUtils.getClass(clazz);
+            return classToLeaf(leafClass);
+        }
+        catch (ClassNotFoundException e)
+        {
+            throw new ConfigurationException(getConfigurationPrefix() + ": 
could not find class " + clazz);
+        }
+    }
+
+    protected T classToLeaf(Class leafClass)
+    {
+        try
+        {
+            Object obj = leafClass.newInstance();
+            return newObjectToLeaf(obj);
+        }
+        catch (IllegalAccessException | InstantiationException e)
+        {
+            throw new ConfigurationException(getConfigurationPrefix() + " : 
could not instanciate class " + leafClass.getName());
+        }
+    }
+
+    protected T newObjectToLeaf(Object obj)
+    {
+        try
+        {
+            return (T)obj;
+        }
+        catch (ClassCastException cce)
+        {
+            throw new ConfigurationException(getConfigurationPrefix() + ": 
unexpected object class", cce);
+        }
+    }
+
+    protected abstract T composeLeaves(T left, T right);
+
+    protected abstract void addEntry(String key, T leaf);
+
+    public void setMapping(String value)
+    {
+        Map map = new HashMap();
+        String[] parts = value.split(",");
+        for (String part : parts)
+        {
+            int eq = part.indexOf('=');
+            if (eq == -1)
+            {
+                // a single default ?
+                T leaf = stringToLeaf(part);
+                map.put("*", leaf);
+                map.put("*.*", leaf);
+            }
+            else
+            {
+                String key = part.substring(0, eq);
+                String val = part.substring(eq +  1);
+                map.put(key, val);
+            }
+        }
+        setMapping(map);
+    }
+
+    public void setMapping(Map map)
+    {
+        if (map == null)
+        {
+            return;
+        }
+        for (Map.Entry entry : (Set<Map.Entry>)map.entrySet())
+        {
+            String key = (String)entry.getKey();
+            T leaf = valueToLeaf(entry.getValue());
+            addEntry(key, leaf);
+        }
+    }
+
+    public class MappingEntry
+    {
+        MappingEntry(String pattern)
+        {
+            this(pattern, null);
+        }
+
+        MappingEntry(String pattern, T value)
+        {
+            this.pattern = Pattern.compile(GlobToRegex.toRegex(pattern, "."), 
Pattern.CASE_INSENSITIVE);
+            this.leaf = value;
+        }
+
+        public T getLeaf()
+        {
+            return leaf;
+        }
+
+        public void setLeaf(T leaf)
+        {
+            this.leaf = leaf;
+        }
+
+        public boolean matches(String name)
+        {
+            return pattern.matcher(name).matches();
+        }
+
+        private Pattern pattern;
+        private T leaf;
+    }
+
+    protected String getConfigurationPrefix()
+    {
+        return configurationPrefix;
+    }
+
+    protected void addStockObject(String key, T object)
+    {
+        stockObjects.put(key, object);
+    }
+
+    protected T getStockObject(String key)
+    {
+        return stockObjects.get(key);
+    }
+
+    private String configurationPrefix;
+
+    private Map<String, T> stockObjects = new HashMap<>();
+
+}

Added: 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/TableMapper.java
URL: 
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/TableMapper.java?rev=1857753&view=auto
==============================================================================
--- 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/TableMapper.java
 (added)
+++ 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/TableMapper.java
 Thu Apr 18 14:54:42 2019
@@ -0,0 +1,62 @@
+package org.apache.velocity.tools.model.filter;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Node : For speed considerations, filters are calculated for each known 
column at configuration time. It means that
+ * unknown result set column names will only be applied the <b>default</b> 
column filter, aka *.*
+ * @param <T>
+ */
+
+public abstract class TableMapper<T extends Serializable> extends Mapper<T>
+{
+    public TableMapper(String configurationPrefix)
+    {
+        super(configurationPrefix);
+    }
+
+    @Override
+    protected void addEntry(String pattern, T leaf)
+    {
+        MappingEntry mappingEntry = new MappingEntry(pattern, leaf);
+        addTableEntry(pattern, mappingEntry);
+    }
+
+    protected void addTableEntry(String pattern, MappingEntry mappingEntry)
+    {
+        MappingEntry prev = tablesMapping.put(pattern, mappingEntry);
+        if (prev != null)
+        {
+            getLogger().warn("overriding " + getConfigurationPrefix() + ".{}", 
pattern);
+        }
+    }
+
+    public T getTableEntry(String table)
+    {
+        T ret = null;
+        for (MappingEntry mappingEntry : tablesMapping.values())
+        {
+            if (mappingEntry.matches(table))
+            {
+                if (ret == null)
+                {
+                    ret = mappingEntry.getLeaf();
+                }
+                else
+                {
+                    ret = composeLeaves(mappingEntry.getLeaf(), ret);
+                }
+            }
+        }
+        return ret;
+    }
+
+    protected Map<String, MappingEntry> getTablesMapping()
+    {
+        return tablesMapping;
+    }
+
+    private Map<String, MappingEntry> tablesMapping = new HashMap<>();
+}

Added: 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/TypeMapper.java
URL: 
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/TypeMapper.java?rev=1857753&view=auto
==============================================================================
--- 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/TypeMapper.java
 (added)
+++ 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/TypeMapper.java
 Thu Apr 18 14:54:42 2019
@@ -0,0 +1,53 @@
+package org.apache.velocity.tools.model.filter;
+
+import org.apache.velocity.tools.ClassUtils;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class TypeMapper<T extends Serializable> extends 
ColumnMapper<T>
+{
+    public TypeMapper(String configurationPrefix)
+    {
+        super(configurationPrefix);
+    }
+
+    @Override
+    protected void addEntry(String key, T leaf)
+    {
+        try
+        {
+            Class clazz = ClassUtils.getClass(key);
+            addTypeEntry(clazz, leaf);
+        }
+        catch (ClassNotFoundException cnfe)
+        {
+            super.addEntry(key, leaf);
+        }
+    }
+
+    protected void addTypeEntry(Class clazz, T leaf)
+    {
+        typesMapping.put(clazz, leaf);
+    }
+
+    public T getTypeEntry(Class clazz)
+    {
+        T ret = null;
+        // apply the most specific one
+        while (clazz != null)
+        {
+            ret = typesMapping.get(clazz);
+            if (ret != null)
+            {
+                break;
+            }
+            clazz = clazz.getSuperclass();
+        }
+        return ret;
+    }
+
+
+    private Map<Class, T> typesMapping = new HashMap<>();
+}

Added: 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/ValueFilterHandler.java
URL: 
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/ValueFilterHandler.java?rev=1857753&view=auto
==============================================================================
--- 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/ValueFilterHandler.java
 (added)
+++ 
velocity/tools/branches/model/velocity-tools-model/src/main/java/org/apache/velocity/tools/model/filter/ValueFilterHandler.java
 Thu Apr 18 14:54:42 2019
@@ -0,0 +1,62 @@
+package org.apache.velocity.tools.model.filter;
+
+import org.apache.velocity.tools.model.util.Cryptograph;
+import org.apache.velocity.tools.model.util.TypeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.util.Calendar;
+import java.util.Locale;
+
+public class ValueFilterHandler extends FilterHandler<Serializable>
+{
+    protected static Logger logger = 
LoggerFactory.getLogger(ValueFilterHandler.class);
+
+    public ValueFilterHandler(String configurationPrefix)
+    {
+        super(configurationPrefix);
+        addStockObject("lowercase", x -> 
String.valueOf(x).toLowerCase(Locale.ROOT));
+        addStockObject("uppercase", x -> 
String.valueOf(x).toUpperCase(Locale.ROOT));
+        addStockObject("calendar_to_date", x -> x != null && x instanceof 
Calendar ? TypeUtils.toDate(x) : x);
+        addStockObject("date_to_calendar", x -> x != null && x instanceof 
java.sql.Date ? TypeUtils.toCalendar(x) : x);
+        addStockObject("number_to_boolean", x -> x != null && x instanceof 
Number ? ((Number)x).longValue() != 0 : x);
+        addStockObject("raw_obfuscate", x -> x != null ? 
cryptograph.encrypt(TypeUtils.toString(x)) : null);
+        addStockObject("raw_deobfuscate", x -> x != null ? 
cryptograph.decrypt(TypeUtils.toBytes(x)) : null);
+        addStockObject("obfuscate", x -> x != null ? 
TypeUtils.base64Encode(cryptograph.encrypt(String.valueOf(x))) : null);
+        addStockObject("deobfuscate", x -> x != null ? 
cryptograph.decrypt(TypeUtils.base64Decode(x)) : null);
+        addStockObject("deobfuscate_strings", x -> x != null && x instanceof 
String ? cryptograph.decrypt(TypeUtils.base64Decode(x)) : x);
+        addStockObject("base64_encode", x -> TypeUtils.base64Encode(x));
+        addStockObject("base64_decode", x -> TypeUtils.base64Decode(x));
+    }
+
+    @Override
+    protected Filter<Serializable> getStockObject(String key)
+    {
+        if (key.contains("obfuscate"))
+        {
+            needsCryptograph = true;
+        }
+        return super.getStockObject(key);
+    }
+
+
+    @Override
+    protected Logger getLogger()
+    {
+        return logger;
+    }
+
+    public void setCryptograph(Cryptograph cryptograph)
+    {
+        this.cryptograph = cryptograph;
+    }
+
+    public boolean needsCryptograph()
+    {
+        return needsCryptograph;
+    }
+
+    private Cryptograph cryptograph = null;
+    private boolean needsCryptograph = false;
+}


Reply via email to