Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

PropertysetItem.java 9.4KB

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