org.apache.commons.jexl3.introspection.JexlUberspect Java Examples

The following examples show how to use org.apache.commons.jexl3.introspection.JexlUberspect. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: StrategyTest.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
@Test
public void testRawResolvers() throws Exception {
    Object map  = new HashMap<String, Object>();
    final JexlEngine jexl = new JexlBuilder().create();
    JexlUberspect uberspect = jexl.getUberspect();
    JexlUberspect.PropertyResolver rfieldp = JexlUberspect.JexlResolver.FIELD;
    JexlPropertyGet fget = rfieldp.getPropertyGet(uberspect, map, "key");
    Assert.assertNull(fget);
    JexlPropertySet fset = rfieldp.getPropertySet(uberspect, map, "key", "value");
    Assert.assertNull(fset);
    JexlUberspect.PropertyResolver rmap = JexlUberspect.JexlResolver.MAP;
    JexlPropertyGet mget = rmap.getPropertyGet(uberspect, map, "key");
    Assert.assertNotNull(mget);
    JexlPropertySet mset = rmap.getPropertySet(uberspect, map, "key", "value");
    Assert.assertNotNull(mset);
}
 
Example #2
Source File: TemplateInterpreter.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
/**
 * Prints to output.
 * <p>
 * This will dynamically try to find the best suitable method in the writer through uberspection.
 * Subclassing Writer by adding 'print' methods should be the preferred way to specialize output.
 * </p>
 * @param info the source info
 * @param arg  the argument to print out
 */
private void doPrint(JexlInfo info, Object arg) {
    try {
        if (writer != null) {
            if (arg instanceof CharSequence) {
                writer.write(arg.toString());
            } else if (arg != null) {
                Object[] value = {arg};
                JexlUberspect uber = jexl.getUberspect();
                JexlMethod method = uber.getMethod(writer, "print", value);
                if (method != null) {
                    method.invoke(writer, value);
                } else {
                    writer.write(arg.toString());
                }
            }
        }
    } catch (java.io.IOException xio) {
        throw TemplateEngine.createException(info, "call print", null, xio);
    } catch (java.lang.Exception xany) {
        throw TemplateEngine.createException(info, "invoke print", null, xany);
    }
}
 
Example #3
Source File: Operators.java    From commons-jexl with Apache License 2.0 6 votes vote down vote up
/**
 * Calculate the <code>size</code> of various types:
 * Collection, Array, Map, String, and anything that has a int size() method.
 * <p>Note that the result may not be an integer.
 *
 * @param node   the node that gave the value to size
 * @param object the object to get the size of
 * @return the evaluation result
 */
protected Object size(JexlNode node, Object object) {
    if (object == null) {
        return 0;
    }
    Object result = tryOverload(node, JexlOperator.SIZE, object);
    if (result != JexlEngine.TRY_FAILED) {
        return result;
    }
    final JexlArithmetic arithmetic = interpreter.arithmetic;
    result = arithmetic.size(object, null);
    if (result == null) {
        final JexlUberspect uberspect = interpreter.uberspect;
        // check if there is a size method on the object that returns an
        // integer and if so, just use it
        JexlMethod vm = uberspect.getMethod(object, "size", Interpreter.EMPTY_PARAMS);
        if (returnsInteger(vm)) {
            try {
                result = vm.invoke(object, Interpreter.EMPTY_PARAMS);
            } catch (Exception xany) {
                interpreter.operatorError(node, JexlOperator.SIZE, xany);
            }
        }
    }
    return result instanceof Number ? ((Number) result).intValue() : 0;
}
 
Example #4
Source File: Operators.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
/**
 * Check for emptyness of various types: Collection, Array, Map, String, and anything that has a boolean isEmpty()
 * method.
 * <p>Note that the result may not be a boolean.
 *
 * @param node   the node holding the object
 * @param object the object to check the emptyness of
 * @return the evaluation result
 */
