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 javax.faces.event.FacesListener;
23 import javax.faces.convert.Converter;
24 import org.rcfaces.core.internal.capability.IConvertValueHolder;
25 import java.lang.Object;
26 import java.util.HashSet;
27 import java.lang.String;
28 import java.util.Arrays;
29 import javax.faces.event.ValueChangeEvent;
30 import org.rcfaces.core.internal.capability.ISubmittedExternalValue;
31
32
33 import org.rcfaces.core.component.capability.IAsyncDecodeModeCapability;
34 import org.rcfaces.core.component.capability.IHiddenModeCapability;
35 import org.rcfaces.core.component.capability.IImmediateCapability;
36 import org.rcfaces.core.component.capability.ILookAndFeelCapability;
37 import org.rcfaces.core.component.capability.IValidationEventCapability;
38 import org.rcfaces.core.component.capability.IVisibilityCapability;
39 import org.rcfaces.core.internal.Constants;
40 import org.rcfaces.core.internal.RcfacesContext;
41
42 import org.rcfaces.core.internal.capability.IVariableScopeCapability;
43 import org.rcfaces.core.internal.capability.IComponentEngine;
44 import org.rcfaces.core.internal.capability.IComponentLifeCycle;
45 import org.rcfaces.core.internal.capability.IListenerStrategy;
46 import org.rcfaces.core.internal.capability.IRCFacesComponent;
47 import org.rcfaces.core.internal.capability.IStateChildrenList;
48 import org.rcfaces.core.internal.component.CameliaComponents;
49 import org.rcfaces.core.internal.component.RestoreViewPhaseListener;
50 import org.rcfaces.core.internal.component.IFactory;
51 import org.rcfaces.core.internal.component.IInitializationState;
52 import org.rcfaces.core.internal.converter.StrategyListenerConverter;
53 import org.rcfaces.core.internal.manager.IContainerManager;
54 import org.rcfaces.core.internal.manager.ITransientAttributesManager;
55 import org.rcfaces.core.internal.renderkit.IAsyncRenderer;
56 import org.rcfaces.core.internal.renderkit.IRendererExtension;
57 import org.rcfaces.core.internal.tools.ComponentTools;
58 import org.rcfaces.core.internal.tools.BindingTools;
59 import org.rcfaces.core.event.IValidationListener;
60 import org.rcfaces.core.event.ValidationEvent;
61
62
63
64
65 public abstract class CameliaInputComponent extends javax.faces.component.UIInput implements
66 IRCFacesComponent, IContainerManager, IComponentLifeCycle, ITransientAttributesManager, IConvertValueHolder, ISubmittedExternalValue {
67 private static final String REVISION = "$Revision: 1.17 $";
68
69 private static final Log LOG = LogFactory.getLog(CameliaInputComponent.class);
70
71 protected static final Set CAMELIA_ATTRIBUTES=new HashSet(Arrays.asList(new String[] {"converter","value"}));
72
73 protected transient IComponentEngine engine;
74
75 private transient IStateChildrenList stateChildrenList;
76
77 private static final Object NULL_VALUE = org.rcfaces.core.internal.tools.ValuesTools.NULL_VALUE;
78
79
80 protected CameliaInputComponent() {
81 IFactory factory = Constants.getCameliaFactory();
82
83 this.engine = factory.createComponentEngine();
84
85 IInitializationState state=factory.createInitializationState();
86 initializeComponent(state);
87 }
88
89 protected void initializeComponent(IInitializationState state) {
90 if (Constants.TEMPLATE_ENGINE_SUPPORT) {
91 if (isTemplateComponent(state) && state.isConstructionState()) {
92 if (LOG.isDebugEnabled()) {
93 LOG.debug("Call construct template method.");
94 }
95 constructTemplate(state);
96 }
97 }
98 if (Constants.COMPONENT_DEFAULT_PROPERTIES_SUPPORT) {
99 if (hasDefaultProperties(state) && state.isConstructionState()) {
100 if (LOG.isDebugEnabled()) {
101 LOG.debug("Call setDefaultProperties method.");
102 }
103 setDefaultProperties(state);
104 }
105 }
106
107 constructPhase(state.getFacesContext());
108 }
109
110 protected boolean isTemplateComponent(IInitializationState state) {
111 return false;
112 }
113
114 protected void constructTemplate(IInitializationState state) {
115 }
116
117 protected boolean hasDefaultProperties(IInitializationState state) {
118 return false;
119 }
120
121 protected void setDefaultProperties(IInitializationState state) {
122 }
123
124 public String getFamily() {
125 return CameliaComponents.FAMILY;
126 }
127
128 public final String getRendererType() {
129 String rendererType = super.getRendererType();
130 if (rendererType == null) {
131 if (LOG.isTraceEnabled()) {
132 LOG.trace("RendererType is null for component id='"+getId()+"' class='"+getClass()+"'");
133 }
134 return null;
135 }
136
137 if ((this instanceof ILookAndFeelCapability) == false) {
138 return rendererType;
139 }
140
141 String lookId = ((ILookAndFeelCapability) this).getLookId();
142 if (lookId == null) {
143 return rendererType;
144 }
145
146 return rendererType + ":" + lookId;
147 }
148
149 public void restoreState(FacesContext context, Object state) {
150 if (LOG.isTraceEnabled()) {
151 LOG.trace("Restoring state of component '"+getId()+"'.");
152 }
153
154 try {
155 Object states[] = (Object[]) state;
156
157 super.restoreState(context, states[0]);
158
159 engine.restoreState(context, states[1]);
160
161 } catch (RuntimeException ex) {
162 LOG.error("Can not restore state of component '"+getId()+"'.", ex);
163
164 throw ex;
165 }
166
167 if (LOG.isTraceEnabled()) {
168 LOG.trace("State of component '"+getId()+"' restored.");
169 }
170 }
171
172 public Object saveState(FacesContext context) {
173 if (LOG.isTraceEnabled()) {
174 LOG.trace("Saving state of component '"+getId()+"'.");
175 }
176
177 Object states[] = new Object[2];
178 try {
179 states[0] = super.saveState(context);
180 states[1] = engine.saveState(context);
181
182 } catch (RuntimeException ex) {
183 LOG.error("Can not save state of component '"+getId()+"'.", ex);
184
185 throw ex;
186 }
187
188 if (LOG.isTraceEnabled()) {
189 LOG.trace("State of component '"+getId()+"' saved.");
190 }
191
192 return states;
193 }
194
195 public void setValueExpression(String name, ValueExpression binding) {
196 if (getCameliaFields().contains(name)) {
197 if (name.equals(getCameliaValueAlias())) {
198 name=Properties.VALUE;
199 }
200
201
202
203 engine.setProperty(name, binding);
204 return;
205 }
206
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 void setConverter(String converterId) {
629
630
631 setConverter(null, converterId);
632
633 }
634
635 public void setConverter(FacesContext facesContext, String converterId) {
636
637
638 if (facesContext==null) {
639 facesContext=FacesContext.getCurrentInstance();
640 }
641 Converter converter = facesContext.getApplication().createConverter(converterId);
642 this.setConverter(converter);
643
644 }
645
646 public void broadcast(FacesEvent event) {
647
648
649 if (!Constants.MYFACES_INPUT_BROADCAST_BUG) {
650 super.broadcast(event);
651 return;
652 }
653
654
655 if (event instanceof ValueChangeEvent) {
656 super.broadcast(event);
657 return;
658 }
659
660 FacesListener listeners[]=getFacesListeners(FacesListener.class);
661 ComponentTools.broadcast(this, event, listeners);
662
663
664 }
665
666 public Object getLocalValue() {
667
668
669 Object value=super.getLocalValue();
670
671 if (NULL_VALUE.equals(value)) {
672 value=null;
673 }
674
675 return value;
676
677 }
678
679 protected Object getConvertedValue(FacesContext context, Object submittedValue) {
680
681
682 if (NULL_VALUE.equals(submittedValue)) {
683 submittedValue=null;
684 }
685
686 return super.getConvertedValue(context, submittedValue);
687
688 }
689
690 public Object getSubmittedExternalValue() {
691
692
693 Object value=super.getSubmittedValue();
694
695 if (NULL_VALUE.equals(value)) {
696 value=null;
697 }
698
699 return value;
700
701 }
702
703 public void setSubmittedExternalValue(Object submittedValue) {
704
705
706 if (submittedValue==null) {
707 submittedValue=NULL_VALUE;
708 }
709
710 super.setSubmittedValue(submittedValue);
711
712 }
713
714 public boolean isSubmittedValueSetted() {
715
716
717 Object value=super.getSubmittedValue();
718
719 if (NULL_VALUE.equals(value)) {
720 return true;
721 }
722
723 return value!=null;
724
725 }
726
727 public Object getValue() {
728
729
730 Object value=super.getValue();
731
732 if (NULL_VALUE.equals(value)) {
733 value=null;
734 }
735
736 return value;
737
738 }
739
740
741 }