1. /* $Id: SetPropertyRule.java,v 1.18 2004/05/10 06:30:06 skitching Exp $
  2. *
  3. * Copyright 2001-2004 The Apache Software Foundation.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package org.apache.commons.digester;
  18. import java.beans.PropertyDescriptor;
  19. import org.apache.commons.beanutils.BeanUtils;
  20. import org.apache.commons.beanutils.DynaBean;
  21. import org.apache.commons.beanutils.DynaProperty;
  22. import org.apache.commons.beanutils.PropertyUtils;
  23. import org.xml.sax.Attributes;
  24. /**
  25. * Rule implementation that sets an individual property on the object at the
  26. * top of the stack, based on attributes with specified names.
  27. */
  28. public class SetPropertyRule extends Rule {
  29. // ----------------------------------------------------------- Constructors
  30. /**
  31. * Construct a "set property" rule with the specified name and value
  32. * attributes.
  33. *
  34. * @param digester The digester with which this rule is associated
  35. * @param name Name of the attribute that will contain the name of the
  36. * property to be set
  37. * @param value Name of the attribute that will contain the value to which
  38. * the property should be set
  39. *
  40. * @deprecated The digester instance is now set in the {@link Digester#addRule} method.
  41. * Use {@link #SetPropertyRule(String name, String value)} instead.
  42. */
  43. public SetPropertyRule(Digester digester, String name, String value) {
  44. this(name, value);
  45. }
  46. /**
  47. * Construct a "set property" rule with the specified name and value
  48. * attributes.
  49. *
  50. * @param name Name of the attribute that will contain the name of the
  51. * property to be set
  52. * @param value Name of the attribute that will contain the value to which
  53. * the property should be set
  54. */
  55. public SetPropertyRule(String name, String value) {
  56. this.name = name;
  57. this.value = value;
  58. }
  59. // ----------------------------------------------------- Instance Variables
  60. /**
  61. * The attribute that will contain the property name.
  62. */
  63. protected String name = null;
  64. /**
  65. * The attribute that will contain the property value.
  66. */
  67. protected String value = null;
  68. // --------------------------------------------------------- Public Methods
  69. /**
  70. * Process the beginning of this element.
  71. *
  72. * @param attributes The attribute list of this element
  73. *
  74. * @exception NoSuchMethodException if the bean does not
  75. * have a writeable property of the specified name
  76. */
  77. public void begin(Attributes attributes) throws Exception {
  78. // Identify the actual property name and value to be used
  79. String actualName = null;
  80. String actualValue = null;
  81. for (int i = 0; i < attributes.getLength(); i++) {
  82. String name = attributes.getLocalName(i);
  83. if ("".equals(name)) {
  84. name = attributes.getQName(i);
  85. }
  86. String value = attributes.getValue(i);
  87. if (name.equals(this.name)) {
  88. actualName = value;
  89. } else if (name.equals(this.value)) {
  90. actualValue = value;
  91. }
  92. }
  93. // Get a reference to the top object
  94. Object top = digester.peek();
  95. // Log some debugging information
  96. if (digester.log.isDebugEnabled()) {
  97. digester.log.debug("[SetPropertyRule]{" + digester.match +
  98. "} Set " + top.getClass().getName() + " property " +
  99. actualName + " to " + actualValue);
  100. }
  101. // Force an exception if the property does not exist
  102. // (BeanUtils.setProperty() silently returns in this case)
  103. if (top instanceof DynaBean) {
  104. DynaProperty desc =
  105. ((DynaBean) top).getDynaClass().getDynaProperty(actualName);
  106. if (desc == null) {
  107. throw new NoSuchMethodException
  108. ("Bean has no property named " + actualName);
  109. }
  110. } else /* this is a standard JavaBean */ {
  111. PropertyDescriptor desc =
  112. PropertyUtils.getPropertyDescriptor(top, actualName);
  113. if (desc == null) {
  114. throw new NoSuchMethodException
  115. ("Bean has no property named " + actualName);
  116. }
  117. }
  118. // Set the property (with conversion as necessary)
  119. BeanUtils.setProperty(top, actualName, actualValue);
  120. }
  121. /**
  122. * Render a printable version of this Rule.
  123. */
  124. public String toString() {
  125. StringBuffer sb = new StringBuffer("SetPropertyRule[");
  126. sb.append("name=");
  127. sb.append(name);
  128. sb.append(", value=");
  129. sb.append(value);
  130. sb.append("]");
  131. return (sb.toString());
  132. }
  133. }