1 package org.weda.model.impl;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.HashMap;
6 import java.util.Iterator;
7 import java.util.LinkedList;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.Set;
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13 import org.weda.action.ActionContainer;
14 import org.weda.action.ActionContainerProvider;
15 import org.weda.common.NamesListRegistry;
16 import org.weda.enhance.InjectHivemindObject;
17 import org.weda.model.TableModelListener;
18 import org.weda.property.Constraint;
19 import org.weda.property.ObjectDescriptorRegistry;
20 import org.weda.property.PropertyValue;
21 import org.weda.model.TableModel;
22 import org.weda.model.TableModelException;
23 import org.weda.property.SetConstraint;
24 import org.weda.property.SetValue;
25 import org.weda.store.ObjectSource;
26 import org.weda.store.ObjectSourceException;
27 import org.weda.store.ObjectSourceListener;
28 import org.weda.store.ObjectSourceRegistry;
29 import org.weda.action.impl.AbstractActionContainer;
30 import org.weda.model.TableModel.Mode;
31 import org.weda.property.PropertyDescriptor;
32 import org.weda.store.RowsChangeEvent;
33 import org.weda.store.SummaryRow;
34
35 /**
36 *
37 * @author Mikhail Titov
38 */
39 public class ObjectTableModel
40 extends AbstractActionContainer
41 implements
42 TableModel<ObjectTableModelData>
43 , ActionContainerProvider
44 , ObjectSourceListener
45 {
46 private final static Log log = LogFactory.getLog(ObjectTableModel.class);
47 private String name;
48
49 @InjectHivemindObject()
50 private static ObjectSourceRegistry objectSourceRegistry;
51 @InjectHivemindObject()
52 private static ObjectDescriptorRegistry objectDescriptorRegistry;
53 @InjectHivemindObject()
54 private static PropertyValue propertyValueGetter;
55 @InjectHivemindObject()
56 private static NamesListRegistry namesListRegistry;
57
58 private String objectSourceName;
59 private List<PropertyDescriptor> columnDescriptors =
60 new ArrayList<PropertyDescriptor>();
61 private Map<Object, String>[] valuesAliases;
62 private List<ColumnDescriptorImpl> properties =
63 new LinkedList<ColumnDescriptorImpl>();
64 private Map<String, IndexedObjectAlias> objectAliases =
65 new HashMap<String, IndexedObjectAlias>();
66 private Map<Integer, Position> expressions =
67 new HashMap<Integer, Position>();
68 private Position[] positions;
69 private IndexedObjectAlias defaultObjectAlias;
70 private String namesListName;
71 private List<TableModelListener> modelListeners;
72 private boolean pageable = false;
73 private int pageSize = 20;
74
75 public void init() throws TableModelException {
76 try{
77 if (log.isDebugEnabled())
78 log.debug("Initializing object table model ("+name+")");
79 setActionContainerName(name);
80 ObjectSource objectSource = getObjectSource();
81 if (namesListName != null){
82 List<String> names =
83 namesListRegistry.getNamesList(namesListName);
84 for (String name: names){
85 ColumnDescriptorImpl desc = new ColumnDescriptorImpl();
86 desc.setName(name);
87 addPropertyDescriptor(desc);
88 }
89 }
90 positions = new Position[properties.size()];
91 int i=0;
92 defaultObjectAlias = new IndexedObjectAlias();
93 defaultObjectAlias.setAlias(objectSource.getBaseClassAlias());
94 defaultObjectAlias.setObjectClass(objectSource.getBaseClass());
95 defaultObjectAlias.setPosition(
96 objectSource.getBaseClassPosition());
97 valuesAliases = new Map[properties.size()];
98 for (ColumnDescriptorImpl desc: properties){
99
100 if (log.isDebugEnabled())
101 log.debug(" initializing property ("+desc.getName()+")");
102 columnDescriptors.add(desc);
103 IndexedObjectAlias objectAlias;
104 if (desc.getObjectAlias()==null)
105 objectAlias = defaultObjectAlias;
106 else
107 objectAlias = objectAliases.get(desc.getObjectAlias());
108 if (objectAlias==null)
109 throw new TableModelException(
110 String.format(
111 "Object alias (%s) does not exist"
112 , desc.getObjectAlias()));
113 Class objectClass = objectAlias.getObjectClass();
114
115 PropertyDescriptor parent = null;
116 if (desc.getName()!=null)
117 parent =
118 objectDescriptorRegistry.getPropertyDescriptor(
119 objectClass, desc.getName());
120 else {
121 desc.setPropertyClass(objectAlias.getObjectClass());
122 desc.setMimeType("object/property");
123 }
124 desc.setParent(parent);
125 desc.setTableModel(this);
126 desc.setActionRegistry(getActionRegistry());
127 desc.init();
128
129 SummaryRow summaryRow = getObjectSource().getSummaryRow();
130 boolean hasSummaryValue =
131 summaryRow != null
132 && summaryRow.hasElement(
133 objectAlias.getPosition(), desc.getName());
134 Integer propertyIndex = null;
135 if (desc.getName()!=null)
136 propertyIndex =
137 propertyValueGetter.compileGetter(
138 objectClass, desc.getName());
139 Position position =
140 new Position(
141 objectAlias.getPosition(), propertyIndex
142 , hasSummaryValue);
143 positions[i] = position;
144
145 if (desc.getConstraints()!=null){
146 for (Constraint constraint: desc.getConstraints())
147 if (constraint instanceof SetConstraint){
148 SetConstraint setConstraint =
149 (SetConstraint)constraint;
150 if (setConstraint.isValuesAliased()){
151 valuesAliases[i] =
152 new HashMap<Object, String>();
153 for (Iterator<SetValue> it=
154 setConstraint.iterator(); it.hasNext();)
155 {
156 SetValue value = it.next();
157 valuesAliases[i].put(
158 value.getValue(), value.getAlias());
159 }
160 }
161 break;
162 }
163 }
164 i++;
165 }
166 objectSource.addListener(this);
167 }catch(Exception e){
168 throw new TableModelException(
169 String.format(
170 "Can't initialize object table model (%s)"
171 , getName())
172 , e);
173 }
174 }
175
176 public void addPropertyDescriptor(
177 ColumnDescriptorImpl propertyDescriptor)
178 {
179 if (log.isDebugEnabled())
180 log.debug(
181 String.format(
182 "Adding property (%s) to model"
183 , propertyDescriptor.getName()));
184 properties.add(propertyDescriptor);
185 }
186
187 public void addObjectAlias(IndexedObjectAlias objectAlias){
188 objectAliases.put(objectAlias.getAlias(), objectAlias);
189 }
190
191 public List<PropertyDescriptor> getColumnDescriptors() {
192 return columnDescriptors;
193 }
194
195 protected ObjectSource getObjectSource()
196 throws TableModelException
197 {
198 try{
199 return objectSourceRegistry.getObjectSource(getObjectSourceName());
200 }catch(Exception e){
201 throw new TableModelException(
202 String.format(
203 "Error while getting object source (%s) " +
204 "for table model (%s)"
205 , getObjectSourceName()
206 , name)
207 , e);
208 }
209 }
210
211 public String getObjectSourceName() {
212 return objectSourceName;
213 }
214
215 public void setObjectSourceName(String objectSourceName) {
216 this.objectSourceName = objectSourceName;
217 }
218
219 public String getName() {
220 return name;
221 }
222
223 public void setName(String name) {
224 this.name = name;
225 }
226
227 public PropertyValue getPropertyValueGetter() {
228 return propertyValueGetter;
229 }
230
231 public Set<Class> getDisabledActions() {
232 return null;
233 }
234
235 public int getColumnCount() throws TableModelException {
236 return columnDescriptors.size();
237 }
238
239 public List<ActionContainer> getActionContainers() throws Exception {
240 ObjectSource ds = getObjectSource();
241 return Arrays.asList((ActionContainer)ds);
242 }
243
244 public String getNamesListName() {
245 return namesListName;
246 }
247
248 public void setNamesListName(String namesListName) {
249 this.namesListName = namesListName;
250 }
251
252 public void close() throws TableModelException {
253 try {
254 getObjectSource().close();
255 } catch (Exception e) {
256 throw new TableModelException(
257 String.format(
258 "Error while clearing table model (%s)", name)
259 , e);
260 }
261 }
262
263 protected Position[] getPositions(){
264 return positions;
265 }
266
267 protected Map<Object, String>[] getValuesAliases() {
268 return valuesAliases;
269 }
270
271 public void addListener(TableModelListener listener) {
272 if (modelListeners==null)
273 modelListeners = new ArrayList<TableModelListener>(5);
274 modelListeners.add(listener);
275 }
276
277 public void open() throws TableModelException {
278 try {
279 if (getMode()==Mode.CLOSED)
280 getObjectSource().open();
281 }catch (ObjectSourceException ex) {
282 throw new TableModelException(
283 String.format(
284 "Error while opening table model (%s)", name)
285 , ex);
286 }
287 }
288
289 public TableModel.Mode getMode() throws TableModelException {
290 if (getObjectSource().getMode()==ObjectSource.Mode.CLOSED)
291 return Mode.CLOSED;
292 else
293 return Mode.VIEW;
294 }
295
296 public ObjectTableModelData getData() throws TableModelException {
297 if (getMode()==Mode.VIEW)
298 return new ObjectTableModelData(this);
299 else
300 throw new TableModelException(
301 String.format(
302 "Can't perform getData operation " +
303 "on closed table model (%s)", name));
304 }
305
306 public void rowsChanging(RowsChangeEvent event) {
307 fireTableModelEvent(event);
308 }
309
310 public void rowsChanged(RowsChangeEvent event) {
311 fireTableModelEvent(event);
312 }
313
314 protected void fireTableModelEvent(RowsChangeEvent event){
315 if (modelListeners != null)
316 for (TableModelListener listener: modelListeners)
317 listener.modelChanged(
318 new TableModelEventImpl(event.getChangeType()));
319 }
320
321 public class Position implements java.io.Serializable {
322 public int inPos;
323 public Integer propertyIndex;
324 public boolean hasSummaryValue;
325
326 public Position(
327 int inPos, Integer propertyIndex, boolean hasSummaryValue)
328 {
329 this.inPos=inPos;
330 this.propertyIndex=propertyIndex;
331 this.hasSummaryValue = hasSummaryValue;
332 }
333 }
334
335 public boolean isPageable() {
336 return pageable;
337 }
338
339 public void setPageable(boolean pageable) {
340 this.pageable = pageable;
341 }
342
343 public int getPageSize() {
344 return pageSize;
345 }
346
347 public void setPageSize(int pageSize) {
348 this.pageSize = pageSize;
349 }
350 }