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.tag;
20  
21  import java.io.FileNotFoundException;
22  import java.io.IOException;
23  import java.net.URL;
24  import java.util.Collection;
25  import java.util.HashMap;
26  import java.util.Map;
27  
28  import javax.el.ELException;
29  import javax.el.ValueExpression;
30  import javax.el.VariableMapper;
31  import javax.faces.FacesException;
32  import javax.faces.component.UIComponent;
33  import javax.faces.view.facelets.FaceletContext;
34  import javax.faces.view.facelets.FaceletException;
35  import javax.faces.view.facelets.TagAttribute;
36  import javax.faces.view.facelets.TagConfig;
37  import javax.faces.view.facelets.TagException;
38  import javax.faces.view.facelets.TagHandler;
39  
40  import org.apache.myfaces.view.facelets.AbstractFaceletContext;
41  import org.apache.myfaces.view.facelets.TemplateClient;
42  import org.apache.myfaces.view.facelets.TemplateContext;
43  import org.apache.myfaces.view.facelets.el.VariableMapperWrapper;
44  import org.apache.myfaces.view.facelets.impl.TemplateContextImpl;
45  import org.apache.myfaces.view.facelets.tag.ui.DefineHandler;
46  
47  /**
48   * A Tag that is specified in a FaceletFile. Takes all attributes specified and sets them on the FaceletContext before
49   * including the targeted Facelet file.
50   * 
51   * @author Jacob Hookom
52   * @version $Id: UserTagHandler.java 1306698 2012-03-29 03:13:06Z lu4242 $
53   */
54  final class UserTagHandler extends TagHandler implements TemplateClient, ComponentContainerHandler
55  {
56  
57      protected final TagAttribute[] _vars;
58  
59      protected final URL _location;
60  
61      protected final Map<String, DefineHandler> _handlers;
62  
63      /**
64       * @param config
65       */
66      public UserTagHandler(TagConfig config, URL location)
67      {
68          super(config);
69          this._vars = this.tag.getAttributes().getAll();
70          this._location = location;
71          
72          Collection<DefineHandler> defines = TagHandlerUtils.findNextByType(nextHandler, DefineHandler.class);
73          if (defines.isEmpty())
74          {
75              _handlers = null;
76          }
77          else
78          {
79              _handlers = new HashMap<String, DefineHandler>();
80              for (DefineHandler handler : defines)
81              {
82                  _handlers.put(handler.getName(), handler);
83              }
84          }
85      }
86  
87      /**
88       * Iterate over all TagAttributes and set them on the FaceletContext's VariableMapper, then include the target
89       * Facelet. Finally, replace the old VariableMapper.
90       * 
91       * @see TagAttribute#getValueExpression(FaceletContext, Class)
92       * @see VariableMapper
93       * @see javax.faces.view.facelets.FaceletHandler#apply(javax.faces.view.facelets.FaceletContext, javax.faces.component.UIComponent)
94       */
95      public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
96              ELException
97      {
98          //VariableMapper orig = ctx.getVariableMapper();
99  
100         // setup a variable map
101         //if (this._vars.length > 0)
102         //{
103             //VariableMapper varMapper = new VariableMapperWrapper(orig);
104             //for (int i = 0; i < this._vars.length; i++)
105             //{
106             //    varMapper.setVariable(this._vars[i].getLocalName(), this._vars[i].getValueExpression(ctx, Object.class));
107             //}
108             //ctx.setVariableMapper(varMapper);
109         //}
110 
111         AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
112         // eval include
113         try
114         {
115             String[] names = null;
116             ValueExpression[] values = null;
117             if (this._vars.length > 0)
118             {
119                 names = new String[_vars.length];
120                 values = new ValueExpression[_vars.length];
121                 for (int i = 0; i < _vars.length; i++)
122                 {
123                     names[i] = _vars[i].getLocalName();
124                     values[i] = _vars[i].getValueExpression(ctx, Object.class);
125                 }
126             }
127             actx.pushTemplateContext(new TemplateContextImpl());
128             if (this._vars.length > 0)
129             {
130                 for (int i = 0; i < this._vars.length; i++)
131                 {
132                     ((AbstractFaceletContext) ctx).getTemplateContext().setParameter(names[i], values[i]);
133                 }
134             }
135             //Disable caching always, even in 'always' mode
136             actx.getTemplateContext().setAllowCacheELExpressions(false);
137             actx.pushClient(this);
138             ctx.includeFacelet(parent, this._location);
139         }
140         catch (FileNotFoundException e)
141         {
142             throw new TagException(this.tag, e.getMessage());
143         }
144         finally
145         {
146 
147             // make sure we undo our changes
148             actx.popClient(this);
149             actx.popTemplateContext();
150             //ctx.setVariableMapper(orig);
151         }
152     }
153 
154     public boolean apply(FaceletContext ctx, UIComponent parent, String name) throws IOException, FacesException,
155             FaceletException, ELException
156     {
157         if (name != null)
158         {
159             if (this._handlers == null)
160             {
161                 return false;
162             }
163             DefineHandler handler = (DefineHandler) this._handlers.get(name);
164             if (handler != null)
165             {
166                 AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
167                 TemplateContext itc = actx.popTemplateContext();
168                 try
169                 {
170                     handler.applyDefinition(ctx, parent);
171                 }
172                 finally
173                 {
174                     actx.pushTemplateContext(itc);
175                 }
176                 return true;
177             }
178             else
179             {
180                 return false;
181             }
182         }
183         else
184         {
185             AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
186             TemplateContext itc = actx.popTemplateContext();
187             try
188             {
189                 this.nextHandler.apply(ctx, parent);
190             }
191             finally
192             {
193                 actx.pushTemplateContext(itc);
194             }
195             return true;
196         }
197     }
198 
199 }