1 10 package org.mmbase.bridge.jsp.taglib.util; 11 12 import java.util.*; 13 14 import javax.servlet.jsp.JspTagException ; 15 16 import org.mmbase.bridge.jsp.taglib.ContextReferrerTag; 17 import org.mmbase.cache.Cache; 18 import org.mmbase.util.*; 19 import org.mmbase.util.logging.*; 20 21 30 31 public class Attribute { 32 private static final Logger log = Logging.getLoggerInstance(Attribute.class); 33 34 private final static AttributeCache cache = new AttributeCache(); 35 37 public final static Attribute NULL = new NullAttribute(); 38 39 static { 40 cache.putCache(); 42 } 43 44 48 public static final Attribute getAttribute(final Object at) throws JspTagException { 49 if (at == null) return NULL; 50 return cache.getAttribute(at); 51 } 52 53 56 private boolean containsVars; 57 58 final boolean containsVars() { 59 return containsVars; 60 } 61 62 65 private Object attribute; 66 67 72 private List attributeParts; 73 74 77 protected Attribute(Object at) throws JspTagException { 78 attribute = at; 79 parse(); 80 } 81 82 protected Attribute() {} 83 84 90 91 public void appendValue(ContextReferrerTag tag, StringBuffer buffer) throws JspTagException { 92 if (log.isDebugEnabled()) { 93 log.debug("Appending " + attribute); 94 } 95 if (! containsVars) buffer.append(attribute.toString()); 96 Iterator i = attributeParts.iterator(); 97 while (i.hasNext()) { 98 Part ap = (Part) i.next(); 99 ap.appendValue(tag, buffer); 100 } 101 } 102 103 106 public Object getValue(ContextReferrerTag tag) throws JspTagException { 107 if (! containsVars) return attribute; 108 109 if (attributeParts.size() == 1) { Part ap = (Part) attributeParts.get(0); 111 return ap.getValue(tag); 112 } 113 StringBuffer result = new StringBuffer (); 114 appendValue(tag, result); 115 return result.toString(); 116 } 117 118 119 122 public String getString(ContextReferrerTag tag) throws JspTagException { 123 return Casting.toString(getValue(tag)); 124 } 125 126 129 130 public int getInt(ContextReferrerTag tag, int def) throws JspTagException { 131 return org.mmbase.util.Casting.toInt(getValue(tag), def); 132 } 133 134 public long getLong(ContextReferrerTag tag, long def) throws JspTagException { 135 return org.mmbase.util.Casting.toLong(getValue(tag), def); 136 } 137 138 143 144 public List getList(ContextReferrerTag tag) throws JspTagException { 145 return Arrays.asList( getString(tag).trim().split("\\s*,\\s*") ); 146 } 147 148 155 156 public boolean getBoolean(ContextReferrerTag tag, boolean def) throws JspTagException { 157 String val = getString(tag).toLowerCase(); 158 if ("true".equals(val)) return true; 159 if ("false".equals(val)) return false; 160 if ("yes".equals(val)) return true; 161 if ("no".equals(val)) return false; 162 if ("1".equals(val)) return true; 163 if ("0".equals(val)) return false; 164 if ("".equals(val)) return def; 165 throw new JspTagException (" " + getString(tag) + " is no boolean"); 166 } 167 168 171 public String toString() { 172 return "att: " + attribute.toString() + " parts: " + attributeParts; 173 } 174 175 180 181 protected void parse() throws JspTagException { 182 String attr = (String ) attribute; 183 int foundPos = attr.indexOf('$'); 185 if (foundPos == -1) { 186 containsVars = false; 187 return; } else { 189 attributeParts = new ArrayList(); 190 containsVars = true; 191 } 192 193 int pos = 0; 194 while (foundPos >= 0) { String npart = attr.substring(pos, foundPos); 196 if (npart.length() > 0) { 197 attributeParts.add(new StringPart(npart)); 198 } 199 foundPos ++; 201 if (foundPos >= attr.length()) { break; 204 } 205 char c = attr.charAt(foundPos); 206 if (c == '{' || c == '[') { char close = (c == '{' ? '}' : ']'); 208 pos = ++foundPos; 210 int opened = 1; 211 while (opened > 0) { 212 int posClose = attr.indexOf(close, pos); 213 if (posClose == -1) { 214 log.error("Unbalanced parentheses in '" + this + "'"); 215 throw new AttributeException("Unbalanced parentheses in '" + this + "'"); 216 } 217 int posOpen = attr.indexOf(c, pos); 218 219 if (posOpen > -1 && posOpen < posClose) { opened++; 221 pos = posOpen + 1; 222 } else { 223 opened--; 224 pos = posClose + 1; 225 } 226 } 227 if (attr.charAt(foundPos) != '+') { 228 Attribute var = getAttribute(attr.substring(foundPos, pos - 1)); 229 attributeParts.add(new VariablePart(var)); 230 } else { 231 Attribute var = getAttribute(attr.substring(foundPos + 1, pos - 1)); 232 attributeParts.add(new ExpressionPart(var)); 233 } 234 } else { pos = foundPos; 236 if (c == '$') { attributeParts.add(new StringPart("$")); 238 pos++; 239 } else { StringBuffer varName = new StringBuffer (); 241 while (ContextContainer.isContextIdentifierChar(c)) { 242 varName.append(c); 243 pos++; 244 if (pos >= attr.length()) break; c = attr.charAt(pos); 246 } 247 Attribute var = getAttribute(varName.toString()); 248 attributeParts.add(new VariablePart(var)); 249 } 250 } 251 foundPos = attr.indexOf('$', pos); 253 } 254 String rest = attr.substring(pos); 256 if (rest.length() > 0) { 257 attributeParts.add(new StringPart(rest)); 258 } 259 return; 260 } 261 262 265 266 static abstract class Part { 267 268 protected Object part; 269 270 273 abstract protected String getType(); 274 275 278 public String toString() { 279 return "(" + getType() + "/" + part.toString() + ")"; 280 } 281 282 abstract Object getValue(ContextReferrerTag tag) throws JspTagException ; 283 284 final void appendValue(ContextReferrerTag tag, StringBuffer buffer) throws JspTagException { 285 Casting.toStringBuffer(buffer, getValue(tag)); 286 } 287 } 288 289 292 static class VariablePart extends Part { 293 protected boolean containsVars; VariablePart(Attribute a) throws JspTagException { 295 containsVars = a.containsVars(); 296 if (containsVars) { 297 part = a; 298 } else { 299 String var = (String ) a.getValue(null); 300 if (var.length() < 1) { 301 log.error("Expression too short :" + var); 302 throw new AttributeException("Expression too short"); 303 } 304 part = var; 305 } 306 } 307 protected String getType() { return "Variable"; } 308 final Object getValue(ContextReferrerTag tag) throws JspTagException { 309 String v; 310 if (containsVars) { 311 v = (String ) ((Attribute) part).getValue(tag); 312 } else { 313 v = (String ) part; 314 } 315 if ("_".equals(v)) { 316 return tag.findWriter().getWriterValue(); 317 } else { 318 return tag.getObject(v); 319 } 320 } 321 } 322 323 328 329 static class ExpressionPart extends Part { 330 protected boolean evaluated; 331 protected String getEvaluated() { 332 return evaluated ? "evaluated" : "not evaluated"; 333 } 334 335 ExpressionPart(Attribute a) throws JspTagException { 336 if (a.containsVars()) { 337 evaluated = false; 338 part = a; 339 } else { 340 evaluated = true; 341 ExprCalc cl = new ExprCalc((String ) a.getValue(null)); 342 part = new Double (cl.getResult()); 343 } 344 } 345 protected String getType() { return "Expression (" + getEvaluated() + ")"; } 346 final Object getValue(ContextReferrerTag tag) throws JspTagException { 347 if (evaluated) { 348 return part; 349 } else { 350 ExprCalc cl = new ExprCalc( ((Attribute) part).getString(tag)); 351 return new Double (cl.getResult()); 352 } 353 } 354 } 355 356 360 361 static class StringPart extends Part { 362 StringPart(String o) { part = o; } 363 protected String getType() { return "String"; } 364 final Object getValue(ContextReferrerTag tag) throws JspTagException { 365 return part; 366 } 367 } 368 } 369 370 371 377 378 class AttributeCache extends Cache { 379 380 AttributeCache() { 381 super(1000); 382 } 383 384 public String getName() { return "TagAttributeCache"; } 385 public String getDescription() { return "Cache for parsed Tag Attributes"; } 386 public final Attribute getAttribute(final Object att) throws JspTagException { 387 Attribute res = (Attribute) super.get(att); 388 if (res == null) { 389 res = new Attribute(att); 390 super.put(att, res); 391 } 392 return res; 393 } 394 395 } 396 397 400 class AttributeException extends JspTagException { 401 AttributeException(String s) { super(s); } 402 } 403 404 408 final class NullAttribute extends Attribute { 409 NullAttribute() { } 410 public final Object getValue(ContextReferrerTag tag) throws JspTagException { return null; } 411 public final String getString(ContextReferrerTag tag) throws JspTagException { return ""; } 412 public final void appendValue(ContextReferrerTag tag, StringBuffer buffer) throws JspTagException { return; } 413 public final String toString() { return "NULLATTRIBUTE"; } 414 } 415 | Popular Tags |