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: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 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 public void setVariables(final Map map) { 093 if (map == null) { 094 throw new IllegalArgumentException("map"); 095 } 096 context.setVars(map); 097 } 098 099 private FlatResolver resolver = new FlatResolver(true); 100 101 protected Expression createExpression(final String expression) throws Exception { 102 // assert expression != null; 103 104 Expression expr = ExpressionFactory.createExpression(expression); 105 expr.addPreResolver(resolver); 106 107 return expr; 108 } 109 110 public Object evaluate(final String expression) throws Exception { 111 if (expression == null) { 112 throw new IllegalArgumentException("expression"); 113 } 114 115 boolean trace = log.isTraceEnabled(); 116 if (trace) { 117 log.trace("Evaluating expression: " + expression); 118 } 119 120 Expression expr = createExpression(expression); 121 Object obj = expr.evaluate(context); 122 if (trace) { 123 log.trace("Result: " + obj); 124 } 125 126 return obj; 127 } 128 129 public String parse(final String input) { 130 if (input == null) { 131 throw new IllegalArgumentException("input"); 132 } 133 134 boolean trace = log.isTraceEnabled(); 135 if (trace) { 136 log.trace("Parsing input: " + input); 137 } 138 139 StringBuffer buff = new StringBuffer(); 140 141 int cur = 0; 142 int prefixLoc; 143 int suffixLoc; 144 145 while (cur < input.length()) { 146 prefixLoc = input.indexOf("${", cur); 147 148 if (prefixLoc < 0) { 149 break; 150 } 151 152 suffixLoc = findBlockEnd(prefixLoc + 2, input); 153 if (suffixLoc < 0) { 154 throw new RuntimeException("Missing '}': " + input); 155 } 156 157 String expr = input.substring(prefixLoc + 2, suffixLoc); 158 buff.append(input.substring(cur, prefixLoc)); 159 160 try { 161 buff.append(evaluate(expr)); 162 } 163 catch (Exception e) { 164 throw new RuntimeException("Failed to evaluate: " + expr, e); 165 } 166 167 cur = suffixLoc + 1; 168 } 169 170 buff.append(input.substring(cur)); 171 172 if (trace) { 173 log.trace("Parsed result: " + buff); 174 } 175 176 return buff.toString(); 177 } 178 179 private int findBlockEnd(int pos, String input) { 180 int nested = 0; 181 while (pos < input.length()) { 182 char ch = input.charAt(pos); 183 if (ch == '{') { 184 nested++; 185 } else if (ch == '}') { 186 if (nested == 0) { 187 return pos; 188 } else { 189 nested--; 190 } 191 } 192 pos++; 193 } 194 return -1; 195 } 196 197 public String parse(final String input, final boolean trim) { 198 String output = parse(input); 199 if (trim && output != null) { 200 output = output.trim(); 201 } 202 203 return output; 204 } 205 }