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