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.custom.aliasbean;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.HashMap;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Map;
27  
28  import javax.faces.FacesException;
29  import javax.faces.component.ContextCallback;
30  import javax.faces.component.UIComponent;
31  import javax.faces.component.UIComponentBase;
32  import javax.faces.context.FacesContext;
33  import javax.faces.event.AbortProcessingException;
34  import javax.faces.event.FacesEvent;
35  
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
39  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperties;
40  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
41  import org.apache.myfaces.shared_tomahawk.component.BindingAware;
42  import org.apache.myfaces.shared_tomahawk.util.RestoreStateUtils;
43  
44  /**
45   * Holds several aliases that are configured by aliasBean tags.
46   * <p>
47   * The aliasBean tag must enclose all the components that are within the scope
48   * of the alias. When multiple aliasas are defined, this makes the page structure
49   * very clumsy; for example defining 5 aliases means the content must be nested
50   * 5 indentation levels deep. This tag instead allows the content block to be
51   * wrapped in just one AliasBeansScope tag, and then have AliasBean tags with
52   * empty bodies added as direct children of this component. The scope of the AliasBean
53   * tag still starts when the tag begins, but instead of ending when the tag ends
54   * the scope of the nested AliasBean tags extends to the end of this component.
55   * </p>
56   * 
57   * @author Sylvain Vieujot (latest modification by $Author: lu4242 $)
58   * @version $Revision: 1082663 $ $Date: 2011-03-17 14:47:10 -0500 (Thu, 17 Mar 2011) $
59   */
60  @JSFComponent(
61          name = "t:aliasBeansScope",
62          tagClass = "org.apache.myfaces.custom.aliasbean.AliasBeansScopeTag",
63          tagHandler = "org.apache.myfaces.custom.aliasbean.AliasBeansScopeTagHandler")
64  @JSFJspProperties(properties={
65          @JSFJspProperty(
66                  name = "rendered",
67                  returnType = "boolean", 
68                  tagExcluded = true),
69          @JSFJspProperty(
70                  name = "binding",
71                  returnType = "java.lang.String",
72                  tagExcluded = true)
73                  })
74  public class AliasBeansScope extends UIComponentBase implements BindingAware
75  {
76      static final Log log = LogFactory.getLog(AliasBeansScope.class);
77  
78      public static final String COMPONENT_TYPE = "org.apache.myfaces.AliasBeansScope";
79      public static final String COMPONENT_FAMILY = "javax.faces.Data";
80  
81      private ArrayList _aliases = new ArrayList();
82      transient FacesContext _context = null;
83  
84      void addAlias(Alias alias)
85      {
86          _aliases.add(alias);
87      }
88  
89      public String getFamily()
90      {
91          return COMPONENT_FAMILY;
92      }
93  
94      public String getRendererType() {
95        return null;
96      }
97  
98    public Object saveState(FacesContext context)
99      {
100         log.debug("saveState");
101         _context = context;
102 
103         return super.saveState(context);
104     }
105 
106     public void restoreState(FacesContext context, Object state)
107     {
108         log.debug("restoreState");
109         _context = context;
110 
111         super.restoreState(context, state);
112     }
113 
114     public Object processSaveState(FacesContext context)
115     {
116         if (context == null)
117             throw new NullPointerException("context");
118         if (isTransient())
119             return null;
120 
121         makeAliases(context);
122 
123         Map facetMap = null;
124         for (Iterator it = getFacets().entrySet().iterator(); it.hasNext();)
125         {
126             Map.Entry entry = (Map.Entry) it.next();
127             if (facetMap == null)
128                 facetMap = new HashMap();
129             UIComponent component = (UIComponent) entry.getValue();
130             if (!component.isTransient())
131             {
132                 facetMap.put(entry.getKey(), component.processSaveState(context));
133             }
134         }
135 
136         List childrenList = null;
137         if (getChildCount() > 0)
138         {
139             for (Iterator it = getChildren().iterator(); it.hasNext();)
140             {
141                 UIComponent child = (UIComponent) it.next();
142                 if (!child.isTransient())
143                 {
144                     if (childrenList == null)
145                         childrenList = new ArrayList(getChildCount());
146                     childrenList.add(child.processSaveState(context));
147                 }
148             }
149         }
150 
151         removeAliases(context);
152 
153         return new Object[]{saveState(context), facetMap, childrenList};
154     }
155 
156     public void processRestoreState(FacesContext context, Object state)
157     {
158         if (context == null)
159             throw new NullPointerException("context");
160         Object myState = ((Object[]) state)[0];
161 
162         restoreState(context, myState);
163 
164         makeAliases(context);
165 
166         Map facetMap = (Map) ((Object[]) state)[1];
167 
168         for (Iterator it = getFacets().entrySet().iterator(); it.hasNext();)
169         {
170             Map.Entry entry = (Map.Entry) it.next();
171             Object facetState = facetMap.get(entry.getKey());
172             if (facetState != null)
173             {
174                 ((UIComponent) entry.getValue()).processRestoreState(context, facetState);
175             }
176             else
177             {
178                 context.getExternalContext().log("No state found to restore facet " + entry.getKey());
179             }
180         }
181 
182         List childrenList = (List) ((Object[]) state)[2];
183         if (getChildCount() > 0)
184         {
185             int idx = 0;
186             for (Iterator it = getChildren().iterator(); it.hasNext();)
187             {
188                 UIComponent child = (UIComponent) it.next();
189                 Object childState = childrenList.get(idx++);
190                 if (childState != null)
191                 {
192                     child.processRestoreState(context, childState);
193                 }
194                 else
195                 {
196                     context.getExternalContext().log("No state found to restore child of component " + getId());
197                 }
198             }
199         }
200 
201         removeAliases(context);
202     }
203 
204     public void processValidators(FacesContext context)
205     {
206         log.debug("processValidators");
207         makeAliases(context);
208         super.processValidators(context);
209         removeAliases(context);
210     }
211 
212     public void processDecodes(FacesContext context)
213     {
214         log.debug("processDecodes");
215         makeAliases(context);
216         super.processDecodes(context);
217         removeAliases(context);
218     }
219 
220     public void processUpdates(FacesContext context)
221     {
222         log.debug("processUpdates");
223         makeAliases(context);
224         super.processUpdates(context);
225         removeAliases(context);
226     }
227 
228     public void encodeBegin(FacesContext context) throws IOException
229     {
230         log.debug("encodeBegin");
231         makeAliases(context);
232     }
233 
234     public void encodeEnd(FacesContext context)
235     {
236         log.debug("encodeEnd");
237         removeAliases(context);
238     }
239 
240     public void queueEvent(FacesEvent event)
241     {
242         super.queueEvent(new FacesEventWrapper(event, this));
243     }
244 
245     public void broadcast(FacesEvent event) throws AbortProcessingException
246     {
247         makeAliases();
248 
249         if (event instanceof FacesEventWrapper)
250         {
251             FacesEvent originalEvent = ((FacesEventWrapper) event).getWrappedFacesEvent();
252             originalEvent.getComponent().broadcast(originalEvent);
253         }
254         else
255         {
256             super.broadcast(event);
257         }
258 
259         removeAliases();
260     }
261 
262     void makeAliases(FacesContext context)
263     {
264         _context = context;
265         makeAliases();
266     }
267 
268     private void makeAliases()
269     {
270         for (Iterator i = _aliases.iterator(); i.hasNext();)
271             ((Alias) i.next()).make(_context);
272     }
273 
274     void removeAliases(FacesContext context)
275     {
276         _context = context;
277         removeAliases();
278     }
279 
280     private void removeAliases()
281     {
282         for (Iterator i = _aliases.iterator(); i.hasNext();)
283             ((Alias) i.next()).remove(_context);
284     }
285 
286     public void handleBindings()
287     {
288         makeAliases(getFacesContext());
289 
290         RestoreStateUtils.recursivelyHandleComponentReferencesAndSetValid(getFacesContext(), this, true);
291 
292         removeAliases(getFacesContext());
293     }
294 
295     @Override
296     public boolean invokeOnComponent(FacesContext context, String clientId,
297             ContextCallback callback) throws FacesException
298     {
299         makeAliases(getFacesContext());
300         try
301         {
302             return super.invokeOnComponent(context, clientId, callback);
303         }
304         finally
305         {
306             removeAliases(getFacesContext());
307         }
308     }
309 
310 }