001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.system.configuration.condition;
018
019 import java.util.Map;
020
021 import org.apache.commons.jexl.Expression;
022 import org.apache.commons.jexl.ExpressionFactory;
023 import org.apache.commons.jexl.JexlContext;
024 import org.apache.commons.jexl.JexlHelper;
025 import org.apache.commons.jexl.resolver.FlatResolver;
026 import org.apache.commons.logging.Log;
027 import org.apache.commons.logging.LogFactory;
028
029 /**
030 * Parses expressions using <a href="http://jakarta.apache.org/commons/jexl/">Commons Jexl</a>.
031 *
032 * @version $Rev: 514355 $ $Date: 2007-03-03 23:29:59 -0500 (Sat, 03 Mar 2007) $
033 */
034 public class JexlExpressionParser {
035 private static final Log log = LogFactory.getLog(JexlExpressionParser.class);
036
037 protected JexlContext context;
038
039 public JexlExpressionParser(final Map vars) {
040 if (vars == null) {
041 throw new IllegalArgumentException("vars");
042 }
043
044 context = JexlHelper.createContext();
045 context.setVars(vars);
046
047 if (log.isTraceEnabled()) {
048 log.trace("Using variables: " + context.getVars());
049 }
050 }
051
052 public JexlExpressionParser() {
053 this(System.getProperties());
054 }
055
056 public Map getVariables() {
057 return context.getVars();
058 }
059
060 public Object getVariable(final Object name) {
061 if (name == null) {
062 throw new IllegalArgumentException("name");
063 }
064
065 return getVariables().get(name);
066 }
067
068 public Object setVariable(final Object name, final Object value) {
069 if (name == null) {
070 throw new IllegalArgumentException("name");
071 }
072
073 return getVariables().put(name, value);
074 }
075
076 public Object unsetVariable(final Object name) {
077 if (name == null) {
078 throw new IllegalArgumentException("name");
079 }
080
081 return getVariables().remove(name);
082 }
083
084 public void addVariables(final Map map) {
085 if (map == null) {
086 throw new IllegalArgumentException("map");
087 }
088
089 getVariables().putAll(map);
090 }
091
092 private FlatResolver resolver = new FlatResolver(true);
093
094 protected Expression createExpression(final String expression) throws Exception {
095 // assert expression != null;
096
097 Expression expr = ExpressionFactory.createExpression(expression);
098 expr.addPreResolver(resolver);
099
100 return expr;
101 }
102
103 public Object evaluate(final String expression) throws Exception {
104 if (expression == null) {
105 throw new IllegalArgumentException("expression");
106 }
107
108 boolean trace = log.isTraceEnabled();
109 if (trace) {
110 log.trace("Evaluating expression: " + expression);
111 }
112
113 Expression expr = createExpression(expression);
114 Object obj = expr.evaluate(context);
115 if (trace) {
116 log.trace("Result: " + obj);
117 }
118
119 return obj;
120 }
121
122 public String parse(final String input) {
123 if (input == null) {
124 throw new IllegalArgumentException("input");
125 }
126
127 boolean trace = log.isTraceEnabled();
128 if (trace) {
129 log.trace("Parsing input: " + input);
130 }
131
132 StringBuffer buff = new StringBuffer();
133
134 int cur = 0;
135 int prefixLoc;
136 int suffixLoc;
137
138 while (cur < input.length()) {
139 prefixLoc = input.indexOf("${", cur);
140
141 if (prefixLoc < 0) {
142 break;
143 }
144
145 suffixLoc = input.indexOf("}", prefixLoc);
146 if (suffixLoc < 0) {
147 throw new RuntimeException("Missing '}': " + input);
148 }
149
150 String expr = input.substring(prefixLoc + 2, suffixLoc);
151 buff.append(input.substring(cur, prefixLoc));
152
153 try {
154 buff.append(evaluate(expr));
155 }
156 catch (Exception e) {
157 throw new RuntimeException("Failed to evaluate: " + expr, e);
158 }
159
160 cur = suffixLoc + 1;
161 }
162
163 buff.append(input.substring(cur));
164
165 if (trace) {
166 log.trace("Parsed result: " + buff);
167 }
168
169 return buff.toString();
170 }
171
172 public String parse(final String input, final boolean trim) {
173 String output = parse(input);
174 if (trim && output != null) {
175 output = output.trim();
176 }
177
178 return output;
179 }
180 }