選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

PropertysetItem.java 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.data.util;
  5. import java.util.Collection;
  6. import java.util.Collections;
  7. import java.util.EventObject;
  8. import java.util.HashMap;
  9. import java.util.Iterator;
  10. import java.util.LinkedList;
  11. import com.vaadin.data.Item;
  12. import com.vaadin.data.Property;
  13. /**
  14. * Class for handling a set of identified Properties. The elements contained in
  15. * a </code>MapItem</code> can be referenced using locally unique identifiers.
  16. * The class supports listeners who are interested in changes to the Property
  17. * set managed by the class.
  18. *
  19. * @author IT Mill Ltd.
  20. * @version
  21. * @VERSION@
  22. * @since 3.0
  23. */
  24. @SuppressWarnings("serial")
  25. public class PropertysetItem implements Item, Item.PropertySetChangeNotifier,
  26. Cloneable {
  27. /* Private representation of the item */
  28. /**
  29. * Mapping from property id to property.
  30. */
  31. private HashMap map = new HashMap();
  32. /**
  33. * List of all property ids to maintain the order.
  34. */
  35. private LinkedList list = new LinkedList();
  36. /**
  37. * List of property set modification listeners.
  38. */
  39. private LinkedList propertySetChangeListeners = null;
  40. /* Item methods */
  41. /**
  42. * Gets the Property corresponding to the given Property ID stored in the
  43. * Item. If the Item does not contain the Property, <code>null</code> is
  44. * returned.
  45. *
  46. * @param id
  47. * the identifier of the Property to get.
  48. * @return the Property with the given ID or <code>null</code>
  49. */
  50. public Property getItemProperty(Object id) {
  51. return (Property) map.get(id);
  52. }
  53. /**
  54. * Gets the collection of IDs of all Properties stored in the Item.
  55. *
  56. * @return unmodifiable collection containing IDs of the Properties stored
  57. * the Item
  58. */
  59. public Collection getItemPropertyIds() {
  60. return Collections.unmodifiableCollection(list);
  61. }
  62. /* Item.Managed methods */
  63. /**
  64. * Removes the Property identified by ID from the Item. This functionality
  65. * is optional. If the method is not implemented, the method always returns
  66. * <code>false</code>.
  67. *
  68. * @param id
  69. * the ID of the Property to be removed.
  70. * @return <code>true</code> if the operation succeeded <code>false</code>
  71. * if not
  72. */
  73. public boolean removeItemProperty(Object id) {
  74. // Cant remove missing properties
  75. if (map.remove(id) == null) {
  76. return false;
  77. }
  78. list.remove(id);
  79. // Send change events
  80. fireItemPropertySetChange();
  81. return true;
  82. }
  83. /**
  84. * Tries to add a new Property into the Item.
  85. *
  86. * @param id
  87. * the ID of the new Property.
  88. * @param property
  89. * the Property to be added and associated with the id.
  90. * @return <code>true</code> if the operation succeeded, <code>false</code>
  91. * if not
  92. */
  93. public boolean addItemProperty(Object id, Property property) {
  94. // Null ids are not accepted
  95. if (id == null) {
  96. throw new NullPointerException("Item property id can not be null");
  97. }
  98. // Cant add a property twice
  99. if (map.containsKey(id)) {
  100. return false;
  101. }
  102. // Put the property to map
  103. map.put(id, property);
  104. list.add(id);
  105. // Send event
  106. fireItemPropertySetChange();
  107. return true;
  108. }
  109. /**
  110. * Gets the <code>String</code> representation of the contents of the Item.
  111. * The format of the string is a space separated catenation of the
  112. * <code>String</code> representations of the Properties contained by the
  113. * Item.
  114. *
  115. * @return <code>String</code> representation of the Item contents
  116. */
  117. @Override
  118. public String toString() {
  119. String retValue = "";
  120. for (final Iterator i = getItemPropertyIds().iterator(); i.hasNext();) {
  121. final Object propertyId = i.next();
  122. retValue += getItemProperty(propertyId).toString();
  123. if (i.hasNext()) {
  124. retValue += " ";
  125. }
  126. }
  127. return retValue;
  128. }
  129. /* Notifiers */
  130. /**
  131. * An <code>event</code> object specifying an Item whose Property set has
  132. * changed.
  133. *
  134. * @author IT Mill Ltd.
  135. * @version
  136. * @VERSION@
  137. * @since 3.0
  138. */
  139. private class PropertySetChangeEvent extends EventObject implements
  140. Item.PropertySetChangeEvent {
  141. private PropertySetChangeEvent(Item source) {
  142. super(source);
  143. }
  144. /**
  145. * Gets the Item whose Property set has changed.
  146. *
  147. * @return source object of the event as an <code>Item</code>
  148. */
  149. public Item getItem() {
  150. return (Item) getSource();
  151. }
  152. }
  153. /**
  154. * Registers a new property set change listener for this Item.
  155. *
  156. * @param listener
  157. * the new Listener to be registered.
  158. */
  159. public void addListener(Item.PropertySetChangeListener listener) {
  160. if (propertySetChangeListeners == null) {
  161. propertySetChangeListeners = new LinkedList();
  162. }
  163. propertySetChangeListeners.add(listener);
  164. }
  165. /**
  166. * Removes a previously registered property set change listener.
  167. *
  168. * @param listener
  169. * the Listener to be removed.
  170. */
  171. public void removeListener(Item.PropertySetChangeListener listener) {
  172. if (propertySetChangeListeners != null) {
  173. propertySetChangeListeners.remove(listener);
  174. }
  175. }
  176. /**
  177. * Sends a Property set change event to all interested listeners.
  178. */
  179. private void fireItemPropertySetChange() {
  180. if (propertySetChangeListeners != null) {
  181. final Object[] l = propertySetChangeListeners.toArray();
  182. final Item.PropertySetChangeEvent event = new PropertysetItem.PropertySetChangeEvent(
  183. this);
  184. for (int i = 0; i < l.length; i++) {
  185. ((Item.PropertySetChangeListener) l[i])
  186. .itemPropertySetChange(event);
  187. }
  188. }
  189. }
  190. /**
  191. * Creates and returns a copy of this object.
  192. * <p>
  193. * The method <code>clone</code> performs a shallow copy of the
  194. * <code>PropertysetItem</code>.
  195. * </p>
  196. * <p>
  197. * Note : All arrays are considered to implement the interface Cloneable.
  198. * Otherwise, this method creates a new instance of the class of this object
  199. * and initializes all its fields with exactly the contents of the
  200. * corresponding fields of this object, as if by assignment, the contents of
  201. * the fields are not themselves cloned. Thus, this method performs a
  202. * "shallow copy" of this object, not a "deep copy" operation.
  203. * </p>
  204. *
  205. * @throws CloneNotSupportedException
  206. * if the object's class does not support the Cloneable
  207. * interface.
  208. *
  209. * @see java.lang.Object#clone()
  210. */
  211. @Override
  212. public Object clone() throws CloneNotSupportedException {
  213. final PropertysetItem npsi = new PropertysetItem();
  214. npsi.list = list != null ? (LinkedList) list.clone() : null;
  215. npsi.propertySetChangeListeners = propertySetChangeListeners != null ? (LinkedList) propertySetChangeListeners
  216. .clone() : null;
  217. npsi.map = (HashMap) map.clone();
  218. return npsi;
  219. }
  220. /*
  221. * (non-Javadoc)
  222. *
  223. * @see java.lang.Object#equals(java.lang.Object)
  224. */
  225. @Override
  226. public boolean equals(Object obj) {
  227. if (obj == null || !(obj instanceof PropertysetItem)) {
  228. return false;
  229. }
  230. final PropertysetItem other = (PropertysetItem) obj;
  231. if (other.list != list) {
  232. if (other.list == null) {
  233. return false;
  234. }
  235. if (!other.list.equals(list)) {
  236. return false;
  237. }
  238. }
  239. if (other.map != map) {
  240. if (other.map == null) {
  241. return false;
  242. }
  243. if (!other.map.equals(map)) {
  244. return false;
  245. }
  246. }
  247. if (other.propertySetChangeListeners != propertySetChangeListeners) {
  248. if (other.propertySetChangeListeners == null) {
  249. return false;
  250. }
  251. if (!other.propertySetChangeListeners
  252. .equals(propertySetChangeListeners)) {
  253. return false;
  254. }
  255. }
  256. return true;
  257. }
  258. /*
  259. * (non-Javadoc)
  260. *
  261. * @see java.lang.Object#hashCode()
  262. */
  263. @Override
  264. public int hashCode() {
  265. return (list == null ? 0 : list.hashCode())
  266. ^ (map == null ? 0 : map.hashCode())
  267. ^ (propertySetChangeListeners == null ? 0
  268. : propertySetChangeListeners.hashCode());
  269. }
  270. }