1 package org.shortbrain.vaadin.container;
2
3 import java.io.InvalidClassException;
4 import java.lang.reflect.Constructor;
5 import java.lang.reflect.InvocationTargetException;
6 import java.util.Collection;
7 import java.util.List;
8
9 import org.apache.commons.beanutils.ConstructorUtils;
10 import org.shortbrain.vaadin.container.property.PropertyMetadata;
11 import org.shortbrain.vaadin.container.property.PropertyReaderAlgorithm;
12
13 import com.vaadin.data.Container;
14 import com.vaadin.data.Container.Filterable;
15 import com.vaadin.data.Container.Hierarchical;
16 import com.vaadin.data.util.AbstractBeanContainer;
17 import com.vaadin.data.util.AbstractBeanContainer.BeanIdResolver;
18 import com.vaadin.data.util.BeanContainer;
19 import com.vaadin.data.util.BeanItemContainer;
20
21 import static org.shortbrain.vaadin.container.ContainerUtils.addContainerProperty;
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 @SuppressWarnings({ "rawtypes", "unchecked" })
37 public abstract class AbstractBeanContainerFactory<IDTYPE, BEANTYPE> extends BeanContainerFactory<IDTYPE, BEANTYPE> {
38
39
40
41
42 private final Class<? super BEANTYPE> beanClass;
43
44 private Constructor<? extends AbstractBeanContainer> containerConstructor;
45
46 private String propertyId;
47
48 private BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver;
49
50
51
52
53 private final PropertyReaderAlgorithm propertyReaderAlgorithm;
54
55
56
57
58
59
60
61
62
63
64
65
66
67 public AbstractBeanContainerFactory(Class<? super BEANTYPE> beanClass,
68 PropertyReaderAlgorithm propertyReaderAlgorithm, Class<? extends AbstractBeanContainer> beanContainerType,
69 String propertyId) {
70 this(beanClass, propertyReaderAlgorithm, beanContainerType, propertyId, null);
71 }
72
73
74
75
76
77
78
79
80
81
82
83
84
85 public AbstractBeanContainerFactory(Class<? super BEANTYPE> beanClass,
86 PropertyReaderAlgorithm propertyReaderAlgorithm, Class<? extends AbstractBeanContainer> beanContainerType,
87 BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver) {
88 this(beanClass, propertyReaderAlgorithm, beanContainerType, null, beanIdResolver);
89 }
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109 private AbstractBeanContainerFactory(Class<? super BEANTYPE> beanClass,
110 PropertyReaderAlgorithm propertyReaderAlgorithm, Class<? extends AbstractBeanContainer> beanContainerType,
111 String propertyId, BeanIdResolver<IDTYPE, BEANTYPE> beanIdResolver) {
112 this.beanClass = beanClass;
113 this.containerConstructor = ConstructorUtils.getAccessibleConstructor(beanContainerType, Class.class);
114 this.propertyReaderAlgorithm = propertyReaderAlgorithm;
115 this.propertyId = propertyId;
116 this.beanIdResolver = beanIdResolver;
117 }
118
119
120
121
122 @Override
123 public Container getContainerFromCollection(Container container, Collection<BEANTYPE> beans) {
124 Class<? extends Container> containerClass = (container != null) ? container.getClass() : Filterable.class;
125 return getContainerFromCollection(container, beans, containerClass);
126 }
127
128
129
130
131 @Override
132 public Container getContainerFromCollection(Collection<BEANTYPE> beans, Class<? extends Container> containerClass) {
133 return getContainerFromCollection(null, beans, containerClass);
134 }
135
136
137
138
139 @Override
140 public Container getContainerFromCollection(Container container, Collection<BEANTYPE> beans,
141 Class<? extends Container> containerClass) {
142
143
144 try {
145 if (container == null || !(container instanceof AbstractBeanContainer<?, ?>)) {
146 container = initContainer(containerClass);
147 }
148 updateProperties(container);
149 if (container.removeAllItems()) {
150
151 if (container instanceof BeanContainer<?, ?>) {
152 ((BeanContainer<IDTYPE, BEANTYPE>) container).addAll(beans);
153 } else if (container instanceof BeanItemContainer<?>) {
154 ((BeanItemContainer<BEANTYPE>) container).addAll(beans);
155 } else {
156
157 throw new InvalidClassException("container class is not supported.");
158 }
159 }
160 } catch (IllegalArgumentException e) {
161
162 e.printStackTrace();
163 } catch (InstantiationException e) {
164
165 e.printStackTrace();
166 } catch (IllegalAccessException e) {
167
168 e.printStackTrace();
169 } catch (InvocationTargetException e) {
170
171 e.printStackTrace();
172 } catch (InvalidClassException e) {
173
174 e.printStackTrace();
175 }
176 return container;
177 }
178
179 private Container initContainer(Class<? extends Container> containerClass) throws InvalidClassException,
180 IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
181 Container container = containerConstructor.newInstance(beanClass);
182 if (container instanceof BeanContainer<?, ?>) {
183 if (beanIdResolver != null) {
184 ((BeanContainer<IDTYPE, BEANTYPE>) container).setBeanIdResolver(beanIdResolver);
185 } else if (propertyId != null) {
186 ((BeanContainer<IDTYPE, BEANTYPE>) container).setBeanIdProperty(propertyId);
187 }
188 } else if (container instanceof BeanItemContainer<?> || container instanceof ShortcutBeanItemContainer<?>) {
189
190 } else {
191
192 throw new InvalidClassException("container class is not supported.");
193 }
194 return container;
195 }
196
197
198
199
200
201
202
203 private List<PropertyMetadata> updateProperties(Container container) {
204 if (propertyReaderAlgorithm != null) {
205 List<PropertyMetadata> properties = propertyReaderAlgorithm.getProperties(beanClass);
206 Collection<?> containerProperties = container.getContainerPropertyIds();
207 for (PropertyMetadata property : properties) {
208 if (!containerProperties.contains(property.getPropertyName())) {
209 addContainerProperty(container, property);
210 }
211 }
212 return properties;
213 }
214 return null;
215 }
216
217 }