1 24 package org.ofbiz.base.util.string; 25 26 import java.io.Serializable ; 27 import java.util.Iterator ; 28 import java.util.LinkedList ; 29 import java.util.List ; 30 import java.util.Locale ; 31 import java.util.Map ; 32 33 import org.ofbiz.base.util.BshUtil; 34 import org.ofbiz.base.util.Debug; 35 import org.ofbiz.base.util.collections.FlexibleMapAccessor; 36 37 import bsh.EvalError; 38 39 48 public class FlexibleStringExpander implements Serializable { 49 50 public static final String module = FlexibleStringExpander.class.getName(); 51 52 protected String original; 53 protected List stringElements = new LinkedList (); 54 55 public FlexibleStringExpander(String original) { 56 this.original = original; 57 58 ParseElementHandler handler = new PreParseHandler(stringElements); 59 parseString(original, handler); 60 } 61 62 public boolean isEmpty() { 63 if (this.original == null || this.original.length() == 0) { 64 return true; 65 } else { 66 return false; 67 } 68 } 69 70 public String getOriginal() { 71 return this.original; 72 } 73 74 83 public String expandString(Map context) { 84 return this.expandString(context, null); 85 } 86 87 96 public String expandString(Map context, Locale locale) { 97 StringBuffer expanded = new StringBuffer (); 98 99 Iterator stringElementIter = stringElements.iterator(); 100 while (stringElementIter.hasNext()) { 101 StringElement element = (StringElement) stringElementIter.next(); 102 element.appendElement(expanded, context, locale); 103 } 104 105 return expandString(expanded.toString(), context); 107 } 108 109 120 public static String expandString(String original, Map context) { 121 return expandString(original, context, null); 122 } 123 124 135 public static String expandString(String original, Map context, Locale locale) { 136 if (original == null || original.length() < 3) { 138 return original; 139 } 140 141 int start = original.indexOf("${"); 144 if (start == -1) { 145 return original; 146 } else { 147 if (original.indexOf("}", start) == -1) { 148 Debug.logWarning("Found a ${ without a closing } (curly-brace) in the String: " + original, module); 150 return original; 151 } 152 } 153 154 StringBuffer expanded = new StringBuffer (); 155 ParseElementHandler handler = new OnTheFlyHandler(expanded, context, locale); 156 parseString(original, handler); 157 158 return expandString(expanded.toString(), context); 160 } 161 162 public static void parseString(String original, ParseElementHandler handler) { 163 if (original == null || original.length() == 0) { 164 return; 165 } 166 167 int start = original.indexOf("${"); 168 if (start == -1) { 169 handler.handleConstant(original, 0); 170 return; 171 } 172 int currentInd = 0; 173 int end = -1; 174 while (start != -1) { 175 end = original.indexOf("}", start); 176 if (end == -1) { 177 Debug.logWarning("Found a ${ without a closing } (curly-brace) in the String: " + original, module); 178 break; 179 } 180 181 int possibleNestedStart = original.lastIndexOf("${", end); 184 if (start != possibleNestedStart) { 185 start = possibleNestedStart; 187 } 188 189 handler.handleConstant(original, currentInd, start); 191 192 if (original.indexOf("bsh:", start+2) == start+2) { 194 handler.handleBsh(original, start+6, end); 196 } else { 197 handler.handleVariable(original, start+2, end); 199 } 200 201 currentInd = end + 1; 203 start = original.indexOf("${", currentInd); 204 } 205 206 if (currentInd < original.length()) { 208 handler.handleConstant(original, currentInd); 209 } 210 } 211 212 public static interface StringElement extends Serializable { 213 public void appendElement(StringBuffer buffer, Map context, Locale locale); 214 } 215 216 public static class ConstantElement implements StringElement { 217 protected String value; 218 219 public ConstantElement(String value) { 220 this.value = value; 221 } 222 223 public void appendElement(StringBuffer buffer, Map context, Locale locale) { 224 buffer.append(this.value); 225 } 226 } 227 228 public static class BshElement implements StringElement { 229 String scriptlet; 230 231 public BshElement(String scriptlet) { 232 this.scriptlet = scriptlet; 233 } 234 235 public void appendElement(StringBuffer buffer, Map context, Locale locale) { 236 try { 237 Object scriptResult = BshUtil.eval(scriptlet, context); 238 if (scriptResult != null) { 239 buffer.append(scriptResult.toString()); 240 } else { 241 Debug.logWarning("BSH scriplet evaluated to null [" + scriptlet + "], got no return so inserting nothing.", module); 242 } 243 } catch (EvalError e) { 244 Debug.logWarning(e, "Error evaluating BSH scriplet [" + scriptlet + "], inserting nothing; error was: " + e.toString(), module); 245 } 246 } 247 } 248 public static class VariableElement implements StringElement { 249 protected FlexibleMapAccessor fma; 250 251 public VariableElement(String valueName) { 252 this.fma = new FlexibleMapAccessor(valueName); 253 } 254 255 public void appendElement(StringBuffer buffer, Map context, Locale locale) { 256 Object retVal = fma.get(context, locale); 257 if (retVal != null) { 258 buffer.append(retVal.toString()); 259 } else { 260 } 262 } 263 } 264 265 public static interface ParseElementHandler extends Serializable { 266 public void handleConstant(String original, int start); 267 public void handleConstant(String original, int start, int end); 268 public void handleVariable(String original, int start, int end); 269 public void handleBsh(String original, int start, int end); 270 } 271 272 public static class PreParseHandler implements ParseElementHandler { 273 protected List stringElements; 274 275 public PreParseHandler(List stringElements) { 276 this.stringElements = stringElements; 277 } 278 279 public void handleConstant(String original, int start) { 280 stringElements.add(new ConstantElement(original.substring(start))); 281 } 282 283 public void handleConstant(String original, int start, int end) { 284 stringElements.add(new ConstantElement(original.substring(start, end))); 285 } 286 287 public void handleVariable(String original, int start, int end) { 288 stringElements.add(new VariableElement(original.substring(start, end))); 289 } 290 291 public void handleBsh(String original, int start, int end) { 292 stringElements.add(new BshElement(original.substring(start, end))); 293 } 294 } 295 296 public static class OnTheFlyHandler implements ParseElementHandler { 297 protected StringBuffer targetBuffer; 298 protected Map context; 299 protected Locale locale; 300 301 public OnTheFlyHandler(StringBuffer targetBuffer, Map context, Locale locale) { 302 this.targetBuffer = targetBuffer; 303 this.context = context; 304 this.locale = locale; 305 } 306 307 public void handleConstant(String original, int start) { 308 targetBuffer.append(original.substring(start)); 309 } 310 311 public void handleConstant(String original, int start, int end) { 312 targetBuffer.append(original.substring(start, end)); 313 } 314 315 public void handleVariable(String original, int start, int end) { 316 String envName = original.substring(start, end); 318 FlexibleMapAccessor fma = new FlexibleMapAccessor(envName); 319 Object envVal = fma.get(context, locale); 320 if (envVal != null) { 321 targetBuffer.append(envVal.toString()); 322 } else { 323 Debug.logWarning("Could not find value in environment for the name [" + envName + "], inserting nothing.", module); 324 } 325 } 326 327 public void handleBsh(String original, int start, int end) { 328 String scriptlet = original.substring(start, end); 330 try { 331 Object scriptResult = BshUtil.eval(scriptlet, context); 332 if (scriptResult != null) { 333 targetBuffer.append(scriptResult.toString()); 334 } else { 335 Debug.logWarning("BSH scriplet evaluated to null [" + scriptlet + "], got no return so inserting nothing.", module); 336 } 337 } catch (EvalError e) { 338 Debug.logWarning(e, "Error evaluating BSH scriplet [" + scriptlet + "], inserting nothing; error was: " + e.toString(), module); 339 } 340 } 341 } 342 } 343 | Popular Tags |