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.RuntimeLogger;
26  import org.apache.velocity.runtime.log.Log;
27  import org.apache.velocity.runtime.log.RuntimeLoggerLog;
28  import org.apache.velocity.util.introspection.Introspector;
29  
30  /**
31   * Returned the value of object property when executed.
32   */
33  public class PropertyExecutor extends AbstractExecutor
34  {
35      private final Introspector introspector;
36  
37      /**
38       * @param log
39       * @param introspector
40       * @param clazz
41       * @param property
42       */
43      public PropertyExecutor(final Log log, final Introspector introspector,
44              final Class clazz, final String property)
45      {
46          this.log = log;
47          this.introspector = introspector;
48  
49          // Don't allow passing in the empty string or null because
50          // it will either fail with a StringIndexOutOfBounds error
51          // or the introspector will get confused.
52          if (StringUtils.isNotEmpty(property))
53          {
54              discover(clazz, property);
55          }
56      }
57  
58      /**
59       * @param r
60       * @param introspector
61       * @param clazz
62       * @param property
63       * @deprecated RuntimeLogger is deprecated. Use the other constructor.
64       */
65      public PropertyExecutor(final RuntimeLogger r, final Introspector introspector,
66              final Class clazz, final String property)
67      {
68          this(new RuntimeLoggerLog(r), introspector, clazz, property);
69      }
70  
71      /**
72       * @return The current introspector.
73       */
74      protected Introspector getIntrospector()
75      {
76          return this.introspector;
77      }
78  
79      /**
80       * @param clazz
81       * @param property
82       */
83      protected void discover(final Class clazz, final String property)
84      {
85          /*
86           *  this is gross and linear, but it keeps it straightforward.
87           */
88  
89          try
90          {
91              Object [] params = {};
92  
93              StringBuffer sb = new StringBuffer("get");
94              sb.append(property);
95  
96              setMethod(introspector.getMethod(clazz, sb.toString(), params));
97  
98              if (!isAlive())
99              {
100                 /*
101                  *  now the convenience, flip the 1st character
102                  */
103 
104                 char c = sb.charAt(3);
105 
106                 if (Character.isLowerCase(c))
107                 {
108                     sb.setCharAt(3, Character.toUpperCase(c));
109                 }
110                 else
111                 {
112                     sb.setCharAt(3, Character.toLowerCase(c));
113                 }
114 
115                 setMethod(introspector.getMethod(clazz, sb.toString(), params));
116             }
117         }
118         /**
119          * pass through application level runtime exceptions
120          */
121         catch( RuntimeException e )
122         {
123             throw e;
124         }
125         catch(Exception e)
126         {
127             log.error("While looking for property getter for '" + property + "':", e);
128         }
129     }
130 
131     /**
132      * @see org.apache.velocity.runtime.parser.node.AbstractExecutor#execute(java.lang.Object)
133      */
134     public Object execute(Object o)
135         throws IllegalAccessException,  InvocationTargetException
136     {
137         return isAlive() ? getMethod().invoke(o, ((Object []) null)) : null;
138     }
139 }