protected Object empty(JexlNode node, Object object) {
    if (object == null) {
        return true;
    }
    Object result = tryOverload(node, JexlOperator.EMPTY, object);
    if (result != JexlEngine.TRY_FAILED) {
        return result;
    }
    final JexlArithmetic arithmetic = interpreter.arithmetic;
    result = arithmetic.isEmpty(object, null);
    if (result == null) {
        final JexlUberspect uberspect = interpreter.uberspect;
        result = false;
        // check if there is an isEmpty method on the object that returns a
        // boolean and if so, just use it
        JexlMethod vm = uberspect.getMethod(object, "isEmpty", Interpreter.EMPTY_PARAMS);
        if (returnsBoolean(vm)) {
            try {
                result = vm.invoke(object, Interpreter.EMPTY_PARAMS);
            } catch (Exception xany) {
                interpreter.operatorError(node, JexlOperator.EMPTY, xany);
            }
        }
    }
    return result instanceof Boolean ? (Boolean) result : true;
}
 
Example #5
Source File: Operators.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
/**
 * The 'match'/'in' operator implementation.
 * <p>
 * Note that 'x in y' or 'x matches y' means 'y contains x' ;
 * the JEXL operator arguments order syntax is the reverse of this method call.
 * </p>
 * @param node  the node
 * @param op    the calling operator, =~ or !~
 * @param right the left operand
 * @param left  the right operand
 * @return true if left matches right, false otherwise
 */
protected boolean contains(JexlNode node, String op, Object left, Object right) {
    final JexlArithmetic arithmetic = interpreter.arithmetic;
    final JexlUberspect uberspect = interpreter.uberspect;
    try {
        // try operator overload
        Object result = tryOverload(node, JexlOperator.CONTAINS, left, right);
        if (result instanceof Boolean) {
            return (Boolean) result;
        }
        // use arithmetic / pattern matching ?
        Boolean matched = arithmetic.contains(left, right);
        if (matched != null) {
            return matched;
        }
        // try a contains method (duck type set)
        try {
            Object[] argv = {right};
            JexlMethod vm = uberspect.getMethod(left, "contains", argv);
            if (returnsBoolean(vm)) {
                return (Boolean) vm.invoke(left, argv);
            } else if (arithmetic.narrowArguments(argv)) {
                vm = uberspect.getMethod(left, "contains", argv);
                if (returnsBoolean(vm)) {
                    return (Boolean) vm.invoke(left, argv);
                }
            }
        } catch (Exception e) {
            throw new JexlException(node, op + " error", e);
        }
        // defaults to equal
        return arithmetic.equals(left, right);
    } catch (ArithmeticException xrt) {
        throw new JexlException(node, op + " error", xrt);
    }
}
 
Example #6
Source File: Uberspect.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a new Uberspect.
 * @param runtimeLogger the logger used for all logging needs
 * @param sty the resolver strategy
 * @param perms the introspector permissions
 */
public Uberspect(Log runtimeLogger, JexlUberspect.ResolverStrategy sty, Permissions perms) {
    logger = runtimeLogger;
    strategy = sty == null? JexlUberspect.JEXL_STRATEGY : sty;
    permissions  = perms;
    ref = new SoftReference<Introspector>(null);
    loader = new SoftReference<ClassLoader>(getClass().getClassLoader());
    operatorMap = new ConcurrentHashMap<Class<? extends JexlArithmetic>, Set<JexlOperator>>();
    version = new AtomicInteger(0);
}
 
Example #7
Source File: SandboxUberspect.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
/**
 * A constructor for JexlSandbox uberspect.
 * @param theUberspect the JexlUberspect to sandbox
 * @param theSandbox the sandbox which is copied to avoid changes at runtime
 */
public SandboxUberspect(final JexlUberspect theUberspect, final JexlSandbox theSandbox) {
    if (theSandbox == null) {
        throw new NullPointerException("sandbox can not be null");
    }
    if (theUberspect == null) {
        throw new NullPointerException("uberspect can not be null");
    }
    this.uberspect = theUberspect;
    this.sandbox = theSandbox.copy();
}
 
Example #8
Source File: Operators.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
/**
 * Constructor.
 * @param owner the owning interpreter
 */
