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      @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                 actx.getPageContext().setAllowCacheELExpressions(false);
142             }
143         }
144         else
145         {
146             // Check attributes
147             if (this.target == null || this.property == null || this.value == null)
148             {
149                 throw new TagException(
150                         tag, "either attributes var and value or target, property and value must be set");
151             }
152             if (this.target.isLiteral())
153             {
154                 throw new TagException(tag, "attribute target must contain a value expression");
155             }
156 
157             // Get target object and name of property to set
158             ELContext elCtx = ctx.getFacesContext().getELContext();
159             ValueExpression targetExpr = this.target.getValueExpression(ctx, Object.class);
160             Object targetObj = targetExpr.getValue(elCtx);
161             String propertyName = this.property.getValue(ctx);
162             // Set property on target object
163             ctx.getELResolver().setValue(elCtx, targetObj, propertyName, veObj.getValue(elCtx));
164         }
165     }
166 }