1
2
3 package org.rcfaces.core.internal.component;
4
5 import java.util.List;
6 import java.util.Collections;
7 import java.util.Set;
8 import java.io.IOException;
9
10 import javax.el.ValueExpression;
11
12 import javax.faces.context.FacesContext;
13 import javax.faces.render.Renderer;
14 import javax.faces.event.ActionEvent;
15 import javax.faces.event.FacesEvent;
16 import javax.faces.event.FacesListener;
17 import javax.faces.event.PhaseId;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21
22 import org.rcfaces.core.internal.tools.GridTools;
23 import javax.faces.component.NamingContainer;
24 import javax.faces.model.DataModel;
25 import java.util.HashSet;
26 import java.util.Arrays;
27
28
29 import org.rcfaces.core.component.capability.IAsyncDecodeModeCapability;
30 import org.rcfaces.core.component.capability.IHiddenModeCapability;
31 import org.rcfaces.core.component.capability.IImmediateCapability;
32 import org.rcfaces.core.component.capability.ILookAndFeelCapability;
33 import org.rcfaces.core.component.capability.IValidationEventCapability;
34 import org.rcfaces.core.component.capability.IVisibilityCapability;
35 import org.rcfaces.core.internal.Constants;
36 import org.rcfaces.core.internal.RcfacesContext;
37
38 import org.rcfaces.core.internal.capability.IVariableScopeCapability;
39 import org.rcfaces.core.internal.capability.IComponentEngine;
40 import org.rcfaces.core.internal.capability.IComponentLifeCycle;
41 import org.rcfaces.core.internal.capability.IListenerStrategy;
42 import org.rcfaces.core.internal.capability.IRCFacesComponent;
43 import org.rcfaces.core.internal.capability.IStateChildrenList;
44 import org.rcfaces.core.internal.component.CameliaComponents;
45 import org.rcfaces.core.internal.component.RestoreViewPhaseListener;
46 import org.rcfaces.core.internal.component.IFactory;
47 import org.rcfaces.core.internal.component.IInitializationState;
48 import org.rcfaces.core.internal.converter.StrategyListenerConverter;
49 import org.rcfaces.core.internal.manager.IContainerManager;
50 import org.rcfaces.core.internal.manager.ITransientAttributesManager;
51 import org.rcfaces.core.internal.renderkit.IAsyncRenderer;
52 import org.rcfaces.core.internal.renderkit.IRendererExtension;
53 import org.rcfaces.core.internal.tools.ComponentTools;
54 import org.rcfaces.core.internal.tools.BindingTools;
55 import org.rcfaces.core.event.IValidationListener;
56 import org.rcfaces.core.event.ValidationEvent;
57
58
59
60
61 public abstract class CameliaGridComponent extends javax.faces.component.UIComponentBase implements
62 IRCFacesComponent, IContainerManager, IComponentLifeCycle, ITransientAttributesManager, NamingContainer {
63 private static final String REVISION = "$Revision: 1.17 $";
64
65 private static final Log LOG = LogFactory.getLog(CameliaGridComponent.class);
66
67 protected static final Set CAMELIA_ATTRIBUTES=new HashSet(Arrays.asList(new String[] {"value"}));
68
69 protected transient IComponentEngine engine;
70
71 private transient IStateChildrenList stateChildrenList;
72
73 private transient DataModel dataModel = null;
74
75
76 protected CameliaGridComponent() {
77 IFactory factory = Constants.getCameliaFactory();
78
79 this.engine = factory.createComponentEngine();
80
81 IInitializationState state=factory.createInitializationState();
82 initializeComponent(state);
83 }
84
85 protected void initializeComponent(IInitializationState state) {
86 if (Constants.TEMPLATE_ENGINE_SUPPORT) {
87 if (isTemplateComponent(state) && state.isConstructionState()) {
88 if (LOG.isDebugEnabled()) {
89 LOG.debug("Call construct template method.");
90 }
91 constructTemplate(state);
92 }
93 }
94 if (Constants.COMPONENT_DEFAULT_PROPERTIES_SUPPORT) {
95 if (hasDefaultProperties(state) && state.isConstructionState()) {
96 if (LOG.isDebugEnabled()) {
97 LOG.debug("Call setDefaultProperties method.");
98 }
99 setDefaultProperties(state);
100 }
101 }
102
103 constructPhase(state.getFacesContext());
104 }
105
106 protected boolean isTemplateComponent(IInitializationState state) {
107 return false;
108 }
109
110 protected void constructTemplate(IInitializationState state) {
111 }
112
113 protected boolean hasDefaultProperties(IInitializationState state) {
114 return false;
115 }
116
117 protected void setDefaultProperties(IInitializationState state) {
118 }
119
120 public String getFamily() {
121 return CameliaComponents.FAMILY;
122 }
123
124 public final String getRendererType() {
125 String rendererType = super.getRendererType();
126 if (rendererType == null) {
127 if (LOG.isTraceEnabled()) {
128 LOG.trace("RendererType is null for component id='"+getId()+"' class='"+getClass()+"'");
129 }
130 return null;
131 }
132
133 if ((this instanceof ILookAndFeelCapability) == false) {
134 return rendererType;
135 }
136
137 String lookId = ((ILookAndFeelCapability) this).getLookId();
138 if (lookId == null) {
139 return rendererType;
140 }
141
142 return rendererType + ":" + lookId;
143 }
144
145 public void restoreState(FacesContext context, Object state) {
146 if (LOG.isTraceEnabled()) {
147 LOG.trace("Restoring state of component '"+getId()+"'.");
148 }
149
150 try {
151 Object states[] = (Object[]) state;
152
153 super.restoreState(context, states[0]);
154
155 engine.restoreState(context, states[1]);
156
157 } catch (RuntimeException ex) {
158 LOG.error("Can not restore state of component '"+getId()+"'.", ex);
159
160 throw ex;
161 }
162
163 if (LOG.isTraceEnabled()) {
164 LOG.trace("State of component '"+getId()+"' restored.");
165 }
166 }
167
168 public Object saveState(FacesContext context) {
169 if (LOG.isTraceEnabled()) {
170 LOG.trace("Saving state of component '"+getId()+"'.");
171 }
172
173 Object states[] = new Object[2];
174 try {
175 states[0] = super.saveState(context);
176 states[1] = engine.saveState(context);
177
178 } catch (RuntimeException ex) {
179 LOG.error("Can not save state of component '"+getId()+"'.", ex);
180
181 throw ex;
182 }
183
184 if (LOG.isTraceEnabled()) {
185 LOG.trace("State of component '"+getId()+"' saved.");
186 }
187
188 return states;
189 }
190
191 public void setValueExpression(String name, ValueExpression binding) {
192 if (getCameliaFields().contains(name)) {
193 if (name.equals(getCameliaValueAlias())) {
194 name=Properties.VALUE;
195 }
196
197 if (Properties.VALUE.equals(name)) {
198 dataModel=null;
199 }
200
201 engine.setProperty(name, binding);
202 return;
203 }
204
205 if (Properties.VALUE.equals(name)) {
206 dataModel=null;
207 }
208
209 super.setValueExpression(name, binding);
210 }
211
212 protected Set getCameliaFields() {
213 return CAMELIA_ATTRIBUTES;
214 }
215
216 protected String getCameliaValueAlias() {
217 return null;
218 }
219
220 public final ValueExpression getValueExpression(String name) {
221 if (getCameliaFields().contains(name)) {
222 if (name.equals(getCameliaValueAlias())) {
223 name=Properties.VALUE;
224 }
225
226 return engine.getValueExpressionProperty(name);
227 }
228
229 return super.getValueExpression(name);
230 }
231
232
233
234
235
236
237
238
239
240 public void encodeBegin(FacesContext context) throws IOException {
241 if (context == null) {
242 throw new NullPointerException("FacesContext is null");
243 }
244
245 try {
246 super.encodeBegin(context);
247
248 } catch (RuntimeException ex) {
249 LOG.error("Can not encode-begin component '"+getId()+"'.", ex);
250
251 throw ex;
252 }
253 }
254
255 public void encodeChildren(FacesContext context) throws IOException {
256 if (context == null) {
257 throw new NullPointerException("FacesContext is null");
258 }
259
260 try {
261 super.encodeChildren(context);
262
263 } catch (RuntimeException ex) {
264 LOG.error("Can not encode children of component '"+getId()+"'.", ex);
265
266 throw ex;
267 }
268 }
269
270 public void encodeEnd(FacesContext context) throws IOException {
271 if (context == null) {
272 throw new NullPointerException("FacesContext is null");
273 }
274
275 try {
276 super.encodeEnd(context);
277
278 } catch (RuntimeException ex) {
279 LOG.error("Can not encode-end component '"+getId()+"'.", ex);
280
281 throw ex;
282 }
283 }
284
285 protected boolean verifyAsyncDecode(FacesContext context, PhaseId phaseId) {
286 return ComponentTools.verifyAsyncDecode(context, (IAsyncDecodeModeCapability) this, phaseId);
287 }
288
289 public void processDecodes(FacesContext context) {
290 if (context == null) {
291 throw new NullPointerException();
292 }
293
294 try {
295 if (isRendered()==false) {
296 return;
297 }
298
299 if (this instanceof IAsyncDecodeModeCapability) {
300 if (verifyAsyncDecode(context, PhaseId.APPLY_REQUEST_VALUES)==false) {
301 return;
302 }
303 }
304
305 ComponentTools.IVarScope varScope = null;
306 if (this instanceof IVariableScopeCapability) {
307 varScope=BindingTools.processVariableScope(context, (IVariableScopeCapability)this, PhaseId.APPLY_REQUEST_VALUES);
308 }
309
310 engine.startDecodes(context);
311
312 Renderer renderer = getRenderer(context);
313 if ((renderer instanceof IRendererExtension) == false) {
314 super.processDecodes(context);
315
316 } else {
317 CameliaComponents.processDecodes(context, this, renderer);
318 }
319
320 boolean immediate=false;
321 if (this instanceof IValidationEventCapability) {
322 if (this instanceof IImmediateCapability) {
323 immediate=((IImmediateCapability)this).isImmediate();
324 }
325 }
326
327 if (immediate) {
328 if (ComponentTools.hasValidationServerListeners(getFacesListeners(IValidationListener.class))) {
329 this.broadcast(new ValidationEvent(this));
330 }
331 processEngineValidators(context);
332 }
333
334 if (varScope!=null) {
335 varScope.popVar(context);
336 }
337
338 } catch (RuntimeException ex) {
339 LOG.error("Can not decode component '"+getId()+"'.", ex);
340
341 throw ex;
342 }
343 }
344
345 public void processValidators(FacesContext context) {
346 if (context == null) {
347 throw new NullPointerException("Context is NULL to processValidators");
348 }
349
350 try {
351
352 if (isRendered()==false) {
353 return;
354 }
355
356 if (this instanceof IAsyncDecodeModeCapability) {
357 if (verifyAsyncDecode(context, PhaseId.PROCESS_VALIDATIONS)==false) {
358 return;
359 }
360 }
361
362 ComponentTools.IVarScope varScope = null;
363 if (this instanceof IVariableScopeCapability) {
364 varScope=BindingTools.processVariableScope(context, (IVariableScopeCapability)this, PhaseId.PROCESS_VALIDATIONS);
365 }
366
367 super.processValidators(context);
368
369 boolean immediate=false;
370 if (this instanceof IValidationEventCapability) {
371 if (this instanceof IImmediateCapability) {
372 immediate=((IImmediateCapability)this).isImmediate();
373 }
374 }
375
376 if (immediate==false) {
377 if (ComponentTools.hasValidationServerListeners(getFacesListeners(IValidationListener.class))) {
378 this.broadcast(new ValidationEvent(this));
379 }
380
381 processEngineValidators(context);
382 }
383
384 if (varScope!=null) {
385 varScope.popVar(context);
386 }
387
388 } catch (RuntimeException ex) {
389 LOG.error("Can not valid component '"+getId()+"'.", ex);
390
391 throw ex;
392 }
393 }
394
395 protected void processEngineValidators(FacesContext context) {
396 engine.processValidation(context);
397 }
398
399 public void processUpdates(FacesContext context) {
400
401 try {
402
403 if (isRendered()==false) {
404 return;
405 }
406
407 if (this instanceof IAsyncDecodeModeCapability) {
408 if (verifyAsyncDecode(context, PhaseId.UPDATE_MODEL_VALUES)==false) {
409 return;
410 }
411 }
412
413 ComponentTools.IVarScope varScope = null;
414 if (this instanceof IVariableScopeCapability) {
415 varScope=BindingTools.processVariableScope(context, (IVariableScopeCapability)this, PhaseId.UPDATE_MODEL_VALUES);
416 }
417
418 processEngineUpdates(context);
419
420 super.processUpdates(context);
421
422 if (varScope!=null) {
423 varScope.popVar(context);
424 }
425
426 } catch (RuntimeException ex) {
427 LOG.error("Can not update component '"+getId()+"'.", ex);
428
429 throw ex;
430 }
431 }
432
433 protected void processEngineUpdates(FacesContext context) {
434 engine.processUpdates(context);
435 }
436
437
438
439
440
441
442 public final List getChildren() {
443 if (Constants.STATED_COMPONENT_CHILDREN_LIST==false) {
444 return super.getChildren();
445 }
446
447 List list = super.getChildren();
448
449 if (stateChildrenList == null) {
450 stateChildrenList = engine.createStateChildrenList();
451 }
452
453 stateChildrenList.setChildren(list);
454
455 return stateChildrenList;
456 }
457
458 public final int getChildrenListState() {
459 if (Constants.STATED_COMPONENT_CHILDREN_LIST==false) {
460 throw new UnsupportedOperationException("STATED_COMPONENT_CHILDREN_LIST=false");
461 }
462
463 if (stateChildrenList == null) {
464 return 0;
465 }
466
467 return stateChildrenList.getState();
468 }
469
470 public final Object getTransientAttribute(String name) {
471 return engine.getTransientAttribute(name);
472 }
473
474 public final Object setTransientAttribute(String name, Object value) {
475 return engine.setTransientAttribute(name, value);
476 }
477
478 public final boolean isClientRendered() {
479 if ((this instanceof IVisibilityCapability)==false) {
480 return true;
481 }
482
483 IVisibilityCapability visibilityCapability=(IVisibilityCapability)this;
484
485 Boolean visible=visibilityCapability.getVisibleState();
486 if (visible==null || visible.booleanValue()) {
487 return true;
488 }
489
490 if ((this instanceof IHiddenModeCapability)==false) {
491 return false;
492 }
493
494 IHiddenModeCapability hiddenModeCapability=(IHiddenModeCapability)this;
495
496 int hiddenMode=hiddenModeCapability.getHiddenMode();
497 if (IHiddenModeCapability.SERVER_HIDDEN_MODE==hiddenMode) {
498 return false;
499 }
500
501 return true;
502 }
503
504 public boolean isRendered() {
505 if (super.isRendered()==false) {
506 return false;
507 }
508
509 return isClientRendered();
510 }
511
512 public void setRendered(ValueExpression binding) {
513 setValueExpression("rendered", binding);
514 }
515
516
517 public final IAsyncRenderer getAsyncRenderer(FacesContext facesContext) {
518 Renderer renderer=getRenderer(facesContext);
519 if (renderer instanceof IAsyncRenderer) {
520 return (IAsyncRenderer) renderer;
521 }
522
523 return null;
524 }
525
526 public void queueEvent(FacesEvent e) {
527
528
529 if ((e instanceof ActionEvent) && e.getComponent()==this) {
530 if (this instanceof IImmediateCapability) {
531 IImmediateCapability immediateCapability=(IImmediateCapability)this;
532
533 if (immediateCapability.isImmediate()) {
534 e.setPhaseId(PhaseId.APPLY_REQUEST_VALUES);
535
536 } else {
537 e.setPhaseId(PhaseId.INVOKE_APPLICATION);
538 }
539 }
540 }
541
542 super.queueEvent(e);
543 }
544
545 public void clearListeners() {
546 FacesListener fcs[]=getFacesListeners(FacesListener.class);
547 for(int i=0;i<fcs.length;i++) {
548 removeFacesListener(fcs[i]);
549 }
550 }
551
552 public void constructPhase(FacesContext facesContext) {
553 }
554
555 public void initializePhase(FacesContext facesContext, boolean reused) {
556 if (reused) {
557
558 RcfacesContext rcfacesContext = RcfacesContext
559 .getInstance(facesContext);
560 int faceletListenerMode = rcfacesContext
561 .getListenerManagerStrategy();
562
563 if ((IListenerStrategy.CLEAN_ALL & faceletListenerMode) > 0) {
564 clearListeners();
565 }
566 }
567 }
568
569 public void decodePhase(FacesContext facesContext) {
570 }
571
572 public void validationPhase(FacesContext facesContext) {
573 }
574
575 public void updatePhase(FacesContext facesContext) {
576 }
577
578 public void renderPhase(FacesContext facesContext) {
579 }
580
581 public boolean confirmListenerAppend(FacesContext facesContext, Class facesListenerClass){
582
583 RcfacesContext rcfacesContext = RcfacesContext
584 .getInstance(facesContext);
585 int faceletListenerMode = rcfacesContext.getListenerManagerStrategy();
586
587 if (((IListenerStrategy.ADD_IF_NEW | IListenerStrategy.CLEAN_BY_CLASS) & faceletListenerMode) == 0) {
588 return true;
589 }
590
591 FacesListener fcs[] = getFacesListeners(facesListenerClass);
592 if ((IListenerStrategy.ADD_IF_NEW & faceletListenerMode) > 0) {
593 return fcs.length == 0;
594 }
595
596 if ((IListenerStrategy.CLEAN_BY_CLASS & faceletListenerMode) > 0) {
597 for (int i = 0; i < fcs.length; i++) {
598 removeFacesListener(fcs[i]);
599 }
600
601 return true;
602 }
603
604 return true;
605 }
606
607 public String toString() {
608 String name=getClass().getName();
609 name=name.substring(name.lastIndexOf('.')+1);
610
611 String s=name+"[id='"+getId()+"'";
612
613 if (isRendered()==false) {
614 s+=",rendered=false";
615 }
616
617 s+=","+engine.toString();
618
619 s+=",rendererId='"+getRendererType()+"'";
620
621 if (getFamily()!=CameliaComponents.FAMILY) {
622 s+=",family='"+getFamily()+"'";
623 }
624
625 return s+"]";
626 }
627
628 public boolean isRowAvailable() {
629
630
631 return isRowAvailable(null);
632
633 }
634
635 public boolean isRowAvailable(FacesContext facesContext) {
636
637
638 return getDataModel(facesContext).isRowAvailable();
639
640 }
641
642 public int getRowCount() {
643
644
645 return getDataModel(null).getRowCount();
646
647 }
648
649 public Object getRowData() {
650
651
652 return getDataModel(null).getRowData();
653
654 }
655
656 public DataModel getDataModel(FacesContext facesContext) {
657
658
659 if (dataModel!=null) {
660 return dataModel;
661 }
662
663 Object value=getValue(facesContext);
664 dataModel=GridTools.getDataModel(value, this, facesContext);
665
666 return dataModel;
667
668 }
669
670 public DataModel getDataModelValue() {
671
672
673 return getDataModel(null);
674
675 }
676
677 public Object getValue() {
678
679
680 return getValue(null);
681
682 }
683
684 public Object getValue(FacesContext context) {
685
686
687 return engine.getValue(Properties.VALUE, context);
688
689 }
690
691 public void setValue(Object value) {
692
693
694 dataModel=null;
695 engine.setValue(Properties.VALUE, value);
696
697 }
698
699
700 }