View Javadoc

1   package com.vaadin.data.util;
2   
3   import java.util.Collection;
4   import java.util.HashMap;
5   import java.util.Map;
6   import java.util.Map.Entry;
7   
8   import org.shortbrain.vaadin.container.ShortcutBeanContainer;
9   import org.shortbrain.vaadin.container.property.HierarchicalBeanBuilder;
10  
11  import com.vaadin.data.Container;
12  import com.vaadin.data.Item;
13  import com.vaadin.data.Property;
14  import com.vaadin.data.Container.Hierarchical;
15  import com.vaadin.data.Property.ValueChangeEvent;
16  import com.vaadin.data.util.filter.UnsupportedFilterException;
17  
18  /**
19   * An extension of {@link BeanContainer} that is {@link Hierarchical}. This is the Abstract class that define common stuff for all
20   * BeanContainer type ({@link BeanContainer}, {@link BeanItemContainer}, {@link ShortcutBeanContainer}, ...)
21   * 
22   * <p>
23   * Behind the scene it uses {@link ContainerHierarchicalWrapper}.
24   * </p>
25   * 
26   * @author Vincent Demeester <vincent@shortbrain.org>
27   * 
28   * @param <IDTYPE>
29   *            The type of the item identifier
30   * @param <BEANTYPE>
31   *            The type of the Bean
32   * 
33   * @since 0.2.0
34   * 
35   * @see BeanContainer
36   * @see ContainerHierarchicalWrapper
37   * @see Hierarchical
38   */
39  public abstract class AbstractHierarchicalBeanContainer<IDTYPE, BEANTYPE> extends BeanContainer<IDTYPE, BEANTYPE>
40          implements Container.Hierarchical, Container.ItemSetChangeListener, Container.PropertySetChangeListener {
41  
42      private static final long serialVersionUID = 1L;
43  
44      /**
45       * The {@link Hierarchical} wrapper.
46       */
47      private ContainerHierarchicalWrapper wrapper;
48  
49      /**
50       * The wrapped {@link Container} ({@link BeanContainer})
51       */
52      private AbstractBeanContainer<IDTYPE, BEANTYPE> container;
53  
54      private HierarchicalBeanBuilder<IDTYPE, BEANTYPE> hierarchicalBeanBuilder;
55  
56      /**
57       * Create a {@link HierarchicalBeanContainer} with the given IDTYPE and BEANTYPE.
58       * 
59       * @param type
60       *            The type of the Bean
61       * @param container
62       *            The container to be wrapped
63       */
64      public AbstractHierarchicalBeanContainer(Class<BEANTYPE> type, AbstractBeanContainer<IDTYPE, BEANTYPE> container) {
65          super(type);
66          this.container = container;
67          wrapper = new ContainerHierarchicalWrapper(container);
68          wrapper.addListener((Container.ItemSetChangeListener) this);
69          wrapper.addListener((Container.PropertySetChangeListener) this);
70      }
71  
72      @Override
73      public void containerPropertySetChange(PropertySetChangeEvent event) {
74          System.out.println(event);
75      }
76  
77      @Override
78      public void containerItemSetChange(ItemSetChangeEvent event) {
79          // Working only if hierarchicalPropertyId is defined
80          if (hierarchicalBeanBuilder != null) {
81              // Map the parent and their children
82              Map<IDTYPE, Collection<IDTYPE>> mapParent = new HashMap<IDTYPE, Collection<IDTYPE>>();
83              // Walk the container
84              for (IDTYPE itemId : container.getItemIds()) {
85                  BEANTYPE bean = container.getItem(itemId).getBean();
86                  Collection<IDTYPE> ids = hierarchicalBeanBuilder.getChildren(bean);
87                  if (ids != null && !ids.isEmpty()) {
88                      mapParent.put(itemId, ids);
89                  }
90              }
91              // Walk the map and set parents
92              for (Entry<IDTYPE, Collection<IDTYPE>> entry : mapParent.entrySet()) {
93                  IDTYPE parent = entry.getKey();
94                  wrapper.setChildrenAllowed(parent, true);
95                  for (IDTYPE id : entry.getValue()) {
96                      wrapper.setParent(id, parent);
97                  }
98              }
99          }
100         System.out.println(event);
101     }
102 
103     // Getter and Setter
104     /**
105      * Set the {@link HierarchicalBeanBuilder}
106      * 
107      * @param hierarchicalBeanBuilder
108      */
109     public void setHierarchicalBeanBuilder(HierarchicalBeanBuilder<IDTYPE, BEANTYPE> hierarchicalBeanBuilder) {
110         this.hierarchicalBeanBuilder = hierarchicalBeanBuilder;
111     }
112 
113     /**
114      * Get the {@link ContainerHierarchicalWrapper} wrapper
115      * 
116      * @return the wrapper
117      */
118     protected ContainerHierarchicalWrapper getWrapper() {
119         return wrapper;
120     }
121 
122     /**
123      * Get the wrapped container
124      * 
125      * @return the container
126      */
127     protected AbstractBeanContainer<IDTYPE, BEANTYPE> getContainer() {
128         return container;
129     }
130 
131     /**
132      * Get the {@link HierarchicalBeanBuilder}
133      * 
134      * @return the {@link HierarchicalBeanBuilder}
135      */
136     public HierarchicalBeanBuilder<IDTYPE, BEANTYPE> getHierarchicalBeanBuilder() {
137         return hierarchicalBeanBuilder;
138     }
139 
140     // wrapper forwarding
141     @Override
142     public Collection<?> getChildren(Object itemId) {
143         return wrapper.getChildren(itemId);
144     }
145 
146     @Override
147     public Object getParent(Object itemId) {
148         return wrapper.getParent(itemId);
149     }
150 
151     @Override
152     public Collection<?> rootItemIds() {
153         return wrapper.rootItemIds();
154     }
155 
156     @Override
157     public boolean setParent(Object itemId, Object newParentId) throws UnsupportedOperationException {
158         return wrapper.setParent(itemId, newParentId);
159     }
160 
161     @Override
162     public boolean areChildrenAllowed(Object itemId) {
163         return wrapper.areChildrenAllowed(itemId);
164     }
165 
166     @Override
167     public boolean setChildrenAllowed(Object itemId, boolean areChildrenAllowed) throws UnsupportedOperationException {
168         return wrapper.setChildrenAllowed(itemId, areChildrenAllowed);
169     }
170 
171     @Override
172     public boolean isRoot(Object itemId) {
173         return wrapper.isRoot(itemId);
174     }
175 
176     @Override
177     public boolean hasChildren(Object itemId) {
178         return wrapper.hasChildren(itemId);
179     }
180 
181     // container forwarding
182     @Override
183     public BeanItem<BEANTYPE> addItem(IDTYPE itemId, BEANTYPE bean) {
184         return container.addItem(itemId, bean);
185     }
186 
187     @Override
188     public BeanItem<BEANTYPE> addItemAfter(IDTYPE previousItemId, IDTYPE newItemId, BEANTYPE bean) {
189         return container.addItemAfter(previousItemId, newItemId, bean);
190     }
191 
192     @Override
193     public BeanItem<BEANTYPE> addItemAt(int index, IDTYPE newItemId, BEANTYPE bean) {
194         return container.addItemAt(index, newItemId, bean);
195     }
196 
197     @Override
198     public abstract void setBeanIdProperty(Object propertyId);
199 
200     @Override
201     public void setBeanIdResolver(
202             com.vaadin.data.util.AbstractBeanContainer.BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver) {
203         container.setBeanIdResolver(beanIdResolver);
204     }
205 
206     @Override
207     public BeanItem<BEANTYPE> addBean(BEANTYPE bean) throws IllegalStateException, IllegalArgumentException {
208         return container.addBean(bean);
209     }
210 
211     @Override
212     public BeanItem<BEANTYPE> addBeanAfter(IDTYPE previousItemId, BEANTYPE bean) throws IllegalStateException,
213             IllegalArgumentException {
214         return container.addBeanAfter(previousItemId, bean);
215     }
216 
217     @Override
218     public BeanItem<BEANTYPE> addBeanAt(int index, BEANTYPE bean) throws IllegalStateException,
219             IllegalArgumentException {
220         return container.addBeanAt(index, bean);
221     }
222 
223     @Override
224     public void addAll(Collection<? extends BEANTYPE> collection) throws IllegalStateException {
225         container.addAll(collection);
226     }
227 
228     @Override
229     public Class<?> getType(Object propertyId) {
230         return container.getType(propertyId);
231     }
232 
233     @Override
234     public Class<? super BEANTYPE> getBeanType() {
235         return container.getBeanType();
236     }
237 
238     @Override
239     public Collection<String> getContainerPropertyIds() {
240         return container.getContainerPropertyIds();
241     }
242 
243     @Override
244     public boolean removeAllItems() {
245         return container.removeAllItems();
246     }
247 
248     @Override
249     public BeanItem<BEANTYPE> getItem(Object itemId) {
250         return container.getItem(itemId);
251     }
252 
253     @Override
254     public Collection<IDTYPE> getItemIds() {
255         return container.getItemIds();
256     }
257 
258     @Override
259     public Property getContainerProperty(Object itemId, Object propertyId) {
260         return container.getContainerProperty(itemId, propertyId);
261     }
262 
263     @Override
264     public boolean removeItem(Object itemId) {
265         return container.removeItem(itemId);
266     }
267 
268     @Override
269     public void valueChange(ValueChangeEvent event) {
270         container.valueChange(event);
271     }
272 
273     @Override
274     public void addContainerFilter(Object propertyId, String filterString, boolean ignoreCase, boolean onlyMatchPrefix) {
275         container.addContainerFilter(propertyId, filterString, ignoreCase, onlyMatchPrefix);
276     }
277 
278     @Override
279     public void removeAllContainerFilters() {
280         container.removeAllContainerFilters();
281     }
282 
283     @Override
284     public void removeContainerFilters(Object propertyId) {
285         container.removeContainerFilters(propertyId);
286     }
287 
288     @Override
289     public void addContainerFilter(Filter filter) throws UnsupportedFilterException {
290         container.addContainerFilter(filter);
291     }
292 
293     @Override
294     public void removeContainerFilter(Filter filter) {
295         container.removeContainerFilter(filter);
296     }
297 
298     @Override
299     public Collection<?> getSortableContainerPropertyIds() {
300         return container.getSortableContainerPropertyIds();
301     }
302 
303     @Override
304     public void sort(Object[] propertyId, boolean[] ascending) {
305         container.sort(propertyId, ascending);
306     }
307 
308     @Override
309     public ItemSorter getItemSorter() {
310         return container.getItemSorter();
311     }
312 
313     @Override
314     public void setItemSorter(ItemSorter itemSorter) {
315         container.setItemSorter(itemSorter);
316     }
317 
318     @Override
319     public com.vaadin.data.util.AbstractBeanContainer.BeanIdResolver<IDTYPE, BEANTYPE> getBeanIdResolver() {
320         return container.getBeanIdResolver();
321     }
322 
323     @Override
324     public void addListener(PropertySetChangeListener listener) {
325         container.addListener(listener);
326     }
327 
328     @Override
329     public void removeListener(PropertySetChangeListener listener) {
330         container.removeListener(listener);
331     }
332 
333     @Override
334     public boolean addNestedContainerProperty(String propertyId) {
335         return container.addNestedContainerProperty(propertyId);
336     }
337 
338     @Override
339     public boolean removeContainerProperty(Object propertyId) throws UnsupportedOperationException {
340         return container.removeContainerProperty(propertyId);
341     }
342 
343     @Override
344     public int size() {
345         return container.size();
346     }
347 
348     @Override
349     public boolean containsId(Object itemId) {
350         return container.containsId(itemId);
351     }
352 
353     @Override
354     public IDTYPE nextItemId(Object itemId) {
355         return container.nextItemId(itemId);
356     }
357 
358     @Override
359     public IDTYPE prevItemId(Object itemId) {
360         return container.prevItemId(itemId);
361     }
362 
363     @Override
364     public IDTYPE firstItemId() {
365         return container.firstItemId();
366     }
367 
368     @Override
369     public IDTYPE lastItemId() {
370         return container.lastItemId();
371     }
372 
373     @Override
374     public boolean isFirstId(Object itemId) {
375         return container.isFirstId(itemId);
376     }
377 
378     @Override
379     public boolean isLastId(Object itemId) {
380         return container.isLastId(itemId);
381     }
382 
383     @Override
384     public IDTYPE getIdByIndex(int index) {
385         return container.getIdByIndex(index);
386     }
387 
388     @Override
389     public int indexOfId(Object itemId) {
390         return container.indexOfId(itemId);
391     }
392 
393     @Override
394     public Object addItemAt(int index) throws UnsupportedOperationException {
395         return container.addItemAt(index);
396     }
397 
398     @Override
399     public Item addItemAt(int index, Object newItemId) throws UnsupportedOperationException {
400         return container.addItemAt(index, newItemId);
401     }
402 
403     @Override
404     public Object addItemAfter(Object previousItemId) throws UnsupportedOperationException {
405         return container.addItemAfter(previousItemId);
406     }
407 
408     @Override
409     public Item addItemAfter(Object previousItemId, Object newItemId) throws UnsupportedOperationException {
410         return container.addItemAfter(previousItemId, newItemId);
411     }
412 
413     @Override
414     public Item addItem(Object itemId) throws UnsupportedOperationException {
415         return container.addItem(itemId);
416     }
417 
418     @Override
419     public Object addItem() throws UnsupportedOperationException {
420         return container.addItem();
421     }
422 
423     @Override
424     public void addListener(ItemSetChangeListener listener) {
425         container.addListener(listener);
426     }
427 
428     @Override
429     public void removeListener(ItemSetChangeListener listener) {
430         container.removeListener(listener);
431     }
432 
433     @Override
434     public Collection<?> getListeners(Class<?> eventType) {
435         return container.getListeners(eventType);
436     }
437 }