Return-Path: X-Original-To: apmail-commons-commits-archive@minotaur.apache.org Delivered-To: apmail-commons-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B4C547086 for ; Wed, 7 Dec 2011 13:23:02 +0000 (UTC) Received: (qmail 10250 invoked by uid 500); 7 Dec 2011 13:23:02 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 10184 invoked by uid 500); 7 Dec 2011 13:23:02 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 10157 invoked by uid 99); 7 Dec 2011 13:23:02 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 07 Dec 2011 13:23:02 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 07 Dec 2011 13:22:58 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id EE86523889E2 for ; Wed, 7 Dec 2011 13:22:37 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1211428 - in /commons/proper/jexl/trunk: ./ src/main/java/org/apache/commons/jexl3/ src/main/java/org/apache/commons/jexl3/annotations/ src/main/java/org/apache/commons/jexl3/internal/ src/main/java/org/apache/commons/jexl3/internal/intros... Date: Wed, 07 Dec 2011 13:22:37 -0000 To: commits@commons.apache.org From: henrib@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20111207132237.EE86523889E2@eris.apache.org> Author: henrib Date: Wed Dec 7 13:22:36 2011 New Revision: 1211428 URL: http://svn.apache.org/viewvc?rev=1211428&view=rev Log: JEXL-123: Removed subproject jexl-compat (unused); Added NoJexl annotation that allows to completely shield a package/class/etc. from JEXL introspection (JEXL wide sanbdox); Remaining Javadoc / import issues; Checkstyle ok, Cobertura ok, findugs ok Added: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/annotations/ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/annotations/NoJexl.java (with props) commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/annotations/package.html - copied, changed from r1209060, commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/package.html commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Permissions.java (with props) Modified: commons/proper/jexl/trunk/pom.xml commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlEvalContext.java commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JxltEngine.java commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Engine.java commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/TemplateEngine.java commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/AbstractExecutor.java commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ArrayIterator.java commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ClassMap.java commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Introspector.java commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/SandboxTest.java commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/UnifiedJEXLTest.java Modified: commons/proper/jexl/trunk/pom.xml URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/pom.xml?rev=1211428&r1=1211427&r2=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/pom.xml (original) +++ commons/proper/jexl/trunk/pom.xml Wed Dec 7 13:22:36 2011 @@ -111,12 +111,14 @@ test + Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java?rev=1211428&r1=1211427&r2=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java Wed Dec 7 13:22:36 2011 @@ -85,6 +85,10 @@ public class JexlBuilder { * The cache size. */ protected int cache = -1; + /** + * The class loader. + */ + protected ClassLoader loader = null; /** * Sets the JexlUberspect instance the engine will use. @@ -130,6 +134,21 @@ public class JexlBuilder { public Log logger() { return this.logger; } + + /** + * Sets the class loader to use. + * @param l the class loader + * @return this builder + */ + public JexlBuilder loader(ClassLoader l) { + this.loader = l; + return this; + } + + /** @return the class loader */ + public ClassLoader loader() { + return loader; + } /** * Sets whether the engine will throw JexlException during evaluation when an error is triggered. Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlEvalContext.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlEvalContext.java?rev=1211428&r1=1211427&r2=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlEvalContext.java (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlEvalContext.java Wed Dec 7 13:22:36 2011 @@ -53,10 +53,10 @@ public class JexlEvalContext implements * Creates a MapContext wrapping an existing user provided vars. *

The supplied vars should be null only in derived classes that override the get/set/has methods. * For a default vars context with a code supplied vars, use the default no-parameter contructor.

