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