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