001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.jexl2.internal;
018
019 import java.lang.reflect.InvocationTargetException;
020
021 /**
022 * Specialized executor to get a property from an object.
023 * <p>Duck as in duck-typing for an interface like:
024 * <code>
025 * interface Get {
026 * Object get(Object key);
027 * }
028 * </code>
029 * </p>
030 * @since 2.0
031 */
032 public final class DuckGetExecutor extends AbstractExecutor.Get {
033 /** The property. */
034 private final Object property;
035
036 /**
037 * Creates an instance by attempting discovery of the get method.
038 * @param is the introspector
039 * @param clazz the class to introspect
040 * @param identifier the property to get
041 */
042 public DuckGetExecutor(Introspector is, Class<?> clazz, Object identifier) {
043 super(clazz, discover(is, clazz, identifier));
044 property = identifier;
045 }
046
047 /** {@inheritDoc} */
048 @Override
049 public Object getTargetProperty() {
050 return property;
051 }
052
053 /**
054 * Get the property from the object.
055 * @param obj the object.
056 * @return object.get(property)
057 * @throws IllegalAccessException Method is inaccessible.
058 * @throws InvocationTargetException Method body throws an exception.
059 */
060 @Override
061 public Object execute(Object obj)
062 throws IllegalAccessException, InvocationTargetException {
063 Object[] args = {property};
064 return method == null ? null : method.invoke(obj, args);
065 }
066
067 /** {@inheritDoc} */
068 @Override
069 public Object tryExecute(Object obj, Object key) {
070 if (obj != null && method != null
071 // ensure method name matches the property name
072 && property.equals(key)
073 && objectClass.equals(obj.getClass())) {
074 try {
075 Object[] args = {property};
076 return method.invoke(obj, args);
077 } catch (InvocationTargetException xinvoke) {
078 return TRY_FAILED; // fail
079 } catch (IllegalAccessException xill) {
080 return TRY_FAILED;// fail
081 }
082 }
083 return TRY_FAILED;
084 }
085
086 /**
087 * Discovers a method for a {@link GetExecutor.DuckGet}.
088 *@param is the introspector
089 *@param clazz the class to find the get method from
090 *@param identifier the key to use as an argument to the get method
091 *@return the method if found, null otherwise
092 */
093 private static java.lang.reflect.Method discover(Introspector is,
094 final Class<?> clazz, Object identifier) {
095 return is.getMethod(clazz, "get", makeArgs(identifier));
096 }
097 }