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 }