View Javadoc

1   /*
2    * $Id: GridTools.java,v 1.18 2011/06/16 09:29:41 jbmeslin Exp $
3    */
4   package org.rcfaces.core.internal.tools;
5   
6   import java.sql.ResultSet;
7   import java.util.ArrayList;
8   import java.util.Collection;
9   import java.util.Collections;
10  import java.util.List;
11  import java.util.StringTokenizer;
12  
13  import javax.faces.component.UIColumn;
14  import javax.faces.component.UIComponent;
15  import javax.faces.component.UIViewRoot;
16  import javax.faces.context.FacesContext;
17  import javax.faces.model.ArrayDataModel;
18  import javax.faces.model.DataModel;
19  import javax.faces.model.ListDataModel;
20  import javax.faces.model.ResultDataModel;
21  import javax.faces.model.ResultSetDataModel;
22  import javax.faces.model.ScalarDataModel;
23  import javax.servlet.jsp.jstl.sql.Result;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.rcfaces.core.component.ComponentsColumnComponent;
28  import org.rcfaces.core.component.ComponentsGridComponent;
29  import org.rcfaces.core.component.DataColumnComponent;
30  import org.rcfaces.core.component.DataGridComponent;
31  import org.rcfaces.core.component.capability.IOrderCapability;
32  import org.rcfaces.core.component.capability.ISortedChildrenCapability;
33  import org.rcfaces.core.component.iterator.IColumnIterator;
34  import org.rcfaces.core.component.iterator.IComponentsColumnIterator;
35  import org.rcfaces.core.component.iterator.IDataColumnIterator;
36  import org.rcfaces.core.internal.Constants;
37  import org.rcfaces.core.internal.RcfacesContext;
38  import org.rcfaces.core.internal.capability.IGridComponent;
39  import org.rcfaces.core.internal.capability.ISortedComponentsCapability;
40  import org.rcfaces.core.internal.lang.StringAppender;
41  import org.rcfaces.core.internal.tools.CollectionTools.IComponentValueType;
42  import org.rcfaces.core.internal.util.ComponentIterators;
43  import org.rcfaces.core.lang.IAdaptable;
44  import org.rcfaces.core.lang.OrderedSet;
45  import org.rcfaces.core.model.DefaultSortedComponent;
46  import org.rcfaces.core.model.IDataModel;
47  import org.rcfaces.core.model.ISortedComponent;
48  
49  /**
50   * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
51   * @version $Revision: 1.18 $ $Date: 2011/06/16 09:29:41 $
52   */
53  public class GridTools {
54      private static final String REVISION = "$Revision: 1.18 $";
55  
56      private static final Log LOG = LogFactory.getLog(GridTools.class);
57  
58      public static final int SELECTION_VALUES_TYPE = 1;
59  
60      public static final int CHECK_VALUES_TYPE = 2;
61  
62      private static final IDataColumnIterator EMPTY_DATA_COLUMN_ITERATOR = new DataColumnListIterator(
63              Collections.EMPTY_LIST);
64  
65      private static final IColumnIterator EMPTY_COLUMNS_ITERATOR = new ColumnListIterator(
66              Collections.EMPTY_LIST);
67  
68      private static final IComponentsColumnIterator EMPTY_COMPONENTS_COLUMN_ITERATOR = new ComponentsColumnListIterator(
69              Collections.EMPTY_LIST);
70  
71      private static final String ALL_INDEX = "all";
72  
73      private static final ISortedComponent[] SORTED_COMPONENTS_EMPTY_ARRAY = new ISortedComponent[0];
74  
75      private static final UIColumn[] COLUMN_EMPTY_ARRAY = new UIColumn[0];
76  
77      private static final UIComponent[] COMPONENT_EMPTY_ARRAY = new UIComponent[0];
78  
79      public static IColumnIterator listColumns(IGridComponent component,
80              Class filter) {
81          List list = ComponentIterators.list((UIComponent) component, filter);
82          if (list.isEmpty()) {
83              return EMPTY_COLUMNS_ITERATOR;
84          }
85  
86          return new ColumnListIterator(list);
87      }
88  
89      public static IDataColumnIterator listDataColumns(IGridComponent component) {
90          List list = ComponentIterators.list((UIComponent) component,
91                  DataColumnComponent.class);
92          if (list.isEmpty()) {
93              return EMPTY_DATA_COLUMN_ITERATOR;
94          }
95  
96          return new DataColumnListIterator(list);
97      }
98  
99      public static IComponentsColumnIterator listComponentsColumns(
100             IGridComponent component) {
101         List list = ComponentIterators.list((UIComponent) component,
102                 ComponentsColumnComponent.class);
103         if (list.isEmpty()) {
104             return EMPTY_COMPONENTS_COLUMN_ITERATOR;
105         }
106 
107         return new ComponentsColumnListIterator(list);
108     }
109 
110     /**
111      * 
112      * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
113      * @version $Revision: 1.18 $ $Date: 2011/06/16 09:29:41 $
114      */
115     private static final class DataColumnListIterator extends
116             ComponentIterators.ComponentListIterator implements
117             IDataColumnIterator {
118         private static final String REVISION = "$Revision: 1.18 $";
119 
120         public DataColumnListIterator(List list) {
121             super(list);
122         }
123 
124         public final DataColumnComponent next() {
125             return (DataColumnComponent) nextComponent();
126         }
127 
128         public DataColumnComponent[] toArray() {
129             return (DataColumnComponent[]) toArray(new DataColumnComponent[count()]);
130         }
131 
132     }
133 
134     /**
135      * 
136      * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
137      * @version $Revision: 1.18 $ $Date: 2011/06/16 09:29:41 $
138      */
139     private static final class ComponentsColumnListIterator extends
140             ComponentIterators.ComponentListIterator implements
141             IComponentsColumnIterator {
142         private static final String REVISION = "$Revision: 1.18 $";
143 
144         public ComponentsColumnListIterator(List list) {
145             super(list);
146         }
147 
148         public final ComponentsColumnComponent next() {
149             return (ComponentsColumnComponent) nextComponent();
150         }
151 
152         public ComponentsColumnComponent[] toArray() {
153             return (ComponentsColumnComponent[]) toArray(new ComponentsColumnComponent[count()]);
154         }
155 
156     }
157 
158     /**
159      * 
160      * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
161      * @version $Revision: 1.18 $ $Date: 2011/06/16 09:29:41 $
162      */
163     private static final class ColumnListIterator extends
164             ComponentIterators.ComponentListIterator implements IColumnIterator {
165         private static final String REVISION = "$Revision: 1.18 $";
166 
167         public ColumnListIterator(List list) {
168             super(list);
169         }
170 
171         public final UIColumn next() {
172             return (UIColumn) nextComponent();
173         }
174 
175         public UIColumn[] toArray() {
176             return (UIColumn[]) toArray(new UIColumn[count()]);
177         }
178 
179     }
180 
181     /*
182      * public static final IIndexesModel getIndexesModel(Object object,
183      * DataModel dataModel) { if (object == null) { return new
184      * ArrayIndexesModel(); }
185      * 
186      * if (object instanceof IIndexesModel) { return (IIndexesModel) object; }
187      * 
188      * if (ALL_INDEX.equals(object)) { Object value = dataModel;
189      * 
190      * if (value == null) { return new ArrayIndexesModel(); }
191      * 
192      * Class valueClass = value.getClass(); if (valueClass.isArray()) { int size =
193      * Array.getLength(value);
194      * 
195      * return IndexesModels.selectAll(size); }
196      * 
197      * if (value instanceof Collection) { Collection collection = (Collection)
198      * value;
199      * 
200      * return IndexesModels.selectAll(collection.size()); }
201      * 
202      * if (value instanceof Map) { Map collection = (Map) value;
203      * 
204      * return IndexesModels.selectAll(collection.size()); }
205      * 
206      * throw new FacesException( "'all' keyword for index model, does not
207      * support value type: '" + value.getClass() + "'."); }
208      * 
209      * if (object instanceof Collection) { return new
210      * CollectionIndexesModel((Collection) object); }
211      * 
212      * if (object instanceof Map) { return new MapIndexesModel((Map) object); }
213      * 
214      * List l = new ArrayList(1); l.add(object);
215      * 
216      * return new CollectionIndexesModel(l); }
217      */
218 
219     public static ISortedComponent[] listSortedComponents(FacesContext context,
220             ISortedChildrenCapability dataGridComponent) {
221 
222         UIComponent sortedColumns[] = dataGridComponent.getSortedChildren();
223         if (sortedColumns.length < 1) {
224             return SORTED_COMPONENTS_EMPTY_ARRAY;
225         }
226 
227         UIColumn columns[] = ((IGridComponent) dataGridComponent).listColumns()
228                 .toArray();
229 
230         List l = new ArrayList(sortedColumns.length);
231         for (int i = 0; i < sortedColumns.length; i++) {
232 
233             UIColumn column = (UIColumn) sortedColumns[i];
234 
235             if ((column instanceof IOrderCapability) == false) {
236                 continue;
237             }
238 
239             int index = -1;
240             for (int j = 0; j < columns.length; j++) {
241                 if (columns[j] != column) {
242                     continue;
243                 }
244                 index = j;
245                 break;
246             }
247 
248             if (index < 0) {
249                 LOG.error("Can not find column #" + i + " " + column);
250                 continue;
251             }
252 
253             l.add(new DefaultSortedComponent(column, index,
254                     ((IOrderCapability) column).isAscending()));
255 
256         }
257 
258         return (ISortedComponent[]) l.toArray(new ISortedComponent[l.size()]);
259     }
260 
261     public static DataModel getDataModel(Object current, UIComponent component,
262             FacesContext facesContext) {
263 
264         if (current == null) {
265             if (LOG.isDebugEnabled()) {
266                 LOG.debug("DataModel conversion: null value type '" + current
267                         + "' for component '" + component.getId()
268                         + ", return a ListDataModel.");
269             }
270 
271             return new ListDataModel(Collections.EMPTY_LIST);
272         }
273 
274         if (current instanceof DataModel) {
275             if (LOG.isDebugEnabled()) {
276                 LOG.debug("DataModel conversion: DataModel value type '"
277                         + current + "' for component '" + component.getId()
278                         + ", return the value.");
279             }
280 
281             return (DataModel) current;
282         }
283 
284         if (current instanceof List) {
285             if (LOG.isDebugEnabled()) {
286                 LOG.debug("DataModel conversion: List value type '" + current
287                         + "' for component '" + component.getId()
288                         + ", return a ListDataModel.");
289             }
290 
291             return new ListDataModel((List) current);
292         }
293 
294         if (Object[].class.isAssignableFrom(current.getClass())) {
295             if (LOG.isDebugEnabled()) {
296                 LOG.debug("DataModel conversion: Object array value type '"
297                         + current + "' for component '" + component.getId()
298                         + ", return an ArrayDataModel.");
299             }
300 
301             return new ArrayDataModel((Object[]) current);
302         }
303 
304         if (current instanceof ResultSet) {
305             if (LOG.isDebugEnabled()) {
306                 LOG.debug("DataModel conversion: ResultSet value type '"
307                         + current + "' for component '" + component.getId()
308                         + ", return a ResultSetDataModel.");
309             }
310 
311             return new ResultSetDataModel((ResultSet) current);
312         }
313 
314         if (current instanceof Result) {
315             if (LOG.isDebugEnabled()) {
316                 LOG.debug("DataModel conversion: Result value type '" + current
317                         + "' for component '" + component.getId()
318                         + ", return a ResultDataModel.");
319             }
320 
321             return new ResultDataModel((Result) current);
322         }
323 
324         if (Constants.COLLECTION_DATAMODEL_SUPPORT) {
325             if (current instanceof Collection) {
326                 if (LOG.isDebugEnabled()) {
327                     LOG.debug("DataModel conversion: Collection value type '"
328                             + current + "' for component '" + component.getId()
329                             + ", return an ArrayDataModel.");
330                 }
331 
332                 return new ArrayDataModel(((Collection) current).toArray());
333             }
334         }
335 
336         if (current instanceof IDataModel) {
337             if (LOG.isDebugEnabled()) {
338                 LOG.debug("DataModel conversion: IDataModel value type '"
339                         + current + "' for component '" + component.getId()
340                         + ", return a DataModelWrapper.");
341             }
342 
343             return new DataModelWrapper((IDataModel) current);
344         }
345 
346         if (Constants.ADAPTABLE_DATAMODEL_SUPPORT) {
347             if (current instanceof IAdaptable) {
348                 DataModel dataModel = (DataModel) ((IAdaptable) current)
349                         .getAdapter(DataModel.class, component);
350                 if (dataModel != null) {
351                     if (LOG.isDebugEnabled()) {
352                         LOG
353                                 .debug("DataModel conversion: IAdaptable value type '"
354                                         + current
355                                         + "' for component '"
356                                         + component.getId()
357                                         + ", return a DataModel.");
358                     }
359 
360                     return dataModel;
361                 }
362             }
363 
364             RcfacesContext rcfacesContext = RcfacesContext
365                     .getInstance(facesContext);
366 
367             DataModel dataModel = (DataModel) rcfacesContext
368                     .getAdapterManager().getAdapter(current, DataModel.class,
369                             component);
370 
371             if (dataModel != null) {
372                 if (LOG.isDebugEnabled()) {
373                     LOG
374                             .debug("DataModel conversion: AdaptableFactory response for type '"
375                                     + current
376                                     + "' for component '"
377                                     + component.getId()
378                                     + ", return a DataModel.");
379                 }
380 
381                 return dataModel;
382             }
383         }
384 
385         if (LOG.isDebugEnabled()) {
386             LOG.debug("DataModel conversion: Unknown value type '" + current
387                     + "' for component '" + component.getId()
388                     + ", return a ScalarDataModel.");
389         }
390 
391         return new ScalarDataModel(current);
392     }
393 
394     /**
395      * 
396      * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
397      * @version $Revision: 1.18 $ $Date: 2011/06/16 09:29:41 $
398      */
399     static final class DataModelWrapper extends DataModel implements IDataModel {
400         private static final String REVISION = "$Revision: 1.18 $";
401 
402         private final IDataModel dataModel;
403 
404         public DataModelWrapper(IDataModel dataModel) {
405             this.dataModel = dataModel;
406         }
407 
408         public int getRowCount() {
409             return dataModel.getRowCount();
410         }
411 
412         public Object getRowData() {
413             return dataModel.getRowData();
414         }
415 
416         public int getRowIndex() {
417             return dataModel.getRowIndex();
418         }
419 
420         public Object getWrappedData() {
421             return dataModel.getWrappedData();
422         }
423 
424         public boolean isRowAvailable() {
425             return dataModel.isRowAvailable();
426         }
427 
428         public void setRowIndex(int rowIndex) {
429             dataModel.setRowIndex(rowIndex);
430         }
431 
432         public void setWrappedData(Object data) {
433             dataModel.setWrappedData(data);
434         }
435 
436     }
437 
438     public static void setOrderIds(IGridComponent gridComponent,
439             String columnsOrder) {
440     }
441 
442     public static String getOrderIds(IGridComponent dataGridComponent) {
443         // TODO Auto-generated method stub
444         return null;
445     }
446 
447     public static void setSortIds(IGridComponent gridComponent,
448             String sortedColumnIds) {
449         if (sortedColumnIds == null) {
450             return;
451         }
452 
453         if (gridComponent instanceof ISortedComponentsCapability) {
454             ISortedChildrenCapability sortedChildrenCapability = (ISortedChildrenCapability) gridComponent;
455 
456             if (sortedColumnIds.length() < 1) {
457                 sortedChildrenCapability
458                         .setSortedChildren(COMPONENT_EMPTY_ARRAY);
459                 return;
460             }
461 
462             UIColumn columns[] = gridComponent.listColumns().toArray();
463 
464             StringTokenizer st = new StringTokenizer(sortedColumnIds, ",");
465             List components = new ArrayList(st.countTokens());
466 
467             for (; st.hasMoreTokens();) {
468                 String id = st.nextToken().trim();
469 
470                 boolean ascending = false;
471                 int idx = id.indexOf("::");
472                 if (idx >= 0) {
473                     String cmd = id.substring(0, idx);
474                     id = id.substring(idx + 2);
475 
476                     ascending = ("asc".equals(cmd));
477                 }
478 
479                 UIComponent component = null;
480                 if (id.charAt(0) == '#') {
481                     int columnIdx = Integer.parseInt(id.substring(1));
482 
483                     if (columnIdx >= columns.length) {
484                         continue;
485                     }
486 
487                     component = columns[columnIdx];
488 
489                 } else {
490                     for (int j = 0; j < columns.length; j++) {
491                         if (id.equals(columns[j].getId()) == false) {
492                             continue;
493                         }
494 
495                         component = columns[j];
496                         break;
497                     }
498                 }
499 
500                 if (component == null) {
501                     continue;
502                 }
503 
504                 if ((component instanceof UIColumn) == false) {
505                     continue;
506                 }
507 
508                 components.add(component);
509 
510                 if (component instanceof IOrderCapability) {
511                     ((IOrderCapability) component).setAscending(ascending);
512                 }
513             }
514 
515             sortedChildrenCapability
516                     .setSortedChildren((UIComponent[]) components
517                             .toArray(new UIComponent[components.size()]));
518             return;
519         }
520 
521     }
522 
523     public static String getSortIds(IGridComponent gridComponent) {
524         if (gridComponent instanceof ISortedComponentsCapability) {
525             UIComponent components[] = ((ISortedChildrenCapability) gridComponent)
526                     .getSortedChildren();
527 
528             if (components.length < 1) {
529                 return "";
530             }
531 
532             UIColumn children[] = null;
533 
534             StringAppender sa = new StringAppender(components.length * 32);
535             for (int i = 0; i < components.length; i++) {
536                 UIComponent component = components[i];
537                 if (sa.length() > 0) {
538                     sa.append(',');
539                 }
540 
541                 if (component instanceof IOrderCapability) {
542                     if (((IOrderCapability) component).isAscending()) {
543                         sa.append("asc::");
544                     } else {
545                         sa.append("desc::");
546                     }
547                 }
548 
549                 String id = component.getId();
550                 if (id.startsWith(UIViewRoot.UNIQUE_ID_PREFIX)) {
551                     if (children == null) {
552                         children = gridComponent.listColumns().toArray();
553                     }
554 
555                     int index = -1;
556                     for (int j = 0; j < children.length; j++) {
557                         if (children[j] != component) {
558                             continue;
559                         }
560 
561                         index = j;
562                         break;
563                     }
564 
565                     if (index < 0) {
566                         LOG.error("Can not find column '" + component + "'.");
567                         continue;
568                     }
569 
570                     sa.append('#').append(index);
571                     continue;
572                 }
573 
574                 sa.append(id);
575             }
576 
577             return sa.toString();
578         }
579         return null;
580     }
581 
582     public static final IComponentValueType DATA_GRID_VALUE_TYPE = new IComponentValueType() {
583         private static final String REVISION = "$Revision: 1.18 $";
584 
585         public Object createNewValue(UIComponent component) {
586             DataGridComponent dataGridComponent = (DataGridComponent) component;
587 
588             if (dataGridComponent.isRowValueColumnIdSetted()) {
589                 return new OrderedSet();
590             }
591 
592             return new ArrayIndexesModel();
593         }
594     };
595 
596     public static final IComponentValueType COMBO_GRID_VALUE_TYPE = DATA_GRID_VALUE_TYPE;
597 
598     public static final IComponentValueType COMPONENTS_GRID_VALUE_TYPE = new IComponentValueType() {
599         private static final String REVISION = "$Revision: 1.18 $";
600 
601         public Object createNewValue(UIComponent component) {
602             ComponentsGridComponent gridComponent = (ComponentsGridComponent) component;
603 
604             if (gridComponent.isRowValueSetted()) {
605                 return new OrderedSet();
606             }
607 
608             return new ArrayIndexesModel();
609         }
610     };
611 
612 }