View Javadoc

1   package org.apache.velocity.runtime.parser.node;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.    
20   */
21  
22  import java.lang.reflect.InvocationTargetException;
23  
24  import org.apache.commons.lang.StringUtils;
25  import org.apache.commons.lang.text.StrBuilder;
26  import org.apache.velocity.exception.VelocityException;
27  import org.apache.velocity.runtime.log.Log;
28  import org.apache.velocity.util.introspection.Introspector;
29  
30  /**
31   * Executor for looking up property names in the passed in class
32   * This will try to find a set<foo>(key, value) method
33   *
34   * @author <a href="mailto:henning@apache.org">Henning P. Schmiedehausen</a>
35   * @version $Id: SetPropertyExecutor.java 687177 2008-08-19 22:00:32Z nbubna $
36   * @since 1.5
37   */
38  public class SetPropertyExecutor
39          extends SetExecutor
40  {
41      private final Introspector introspector;
42  
43      /**
44       * @param log
45       * @param introspector
46       * @param clazz
47       * @param property
48       * @param arg
49       */
50      public SetPropertyExecutor(final Log log, final Introspector introspector,
51              final Class clazz, final String property, final Object arg)
52      {
53          this.log = log;
54          this.introspector = introspector;
55  
56          // Don't allow passing in the empty string or null because
57          // it will either fail with a StringIndexOutOfBounds error
58          // or the introspector will get confused.
59          if (StringUtils.isNotEmpty(property))
60          {
61              discover(clazz, property, arg);
62          }
63      }
64  
65      /**
66       * @return The current introspector.
67       */
68      protected Introspector getIntrospector()
69      {
70          return this.introspector;
71      }
72  
73      /**
74       * @param clazz
75       * @param property
76       * @param arg
77       */
78      protected void discover(final Class clazz, final String property, final Object arg)
79      {
80          Object [] params = new Object [] { arg };
81  
82          try
83          {
84              StrBuilder sb = new StrBuilder("set");
85              sb.append(property);
86  
87              setMethod(introspector.getMethod(clazz, sb.toString(), params));
88  
89              if (!isAlive())
90              {
91                  /*
92                   *  now the convenience, flip the 1st character
93                   */
94  
95                  char c = sb.charAt(3);
96  
97                  if (Character.isLowerCase(c))
98                  {
99                      sb.setCharAt(3, Character.toUpperCase(c));
100                 }
101                 else
102                 {
103                     sb.setCharAt(3, Character.toLowerCase(c));
104                 }
105 
106                 setMethod(introspector.getMethod(clazz, sb.toString(), params));
107             }
108         }
109         /**
110          * pass through application level runtime exceptions
111          */
112         catch( RuntimeException e )
113         {
114             throw e;
115         }
116         catch(Exception e)
117         {
118             String msg = "Exception while looking for property setter for '" + property;
119             log.error(msg, e);
120             throw new VelocityException(msg, e);
121         }
122     }
123 
124     /**
125      * Execute method against context.
126      * @param o
127      * @param value
128      * @return The value of the invocation.
129      * @throws IllegalAccessException
130      * @throws InvocationTargetException
131      */
132     public Object execute(final Object o, final Object value)
133         throws IllegalAccessException,  InvocationTargetException
134     {
135         Object [] params = new Object [] { value };
136         return isAlive() ? getMethod().invoke(o, params) : null;
137     }
138 }