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: 1657957 $ $Date: 2015-02-06 20:47:56 +0000 (Fri, 06 Feb 2015) $
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      * Start a new unique id section, which means a new counter is used to
453      * generate unique ids to components, but appending a base to the
454      * new counter.
455      * 
456      * @return
457      */
458     public String startComponentUniqueIdSection(String base)
459     {
460         return null;
461     }
462     
463     /**
464      * @param base 
465      */
466     public void endComponentUniqueIdSection(String base)
467     {
468     }
469     
470     /**
471      * Generate a unique id that will be used later to derive a unique id per tag
472      * by FaceletContext.generateUniqueId(). This generator ensures uniqueness per
473      * view but FaceletContext.generateUniqueId() ensures uniqueness per view and
474      * per facelet hierarchy, so different included facelets will generate different
475      * ids.
476      * 
477      * @return
478      */
479     public String generateUniqueId()
480     {
481         return null;
482     }
483     
484     public void generateUniqueId(StringBuilder builderToAdd)
485     {
486     }
487     
488     /**
489      * Generate a unique id for component instances. 
490      * 
491      * @return
492      */
493     public String generateUniqueComponentId()
494     {
495         return null;
496     }
497 
498     /**
499      * Ends the current unique id section, so the previous counter will be used
500      * to generate unique ids to components.
501      */
502     public void endComponentUniqueIdSection()
503     {
504     }
505     
506     /**
507      * Set the iterator used to retrieve unique ids.
508      * 
509      * since 2.1.7, 2.0.13
510      * @param uniqueIdsIterator 
511      */
512     public void setUniqueIdsIterator(Iterator<String> uniqueIdsIterator)
513     {
514     }
515     
516     /**
517      * Activater record unique id mode, so an structure will be
518      * used to hold those values.
519      * 
520      * since 2.1.7, 2.0.13
521      */
522     public void initUniqueIdRecording()
523     {
524     }
525     
526     /**
527      * Add an unique id to the list if recording is enabled,
528      * if recording is not enabled it has no effect.
529      * 
530      * since 2.1.7, 2.0.13
531      * @param uniqueId 
532      */
533     public void addUniqueId(String uniqueId)
534     {
535     }
536     
537     /**
538      * Return the unique id from the iterator if applies
539      * 
540      * since 2.1.7, 2.0.13
541      * @return 
542      */
543     public String getUniqueIdFromIterator()
544     {
545         return null;
546     }
547     
548     /**
549      * Return the list of unique ids
550      * 
551      * since 2.1.7, 2.0.13
552      * @return 
553      */
554     public List<String> getUniqueIdList()
555     {
556         return null;
557     }
558 
559     /**
560      * Increment the unique id without construct it.
561      * 
562      * since 2.1.7, 2.0.13
563      * @return 
564      */
565     public void incrementUniqueId()
566     {
567     }
568 
569     /**
570      * Check if the facelet is building view metadata
571      * 
572      * since 2.1.7, 2.0.13
573      * @return 
574      */
575     public boolean isBuildingViewMetadata()
576     {
577         return FaceletViewDeclarationLanguage.isBuildingViewMetadata(
578                 FacesContext.getCurrentInstance());
579     }
580     
581     /**
582      * Call this method to indicate a f:metadata section is about to be processed
583      * 
584      * since 2.1.7, 2.0.13
585      * @return 
586      */
587     public void startMetadataSection()
588     {
589     }
590     
591     /**
592      * Call this method to indicate f:metadata section has been already processed
593      * 
594      * since 2.1.7, 2.0.13
595      * @return 
596      */
597     public void endMetadataSection()
598     {
599     }
600     
601     /**
602      * Check if the component is created inside f:metadata section
603      * 
604      * since 2.1.7, 2.0.13
605      * @return 
606      */
607     public boolean isInMetadataSection()
608     {
609        return false;
610     }
611     
612     /**
613      * Check if the section to be processed is being refreshed.
614      * 
615      * since 2.1.7, 2.0.13
616      * @return 
617      */
618     public boolean isRefreshingSection()
619     {
620        return isRefreshingTransientBuild() ||  (!isBuildingViewMetadata() && isInMetadataSection());
621     }
622 
623     /**
624      * 
625      * @since 2.1.8, 2.0.14
626      */
627     public void incrementUniqueComponentId()
628     {
629     }
630     
631     public StringBuilder getSharedStringBuilder()
632     {
633         return new StringBuilder();
634     }
635 
636     /**
637      * Returns the current nesting level of composite components found. If
638      * no composite component has been used returns 0.
639      * 
640      * @since 2.1.9, 2.0.15
641      */
642     public int getCompositeComponentLevel()
643     {
644         return 0;
645     }
646 }