View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.view.facelets;
20  
21  import java.util.Iterator;
22  import java.util.List;
23  import java.util.Map;
24  
25  import javax.faces.component.UIComponent;
26  import javax.faces.component.UIViewRoot;
27  import javax.faces.component.UniqueIdVendor;
28  import javax.faces.context.FacesContext;
29  import javax.faces.view.AttachedObjectHandler;
30  import javax.faces.view.EditableValueHolderAttachedObjectHandler;
31  import javax.faces.view.facelets.FaceletContext;
32  
33  /**
34   * @since 2.0.1
35   * @author Leonardo Uribe (latest modification by $Author: lu4242 $)
36   * @version $Revision: 1424976 $ $Date: 2012-12-21 10:41:52 -0500 (Fri, 21 Dec 2012) $
37   */
38  abstract public class FaceletCompositionContext
39  {
40      static protected final String FACELET_COMPOSITION_CONTEXT_KEY = "oam.facelets.FACELET_COMPOSITION_CONTEXT";
41  
42      protected FaceletCompositionContext()
43      {
44      }
45      
46      static public FaceletCompositionContext getCurrentInstance()
47      {
48          return (FaceletCompositionContext)
49                  FacesContext.getCurrentInstance().getAttributes().get(FACELET_COMPOSITION_CONTEXT_KEY);
50      }
51      
52      static public FaceletCompositionContext getCurrentInstance(FaceletContext ctx)
53      {
54          if (ctx instanceof AbstractFaceletContext)
55          {
56              return ((AbstractFaceletContext)ctx).getFaceletCompositionContext();
57          }
58          else
59          {
60              // Here we have two choices: retrieve it throught ThreadLocal var
61              // or use the attribute value on FacesContext, but it seems better
62              // use the FacesContext attribute map.
63              return (FaceletCompositionContext)
64                      ctx.getFacesContext().getAttributes().get(FACELET_COMPOSITION_CONTEXT_KEY);
65          }
66      }
67      
68      static public FaceletCompositionContext getCurrentInstance(FacesContext ctx)
69      {
70          return (FaceletCompositionContext) ctx.getAttributes().get(FACELET_COMPOSITION_CONTEXT_KEY);
71      }
72  
73      public void init(FacesContext facesContext)
74      {
75          facesContext.getAttributes().put(
76                  FaceletCompositionContext.FACELET_COMPOSITION_CONTEXT_KEY, this);
77      }
78  
79      /**
80       * Releases the MyFaceletContext object.  This method must only
81       * be called by the code that created the MyFaceletContext.
82       */
83      public void release(FacesContext facesContext)
84      {
85          facesContext.getAttributes().remove(FACELET_COMPOSITION_CONTEXT_KEY);
86      }
87      
88      public abstract FaceletFactory getFaceletFactory();
89      
90      /**
91       * Return the composite component being applied on the current facelet. 
92       * 
93       * Note this is different to UIComponent.getCurrentCompositeComponent, because a composite
94       * component is added to the stack each time a composite:implementation tag handler is applied.
95       * 
96       * This could be used by InsertChildrenHandler and InsertFacetHandler to retrieve the current
97       * composite component to be applied.
98       * 
99       * @since 2.0.1
100      * @return
101      */
102     public abstract UIComponent getCompositeComponentFromStack();
103 
104     /**
105      * @since 2.0.1
106      * @param parent
107      */
108     public abstract void pushCompositeComponentToStack(UIComponent parent);
109 
110     /**
111      * @since 2.0.1
112      */
113     public abstract void popCompositeComponentToStack();
114     
115     /**
116      * Return the latest UniqueIdVendor created from stack. The reason why we need to keep
117      * a UniqueIdVendor stack is because we need to look the closest one in ComponentTagHandlerDelegate.
118      * Note that facelets tree is built from leafs to root, that means use UIComponent.getParent() does not
119      * always return parent components.
120      * 
121      * @since 2.0.1
122      * @return
123      */
124     public abstract UniqueIdVendor getUniqueIdVendorFromStack();
125 
126     /**
127      * @since 2.0.1
128      * @param parent
129      */
130     public abstract void pushUniqueIdVendorToStack(UniqueIdVendor parent);
131 
132     /**
133      * @since 2.0.1
134      */
135     public abstract void popUniqueIdVendorToStack();
136     
137     /**
138      * Gets the top of the validationGroups stack.
139      * @return
140      * @since 2.0.1
141      */
142     @Deprecated
143     public abstract String getFirstValidationGroupFromStack();
144     
145     /**
146      * Removes top of stack.
147      * @since 2.0.1
148      */
149     @Deprecated
150     public abstract void popValidationGroupsToStack();
151     
152     /**
153      * Pushes validationGroups to the stack.
154      * @param validationGroups
155      * @since 2.0.1
156      */
157     @Deprecated
158     public abstract void pushValidationGroupsToStack(String validationGroups);
159     
160     /**
161      * Gets all validationIds on the stack.
162      * @return
163      * @since 2.0.1
164      */
165     @Deprecated
166     public abstract Iterator<String> getExcludedValidatorIds();
167     
168     /**
169      * Removes top of stack.
170      * @since 2.0.1
171      */
172     @Deprecated
173     public abstract void popExcludedValidatorIdToStack();
174     
175     /**
176      * Pushes validatorId to the stack of excluded validatorIds.
177      * @param validatorId
178      * @since 2.0.1
179      */
180     @Deprecated
181     public abstract void pushExcludedValidatorIdToStack(String validatorId);
182     
183     /**
184      * Gets all validationIds on the stack.
185      * @return
186      * @since 2.0.1
187      */
188     @Deprecated
189     public abstract Iterator<String> getEnclosingValidatorIds();
190     
191     /**
192      * Removes top of stack.
193      * @since 2.0.1
194      */
195     public abstract void popEnclosingValidatorIdToStack();
196     
197     /**
198      * Pushes validatorId to the stack of all enclosing validatorIds.
199      * @param validatorId
200      * @since 2.0.1
201      */
202     @Deprecated
203     public abstract void pushEnclosingValidatorIdToStack(String validatorId);
204     
205     /**
206      * Pushes validatorId to the stack of all enclosing validatorIds.
207      * 
208      * @param validatorId
209      * @param attachedObjectHandler
210      * @since 2.0.10
211      */
212     public abstract void pushEnclosingValidatorIdToStack(String validatorId, 
213             EditableValueHolderAttachedObjectHandler attachedObjectHandler);
214 
215     /**
216      * Gets all validationIds with its associated EditableValueHolderAttachedObjectHandler from the stack.
217      * 
218      * @return
219      * @since 2.0.10
220      */
221     public abstract Iterator<Map.Entry<String, EditableValueHolderAttachedObjectHandler>> 
222         getEnclosingValidatorIdsAndHandlers();
223     
224     /**
225      * 
226      * @param id
227      * @return
228      * @since 2.0.10
229      */
230     public abstract boolean containsEnclosingValidatorId(String id);
231     
232     /**
233      * Check if this build is being refreshed, adding transient components
234      * and adding/removing components under c:if or c:forEach or not.
235      * 
236      * @return
237      * @since 2.0.1
238      */
239     public abstract boolean isRefreshingTransientBuild();
240     
241     /**
242      * Check if this build should be marked as initial state. In other words,
243      * all components must call UIComponent.markInitialState.
244      * 
245      * @return
246      * @since 2.0.1
247      */
248     public abstract boolean isMarkInitialState();
249     
250     public void setMarkInitialState(boolean value)
251     {
252     }
253     
254     /**
255      * Check if the current view will be refreshed with partial state saving.
256      * 
257      * This param is used in two posible events:
258      * 
259      * 1. To notify UIInstruction instances to look for instances moved by
260      *    cc:insertChildren or cc:insertFacet.
261      * 2. To do proper actions when a tag that could change tree structure is applied
262      *    (c:if, c:forEach...)
263      * 
264      * @return
265      * @since 2.0.1
266      */
267     public abstract boolean isRefreshTransientBuildOnPSS();
268     
269     /**
270      * 
271      * @since 2.0.12, 2.1.6
272      * @return
273      */
274     public boolean isRefreshTransientBuildOnPSSPreserveState()
275     {
276         return false;
277     }
278     
279     /**
280      * Check if we are using partial state saving on this view
281      * 
282      * @return
283      * @since 2.0.1
284      */
285     public abstract boolean isUsingPSSOnThisView();
286     
287     /**
288      * @since 2.0.1
289      * @return
290      */
291     public abstract boolean isMarkInitialStateAndIsRefreshTransientBuildOnPSS();
292 
293     /**
294      * Add to the composite component parent this handler, so it will be processed later when
295      * ViewDeclarationLanguage.retargetAttachedObjects is called.
296      *
297      * Tag Handlers exposing attached objects should call this method to expose them when the
298      * parent to be applied is a composite components.
299      *
300      * @since 2.0.2
301      * @param compositeComponentParent
302      * @param handler
303      */
304     public abstract void addAttachedObjectHandler(UIComponent compositeComponentParent, AttachedObjectHandler handler);
305 
306     /**
307      * Remove from the composite component parent the list of attached handlers.
308      * 
309      * @since 2.0.2
310      * @param compositeComponentParent
311      */
312     public abstract void removeAttachedObjectHandlers(UIComponent compositeComponentParent);
313 
314     /**
315      * Retrieve the list of object handlers attached to a composite component parent. 
316      * 
317      * @since 2.0.2
318      * @param compositeComponentParent
319      */
320     public abstract List<AttachedObjectHandler> getAttachedObjectHandlers(UIComponent compositeComponentParent);
321 
322     /**
323      * Marks all direct children and Facets with an attribute for deletion.
324      *
325      * @since 2.0.2
326      * @see #finalizeForDeletion(UIComponent)
327      * @param component
328      *            UIComponent to mark
329      */
330     public abstract void markForDeletion(UIComponent component);
331     
332     /**
333      * Used in conjunction with markForDeletion where any UIComponent marked will be removed.
334      * 
335      * @since 2.0.2
336      * @param component
337      *            UIComponent to finalize
338      */
339     public abstract void finalizeForDeletion(UIComponent component);
340     
341     public void removeComponentForDeletion(UIComponent component)
342     {
343     }
344 
345     /**
346      * Marks the given resource for deletion. Is to be used for relocatable 
347      * components instead of {@link #markForDeletion(UIComponent)}.
348      *
349      * @since 2.0.17 2.1.11
350      * @param component
351      *            UIComponent to finalize
352      */
353     public void markRelocatableResourceForDeletion(UIComponent component)
354     {
355     }
356 
357     /**
358      * Used to clean up all unused relocatable components on the root component.
359      *
360      * @since 2.0.17 2.1.11
361      * @param component
362      *            UIComponent to finalize (root component)
363      */
364     public void finalizeRelocatableResourcesForDeletion(UIViewRoot root)
365     {
366     }
367 
368     /**
369      * Add a method expression as targeted for the provided composite component
370      * 
371      * @since 2.0.3
372      * @param targetedComponent
373      * @param attributeName
374      * @param backingValue A value that could be useful to revert its effects.
375      */
376     public abstract void addMethodExpressionTargeted(UIComponent targetedComponent, String attributeName,
377                                                      Object backingValue);
378 
379     /**
380      * Check if the MethodExpression attribute has been applied using vdl.retargetMethodExpression 
381      * 
382      * @since 2.0.3
383      * @param compositeComponentParent
384      * @param attributeName
385      * @return
386      */
387     public abstract boolean isMethodExpressionAttributeApplied(UIComponent compositeComponentParent,
388                                                                String attributeName);
389     
390     /**
391      * Mark the MethodExpression attribute as applied using vdl.retargetMethodExpression
392      * 
393      * @since 2.0.3
394      * @param compositeComponentParent
395      * @param attributeName
396      */
397     public abstract void markMethodExpressionAttribute(UIComponent compositeComponentParent, String attributeName);
398     
399     /**
400      * Clear the MethodExpression attribute to call vdl.retargetMethodExpression again
401      * 
402      * @since 2.0.3
403      * @param compositeComponentParent
404      * @param attributeName
405      */
406     public abstract void clearMethodExpressionAttribute(UIComponent compositeComponentParent, String attributeName);
407     
408     /**
409      * Remove a method expression as targeted for the provided composite component
410      * 
411      * @since 2.0.3
412      * @param targetedComponent
413      * @param attributeName
414      * @return A value that could be useful to revert its effects.
415      */
416     public abstract Object removeMethodExpressionTargeted(UIComponent targetedComponent, String attributeName);
417     
418     /**
419      * Indicates if a EL Expression can be or not cached by facelets vdl.
420      * 
421      * @since 2.0.8
422      * @return
423      */
424     public ELExpressionCacheMode getELExpressionCacheMode()
425     {
426         return ELExpressionCacheMode.noCache;
427     }
428     
429     /**
430      * 
431      * @since 2.0.9
432      * @return
433      */
434     public boolean isWrapTagExceptionsAsContextAware()
435     {
436         return true;
437     }
438 
439     /**
440      * Start a new unique id section, which means a new counter is used to
441      * generate unique ids to components
442      * 
443      * @since 2.0.10, 2.1.4
444      * @return
445      */
446     public String startComponentUniqueIdSection()
447     {
448         return null;
449     }
450     
451     /**
452      * Generate a unique id that will be used later to derive a unique id per tag
453      * by FaceletContext.generateUniqueId(). This generator ensures uniqueness per
454      * view but FaceletContext.generateUniqueId() ensures uniqueness per view and
455      * per facelet hierarchy, so different included facelets will generate different
456      * ids.
457      * 
458      * @return
459      */
460     public String generateUniqueId()
461     {
462         return null;
463     }
464     
465     public void generateUniqueId(StringBuilder builderToAdd)
466     {
467     }
468     
469     /**
470      * Generate a unique id for component instances. 
471      * 
472      * @return
473      */
474     public String generateUniqueComponentId()
475     {
476         return null;
477     }
478 
479     /**
480      * Ends the current unique id section, so the previous counter will be used
481      * to generate unique ids to components.
482      */
483     public void endComponentUniqueIdSection()
484     {
485     }
486     
487     /**
488      * Set the iterator used to retrieve unique ids.
489      * 
490      * since 2.1.7, 2.0.13
491      * @param uniqueIdsIterator 
492      */
493     public void setUniqueIdsIterator(Iterator<String> uniqueIdsIterator)
494     {
495     }
496     
497     /**
498      * Activater record unique id mode, so an structure will be
499      * used to hold those values.
500      * 
501      * since 2.1.7, 2.0.13
502      */
503     public void initUniqueIdRecording()
504     {
505     }
506     
507     /**
508      * Add an unique id to the list if recording is enabled,
509      * if recording is not enabled it has no effect.
510      * 
511      * since 2.1.7, 2.0.13
512      * @param uniqueId 
513      */
514     public void addUniqueId(String uniqueId)
515     {
516     }
517     
518     /**
519      * Return the unique id from the iterator if applies
520      * 
521      * since 2.1.7, 2.0.13
522      * @return 
523      */
524     public String getUniqueIdFromIterator()
525     {
526         return null;
527     }
528     
529     /**
530      * Return the list of unique ids
531      * 
532      * since 2.1.7, 2.0.13
533      * @return 
534      */
535     public List<String> getUniqueIdList()
536     {
537         return null;
538     }
539 
540     /**
541      * Increment the unique id without construct it.
542      * 
543      * since 2.1.7, 2.0.13
544      * @return 
545      */
546     public void incrementUniqueId()
547     {
548     }
549 
550     /**
551      * Check if the facelet is building view metadata
552      * 
553      * since 2.1.7, 2.0.13
554      * @return 
555      */
556     public boolean isBuildingViewMetadata()
557     {
558         return FaceletViewDeclarationLanguage.isBuildingViewMetadata(
559                 FacesContext.getCurrentInstance());
560     }
561     
562     /**
563      * Call this method to indicate a f:metadata section is about to be processed
564      * 
565      * since 2.1.7, 2.0.13
566      * @return 
567      */
568     public void startMetadataSection()
569     {
570     }
571     
572     /**
573      * Call this method to indicate f:metadata section has been already processed
574      * 
575      * since 2.1.7, 2.0.13
576      * @return 
577      */
578     public void endMetadataSection()
579     {
580     }
581     
582     /**
583      * Check if the component is created inside f:metadata section
584      * 
585      * since 2.1.7, 2.0.13
586      * @return 
587      */
588     public boolean isInMetadataSection()
589     {
590        return false;
591     }
592     
593     /**
594      * Check if the section to be processed is being refreshed.
595      * 
596      * since 2.1.7, 2.0.13
597      * @return 
598      */
599     public boolean isRefreshingSection()
600     {
601        return isRefreshingTransientBuild() ||  (!isBuildingViewMetadata() && isInMetadataSection());
602     }
603 
604     /**
605      * 
606      * @since 2.1.8, 2.0.14
607      */
608     public void incrementUniqueComponentId()
609     {
610     }
611     
612     public StringBuilder getSharedStringBuilder()
613     {
614         return new StringBuilder();
615     }
616 
617     /**
618      * Returns the current nesting level of composite components found. If
619      * no composite component has been used returns 0.
620      * 
621      * @since 2.1.9, 2.0.15
622      */
623     public int getCompositeComponentLevel()
624     {
625         return 0;
626     }
627 }