    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
    018package org.apache.commons.jexl3.internal.introspection;
    019
    020import java.lang.reflect.Field;
    021import org.apache.commons.jexl3.introspection.JexlPropertyGet;
    022
    023/**
    024 * A JexlPropertyGet for public fields.
    025 */
    026public final class FieldGetExecutor implements JexlPropertyGet {
    027    /**
    028     * The public field.
    029     */
    030    private final Field field;
    031
    032    /**
    033     * Attempts to discover a FieldGetExecutor.
    034     *
    035     * @param is the introspector
    036     * @param clazz the class to find the get method from
    037     * @param identifier the key to use as an argument to the get method
    038     * @return the executor if found, null otherwise
    039     */
    040    public static JexlPropertyGet discover(final Introspector is, final Class<?> clazz, final String identifier) {
    041        if (identifier != null) {
    042            final Field field = is.getField(clazz, identifier);
    043            if (field != null) {
    044                return new FieldGetExecutor(field);
    045            }
    046        }
    047        return null;
    048    }
    049    /**
    050     * Creates a new instance of FieldPropertyGet.
    051     * @param theField the class public field
    052     */
    053    private FieldGetExecutor(final Field theField) {
    054        field = theField;
    055    }
    056
    057    @Override
    058    public Object invoke(final Object obj) throws Exception {
    059        return field.get(obj);
    060    }
    061
    062    @Override
    063    public Object tryInvoke(final Object obj, final Object key) {
    064        if (obj.getClass().equals(field.getDeclaringClass()) && key.equals(field.getName())) {
    065            try {
    066                return field.get(obj);
    067            } catch (final IllegalAccessException xill) {
    068                return Uberspect.TRY_FAILED;
    069            }
    070        }
    071        return Uberspect.TRY_FAILED;
    072    }
    073
    074    @Override
    075    public boolean tryFailed(final Object rval) {
    076        return rval == Uberspect.TRY_FAILED;
    077    }
    078
    079    @Override
    080    public boolean isCacheable() {
    081        return true;
    082    }
    083
    084}