protected Operators(InterpreterBase owner) {
    final JexlArithmetic arithmetic = owner.arithmetic;
    final JexlUberspect uberspect = owner.uberspect;
    this.interpreter = owner;
    this.operators = uberspect.getArithmetic(arithmetic);
}
 
Example #9
Source File: Operators.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
/**
 * The 'startsWith' operator implementation.
 * @param node     the node
 * @param operator the calling operator, $= or $!
 * @param left     the left operand
 * @param right    the right operand
 * @return true if left starts with right, false otherwise
 */
protected boolean startsWith(JexlNode node, String operator, Object left, Object right) {
    final JexlArithmetic arithmetic = interpreter.arithmetic;
    final JexlUberspect uberspect = interpreter.uberspect;
    try {
        // try operator overload
        Object result = tryOverload(node, JexlOperator.STARTSWITH, left, right);
        if (result instanceof Boolean) {
            return (Boolean) result;
        }
        // use arithmetic / pattern matching ?
        Boolean matched = arithmetic.startsWith(left, right);
        if (matched != null) {
            return matched;
        }
        // try a startsWith method (duck type)
        try {
            Object[] argv = {right};
            JexlMethod vm = uberspect.getMethod(left, "startsWith", argv);
            if (returnsBoolean(vm)) {
                return (Boolean) vm.invoke(left, argv);
            } else if (arithmetic.narrowArguments(argv)) {
                vm = uberspect.getMethod(left, "startsWith", argv);
                if (returnsBoolean(vm)) {
                    return (Boolean) vm.invoke(left, argv);
                }
            }
        } catch (Exception e) {
            throw new JexlException(node, operator + " error", e);
        }
        // defaults to equal
        return arithmetic.equals(left, right) ? Boolean.TRUE : Boolean.FALSE;
    } catch (ArithmeticException xrt) {
        throw new JexlException(node, operator + " error", xrt);
    }
}
 
Example #10
Source File: Operators.java    From commons-jexl with Apache License 2.0 5 votes vote down vote up
/**
 * The 'endsWith' operator implementation.
 * @param node     the node
 * @param operator the calling operator, ^= or ^!
 * @param left     the left operand
 * @param right    the right operand
 * @return true if left ends with right, false otherwise
 */
protected boolean endsWith(JexlNode node, String operator, Object left, Object right) {
    final JexlArithmetic arithmetic = interpreter.arithmetic;
    final JexlUberspect uberspect = interpreter.uberspect;
    try {
        // try operator overload
        Object result = tryOverload(node, JexlOperator.ENDSWITH, left, right);
        if (result instanceof Boolean) {
            return (Boolean) result;
        }
        // use arithmetic / pattern matching ?
        Boolean matched = arithmetic.endsWith(left, right);
        if (matched != null) {
            return matched;
        }
        // try a endsWith method (duck type)
        try {
            Object[] argv = {right};
            JexlMethod vm = uberspect.getMethod(left, "endsWith", argv);
            if (returnsBoolean(vm)) {
                return (Boolean) vm.invoke(left, argv);
            } else if (arithmetic.narrowArguments(argv)) {
                vm = uberspect.getMethod(left, "endsWith", argv);
                if (returnsBoolean(vm)) {
                    return (Boolean) vm.invoke(left, argv);
                }
            }
        } catch (Exception e) {
            throw new JexlException(node, operator + " error", e);
        }
        // defaults to equal
        return arithmetic.equals(left, right) ? Boolean.TRUE : Boolean.FALSE;
    } catch (ArithmeticException xrt) {
        throw new JexlException(node, operator + " error", xrt);
    }
}
 
Example #11
Source File: StrategyTest.java    From commons-jexl with Apache License 2.0 4 votes vote down vote up
@Test
public void testMapStrategy() throws Exception {
    final JexlEngine jexl = new JexlBuilder().strategy(JexlUberspect.MAP_STRATEGY).create();
    run171(jexl, false);
}
 
Example #12
Source File: SandboxJexlUberspect.java    From nexus-public with Eclipse Public License 1.0 4 votes vote down vote up
public SandboxJexlUberspect() {
  super(LogFactory.getLog(JexlEngine.class), JexlUberspect.JEXL_STRATEGY);
}
 
