1 17 18 19 package org.apache.commons.digester; 20 21 22 import java.util.List ; 23 import java.util.LinkedList ; 24 import java.util.ArrayList ; 25 import java.util.HashMap ; 26 import java.beans.PropertyDescriptor ; 27 28 import org.apache.commons.beanutils.BeanUtils; 29 import org.apache.commons.beanutils.DynaBean; 30 import org.apache.commons.beanutils.DynaProperty; 31 import org.apache.commons.beanutils.PropertyUtils; 32 33 import org.xml.sax.Attributes ; 34 35 import org.apache.commons.logging.Log; 36 37 38 100 101 public class SetNestedPropertiesRule extends Rule { 102 103 private Log log = null; 104 105 private boolean trimData = true; 106 private boolean allowUnknownChildElements = false; 107 108 private HashMap elementNames = new HashMap (); 109 110 112 120 public SetNestedPropertiesRule() { 121 } 123 124 137 public SetNestedPropertiesRule(String elementName, String propertyName) { 138 elementNames.put(elementName, propertyName); 139 } 140 141 182 public SetNestedPropertiesRule(String [] elementNames, String [] propertyNames) { 183 for (int i=0, size=elementNames.length; i<size; i++) { 184 String propName = null; 185 if (i < propertyNames.length) { 186 propName = propertyNames[i]; 187 } 188 189 this.elementNames.put(elementNames[i], propName); 190 } 191 } 192 193 195 196 public void setDigester(Digester digester) { 197 super.setDigester(digester); 198 log = digester.getLogger(); 199 } 200 201 206 public void setTrimData(boolean trimData) { 207 this.trimData = trimData; 208 } 209 210 211 public boolean getTrimData() { 212 return trimData; 213 } 214 215 229 public void setAllowUnknownChildElements(boolean allowUnknownChildElements) { 230 this.allowUnknownChildElements = allowUnknownChildElements; 231 } 232 233 234 public boolean getAllowUnknownChildElements() { 235 return allowUnknownChildElements; 236 } 237 238 245 public void begin(String namespace, String name, Attributes attributes) 246 throws Exception { 247 Rules oldRules = digester.getRules(); 248 AnyChildRule anyChildRule = new AnyChildRule(); 249 anyChildRule.setDigester(digester); 250 AnyChildRules newRules = new AnyChildRules(anyChildRule); 251 newRules.init(digester.getMatch()+"/", oldRules); 252 digester.setRules(newRules); 253 } 254 255 260 public void body(String bodyText) throws Exception { 261 AnyChildRules newRules = (AnyChildRules) digester.getRules(); 262 digester.setRules(newRules.getOldRules()); 263 } 264 265 273 public void addAlias(String elementName, String propertyName) { 274 elementNames.put(elementName, propertyName); 275 } 276 277 280 public String toString() { 281 StringBuffer sb = new StringBuffer ("SetNestedPropertiesRule["); 282 sb.append("allowUnknownChildElements="); 283 sb.append(allowUnknownChildElements); 284 sb.append(", trimData="); 285 sb.append(trimData); 286 sb.append(", elementNames="); 287 sb.append(elementNames); 288 sb.append("]"); 289 return sb.toString(); 290 } 291 292 294 295 private class AnyChildRules implements Rules { 296 private String matchPrefix = null; 297 private Rules decoratedRules = null; 298 299 private ArrayList rules = new ArrayList (1); 300 private AnyChildRule rule; 301 302 public AnyChildRules(AnyChildRule rule) { 303 this.rule = rule; 304 rules.add(rule); 305 } 306 307 public Digester getDigester() { return null; } 308 public void setDigester(Digester digester) {} 309 public String getNamespaceURI() {return null;} 310 public void setNamespaceURI(String namespaceURI) {} 311 public void add(String pattern, Rule rule) {} 312 public void clear() {} 313 314 public List match(String matchPath) { 315 return match(null,matchPath); 316 } 317 318 public List match(String namespaceURI, String matchPath) { 319 List match = decoratedRules.match(namespaceURI, matchPath); 320 321 if ((matchPath.startsWith(matchPrefix)) && 322 (matchPath.indexOf('/', matchPrefix.length()) == -1)) { 323 324 329 if ((match == null || match.size()==0)) { 330 return rules; 335 } 336 else { 337 LinkedList newMatch = new LinkedList (match); 344 newMatch.addLast(rule); 345 return newMatch; 346 } 347 } 348 else { 349 return match; 350 } 351 } 352 353 public List rules() { 354 throw new RuntimeException ( 356 "AnyChildRules.rules not implemented."); 357 } 358 359 public void init(String prefix, Rules rules) { 360 matchPrefix = prefix; 361 decoratedRules = rules; 362 } 363 364 public Rules getOldRules() { 365 return decoratedRules; 366 } 367 } 368 369 private class AnyChildRule extends Rule { 370 private String currChildNamespaceURI = null; 371 private String currChildElementName = null; 372 373 public void begin(String namespaceURI, String name, 374 Attributes attributes) throws Exception { 375 376 currChildNamespaceURI = namespaceURI; 377 currChildElementName = name; 378 } 379 380 public void body(String value) throws Exception { 381 boolean debug = log.isDebugEnabled(); 382 383 String propName = currChildElementName; 384 if (elementNames.containsKey(currChildElementName)) { 385 propName = (String ) elementNames.get(currChildElementName); 387 if (propName == null) { 388 return; 390 } 391 } 392 393 if (digester.log.isDebugEnabled()) { 394 digester.log.debug("[SetNestedPropertiesRule]{" + digester.match + 395 "} Setting property '" + propName + "' to '" + 396 value + "'"); 397 } 398 399 Object top = digester.peek(); 401 if (digester.log.isDebugEnabled()) { 402 if (top != null) { 403 digester.log.debug("[SetNestedPropertiesRule]{" + digester.match + 404 "} Set " + top.getClass().getName() + 405 " properties"); 406 } else { 407 digester.log.debug("[SetPropertiesRule]{" + digester.match + 408 "} Set NULL properties"); 409 } 410 } 411 412 if (trimData) { 413 value = value.trim(); 414 } 415 416 if (!allowUnknownChildElements) { 417 if (top instanceof DynaBean) { 420 DynaProperty desc = 421 ((DynaBean) top).getDynaClass().getDynaProperty(propName); 422 if (desc == null) { 423 throw new NoSuchMethodException 424 ("Bean has no property named " + propName); 425 } 426 } else { 427 PropertyDescriptor desc = 428 PropertyUtils.getPropertyDescriptor(top, propName); 429 if (desc == null) { 430 throw new NoSuchMethodException 431 ("Bean has no property named " + propName); 432 } 433 } 434 } 435 436 try 437 { 438 BeanUtils.setProperty(top, propName, value); 439 } 440 catch(NullPointerException e) { 441 digester.log.error("NullPointerException: " 442 + "top=" + top + ",propName=" + propName + ",value=" + value + "!"); 443 throw e; 444 } 445 } 446 447 public void end(String namespace, String name) throws Exception { 448 currChildElementName = null; 449 } 450 } 451 } 452 | Popular Tags |