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