Example #13
Source File: JexlBuilder.java    From commons-jexl with Apache License 2.0 4 votes vote down vote up
/** @return the strategy strategy */
public JexlUberspect.ResolverStrategy strategy() {
    return this.strategy;
}
 
Example #14
Source File: JexlBuilder.java    From commons-jexl with Apache License 2.0 4 votes vote down vote up
/** @return the uberspect */
public JexlUberspect uberspect() {
    return this.uberspect;
}
 
Example #15
Source File: InterpreterBase.java    From commons-jexl with Apache License 2.0 4 votes vote down vote up
/**
 * Sets an attribute of an object.
 *
 * @param object    to set the value to
 * @param attribute the attribute of the object, e.g. an index (1, 0, 2) or key for a map
 * @param value     the value to assign to the object's attribute
 * @param node      the node that evaluated as the object
 */
protected void setAttribute(Object object, Object attribute, Object value, JexlNode node) {
    cancelCheck(node);
    final JexlOperator operator = node != null && node.jjtGetParent() instanceof ASTArrayAccess
                                  ? JexlOperator.ARRAY_SET : JexlOperator.PROPERTY_SET;
    Object result = operators.tryOverload(node, operator, object, attribute, value);
    if (result != JexlEngine.TRY_FAILED) {
        return;
    }
    Exception xcause = null;
    try {
        // attempt to reuse last executor cached in volatile JexlNode.value
        if (node != null && cache) {
            Object cached = node.jjtGetValue();
            if (cached instanceof JexlPropertySet) {
                JexlPropertySet setter = (JexlPropertySet) cached;
                Object eval = setter.tryInvoke(object, attribute, value);
                if (!setter.tryFailed(eval)) {
                    return;
                }
            }
        }
        List<JexlUberspect.PropertyResolver> resolvers = uberspect.getResolvers(operator, object);
        JexlPropertySet vs = uberspect.getPropertySet(resolvers, object, attribute, value);
        // if we can't find an exact match, narrow the value argument and try again
        if (vs == null) {
            // replace all numbers with the smallest type that will fit
            Object[] narrow = {value};
            if (arithmetic.narrowArguments(narrow)) {
                vs = uberspect.getPropertySet(resolvers, object, attribute, narrow[0]);
            }
        }
        if (vs != null) {
            // cache executor in volatile JexlNode.value
            vs.invoke(object, value);
            if (node != null && cache && vs.isCacheable()) {
                node.jjtSetValue(vs);
            }
            return;
        }
    } catch (Exception xany) {
        xcause = xany;
    }
    // lets fail
    if (node != null) {
        String attrStr = attribute != null ? attribute.toString() : null;
        unsolvableProperty(node, attrStr, true, xcause);
    } else {
        // direct call
        String error = "unable to set object property"
                + ", class: " + object.getClass().getName()
                + ", property: " + attribute
                + ", argument: " + value.getClass().getSimpleName();
        throw new UnsupportedOperationException(error, xcause);
    }
}
 
Example #16
Source File: Engine.java    From commons-jexl with Apache License 2.0 4 votes vote down vote up
@Override
public JexlUberspect getUberspect() {
    return uberspect;
}
 
Example #17
Source File: Engine.java    From commons-jexl with Apache License 2.0 4 votes vote down vote up
/**
 * Creates a JEXL engine using the provided {@link JexlBuilder}.
 * @param conf the builder
 */
