Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

PropertysetItem.java 9.9KB

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