merged with 1.1
[mir.git] / source / mir / util / ParameterExpander.java
index 6f96209..a65015b 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2001, 2002  The Mir-coders group
+ * Copyright (C) 2001, 2002 The Mir-coders group
  *
  * This file is part of Mir.
  *
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * In addition, as a special exception, The Mir-coders gives permission to link
- * the code of this program with the com.oreilly.servlet library, any library
- * licensed under the Apache Software License, The Sun (tm) Java Advanced
- * Imaging library (JAI), The Sun JIMI library (or with modified versions of
- * the above that use the same license as the above), and distribute linked
- * combinations including the two.  You must obey the GNU General Public
- * License in all respects for all of the code used other than the above
- * mentioned libraries.  If you modify this file, you may extend this exception
- * to your version of the file, but you are not obligated to do so.  If you do
- * not wish to do so, delete this exception statement from your version.
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
  */
-
 package mir.util;
 
 import java.util.HashMap;
@@ -37,9 +35,12 @@ import java.util.List;
 import java.util.Map;
 import java.util.Vector;
 
+import org.apache.commons.beanutils.*;
+
+import multex.Exc;
+
 import mir.generator.Generator;
 import mir.generator.GeneratorExc;
-import multex.Exc;
 
 public class ParameterExpander {
   final static String NODE_SEPARATOR = ".";
@@ -167,33 +168,33 @@ public class ParameterExpander {
     return result.toString();
   }
 
-  public static boolean evaluateBooleanExpression(Map aMap, String anExpression) throws Exception {
+  public static boolean evaluateBooleanExpression(Object aMap, String anExpression) throws Exception {
     Parser parser = new Parser(anExpression, aMap);
 
     return parser.parseBoolean();
   }
 
-  public static String evaluateStringExpression(Map aMap, String anExpression) throws Exception {
+  public static String evaluateStringExpression(Object aMap, String anExpression) throws Exception {
     Parser parser = new Parser(anExpression, aMap);
 
     return parser.parseString();
   }
 
-  public static int evaluateIntegerExpressionWithDefault(Map aMap, String anExpression, int aDefault) throws Exception {
+  public static int evaluateIntegerExpressionWithDefault(Object aMap, String anExpression, int aDefault) throws Exception {
     if (anExpression == null || anExpression.trim().equals(""))
       return aDefault;
     else
       return evaluateIntegerExpression(aMap, anExpression);
   }
 
-  public static int evaluateIntegerExpression(Map aMap, String anExpression) throws Exception {
+  public static int evaluateIntegerExpression(Object aMap, String anExpression) throws Exception {
     Parser parser = new Parser(anExpression, aMap);
 
     return parser.parseInteger();
   }
 
-  public static Object evaluateExpression(Map aMap, String anExpression) throws Exception {
-    Parser parser = new Parser(anExpression, aMap);
+  public static Object evaluateExpression(Object aRoot, String anExpression) throws Exception {
+    Parser parser = new Parser(anExpression, aRoot);
 
     return parser.parseWhole();
   }
@@ -489,9 +490,9 @@ public class ParameterExpander {
 
   private static class Parser {
     private Scanner scanner;
-    private Map valueMap;
+    private Object valueMap;
 
-    public Parser(String anExpression, Map aValueMap) {
+    public Parser(String anExpression, Object aValueMap) {
       scanner = new Scanner(new Reader(anExpression));
       valueMap = aValueMap;
     }
@@ -559,10 +560,6 @@ public class ParameterExpander {
       do {
         expression = parse();
 
-        if (expression==null) {
-          throw new RuntimeException("expression expected");
-        }
-
         result.add(expression);
 
         token = scanner.scan();
@@ -576,6 +573,28 @@ public class ParameterExpander {
       return result;
     }
 
+    private Object evaluateObjectField(Object anObject, Object aField) {
+      if (anObject instanceof Map) {
+        return ((Map) anObject).get(aField);
+      }
+      else if ((aField instanceof String) && PropertyUtils.isReadable(anObject, (String) aField)) {
+        try {
+          return PropertyUtils.getProperty(anObject, (String) aField);
+        }
+        catch (Throwable t) {
+          throw new RuntimeException(t.getMessage());
+        }
+      }
+      else {
+        try {
+          return MethodUtils.invokeExactMethod(anObject, "get", aField);
+        }
+        catch (Throwable t) {
+          throw new RuntimeException("Invalid reference of " + aField + "into " + anObject);
+        }
+      }
+    }
+
     private Object parseVariable() {
       boolean done;
       Token token;
@@ -593,23 +612,13 @@ public class ParameterExpander {
           if (!(token instanceof RightSquareBraceToken))
             throw new RuntimeException("] expected");
 
-          if (currentValue instanceof Map) {
-            currentValue = ((Map) currentValue).get(qualifier);
-          }
-          else {
-            throw new RuntimeException("cannot reference into anything other than a map ('"+qualifier+"')");
-          }
+          currentValue = evaluateObjectField(currentValue, qualifier);
         }
         else if (token instanceof IdentifierToken) {
           scanner.scan();
           qualifier = ((IdentifierToken) token).getName();
 
-          if (currentValue instanceof Map) {
-            currentValue = ((Map) currentValue).get(qualifier);
-          }
-          else {
-            throw new RuntimeException("cannot reference into anything other than a map ('"+qualifier+"')");
-          }
+          currentValue = evaluateObjectField(currentValue, qualifier);
         }
         else if (token instanceof LeftParenthesisToken) {
           if (currentValue instanceof Generator.GeneratorFunction) {
@@ -791,6 +800,8 @@ public class ParameterExpander {
     }
 
     private String interpretAsString(Object aValue) {
+      if (aValue==null)
+        return "";
       if (aValue instanceof String)
         return (String) aValue;
       if (aValue instanceof Integer)