View Javadoc

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