1. /*
  2. * Copyright 2002-2004 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.beans;
  17. import java.io.Serializable;
  18. import java.util.ArrayList;
  19. import java.util.Iterator;
  20. import java.util.List;
  21. import java.util.Map;
  22. import org.springframework.util.StringUtils;
  23. /**
  24. * Default implementation of the PropertyValues interface.
  25. * Allows simple manipulation of properties, and provides constructors
  26. * to support deep copy and construction from a Map.
  27. * @author Rod Johnson
  28. * @since 13 May 2001
  29. * @version $Id: MutablePropertyValues.java,v 1.8 2004/05/18 07:36:40 jhoeller Exp $
  30. */
  31. public class MutablePropertyValues implements PropertyValues, Serializable {
  32. /** List of PropertyValue objects */
  33. private final List propertyValuesList = new ArrayList();
  34. /**
  35. * Creates a new empty MutablePropertyValues object.
  36. * Property values can be added with the addPropertyValue methods.
  37. * @see #addPropertyValue(PropertyValue)
  38. * @see #addPropertyValue(String, Object)
  39. */
  40. public MutablePropertyValues() {
  41. }
  42. /**
  43. * Deep copy constructor. Guarantees PropertyValue references
  44. * are independent, although it can't deep copy objects currently
  45. * referenced by individual PropertyValue objects.
  46. * @param source the PropertyValues to copy
  47. * @see #addPropertyValues(PropertyValues)
  48. */
  49. public MutablePropertyValues(PropertyValues source) {
  50. addPropertyValues(source);
  51. }
  52. /**
  53. * Construct a new PropertyValues object from a Map.
  54. * @param source Map with property values keyed by property name,
  55. * which must be a String
  56. * @see #addPropertyValues(Map)
  57. */
  58. public MutablePropertyValues(Map source) {
  59. addPropertyValues(source);
  60. }
  61. /**
  62. * Copy all given PropertyValues into this object. Guarantees PropertyValue
  63. * references are independent, although it can't deep copy objects currently
  64. * referenced by individual PropertyValue objects.
  65. * @param source the PropertyValues to copy
  66. */
  67. public void addPropertyValues(PropertyValues source) {
  68. if (source != null) {
  69. PropertyValue[] pvs = source.getPropertyValues();
  70. for (int i = 0; i < pvs.length; i++) {
  71. addPropertyValue(new PropertyValue(pvs[i].getName(), pvs[i].getValue()));
  72. }
  73. }
  74. }
  75. /**
  76. * Add all property values from the given Map.
  77. * @param source Map with property values keyed by property name,
  78. * which must be a String
  79. */
  80. public void addPropertyValues(Map source) {
  81. if (source != null) {
  82. Iterator it = source.keySet().iterator();
  83. while (it.hasNext()) {
  84. String key = (String) it.next();
  85. addPropertyValue(new PropertyValue(key, source.get(key)));
  86. }
  87. }
  88. }
  89. /**
  90. * Add a PropertyValue object, replacing any existing one
  91. * for the respective property.
  92. * @param pv PropertyValue object to add
  93. */
  94. public void addPropertyValue(PropertyValue pv) {
  95. for (int i = 0; i < this.propertyValuesList.size(); i++) {
  96. PropertyValue currentPv = (PropertyValue) this.propertyValuesList.get(i);
  97. if (currentPv.getName().equals(pv.getName())) {
  98. this.propertyValuesList.set(i, pv);
  99. return;
  100. }
  101. }
  102. this.propertyValuesList.add(pv);
  103. }
  104. /**
  105. * Overloaded version of addPropertyValue that takes
  106. * a property name and a property value.
  107. * @param propertyName name of the property
  108. * @param propertyValue value of the property
  109. * @see #addPropertyValue(PropertyValue)
  110. */
  111. public void addPropertyValue(String propertyName, Object propertyValue) {
  112. addPropertyValue(new PropertyValue(propertyName, propertyValue));
  113. }
  114. /**
  115. * Remove the given PropertyValue, if contained.
  116. * @param pv the PropertyValue to remove
  117. */
  118. public void removePropertyValue(PropertyValue pv) {
  119. this.propertyValuesList.remove(pv);
  120. }
  121. /**
  122. * Overloaded version of removePropertyValue that takes
  123. * a property name.
  124. * @param propertyName name of the property
  125. * @see #removePropertyValue(PropertyValue)
  126. */
  127. public void removePropertyValue(String propertyName) {
  128. removePropertyValue(getPropertyValue(propertyName));
  129. }
  130. /**
  131. * Modify a PropertyValue object held in this object.
  132. * Indexed from 0.
  133. */
  134. public void setPropertyValueAt(PropertyValue pv, int i) {
  135. this.propertyValuesList.set(i, pv);
  136. }
  137. public PropertyValue[] getPropertyValues() {
  138. return (PropertyValue[]) this.propertyValuesList.toArray(new PropertyValue[0]);
  139. }
  140. public PropertyValue getPropertyValue(String propertyName) {
  141. for (int i = 0; i < this.propertyValuesList.size(); i++) {
  142. PropertyValue pv = (PropertyValue) this.propertyValuesList.get(i);
  143. if (pv.getName().equals(propertyName)) {
  144. return pv;
  145. }
  146. }
  147. return null;
  148. }
  149. public boolean contains(String propertyName) {
  150. return getPropertyValue(propertyName) != null;
  151. }
  152. public PropertyValues changesSince(PropertyValues old) {
  153. MutablePropertyValues changes = new MutablePropertyValues();
  154. if (old == this)
  155. return changes;
  156. // for each property value in the new set
  157. for (int i = 0; i < this.propertyValuesList.size(); i++) {
  158. PropertyValue newPv = (PropertyValue) this.propertyValuesList.get(i);
  159. // if there wasn't an old one, add it
  160. PropertyValue pvOld = old.getPropertyValue(newPv.getName());
  161. if (pvOld == null) {
  162. changes.addPropertyValue(newPv);
  163. }
  164. else if (!pvOld.equals(newPv)) {
  165. // it's changed
  166. changes.addPropertyValue(newPv);
  167. }
  168. }
  169. return changes;
  170. }
  171. public String toString() {
  172. PropertyValue[] pvs = getPropertyValues();
  173. StringBuffer sb = new StringBuffer("MutablePropertyValues: length=" + pvs.length + "; ");
  174. sb.append(StringUtils.arrayToDelimitedString(pvs, ","));
  175. return sb.toString();
  176. }
  177. }