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.jstl.core;
20  
21  import java.io.IOException;
22  
23  import javax.el.ELContext;
24  import javax.el.ELException;
25  import javax.el.ValueExpression;
26  import javax.faces.FacesException;
27  import javax.faces.component.UIComponent;
28  import javax.faces.view.facelets.FaceletContext;
29  import javax.faces.view.facelets.FaceletException;
30  import javax.faces.view.facelets.TagAttribute;
31  import javax.faces.view.facelets.TagConfig;
32  import javax.faces.view.facelets.TagException;
33  import javax.faces.view.facelets.TagHandler;
34  
35  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
36  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
37  import org.apache.myfaces.view.facelets.AbstractFaceletContext;
38  import org.apache.myfaces.view.facelets.ELExpressionCacheMode;
39  import org.apache.myfaces.view.facelets.el.CacheableValueExpressionWrapper;
40  
41  /**
42   * Simplified implementation of c:set
43   * 
44   * Sets the result of an expression evaluation in a 'scope'
45   * 
46   * @author Jacob Hookom
47   * @version $Id$
48   */
49  @JSFFaceletTag(name="c:set")
50  public class SetHandler extends TagHandler
51  {
52  
53      /**
54       * Name of the exported scoped variable to hold the value
55       * specified in the action. The type of the scoped variable is
56       * whatever type the value expression evaluates to.
57       */
58      @JSFFaceletAttribute(className="java.lang.String")
59      private final TagAttribute var;
60  
61      /**
62       * Expression to be evaluated.
63       */
64      @JSFFaceletAttribute(
65              className="javax.el.ValueExpression",
66              deferredValueType="java.lang.Object")
67      private final TagAttribute value;
68  
69      @JSFFaceletAttribute(
70              name="scope",
71              className="java.lang.String",
72              longDescription="Scope for var.")
73      private final TagAttribute scope;
74  
75      @JSFFaceletAttribute(
76          name="target",
77          className="java.lang.String",
78          longDescription="Target object whose property will be set."+
79          " Must evaluate to a JavaBeans object with setter property"+
80          "property, or to a java.util.Map object.")
81      private final TagAttribute target;
82  
83      @JSFFaceletAttribute(
84          name="property",
85          className="java.lang.String",
86          longDescription="Name of the property to be set in the target object.")
87      private final TagAttribute property;
88  
89      public SetHandler(TagConfig config)
90      {
91          super(config);
92          this.value = this.getAttribute("value");
93          this.var = this.getAttribute("var");
94          this.scope = this.getAttribute("scope");
95          this.target = this.getAttribute("target");
96          this.property = this.getAttribute("property");
97      }
98  
99      @Override
100     public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
101             ELException
102     {
103         ValueExpression veObj = this.value.getValueExpression(ctx, Object.class);
104 
105         if (this.var != null)
106         {
107             // Get variable name
108             String varStr = this.var.getValue(ctx);
109 
110             if (this.scope != null)
111             {
112                 String scopeStr = this.scope.getValue(ctx);
113 
114                 // Check scope string
115                 if (scopeStr == null || scopeStr.length() == 0)
116                 {
117                     throw new TagException(tag, "scope must not be empty");
118                 }
119                 if ("page".equals(scopeStr))
120                 {
121                     throw new TagException(tag, "page scope is not allowed");
122                 }
123 
124                 // Build value expression string to set variable
125                 StringBuilder expStr = new StringBuilder().append("#{").append(scopeStr);
126                 if ("request".equals(scopeStr) || "view".equals(scopeStr) || "session".equals(scopeStr)
127                         || "application".equals(scopeStr))
128                 {
129                     expStr.append("Scope");
130                 }
131                 expStr.append(".").append(varStr).append("}");
132                 ELContext elCtx = ctx.getFacesContext().getELContext();
133                 ValueExpression expr = ctx.getExpressionFactory().createValueExpression(
134                         elCtx, expStr.toString(), Object.class);
135                 expr.setValue(elCtx, veObj.getValue(elCtx));
136             }
137             else
138             {
139                 //ctx.getVariableMapper().setVariable(varStr, veObj);
140                 AbstractFaceletContext actx = ((AbstractFaceletContext) ctx);
141                 if (ELExpressionCacheMode.alwaysRecompile.equals(actx.getELExpressionCacheMode()))
142                 {
143                     actx.getPageContext().getAttributes().put(varStr, 
144                         new CacheableValueExpressionWrapper(veObj));
145                 }
146                 else
147                 {
148                     actx.getPageContext().getAttributes().put(varStr, veObj);
149                 }
150                 if (actx.getPageContext().isAllowCacheELExpressions())
151                 {
152                     if (ELExpressionCacheMode.strict.equals(actx.getELExpressionCacheMode()))
153                     {
154                         actx.getPageContext().setAllowCacheELExpressions(false);
155                     }
156                 }
157             }
158         }
159         else
160         {
161             // Check attributes
162             if (this.target == null || this.property == null || this.value == null)
163             {
164                 throw new TagException(
165                         tag, "either attributes var and value or target, property and value must be set");
166             }
167             if (this.target.isLiteral())
168             {
169                 throw new TagException(tag, "attribute target must contain a value expression");
170             }
171 
172             // Get target object and name of property to set
173             ELContext elCtx = ctx.getFacesContext().getELContext();
174             ValueExpression targetExpr = this.target.getValueExpression(ctx, Object.class);
175             Object targetObj = targetExpr.getValue(elCtx);
176             String propertyName = this.property.getValue(ctx);
177             // Set property on target object
178             ctx.getELResolver().setValue(elCtx, targetObj, propertyName, veObj.getValue(elCtx));
179         }
180     }
181 }