- * @param vars the variable vars + * @param map the variables map */ - public JexlEvalContext(Map vars) { - this.vars = vars == EMPTY_MAP ? new HashMap() : vars; + public JexlEvalContext(Map map) { + this.vars = map == EMPTY_MAP ? new HashMap() : map; } @Override Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JxltEngine.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JxltEngine.java?rev=1211428&r1=1211427&r2=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JxltEngine.java (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JxltEngine.java Wed Dec 7 13:22:36 2011 @@ -22,10 +22,10 @@ import java.util.List; import java.util.Set; /** - * A simple JEXL Template engine. + * A simple "JeXL Template" engine. *

* At the base is an evaluator similar to the Unified EL evaluator used in JSP/JSF based on JEXL. - * At the top is a template engine that uses JEXL (instead of OGNL/VTL) as the scripting + * At the top is a template engine inspired by Velocity that uses JEXL (instead of OGNL/VTL) as the scripting * language. *

*

@@ -33,9 +33,9 @@ import java.util.Set; * and facilitate the implementation of expression evaluation. *

*

- * The template engine is intended to output text, html, XML. + * The template engine is intended to output any form of text; html, XML, CSV... *

- * @since 2.0 + * @since 3.0 */ public abstract class JxltEngine { /** @@ -124,7 +124,8 @@ public abstract class JxltEngine { * @param context the variable context * @return the result of this expression evaluation or null if an error occurs and the {@link JexlEngine} is * running in silent mode - * @throws {@link JxltEngine$Exception} if an error occurs and the {@link JexlEngine} is not silent + * @throws Exception if an error occurs and the {@link JexlEngine} + * is not silent */ Object evaluate(JexlContext context); @@ -177,7 +178,7 @@ public abstract class JxltEngine { * @param context the context to use for immediate expression evaluations * @return an {@link UnifiedExpression} or null if an error occurs and the {@link JexlEngine} is running * in silent mode - * @throws {@link JxltEngine.Exception} if an error occurs and the {@link JexlEngine} + * @throws Exception if an error occurs and the {@link JexlEngine} * is not in silent mode */ UnifiedExpression prepare(JexlContext context); @@ -199,7 +200,8 @@ public abstract class JxltEngine { *

* @param expression the {@link Template} string expression * @return the {@link UnifiedExpression}, null if silent and an error occured - * @throws {@link JxltEngine.Exception} if an error occurs and the {@link JexlEngine} is not silent + * @throws Exception if an error occurs and the {@link JexlEngine} + * is not silent */ public abstract UnifiedExpression createExpression(String expression); @@ -245,6 +247,7 @@ public abstract class JxltEngine { * and stores the template expression array and the writer (java.io.Writer) that the 'jexl:print(...)' * delegates the output generation to. *

+ * @since 3.0 */ public interface Template { /** Added: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/annotations/NoJexl.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/annotations/NoJexl.java?rev=1211428&view=auto ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/annotations/NoJexl.java (added) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/annotations/NoJexl.java Wed Dec 7 13:22:36 2011 @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.jexl3.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Indicates JEXL Introspection should not see this element. + *

+ * This allows to completely hide a package, class, interface, constructor, method of field from + * JEXL; a NoJexl annotated element will not be usable through any kind of JEXL expression or script. + *

+ *

See {@link org.apache.commons.jexl3.Sandbox} for another way to restrict JEXL access. + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.PACKAGE}) +public @interface NoJexl { + +} Propchange: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/annotations/NoJexl.java ------------------------------------------------------------------------------ svn:eol-style = native Copied: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/annotations/package.html (from r1209060, commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/package.html) URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/annotations/package.html?p2=commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/annotations/package.html&p1=commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/package.html&r1=1209060&r2=1211428&rev=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/package.html (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/annotations/package.html Wed Dec 7 13:22:36 2011 @@ -16,21 +16,12 @@ limitations under the License. --> - Package Documentation for org.apache.commons.jexl3 Package + Package Documentation for org.apache.commons.jexl3.annotations Package -

Provides utilities for introspection services.

-

- This internal package is not intended for public usage and there is no - guarantee that its public classes or methods will remain as is in subsequent - versions. -

-

- This set of classes implement the various forms of setters and getters - used by Jexl. These are specialized forms for 'pure' properties, discovering - methods of the {s,g}etProperty form, for Maps, Lists and Ducks - - attempting to discover a 'get' or 'set' method, making an object walk and - quack. +

Provides annotation for introspection services.

+

The only annotation in this package allows to restrict what JEXL + can introspect and expose through scripting.

Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Engine.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Engine.java?rev=1211428&r1=1211427&r2=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Engine.java (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Engine.java Wed Dec 7 13:22:36 2011 @@ -16,24 +16,7 @@ */ package org.apache.commons.jexl3.internal; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.io.Reader; -import java.net.URL; -import java.net.URLConnection; -import java.lang.ref.SoftReference; -import java.util.ArrayList; -import java.util.Map; -import java.util.Set; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map.Entry; + import org.apache.commons.jexl3.JexlArithmetic; import org.apache.commons.jexl3.JexlBuilder; import org.apache.commons.jexl3.JexlContext; @@ -43,21 +26,41 @@ import org.apache.commons.jexl3.JexlExpr import org.apache.commons.jexl3.JexlInfo; import org.apache.commons.jexl3.JexlInfoHandle; import org.apache.commons.jexl3.JexlScript; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.commons.jexl3.parser.ParseException; -import org.apache.commons.jexl3.parser.Parser; -import org.apache.commons.jexl3.parser.JexlNode; -import org.apache.commons.jexl3.parser.TokenMgrError; -import org.apache.commons.jexl3.parser.ASTJexlScript; +import org.apache.commons.jexl3.internal.introspection.Uberspect; +import org.apache.commons.jexl3.introspection.JexlMethod; +import org.apache.commons.jexl3.introspection.JexlUberspect; import org.apache.commons.jexl3.parser.ASTArrayAccess; import org.apache.commons.jexl3.parser.ASTIdentifier; +import org.apache.commons.jexl3.parser.ASTJexlScript; import org.apache.commons.jexl3.parser.ASTReference; +import org.apache.commons.jexl3.parser.JexlNode; +import org.apache.commons.jexl3.parser.ParseException; +import org.apache.commons.jexl3.parser.Parser; +import org.apache.commons.jexl3.parser.TokenMgrError; -import org.apache.commons.jexl3.introspection.JexlUberspect; -import org.apache.commons.jexl3.introspection.JexlMethod; -import org.apache.commons.jexl3.internal.introspection.Uberspect; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import java.lang.ref.SoftReference; +import java.net.URL; +import java.net.URLConnection; /** * A JexlEngine implementation. @@ -168,6 +171,10 @@ public class Engine extends JexlEngine { */ public Engine(JexlBuilder conf) { this.uberspect = conf.uberspect() == null ? getUberspect(conf.logger()) : conf.uberspect(); + ClassLoader loader = conf.loader(); + if (loader != null) { + uberspect.setClassLoader(loader); + } this.logger = conf.logger() == null ? LogFactory.getLog(JexlEngine.class) : conf.logger(); this.functions = conf.namespaces() == null ? Collections.emptyMap() : conf.namespaces(); this.silent = conf.silent() == null ? false : conf.silent().booleanValue(); Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/TemplateEngine.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/TemplateEngine.java?rev=1211428&r1=1211427&r2=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/TemplateEngine.java (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/TemplateEngine.java Wed Dec 7 13:22:36 2011 @@ -16,16 +16,6 @@ */ package org.apache.commons.jexl3.internal; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; import org.apache.commons.jexl3.JexlContext; import org.apache.commons.jexl3.JexlEngine; import org.apache.commons.jexl3.JexlException; @@ -37,6 +27,18 @@ import org.apache.commons.jexl3.parser.A import org.apache.commons.jexl3.parser.JexlNode; import org.apache.commons.jexl3.parser.StringParser; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.Writer; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + /** * A JxltEngine implementation. * @since 3.0 Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/AbstractExecutor.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/AbstractExecutor.java?rev=1211428&r1=1211427&r2=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/AbstractExecutor.java (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/AbstractExecutor.java Wed Dec 7 13:22:36 2011 @@ -15,9 +15,11 @@ * limitations under the License. */ package org.apache.commons.jexl3.internal.introspection; + import org.apache.commons.jexl3.introspection.JexlMethod; -import org.apache.commons.jexl3.introspection.JexlPropertySet; import org.apache.commons.jexl3.introspection.JexlPropertyGet; +import org.apache.commons.jexl3.introspection.JexlPropertySet; + import java.lang.reflect.InvocationTargetException; /** Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ArrayIterator.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ArrayIterator.java?rev=1211428&r1=1211427&r2=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ArrayIterator.java (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ArrayIterator.java Wed Dec 7 13:22:36 2011 @@ -17,9 +17,9 @@ package org.apache.commons.jexl3.internal.introspection; +import java.lang.reflect.Array; import java.util.Iterator; import java.util.NoSuchElementException; -import java.lang.reflect.Array; /** *

Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ClassMap.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ClassMap.java?rev=1211428&r1=1211427&r2=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ClassMap.java (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/ClassMap.java Wed Dec 7 13:22:36 2011 @@ -84,7 +84,9 @@ final class ClassMap { if (fields.length > 0) { Map cache = new HashMap(); for (Field field : fields) { - cache.put(field.getName(), field); + if (Modifier.isPublic(field.getModifiers()) && Permissions.allow(field)) { + cache.put(field.getName(), field); + } } return cache; } else { @@ -182,8 +184,8 @@ final class ClassMap { try { Method[] methods = clazz.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { - int modifiers = methods[i].getModifiers(); - if (Modifier.isPublic(modifiers)) { + Method mi = methods[i]; + if (Modifier.isPublic(mi.getModifiers()) && Permissions.allow(mi)) { cache.put(methods[i]); } } Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Introspector.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Introspector.java?rev=1211428&r1=1211427&r2=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Introspector.java (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Introspector.java Wed Dec 7 13:22:36 2011 @@ -16,16 +16,18 @@ */ package org.apache.commons.jexl3.internal.introspection; -import java.lang.reflect.Method; +import org.apache.commons.logging.Log; + import java.lang.reflect.Constructor; import java.lang.reflect.Field; -import java.util.Map; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; - -import org.apache.commons.logging.Log; +import java.util.Map; /** * This basic function of this class is to return a Method object for a @@ -111,8 +113,7 @@ public final class Introspector { */ public Method getMethod(Class c, MethodKey key) { try { - ClassMap classMap = getMap(c); - return classMap.findMethod(key); + return getMap(c).findMethod(key); } catch (MethodKey.AmbiguousException xambiguous) { // whoops. Ambiguous. Make a nice log message and return null... if (rlog != null && rlog.isInfoEnabled()) { @@ -132,8 +133,7 @@ public final class Introspector { * @return the desired field or null if it does not exist or is not accessible * */ public Field getField(Class c, String key) { - ClassMap classMap = getMap(c); - return classMap.findField(c, key); + return getMap(c).findField(c, key); } /** @@ -291,7 +291,9 @@ public final class Introspector { } List> l = new LinkedList>(); for (Constructor ictor : clazz.getConstructors()) { - l.add(ictor); + if (Modifier.isPublic(ictor.getModifiers()) && Permissions.allow(ictor)) { + l.add(ictor); + } } // try to find one ctor = key.getMostSpecificConstructor(l); Added: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Permissions.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Permissions.java?rev=1211428&view=auto ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Permissions.java (added) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Permissions.java Wed Dec 7 13:22:36 2011 @@ -0,0 +1,201 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.jexl3.internal.introspection; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import org.apache.commons.jexl3.annotations.NoJexl; + +/** + * Checks whether an element (ctor, field or method) is visible by Jexl introspection + * by checking if has been annotated with NoJexl. + */ +public class Permissions { + /** Make non instantiable. */ + private Permissions() { + } + + /** + * Checks whether a class or one of its superclasses or implemented interfaces + * explicitly disallows JEXL introspection. + * @param clazz the class to check + * @return true if JEXL is allowed to introspect, false otherwise + */ + public static boolean allow(Class clazz) { + return allow(clazz, true); + } + + /** + * Checks whether a constructor + * explicitly disallows JEXL introspection. + * @param ctor the constructor to check + * @return true if JEXL is allowed to introspect, false otherwise + */ + public static boolean allow(Constructor ctor) { + if (ctor == null) { + return false; + } + Class clazz = ctor.getDeclaringClass(); + if (!allow(clazz, false)) { + return false; + } + // is ctor annotated with nojexl ? + NoJexl nojexl = ctor.getAnnotation(NoJexl.class); + if (nojexl != null) { + return false; + } + return true; + } + + /** + * Checks whether a field + * explicitly disallows JEXL introspection. + * @param field the field to check + * @return true if JEXL is allowed to introspect, false otherwise + */ + public static boolean allow(Field field) { + if (field == null) { + return false; + } + Class clazz = field.getDeclaringClass(); + if (!allow(clazz, false)) { + return false; + } + // is field annotated with nojexl ? + NoJexl nojexl = field.getAnnotation(NoJexl.class); + if (nojexl != null) { + return false; + } + return true; + } + + /** + * Checks whether a method explicitly disallows JEXL introspection. + *

Since methods can be overriden, this also checks that no superclass or interface + * explictly disallows this methods.

+ * @param method the method to check + * @return true if JEXL is allowed to introspect, false otherwise + */ + public static boolean allow(Method method) { + if (method == null) { + return false; + } + // is method annotated with nojexl ? + NoJexl nojexl = method.getAnnotation(NoJexl.class); + if (nojexl != null) { + return false; + } + // is the class annotated with nojexl ? + Class clazz = method.getDeclaringClass(); + nojexl = clazz.getAnnotation(NoJexl.class); + if (nojexl != null) { + return false; + } + // lets walk all interfaces + for (Class inter : clazz.getInterfaces()) { + if (!allow(inter, method)) { + return false; + } + } + // lets walk all super classes + clazz = clazz.getSuperclass(); + // walk all superclasses + while (clazz != null) { + if (!allow(clazz, method)) { + return false; + } + clazz = clazz.getSuperclass(); + } + return true; + } + + /** + * Checks whether a class or one of its superclasses or implemented interfaces + * explicitly disallows JEXL introspection. + * @param clazz the class to check + * @param interf whether interfaces should be checked as well + * @return true if JEXL is allowed to introspect, false otherwise + */ + private static boolean allow(Class clazz, boolean interf) { + if (clazz == null) { + return false; + } + // is package annotated with nojexl ? + Package pack = clazz.getPackage(); + if (pack != null && pack.getAnnotation(NoJexl.class) != null) { + return false; + } + // lets walk all interfaces + if (interf) { + for (Class inter : clazz.getInterfaces()) { + // is clazz annotated with nojexl ? + NoJexl nojexl = inter.getAnnotation(NoJexl.class); + if (nojexl != null) { + return false; + } + } + } + // lets walk all super classes + clazz = clazz.getSuperclass(); + // walk all superclasses + while (clazz != null) { + // is clazz annotated with nojexl ? + NoJexl nojexl = clazz.getAnnotation(NoJexl.class); + if (nojexl != null) { + return false; + } + clazz = clazz.getSuperclass(); + } + return true; + } + + /** + * Check whether a method is allowed to be JEXL introspected in all its + * superclasses and interfaces. + * @param clazz the class + * @param method the method + * @return true if JEXL is allowed to introspect, false otherwise + */ + private static boolean allow(Class clazz, Method method) { + if (clazz != null) { + try { + // check if method in that class is different from the method argument + Method wmethod = clazz.getMethod(method.getName(), method.getParameterTypes()); + if (wmethod != null) { + NoJexl nojexl = clazz.getAnnotation(NoJexl.class); + if (nojexl != null) { + return false; + } + // check if parent declaring class said nojexl (transitivity) + nojexl = wmethod.getAnnotation(NoJexl.class); + if (nojexl != null) { + return false; + } + } + } catch (NoSuchMethodException ex) { + // unexpected, return no + return true; + } catch (SecurityException ex) { + // unexpected, cant do much + return false; + } + } + return true; + } +} Propchange: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/introspection/Permissions.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/SandboxTest.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/SandboxTest.java?rev=1211428&r1=1211427&r2=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/SandboxTest.java (original) +++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/SandboxTest.java Wed Dec 7 13:22:36 2011 @@ -16,9 +16,11 @@ */ package org.apache.commons.jexl3; -import org.apache.commons.jexl3.introspection.Sandbox; +import org.apache.commons.jexl3.annotations.NoJexl; import org.apache.commons.jexl3.internal.introspection.SandboxUberspect; import org.apache.commons.jexl3.introspection.JexlUberspect; +import org.apache.commons.jexl3.introspection.Sandbox; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -27,15 +29,39 @@ import org.apache.commons.logging.LogFac */ public class SandboxTest extends JexlTestCase { static final Log LOGGER = LogFactory.getLog(SandboxTest.class.getName()); - + public SandboxTest() { super("SandboxTest"); } - public static class Foo { + @NoJexl + public interface CantCallMe { + void tryMe(); + } + + public interface TryCallMe { + @NoJexl + void tryMeARiver(); + } + + public static abstract class CallMeNot { + public @NoJexl + String NONO = "should not be accessible!"; + + @NoJexl + public void callMeNot() { + throw new RuntimeException("should not be callable!"); + } + } + + public static class Foo extends CallMeNot implements CantCallMe, TryCallMe { String name; public String alias; + public @NoJexl Foo(String name, String notcallable) { + throw new RuntimeException("should not be callable!"); + } + public Foo(String name) { this.name = name; this.alias = name + "-alias"; @@ -52,6 +78,21 @@ public class SandboxTest extends JexlTes public String Quux() { return name + "-quux"; } + + @NoJexl + public String cantCallMe() { + throw new RuntimeException("should not be callable!"); + } + + @Override + public void tryMe() { + throw new RuntimeException("should not be callable!"); + } + + @Override + public void tryMeARiver() { + throw new RuntimeException("should not be callable!"); + } } public void testCtorBlack() throws Exception { @@ -176,6 +217,35 @@ public class SandboxTest extends JexlTes assertEquals(foo.Quux(), result); } + public void testMethodNoJexl() throws Exception { + Foo foo = new Foo("42"); + String[] exprs = { + "foo.cantCallMe()", + "foo.tryMe()", + "foo.tryMeARiver()", + "foo.callMeNot()", + "foo.NONO", + "new('org.apache.commons.jexl3.SandboxTest$Foo', 'one', 'two')" + }; + JexlScript script; + Object result; + + JexlEngine sjexl = new JexlBuilder().loader(Foo.class.getClassLoader()).strict(true).create(); + for (String expr : exprs) { + script = sjexl.createScript(expr, "foo"); + try { + result = script.execute(null, foo); + fail("should have not been possible"); + } catch (JexlException.Method xjm) { + // ok + LOGGER.info(xjm.toString()); + } catch (JexlException.Property xjm) { + // ok + LOGGER.info(xjm.toString()); + } + } + } + public void testGetWhite() throws Exception { Foo foo = new Foo("42"); String expr = "foo.alias"; @@ -229,7 +299,7 @@ public class SandboxTest extends JexlTes String expr; JexlScript script; Object result; - + script = sjexl.createScript("System.exit()"); try { result = script.execute(context); @@ -237,7 +307,7 @@ public class SandboxTest extends JexlTes } catch (JexlException xjexl) { LOGGER.info(xjexl.toString()); } - + script = sjexl.createScript("new('java.io.File', '/tmp/should-not-be-created')"); try { result = script.execute(context); @@ -245,7 +315,7 @@ public class SandboxTest extends JexlTes } catch (JexlException xjexl) { LOGGER.info(xjexl.toString()); } - + expr = "System.currentTimeMillis()"; script = sjexl.createScript("System.currentTimeMillis()"); result = script.execute(context); Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/UnifiedJEXLTest.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/UnifiedJEXLTest.java?rev=1211428&r1=1211427&r2=1211428&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/UnifiedJEXLTest.java (original) +++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/UnifiedJEXLTest.java Wed Dec 7 13:22:36 2011 @@ -16,19 +16,17 @@ */ package org.apache.commons.jexl3; -import org.apache.commons.jexl3.internal.Engine; -import org.apache.commons.jexl3.internal.TemplateEngine; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; + import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Set; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; /** * Test cases for the UnifiedEL. @@ -36,17 +34,15 @@ import org.apache.commons.logging.LogFac public class UnifiedJEXLTest extends JexlTestCase { private static final JexlEngine ENGINE = new JexlBuilder().silent(false).cache(128).strict(true).create(); - private static final TemplateEngine EL = new TemplateEngine((Engine)ENGINE); + private static final JxltEngine JXLT = ENGINE.jxlt(); private static final Log LOG = LogFactory.getLog(JxltEngine.class); private JexlEvalContext context = null; - private Map vars = null; @Override public void setUp() throws Exception { // ensure jul logging is only error java.util.logging.Logger.getLogger(org.apache.commons.jexl3.JexlEngine.class.getName()).setLevel(java.util.logging.Level.SEVERE); - vars = new HashMap(); - context = new JexlEvalContext(vars); + context = new JexlEvalContext(); } @Override @@ -98,8 +94,8 @@ public class UnifiedJEXLTest extends Jex } public void testStatement() throws Exception { - vars.put("froboz", new Froboz(123)); - JxltEngine.UnifiedExpression check = EL.createExpression("${froboz.value = 32; froboz.plus10(); froboz.value}"); + context.set("froboz", new Froboz(123)); + JxltEngine.UnifiedExpression check = JXLT.createExpression("${froboz.value = 32; froboz.plus10(); froboz.value}"); Object o = check.evaluate(context); assertEquals("Result is not 42", new Integer(42), o); Set> evars = check.getVariables(); @@ -107,8 +103,8 @@ public class UnifiedJEXLTest extends Jex } public void testAssign() throws Exception { - JxltEngine.UnifiedExpression assign = EL.createExpression("${froboz.value = 10}"); - JxltEngine.UnifiedExpression check = EL.createExpression("${froboz.value}"); + JxltEngine.UnifiedExpression assign = JXLT.createExpression("${froboz.value = 10}"); + JxltEngine.UnifiedExpression check = JXLT.createExpression("${froboz.value}"); Object o = assign.evaluate(context); assertEquals("Result is not 10", new Integer(10), o); o = check.evaluate(context); @@ -117,14 +113,14 @@ public class UnifiedJEXLTest extends Jex public void testComposite() throws Exception { String source = "Dear ${p} ${name};"; - JxltEngine.UnifiedExpression expr = EL.createExpression(source); - vars.put("p", "Mr"); - vars.put("name", "Doe"); + JxltEngine.UnifiedExpression expr = JXLT.createExpression(source); + context.set("p", "Mr"); + context.set("name", "Doe"); assertTrue("expression should be immediate", expr.isImmediate()); Object o = expr.evaluate(context); assertEquals("Dear Mr Doe;", o); - vars.put("p", "Ms"); - vars.put("name", "Jones"); + context.set("p", "Ms"); + context.set("name", "Jones"); o = expr.evaluate(context); assertEquals("Dear Ms Jones;", o); assertEquals(source, getSource(expr.toString())); @@ -132,21 +128,22 @@ public class UnifiedJEXLTest extends Jex public void testPrepareEvaluate() throws Exception { final String source = "Dear #{p} ${name};"; - JxltEngine.UnifiedExpression expr = EL.createExpression("Dear #{p} ${name};"); + JxltEngine.UnifiedExpression expr = JXLT.createExpression("Dear #{p} ${name};"); assertTrue("expression should be deferred", expr.isDeferred()); Set> evars = expr.getVariables(); assertEquals(1, evars.size()); assertTrue(evars.contains(Arrays.asList("name"))); - vars.put("name", "Doe"); + context.set("name", "Doe"); JxltEngine.UnifiedExpression phase1 = expr.prepare(context); String as = phase1.asString(); assertEquals("Dear ${p} Doe;", as); Set> evars1 = phase1.getVariables(); assertEquals(1, evars1.size()); assertTrue(evars1.contains(Arrays.asList("p"))); - vars.put("p", "Mr"); - vars.put("name", "Should not be used in 2nd phase"); + context.clearVariables(); + context.set("p", "Mr"); + context.set("name", "Should not be used in 2nd phase"); Object o = phase1.evaluate(context); assertEquals("Dear Mr Doe;", o); @@ -157,14 +154,14 @@ public class UnifiedJEXLTest extends Jex public void testNested() throws Exception { final String source = "#{${hi}+'.world'}"; - JxltEngine.UnifiedExpression expr = EL.createExpression(source); + JxltEngine.UnifiedExpression expr = JXLT.createExpression(source); Set> evars = expr.getVariables(); assertEquals(1, evars.size()); assertTrue(evars.contains(Arrays.asList("hi"))); - vars.put("hi", "greeting"); - vars.put("greeting.world", "Hello World!"); + context.set("hi", "greeting"); + context.set("greeting.world", "Hello World!"); assertTrue("expression should be deferred", expr.isDeferred()); Object o = expr.evaluate(context); assertEquals("Hello World!", o); @@ -175,7 +172,7 @@ public class UnifiedJEXLTest extends Jex public void testImmediate() throws Exception { JexlContext none = null; final String source = "${'Hello ' + 'World!'}"; - JxltEngine.UnifiedExpression expr = EL.createExpression(source); + JxltEngine.UnifiedExpression expr = JXLT.createExpression(source); JxltEngine.UnifiedExpression prepared = expr.prepare(none); assertEquals("prepare should return same expression", "Hello World!", prepared.asString()); Object o = expr.evaluate(none); @@ -188,7 +185,7 @@ public class UnifiedJEXLTest extends Jex public void testConstant() throws Exception { JexlContext none = null; final String source = "Hello World!"; - JxltEngine.UnifiedExpression expr = EL.createExpression(source); + JxltEngine.UnifiedExpression expr = JXLT.createExpression(source); assertTrue("prepare should return same expression", expr.prepare(none) == expr); Object o = expr.evaluate(none); assertTrue("expression should be immediate", expr.isImmediate()); @@ -200,7 +197,7 @@ public class UnifiedJEXLTest extends Jex public void testDeferred() throws Exception { JexlContext none = null; final String source = "#{'world'}"; - JxltEngine.UnifiedExpression expr = EL.createExpression(source); + JxltEngine.UnifiedExpression expr = JXLT.createExpression(source); assertTrue("expression should be deferred", expr.isDeferred()); String as = expr.prepare(none).asString(); assertEquals("prepare should return immediate version", "${'world'}", as); @@ -215,23 +212,23 @@ public class UnifiedJEXLTest extends Jex JxltEngine.UnifiedExpression expr; Object o; // $ and # are escapable in TemplateEngine - expr = EL.createExpression("\\#{'world'}"); + expr = JXLT.createExpression("\\#{'world'}"); o = expr.evaluate(none); assertEquals("#{'world'}", o); - expr = EL.createExpression("\\${'world'}"); + expr = JXLT.createExpression("\\${'world'}"); o = expr.evaluate(none); assertEquals("${'world'}", o); } public void testEscapeString() throws Exception { - JxltEngine.UnifiedExpression expr = EL.createExpression("\\\"${'world\\'s finest'}\\\""); + JxltEngine.UnifiedExpression expr = JXLT.createExpression("\\\"${'world\\'s finest'}\\\""); JexlContext none = null; Object o = expr.evaluate(none); assertEquals("\"world's finest\"", o); } public void testNonEscapeString() throws Exception { - JxltEngine.UnifiedExpression expr = EL.createExpression("c:\\some\\windows\\path"); + JxltEngine.UnifiedExpression expr = JXLT.createExpression("c:\\some\\windows\\path"); JexlContext none = null; Object o = expr.evaluate(none); assertEquals("c:\\some\\windows\\path", o); @@ -239,7 +236,7 @@ public class UnifiedJEXLTest extends Jex public void testMalformed() throws Exception { try { - JxltEngine.UnifiedExpression expr = EL.createExpression("${'world'"); + JxltEngine.UnifiedExpression expr = JXLT.createExpression("${'world'"); JexlContext none = null; expr.evaluate(none); fail("should be malformed"); @@ -252,7 +249,7 @@ public class UnifiedJEXLTest extends Jex public void testMalformedNested() throws Exception { try { - JxltEngine.UnifiedExpression expr = EL.createExpression("#{${hi} world}"); + JxltEngine.UnifiedExpression expr = JXLT.createExpression("#{${hi} world}"); JexlContext none = null; expr.evaluate(none); fail("should be malformed"); @@ -265,7 +262,7 @@ public class UnifiedJEXLTest extends Jex public void testBadContextNested() throws Exception { try { - JxltEngine.UnifiedExpression expr = EL.createExpression("#{${hi}+'.world'}"); + JxltEngine.UnifiedExpression expr = JXLT.createExpression("#{${hi}+'.world'}"); JexlContext none = null; expr.evaluate(none); fail("should be malformed"); @@ -277,15 +274,15 @@ public class UnifiedJEXLTest extends Jex } public void testCharAtBug() throws Exception { - vars.put("foo", "abcdef"); - JxltEngine.UnifiedExpression expr = EL.createExpression("${foo.substring(2,4)/*comment*/}"); + context.set("foo", "abcdef"); + JxltEngine.UnifiedExpression expr = JXLT.createExpression("${foo.substring(2,4)/*comment*/}"); Object o = expr.evaluate(context); assertEquals("cd", o); - vars.put("bar", "foo"); + context.set("bar", "foo"); try { context.setSilent(true); - expr = EL.createExpression("#{${bar}+'.charAt(-2)'}"); + expr = JXLT.createExpression("#{${bar}+'.charAt(-2)'}"); expr = expr.prepare(context); o = expr.evaluate(context); assertEquals(null, o); @@ -300,16 +297,16 @@ public class UnifiedJEXLTest extends Jex StringWriter strw; String output; - JxltEngine.Template t = EL.createTemplate(source); + JxltEngine.Template t = JXLT.createTemplate(source); - vars.put("x", 42); + context.set("x", 42); strw = new StringWriter(); t.evaluate(context, strw); output = strw.toString(); assertEquals("x is 42\n", output); strw = new StringWriter(); - vars.put("x", ""); + context.set("x", ""); t.evaluate(context, strw); output = strw.toString(); assertEquals("no x\n", output); @@ -323,7 +320,7 @@ public class UnifiedJEXLTest extends Jex StringWriter strw; String output; - JxltEngine.Template t = EL.createTemplate("$$", new StringReader(source), "x"); + JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(source), "x"); String dstr = t.asString(); assertNotNull(dstr); @@ -344,7 +341,7 @@ public class UnifiedJEXLTest extends Jex + "${l10n}=#{x}\n" + "$$ }\n"; int[] args = { 42 }; - JxltEngine.Template tl10n = EL.createTemplate(source, "list"); + JxltEngine.Template tl10n = JXLT.createTemplate(source, "list"); String dstr = tl10n.asString(); assertNotNull(dstr); context.set("l10n", "valeur"); @@ -377,7 +374,7 @@ public class UnifiedJEXLTest extends Jex + "The value ${x} is under fourty-two\n" + "$$ }\n" + "$$ }\n"; - JxltEngine.Template t = EL.createTemplate("$$", new StringReader(test42), "list"); + JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader(test42), "list"); StringWriter strw = new StringWriter(); int[] list = {1, 3, 5, 42, 169}; t.evaluate(context, strw, list); @@ -414,7 +411,7 @@ public class UnifiedJEXLTest extends Jex public void testWriter() throws Exception { Froboz froboz = new Froboz(42); Writer writer = new FrobozWriter(new StringWriter()); - JxltEngine.Template t = EL.createTemplate("$$", new StringReader("$$$jexl.print(froboz)"), "froboz"); + JxltEngine.Template t = JXLT.createTemplate("$$", new StringReader("$$$jexl.print(froboz)"), "froboz"); t.evaluate(context, writer, froboz); assertEquals("froboz{42}", writer.toString()); }