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