001: package org.apache.velocity.runtime.parser.node;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.lang.reflect.InvocationTargetException;
023:
024: import org.apache.commons.lang.StringUtils;
025: import org.apache.velocity.runtime.RuntimeLogger;
026: import org.apache.velocity.runtime.log.Log;
027: import org.apache.velocity.runtime.log.RuntimeLoggerLog;
028: import org.apache.velocity.util.introspection.Introspector;
029:
030: /**
031: * Returned the value of object property when executed.
032: */
033: public class PropertyExecutor extends AbstractExecutor {
034: private final Introspector introspector;
035:
036: /**
037: * @param log
038: * @param introspector
039: * @param clazz
040: * @param property
041: */
042: public PropertyExecutor(final Log log,
043: final Introspector introspector, final Class clazz,
044: final String property) {
045: this .log = log;
046: this .introspector = introspector;
047:
048: // Don't allow passing in the empty string or null because
049: // it will either fail with a StringIndexOutOfBounds error
050: // or the introspector will get confused.
051: if (StringUtils.isNotEmpty(property)) {
052: discover(clazz, property);
053: }
054: }
055:
056: /**
057: * @param r
058: * @param introspector
059: * @param clazz
060: * @param property
061: * @deprecated RuntimeLogger is deprecated. Use the other constructor.
062: */
063: public PropertyExecutor(final RuntimeLogger r,
064: final Introspector introspector, final Class clazz,
065: final String property) {
066: this (new RuntimeLoggerLog(r), introspector, clazz, property);
067: }
068:
069: /**
070: * @return The current introspector.
071: */
072: protected Introspector getIntrospector() {
073: return this .introspector;
074: }
075:
076: /**
077: * @param clazz
078: * @param property
079: */
080: protected void discover(final Class clazz, final String property) {
081: /*
082: * this is gross and linear, but it keeps it straightforward.
083: */
084:
085: try {
086: Object[] params = {};
087:
088: StringBuffer sb = new StringBuffer("get");
089: sb.append(property);
090:
091: setMethod(introspector.getMethod(clazz, sb.toString(),
092: params));
093:
094: if (!isAlive()) {
095: /*
096: * now the convenience, flip the 1st character
097: */
098:
099: char c = sb.charAt(3);
100:
101: if (Character.isLowerCase(c)) {
102: sb.setCharAt(3, Character.toUpperCase(c));
103: } else {
104: sb.setCharAt(3, Character.toLowerCase(c));
105: }
106:
107: setMethod(introspector.getMethod(clazz, sb.toString(),
108: params));
109: }
110: }
111: /**
112: * pass through application level runtime exceptions
113: */
114: catch (RuntimeException e) {
115: throw e;
116: } catch (Exception e) {
117: log.error("While looking for property getter for '"
118: + property + "':", e);
119: }
120: }
121:
122: /**
123: * @see org.apache.velocity.runtime.parser.node.AbstractExecutor#execute(java.lang.Object)
124: */
125: public Object execute(Object o) throws IllegalAccessException,
126: InvocationTargetException {
127: return isAlive() ? getMethod().invoke(o, ((Object[]) null))
128: : null;
129: }
130: }
|