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.trinidad.component;
20  
21  import java.util.Collections;
22  import java.util.Set;
23  
24  import org.apache.myfaces.trinidad.context.RequestContext;
25  
26  /**
27   * ProcessingContext passed to FlattenedComponents and ComponentProcessors representing the
28   * current component iteration context.
29   * @see ComponentProcessor
30   * @see UIXComponent#processFlattenedChildren(FacesContext, ComponentProcessor, UIComponent, Object)
31   * @see UIXComponent#processFlattenedChildren(FacesContext, ComponentProcessor, Iterable, Object)
32   * @see UIXComponent#processFlattenedChildren(FacesContext, ComponentProcessingContext, ComponentProcessor, UIComponent, Object)
33   * @see UIXComponent#processFlattenedChildren(FacesContext, ComponentProcessingContext, ComponentProcessor, Iterable, Object)
34   * @see FlattenedComponent
35   */
36  public final class ComponentProcessingContext
37  {
38    ComponentProcessingContext()
39    {      
40      _requestContext = RequestContext.getCurrentInstance();
41    }
42  
43    /**
44     * Hints to the the FlattenedComponents regarding what the flattened iteration is being used for,
45     * The FlattenedComponent may use this information to change its flattening behavior.
46     * For example, a FlattenedComponent may generate output during a <code>PROCESS_FOR_ENCODING</code>
47     * iteration, but not during a normal iteration.
48     */
49    public enum ProcessingHint
50    {
51      /**
52       * Indicates that the iteration is occurring in order to encode iterated components.  This
53       * hint may only be used during the RenderResponse phase and only once per an iterated
54       * component.  Due to these guarantees, the FlattenedComponent is allowed to generate
55       * content during the iteration, an exception to the normal rule that iterations must
56       * be idempotent in case the same component is iterated multiple times.
57       */
58      PROCESS_FOR_ENCODING
59    }
60    
61    /**
62     * Returns the current starting group depth of the ProcessingContext.  The starting depth is only
63     * non-zero for the first rendered child inside a group or nested groups.  If two grouping
64     * components, such as UIXGroup, are nested immediately inside of each other, the first processed
65     * component in the second UIXGroup will see 2 for the start depth.  The second would see 0.
66     * @see #getGroupDepth
67     */
68    public int getStartDepth()
69    {
70      return _startDepth;
71    }
72    
73    /**
74     * Returns the current group depth of the ProcessingContext.  The group depth is equal to the
75     * nesting depth of grouping components, such as UIXGroup that the current iteratior has
76     * entered.  In contrast to <code>getStartDepth()</code>, all siblings at a particular nesting
77     * level see the same group depth.
78     * @see #getStartDepth
79     */
80    public int getGroupDepth()
81    {
82      return _groupDepth;
83    }
84  
85    /**
86     * <p>Returns hints that influence the behavior of the component processing</p>
87     *
88     * @return a non-empty, unmodifiable collection of ProcessingHints
89     */
90    public Set<ProcessingHint> getHints()
91    {
92      return _hints;
93    }
94  
95    public RequestContext getRequestContext()
96    {
97      return _requestContext;
98    }
99  
100   /**
101    * Increment the grouping and startGroup states.
102    * <p>
103    * If pushGroup is called, the seubsequent code should be
104    * wrapped in a <code>try{}finally{ComponentProcessingContext.popGroup()} block to guarantee
105    * that the group is popped correctly in case an exception is thrown.
106    * @see #popGroup
107    */
108   void pushGroup()
109   {
110     _startDepth++;
111     _groupDepth++;
112   }
113   
114   /**
115    * Decrement the grouping and startGroup states.
116    * <p>
117    * If pushGroup is called, the seubsequent code should be
118    * wrapped in a <code>try{}finally{ComponentProcessingContext.popGroup()} block to guarantee
119    * that the group is popped correctly in case an exception is thrown.
120    * @see #pushGroup
121    */
122   void popGroup()
123   {
124     _groupDepth--;
125     
126     if (_startDepth > 0)
127       _startDepth--;
128   }
129   
130   /**
131    * Called by the object performing the iteration over Component instances to 
132    * reset the start depth after the ChildProcessor is called on the first component at the
133    * new depth.  When iterating, the iterator should place the call to <code>resetStartDepth</code>
134    * in a <code>finally</code> block to guarantee that the reset happens correctly in case
135    * an exception is thrown.
136    */
137   void resetStartDepth()
138   {
139     _startDepth = 0;
140   }
141 
142   /**
143    * Handshake from the UIXComponent
144    */
145   void __setIsRendering()
146   {
147     _hints = Collections.singleton(ProcessingHint.PROCESS_FOR_ENCODING);
148   }
149 
150   private int _startDepth;
151   private int _groupDepth;
152   private Set<ProcessingHint> _hints = Collections.emptySet();
153   private RequestContext _requestContext = null;
154 }