PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/features/topology-map/org.opennms.features.topology.api/src/main/java/org/opennms/features/topology/api/support/FilterableHierarchicalContainer.java

https://bitbucket.org/peternixon/opennms-mirror
Java | 347 lines | 242 code | 64 blank | 41 comment | 37 complexity | e2db75989a30690e11be3d57a04a68bb MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-2.0
  1. /*******************************************************************************
  2. * This file is part of OpenNMS(R).
  3. *
  4. * Copyright (C) 2012 The OpenNMS Group, Inc.
  5. * OpenNMS(R) is Copyright (C) 1999-2012 The OpenNMS Group, Inc.
  6. *
  7. * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.
  8. *
  9. * OpenNMS(R) is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published
  11. * by the Free Software Foundation, either version 3 of the License,
  12. * or (at your option) any later version.
  13. *
  14. * OpenNMS(R) is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with OpenNMS(R). If not, see:
  21. * http://www.gnu.org/licenses/
  22. *
  23. * For more information contact:
  24. * OpenNMS(R) Licensing <license@opennms.org>
  25. * http://www.opennms.org/
  26. * http://www.opennms.com/
  27. *******************************************************************************/
  28. package org.opennms.features.topology.api.support;
  29. import java.util.Collection;
  30. import java.util.Collections;
  31. import java.util.HashMap;
  32. import java.util.HashSet;
  33. import java.util.LinkedHashSet;
  34. import java.util.LinkedList;
  35. import java.util.List;
  36. import java.util.Set;
  37. import com.vaadin.data.Container;
  38. import com.vaadin.data.Item;
  39. import com.vaadin.data.Property;
  40. import com.vaadin.data.Container.ItemSetChangeListener;
  41. import com.vaadin.data.util.BeanItem;
  42. import com.vaadin.data.util.HierarchicalContainer;
  43. @SuppressWarnings("serial")
  44. public class FilterableHierarchicalContainer extends HierarchicalContainer implements ItemSetChangeListener {
  45. HierarchicalBeanContainer<?,?> m_container;
  46. List<Object> m_filteredItems;
  47. private LinkedList<Object> m_filteredRoots = null;
  48. private HashMap<Object, LinkedList<Object>> m_filteredChildren = null;
  49. private HashMap<Object, Object> m_filteredParent = null;
  50. private boolean m_includeParentsWhenFiltering = true;
  51. private Set<Object> m_filterOverride = null;
  52. private final HashMap<Object, Object> m_parent = new HashMap<Object, Object>();
  53. public FilterableHierarchicalContainer(HierarchicalBeanContainer<?,?> container) {
  54. super();
  55. m_container = container;
  56. m_container.addListener(this);
  57. m_container.addListener(new PropertySetChangeListener() {
  58. @Override
  59. public void containerPropertySetChange(PropertySetChangeEvent event) {
  60. event.getContainer();
  61. }
  62. });
  63. }
  64. @Override
  65. public BeanItem<?> getItem(Object itemId) {
  66. return m_container.getItem(itemId);
  67. }
  68. @Override
  69. public Collection<String> getContainerPropertyIds() {
  70. return m_container.getContainerPropertyIds();
  71. }
  72. @Override
  73. public Collection<?> getItemIds() {
  74. if(isFiltered()) {
  75. return m_filteredItems;
  76. }else {
  77. return m_container.getItemIds();
  78. }
  79. }
  80. @Override
  81. public Property getContainerProperty(Object itemId, Object propertyId) {
  82. return m_container.getContainerProperty(itemId, propertyId);
  83. }
  84. @Override
  85. public Class<?> getType(Object propertyId) {
  86. return m_container.getType(propertyId);
  87. }
  88. @Override
  89. public int size() {
  90. return m_container.size();
  91. }
  92. @Override
  93. public boolean containsId(Object itemId) {
  94. return m_container.containsId(itemId);
  95. }
  96. @Override
  97. public Item addItem(Object itemId) throws UnsupportedOperationException {
  98. return null;
  99. }
  100. @Override
  101. public Object addItem() throws UnsupportedOperationException {
  102. return null;
  103. }
  104. @Override
  105. public boolean addContainerProperty(Object propertyId, Class<?> type, Object defaultValue) throws UnsupportedOperationException {
  106. return false;
  107. }
  108. @Override
  109. public boolean removeContainerProperty(Object propertyId) throws UnsupportedOperationException {
  110. return false;
  111. }
  112. @Override
  113. public boolean removeAllItems() throws UnsupportedOperationException {
  114. return false;
  115. }
  116. @Override
  117. public Collection<?> getChildren(Object itemId) {
  118. LinkedList<Object> c;
  119. if (m_filteredChildren != null) {
  120. c = m_filteredChildren.get(itemId);
  121. if(c == null) {
  122. return Collections.EMPTY_LIST;
  123. }
  124. return Collections.unmodifiableCollection(c);
  125. } else {
  126. return m_container.getChildren(itemId);
  127. }
  128. }
  129. @Override
  130. public Object getParent(Object itemId) {
  131. if (m_filteredParent != null) {
  132. return m_filteredParent.get(itemId);
  133. }
  134. return m_container.getParent(itemId);
  135. }
  136. @Override
  137. public Collection<?> rootItemIds() {
  138. if(m_filteredRoots != null) {
  139. return Collections.unmodifiableCollection(m_filteredRoots);
  140. }else {
  141. return m_container.rootItemIds();
  142. }
  143. }
  144. @Override
  145. public boolean setParent(Object itemId, Object newParentId) throws UnsupportedOperationException {
  146. return m_container.setParent(itemId, newParentId);
  147. }
  148. @Override
  149. public boolean areChildrenAllowed(Object itemId) {
  150. return m_container.areChildrenAllowed(itemId);
  151. }
  152. @Override
  153. public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) throws UnsupportedOperationException {
  154. return m_container.setChildrenAllowed(itemId, areChildrenAllowed);
  155. }
  156. @Override
  157. public boolean isRoot(Object itemId) {
  158. if(m_filteredRoots != null) {
  159. }
  160. return m_container.isRoot(itemId);
  161. }
  162. @Override
  163. public boolean hasChildren(Object itemId) {
  164. if(m_filteredChildren != null) {
  165. return m_filteredChildren.containsKey(itemId);
  166. }else {
  167. return m_container.hasChildren(itemId);
  168. }
  169. }
  170. @Override
  171. public boolean removeItem(Object itemId) throws UnsupportedOperationException {
  172. return m_container.removeItem(itemId);
  173. }
  174. @Override
  175. protected boolean doFilterContainer(boolean hasFilters) {
  176. if (!hasFilters) {
  177. // All filters removed
  178. m_filteredRoots = null;
  179. m_filteredChildren = null;
  180. m_filteredParent = null;
  181. if(getFilteredItemIds() != null) {
  182. boolean changed = m_container.getItemIds().size() != getFilteredItemIds().size();
  183. setFilteredItemIds(null);
  184. return changed;
  185. }else {
  186. return false;
  187. }
  188. }
  189. // Reset data structures
  190. m_filteredRoots = new LinkedList<Object>();
  191. m_filteredChildren = new HashMap<Object, LinkedList<Object>>();
  192. m_filteredParent = new HashMap<Object, Object>();
  193. if (m_includeParentsWhenFiltering) {
  194. // Filter so that parents for items that match the filter are also
  195. // included
  196. HashSet<Object> includedItems = new HashSet<Object>();
  197. for (Object rootId : m_container.rootItemIds()) {
  198. if (filterIncludingParents(rootId, includedItems)) {
  199. m_filteredRoots.add(rootId);
  200. addFilteredChildrenRecursively(rootId, includedItems);
  201. }
  202. }
  203. // includedItemIds now contains all the item ids that should be
  204. // included. Filter IndexedContainer based on this
  205. m_filterOverride = includedItems;
  206. super.doFilterContainer(hasFilters);
  207. m_filterOverride = null;
  208. return true;
  209. } else {
  210. // Filter by including all items that pass the filter and make items
  211. // with no parent new root items
  212. // Filter IndexedContainer first so getItemIds return the items that
  213. // match
  214. super.doFilterContainer(hasFilters);
  215. LinkedHashSet<Object> filteredItemIds = new LinkedHashSet<Object>(getItemIds());
  216. for (Object itemId : filteredItemIds) {
  217. Object itemParent = m_parent.get(itemId);
  218. if (itemParent == null || !filteredItemIds.contains(itemParent)) {
  219. // Parent is not included or this was a root, in both cases
  220. // this should be a filtered root
  221. m_filteredRoots.add(itemId);
  222. } else {
  223. // Parent is included. Add this to the children list (create
  224. // it first if necessary)
  225. addFilteredChild(itemParent, itemId);
  226. }
  227. }
  228. return true;
  229. }
  230. }
  231. private void addFilteredChildrenRecursively(Object parentItemId, HashSet<Object> includedItems) {
  232. Collection<?> childList = m_container.getChildren(parentItemId);
  233. if (childList == null) {
  234. return;
  235. }
  236. for (Object childItemId : childList) {
  237. if (includedItems.contains(childItemId)) {
  238. addFilteredChild(parentItemId, childItemId);
  239. addFilteredChildrenRecursively(childItemId, includedItems);
  240. }
  241. }
  242. }
  243. private void addFilteredChild(Object parentItemId, Object childItemId) {
  244. LinkedList<Object> parentToChildrenList = m_filteredChildren
  245. .get(parentItemId);
  246. if (parentToChildrenList == null) {
  247. parentToChildrenList = new LinkedList<Object>();
  248. m_filteredChildren.put(parentItemId, parentToChildrenList);
  249. }
  250. m_filteredParent.put(childItemId, parentItemId);
  251. parentToChildrenList.add(childItemId);
  252. }
  253. private boolean filterIncludingParents(Object itemId, HashSet<Object> includedItems) {
  254. boolean toBeIncluded = passesFilters(itemId);
  255. Collection<?> childList = m_container.getChildren(itemId);
  256. if (childList != null) {
  257. for (Object childItemId : m_container.getChildren(itemId)) {
  258. toBeIncluded |= filterIncludingParents(childItemId, includedItems);
  259. }
  260. }
  261. if (toBeIncluded) {
  262. includedItems.add(itemId);
  263. }
  264. return toBeIncluded;
  265. }
  266. public void setFilteredItemIds(List<Object> itemIds) {
  267. m_filteredItems = itemIds;
  268. }
  269. public List<Object> getFilteredItemIds(){
  270. return m_filteredItems;
  271. }
  272. @Override
  273. protected BeanItem<?> getUnfilteredItem(Object itemId) {
  274. return m_container.getItem(itemId);
  275. }
  276. @Override
  277. public void containerItemSetChange(Container.ItemSetChangeEvent event) {
  278. fireItemSetChange();
  279. }
  280. public void fireItemUpdated() {
  281. m_container.fireItemSetChange();
  282. }
  283. }