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 018 package org.apache.commons.jexl2.internal; 019 import java.lang.reflect.InvocationTargetException; 020 021 /** 022 * Specialized executor to get a property from an object. 023 * @since 2.0 024 */ 025 public final class PropertyGetExecutor extends AbstractExecutor.Get { 026 /** A static signature for method(). */ 027 private static final Object[] EMPTY_PARAMS = {}; 028 /** The property. */ 029 private final String property; 030 031 /** 032 * Creates an instance by attempting discovery of the get method. 033 * @param is the introspector 034 * @param clazz the class to introspect 035 * @param identifier the property to get 036 */ 037 public PropertyGetExecutor(Introspector is, Class<?> clazz, String identifier) { 038 super(clazz, discover(is, clazz, identifier)); 039 property = identifier; 040 } 041 042 /** {@inheritDoc} */ 043 @Override 044 public Object getTargetProperty() { 045 return property; 046 } 047 048 /** {@inheritDoc} */ 049 @Override 050 public Object execute(Object o) 051 throws IllegalAccessException, InvocationTargetException { 052 return method == null ? null : method.invoke(o, (Object[]) null); 053 } 054 055 /** {@inheritDoc} */ 056 @Override 057 public Object tryExecute(Object o, Object identifier) { 058 if (o != null && method != null 059 && property.equals(identifier) 060 && objectClass.equals(o.getClass())) { 061 try { 062 return method.invoke(o, (Object[]) null); 063 } catch (InvocationTargetException xinvoke) { 064 return TRY_FAILED; // fail 065 } catch (IllegalAccessException xill) { 066 return TRY_FAILED;// fail 067 } 068 } 069 return TRY_FAILED; 070 } 071 072 /** 073 * Discovers the method for a {@link PropertyGet}. 074 * <p>The method to be found should be named "get{P,p}property.</p> 075 *@param is the introspector 076 *@param clazz the class to find the get method from 077 *@param property the property name to find 078 *@return the method if found, null otherwise 079 */ 080 static java.lang.reflect.Method discover(Introspector is, 081 final Class<?> clazz, String property) { 082 return discoverGet(is, "get", clazz, property); 083 } 084 085 086 /** 087 * Base method for boolean & object property get. 088 * @param is the introspector 089 * @param which "is" or "get" for boolean or object 090 * @param clazz The class being examined. 091 * @param property The property being addressed. 092 * @return The {get,is}{p,P}roperty method if one exists, null otherwise. 093 */ 094 static java.lang.reflect.Method discoverGet(Introspector is, 095 String which, Class<?> clazz, String property) { 096 // this is gross and linear, but it keeps it straightforward. 097 java.lang.reflect.Method method = null; 098 final int start = which.length(); // "get" or "is" so 3 or 2 for char case switch 099 // start with get<Property> 100 StringBuilder sb = new StringBuilder(which); 101 sb.append(property); 102 // uppercase nth char 103 char c = sb.charAt(start); 104 sb.setCharAt(start, Character.toUpperCase(c)); 105 method = is.getMethod(clazz, sb.toString(), EMPTY_PARAMS); 106 //lowercase nth char 107 if (method == null) { 108 sb.setCharAt(start, Character.toLowerCase(c)); 109 method = is.getMethod(clazz, sb.toString(), EMPTY_PARAMS); 110 } 111 return method; 112 } 113 } 114