View Javadoc

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                  //сформируем columnDescriptors            
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                 //добавим связь parent PropertyDescriptor
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 }