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