1 package jimm.datavision; 2 import jimm.datavision.field.Field; 3 import jimm.datavision.field.SpecialField; 4 import jimm.datavision.source.Column; 5 import jimm.util.StringUtils; 6 import jimm.util.XMLWriter; 7 import jimm.util.Replacer; 8 import jimm.util.I18N; 9 10 33 public class Formula extends Expression { 34 35 protected String language; 36 protected Object cachedEvalResult; 37 protected boolean useCache; 38 protected boolean shouldEvaluate; 39 protected boolean showException; 40 41 49 public Formula(Long id, Report report, String name) { 50 this(id, report, name, null); 51 useCache = false; 52 shouldEvaluate = true; 53 showException = true; 54 } 55 56 68 public Formula(Long id, Report report, String name, String evalString) { 69 super(id == null ? report.generateNewFormulaId() : id, report, name, 70 evalString, "#"); 71 language = report.getScripting().getDefaultLanguage(); 72 } 73 74 75 public String dragString() { 76 return "formula:" + getId(); 77 } 78 79 public String designLabel() { 80 return "{@" + getName() + "}"; 81 } 82 83 public String formulaString() { 84 return "{@" + getId() + "}"; 85 } 86 87 91 public void useCache() { useCache = true; } 92 93 97 public void shouldEvaluate() { shouldEvaluate = true; } 98 99 public void setExpression(String newExpression) { 100 super.setExpression(newExpression); 101 showException = true; 102 } 103 104 116 public Object eval() { 117 return eval(null); 118 } 119 120 141 public Object eval(Field formulaField) { 142 if (!useCache || shouldEvaluate) { 143 cachedEvalResult = evaluate(formulaField); 144 shouldEvaluate = false; 145 } 146 return cachedEvalResult; 147 } 148 149 160 protected Object evaluate(final Field formulaField) { 161 String str = getExpression(); 162 if (str == null || str.trim().length() == 0) 163 return null; 164 165 str = StringUtils.replaceDelimited("#", "{%", "}", new Replacer() { 167 public Object replace(String str) { 168 Object obj = SpecialField.value(formulaField, str, report); 169 return obj == null ? "nil" : obj; 170 }}, 171 str); 172 if (str == null) return null; 173 174 str = StringUtils.replaceDelimited("#", "{@", "}", new Replacer() { 176 public Object replace(String str) { 177 Formula f = report.findFormula(str); 178 return f == null ? "nil" : f.eval(formulaField); 179 }}, 180 str); 181 if (str == null) return null; 182 183 str = StringUtils.replaceDelimited("#", "{?", "}", new Replacer() { 185 public Object replace(String str) { 186 Parameter p = report.findParameter(str); 187 return p == null ? "nil" : p.getValue(); 188 }}, 189 str); 190 if (str == null) return null; 191 192 str = StringUtils.replaceDelimited("#", "{!", "}", new Replacer() { 194 public Object replace(String str) { 195 UserColumn uc = report.findUserColumn(str); 196 return uc == null ? "nil" : report.columnValue(uc); 197 }}, 198 str); 199 if (str == null) return null; 200 201 str = StringUtils.replaceDelimited("#", "{", "}", new Replacer() { 203 public Object replace(String str) { 204 Column col = report.findColumn(str); 205 if (col == null) 206 return "{" + str + "}"; 207 208 Object val = null; 209 switch (col.getType()) { 210 case java.sql.Types.CHAR: 211 case java.sql.Types.VARCHAR: 212 case java.sql.Types.DATE: 213 case java.sql.Types.TIME: 214 case java.sql.Types.TIMESTAMP: 215 val = report.columnValue(col); 216 val = val == null ? "nil" : quoted(val); 217 break; 218 default: 219 val = report.columnValue(col); 220 if (val == null) 221 val = "nil"; 222 break; 223 } 224 return val; 225 }}, 226 str); 227 if (str == null || str.trim().length() == 0) return null; 228 229 try { 230 return report.eval(getLanguage(), str, getName()); 231 } 232 catch (Exception e) { 233 if (showException) { 234 showException = false; 235 ErrorHandler.error(I18N.get("Formula.script_error") 238 + " \"" + str + '"' + ": " + e.toString(), 239 I18N.get("Formula.script_error_title")); 240 } 241 return null; 242 } 243 } 244 245 250 public String getLanguage() { 251 return language == null ? report.getScripting().getDefaultLanguage() 252 : language; 253 } 254 255 public void setLanguage(String newLang) { 256 if (newLang == null) newLang = report.getScripting().getDefaultLanguage(); 257 258 if (!language.equals(newLang)) { 259 language = newLang; 260 setChanged(); 261 notifyObservers(); 262 } 263 } 264 265 273 protected String quoted(Object obj) { 274 String val = obj.toString(); 275 StringBuffer buf = new StringBuffer ("\""); 276 int len = val.length(); 277 for (int i = 0; i < len; ++i) { 278 char c = val.charAt(i); 279 switch (c) { 280 case '"': case '\\': 281 buf.append('\\'); 282 buf.append(c); 283 break; 284 default: 285 buf.append(c); 286 break; 287 } 288 } 289 buf.append('"'); 290 return buf.toString(); 291 } 292 293 302 public Object unquoted(Object obj) { 303 if (obj instanceof String ) { 304 String str = (String )obj; 305 if (str.startsWith("\"") && str.endsWith("\"")) { 306 str = str.substring(1, str.length() - 1); 307 StringBuffer buf = new StringBuffer (); 308 int oldPos = 0; 309 for (int pos = str.indexOf("\\"); pos != -1; 310 pos = str.indexOf("\\", oldPos)) 311 { 312 buf.append(str.substring(oldPos, pos)); 313 buf.append(str.charAt(pos + 1)); 314 oldPos = pos + 2; 315 } 316 buf.append(str.substring(oldPos)); 317 return buf.toString(); 318 } 319 } 320 return obj; 321 } 322 323 public void writeXML(XMLWriter out) { 324 writeXML(out, "formula"); 325 } 326 327 protected void writeAdditionalAttributes(XMLWriter out) { 328 if (language != null && language.length() != 0 329 && !language.equals(report.getScripting().getDefaultLanguage())) 330 out.attr("language", language); 331 332 } 333 334 } 335 | Popular Tags |