public Engine(JexlBuilder conf) {
    // options:
    this.options = conf.options().copy();
    this.strict = options.isStrict();
    this.safe = options.isSafe();
    this.silent = options.isSilent();
    this.cancellable = option(conf.cancellable(), !silent && strict);
    options.setCancellable(cancellable);
    this.debug = option(conf.debug(), true);
    this.collectMode = conf.collectMode();
    this.stackOverflow = conf.stackOverflow() > 0? conf.stackOverflow() : Integer.MAX_VALUE;
    // core properties:
    JexlUberspect uber = conf.uberspect() == null ? getUberspect(conf.logger(), conf.strategy()) : conf.uberspect();
    ClassLoader loader = conf.loader();
    if (loader != null) {
        uber.setClassLoader(loader);
    }
    JexlSandbox sandbox = conf.sandbox();
    if (sandbox == null) {
        this.uberspect = uber;
    } else {
        this.uberspect = new SandboxUberspect(uber, sandbox);
    }
    this.logger = conf.logger() == null ? LogFactory.getLog(JexlEngine.class) : conf.logger();
    this.arithmetic = conf.arithmetic() == null ? new JexlArithmetic(this.strict) : conf.arithmetic();
    options.setMathContext(arithmetic.getMathContext());
    options.setMathScale(arithmetic.getMathScale());
    options.setStrictArithmetic(arithmetic.isStrict());
    this.functions = conf.namespaces() == null ? Collections.<String, Object>emptyMap() : conf.namespaces();
    // parsing & features:
    JexlFeatures features = conf.features() == null? DEFAULT_FEATURES : conf.features();
    this.expressionFeatures = new JexlFeatures(features).script(false);
    this.scriptFeatures = new JexlFeatures(features).script(true);
    this.charset = conf.charset();
    // caching:
    this.cache = conf.cache() <= 0 ? null : new SoftCache<Source, ASTJexlScript>(conf.cache());
    this.cacheThreshold = conf.cacheThreshold();
    if (uberspect == null) {
        throw new IllegalArgumentException("uberspect can not be null");
    }
}
 
Example #18
Source File: SandboxUberspect.java    From syncope with Apache License 2.0 4 votes vote down vote up
SandboxUberspect() {
    super(LogFactory.getLog(JexlEngine.class), JexlUberspect.JEXL_STRATEGY);
}
 
Example #19
Source File: Engine.java    From commons-jexl with Apache License 2.0 3 votes vote down vote up
/**
 * Gets the default instance of Uberspect.
 * <p>This is lazily initialized to avoid building a default instance if there
 * is no use for it. The main reason for not using the default Uberspect instance is to
 * be able to use a (low level) introspector created with a given logger
 * instead of the default one.</p>
 * @param logger the logger to use for the underlying Uberspect
 * @param strategy the property resolver strategy
 * @return Uberspect the default uberspector instance.
 */
public static Uberspect getUberspect(Log logger, JexlUberspect.ResolverStrategy strategy) {
    if ((logger == null || logger.equals(LogFactory.getLog(JexlEngine.class)))
        && (strategy == null || strategy == JexlUberspect.JEXL_STRATEGY)) {
        return UberspectHolder.UBERSPECT;
    }
    return new Uberspect(logger, strategy);
}
 
Example #20
Source File: Uberspect.java    From commons-jexl with Apache License 2.0 2 votes vote down vote up
/**
 * Creates a new Uberspect.
 * @param runtimeLogger the logger used for all logging needs
 * @param sty the resolver strategy
 */
public Uberspect(Log runtimeLogger, JexlUberspect.ResolverStrategy sty) {
    this(runtimeLogger, sty, null);
}
 
Example #21
Source File: JexlBuilder.java    From commons-jexl with Apache License 2.0 2 votes vote down vote up
/**
 * Sets the JexlUberspect instance the engine will use.
 *
 * @param u the uberspect
 * @return this builder
 */
public JexlBuilder uberspect(JexlUberspect u) {
    this.uberspect = u;
    return this;
}
 
Example #22
Source File: JexlBuilder.java    From commons-jexl with Apache License 2.0 2 votes vote down vote up
/**
 * Sets the JexlUberspect strategy strategy the engine will use.
 * <p>This is ignored if the uberspect has been set.
 *
 * @param rs the strategy
 * @return this builder
 */
public JexlBuilder strategy(JexlUberspect.ResolverStrategy rs) {
    this.strategy = rs;
    return this;
}
 
Example #23
Source File: JexlEngine.java    From commons-jexl with Apache License 2.0 2 votes vote down vote up
/**
 * Gets this engine underlying {@link JexlUberspect}.
 *
 * @return the uberspect
 */
public abstract JexlUberspect getUberspect();