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 }