1
2
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
51
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
113
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
137
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
161
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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
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
397
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
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 }