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.velocity.runtime.log.Log;
26  import org.apache.velocity.util.introspection.Introspector;
27  
28  /**
29   * Executor for looking up property names in the passed in class
30   * This will try to find a set<foo>(key, value) method
31   *
32   * @author <a href="mailto:henning@apache.org">Henning P. Schmiedehausen</a>
33   * @version $Id: SetPropertyExecutor.java 463298 2006-10-12 16:10:32Z henning $
34   */
35  public class SetPropertyExecutor
36          extends SetExecutor
37  {
38      private final Introspector introspector;
39  
40      /**
41       * @param log
42       * @param introspector
43       * @param clazz
44       * @param property
45       * @param arg
46       */
47      public SetPropertyExecutor(final Log log, final Introspector introspector,
48              final Class clazz, final String property, final Object arg)
49      {
50          this.log = log;
51          this.introspector = introspector;
52  
53          // Don't allow passing in the empty string or null because
54          // it will either fail with a StringIndexOutOfBounds error
55          // or the introspector will get confused.
56          if (StringUtils.isNotEmpty(property))
57          {
58              discover(clazz, property, arg);
59          }
60      }
61  
62      /**
63       * @return The current introspector.
64       */
65      protected Introspector getIntrospector()
66      {
67          return this.introspector;
68      }
69  
70      /**
71       * @param clazz
72       * @param property
73       * @param arg
74       */
75      protected void discover(final Class clazz, final String property, final Object arg)
76      {
77          Object [] params = new Object [] { arg };
78  
79          try
80          {
81              StringBuffer sb = new StringBuffer("set");
82              sb.append(property);
83  
84              setMethod(introspector.getMethod(clazz, sb.toString(), params));
85  
86              if (!isAlive())
87              {
88                  /*
89                   *  now the convenience, flip the 1st character
90                   */
91  
92                  char c = sb.charAt(3);
93  
94                  if (Character.isLowerCase(c))
95                  {
96                      sb.setCharAt(3, Character.toUpperCase(c));
97                  }
98                  else
99                  {
100                     sb.setCharAt(3, Character.toLowerCase(c));
101                 }
102 
103                 setMethod(introspector.getMethod(clazz, sb.toString(), params));
104             }
105         }
106         /**
107          * pass through application level runtime exceptions
108          */
109         catch( RuntimeException e )
110         {
111             throw e;
112         }
113         catch(Exception e)
114         {
115             log.error("While looking for property setter for '" + property + "':", e);
116         }
117     }
118 
119     /**
120      * Execute method against context.
121      * @param o
122      * @param value
123      * @return The value of the invocation.
124      * @throws IllegalAccessException
125      * @throws InvocationTargetException
126      */
127     public Object execute(final Object o, final Object value)
128         throws IllegalAccessException,  InvocationTargetException
129     {
130         Object [] params = new Object [] { value };
131         return isAlive() ? getMethod().invoke(o, params) : null;
132     }
133 }