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