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  
20  package org.apache.myfaces.view.facelets.tag.jstl.core;
21  
22  import java.io.IOException;
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  import org.apache.myfaces.view.facelets.AbstractFaceletContext;
35  
36  /**
37   * Simplified implementation of c:set
38   * 
39   * Sets the result of an expression evaluation in a 'scope'
40   * 
41   * NOTE: This implementation is provided for compatibility reasons and
42   * it is considered faulty. It is enabled using
43   * org.apache.myfaces.STRICT_JSF_2_FACELETS_COMPATIBILITY web config param.
44   * Don't use it if EL expression caching is enabled.
45   * 
46   * @author Jacob Hookom
47   * @version $Id: SetHandler.java,v 1.2 2008/07/13 19:01:44 rlubke Exp $
48   */
49  //@JSFFaceletTag(name="c:set")
50  public class LegacySetHandler 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 LegacySetHandler(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      public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
100             ELException
101     {
102         ValueExpression veObj = this.value.getValueExpression(ctx, Object.class);
103 
104         if (this.var != null)
105         {
106             // Get variable name
107             String varStr = this.var.getValue(ctx);
108 
109             if (this.scope != null)
110             {
111                 String scopeStr = this.scope.getValue(ctx);
112 
113                 // Check scope string
114                 if (scopeStr == null || scopeStr.length() == 0)
115                 {
116                     throw new TagException(tag, "scope must not be empty");
117                 }
118                 if ("page".equals(scopeStr))
119                 {
120                     throw new TagException(tag, "page scope is not allowed");
121                 }
122 
123                 // Build value expression string to set variable
124                 StringBuilder expStr = new StringBuilder().append("#{").append(scopeStr);
125                 if ("request".equals(scopeStr) || "view".equals(scopeStr) || "session".equals(scopeStr)
126                         || "application".equals(scopeStr))
127                 {
128                     expStr.append("Scope");
129                 }
130                 expStr.append(".").append(varStr).append("}");
131                 ELContext elCtx = ctx.getFacesContext().getELContext();
132                 ValueExpression expr = ctx.getExpressionFactory().createValueExpression(
133                         elCtx, expStr.toString(), Object.class);
134                 expr.setValue(elCtx, veObj.getValue(elCtx));
135             }
136             else
137             {
138                 ctx.getVariableMapper().setVariable(varStr, veObj);
139                 AbstractFaceletContext actx = ((AbstractFaceletContext) ctx);
140                 actx.getPageContext().setAllowCacheELExpressions(false);
141             }
142         }
143         else
144         {
145             // Check attributes
146             if (this.target == null || this.property == null || this.value == null)
147             {
148                 throw new TagException(
149                         tag, "either attributes var and value or target, property and value must be set");
150             }
151             if (this.target.isLiteral())
152             {
153                 throw new TagException(tag, "attribute target must contain a value expression");
154             }
155 
156             // Get target object and name of property to set
157             ELContext elCtx = ctx.getFacesContext().getELContext();
158             ValueExpression targetExpr = this.target.getValueExpression(ctx, Object.class);
159             Object targetObj = targetExpr.getValue(elCtx);
160             String propertyName = this.property.getValue(ctx);
161             // Set property on target object
162             ctx.getELResolver().setValue(elCtx, targetObj, propertyName, veObj.getValue(elCtx));
163         }
164     }
165 }