PropertyGetExecutor.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.apache.commons.jexl3.internal.introspection;
  18. import java.lang.reflect.InvocationTargetException;

  19. import org.apache.commons.jexl3.JexlException;

  20. /**
  21.  * Specialized executor to get a property from an object.
  22.  * @since 2.0
  23.  */
  24. public final class PropertyGetExecutor extends AbstractExecutor.Get {
  25.     /** A static signature for method(). */
  26.     private static final Object[] EMPTY_PARAMS = {};
  27.     /**
  28.      * Discovers a PropertyGetExecutor.
  29.      * <p>The method to be found should be named "get{P,p}property.</p>
  30.      *
  31.      * @param is the introspector
  32.      * @param clazz the class to find the get method from
  33.      * @param property the property name to find
  34.      * @return the executor if found, null otherwise
  35.      */
  36.     public static PropertyGetExecutor discover(final Introspector is, final Class<?> clazz, final String property) {
  37.         final java.lang.reflect.Method method = discoverGet(is, "get", clazz, property);
  38.         return method == null ? null : new PropertyGetExecutor(clazz, method, property);
  39.     }

  40.     /**
  41.      * Base method for boolean and object property get.
  42.      * @param is the introspector
  43.      * @param which "is" or "get" for boolean or object
  44.      * @param clazz The class being examined.
  45.      * @param property The property being addressed.
  46.      * @return The {get,is}{p,P}roperty method if one exists, null otherwise.
  47.      */
  48.     static java.lang.reflect.Method discoverGet(final Introspector is,
  49.                                                 final String which,
  50.                                                 final Class<?> clazz,
  51.                                                 final String property) {
  52.         if (property == null || property.isEmpty()) {
  53.             return null;
  54.         }
  55.         //  this is gross and linear, but it keeps it straightforward.
  56.         java.lang.reflect.Method method;
  57.         final int start = which.length(); // "get" or "is" so 3 or 2 for char case switch
  58.         // start with get<Property>
  59.         final StringBuilder sb = new StringBuilder(which);
  60.         sb.append(property);
  61.         // uppercase nth char
  62.         final char c = sb.charAt(start);
  63.         sb.setCharAt(start, Character.toUpperCase(c));
  64.         method = is.getMethod(clazz, sb.toString(), EMPTY_PARAMS);
  65.         //lowercase nth char
  66.         if (method == null) {
  67.             sb.setCharAt(start, Character.toLowerCase(c));
  68.             method = is.getMethod(clazz, sb.toString(), EMPTY_PARAMS);
  69.         }
  70.         return method;
  71.     }

  72.     /** The property. */
  73.     private final String property;

  74.     /**
  75.      * Creates an instance.
  76.      * @param clazz he class the get method applies to
  77.      * @param method the method held by this executor
  78.      * @param identifier the property to get
  79.      */
  80.     private PropertyGetExecutor(final Class<?> clazz, final java.lang.reflect.Method method, final String identifier) {
  81.         super(clazz, method);
  82.         property = identifier;
  83.     }

  84.     @Override
  85.     public Object getTargetProperty() {
  86.         return property;
  87.     }

  88.     @Override
  89.     public Object invoke(final Object o) throws IllegalAccessException, InvocationTargetException {
  90.         return method == null ? null : method.invoke(o, (Object[]) null);
  91.     }

  92.     @Override
  93.     public Object tryInvoke(final Object o, final Object identifier) {
  94.         if (o != null && method != null
  95.             && property.equals(castString(identifier))
  96.             && objectClass.equals(o.getClass())) {
  97.             try {
  98.                 return method.invoke(o, (Object[]) null);
  99.             } catch (IllegalAccessException | IllegalArgumentException xill) {
  100.                 return TRY_FAILED; // fail
  101.             } catch (final InvocationTargetException xinvoke) {
  102.                 throw JexlException.tryFailed(xinvoke); // throw
  103.             }
  104.         }
  105.         return TRY_FAILED;
  106.     }
  107. }