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.jexl2.internal;
019
020import java.util.Map;
021
022 /**
023 * Specialized executor to get a property from a Map.
024  * @since 2.0
025 */
026public final class MapGetExecutor extends AbstractExecutor.Get {
027    /** The java.util.map.get method used as an active marker in MapGet. */
028    private static final java.lang.reflect.Method MAP_GET =
029            initMarker(Map.class, "get", Object.class);
030    /** The property. */
031    private final Object property;
032
033    /**
034     * Creates an instance checking for the Map interface.
035     * @param is the introspector
036     * @param clazz the class that might implement the map interface
037     * @param key the key to use in map.get(key)
038     */
039    public MapGetExecutor(Introspector is, Class<?> clazz, Object key) {
040        super(clazz, discover(clazz));
041        property = key;
042    }
043
044    /** {@inheritDoc} */
045    @Override
046    public Object getTargetProperty() {
047        return property;
048    }
049    
050    /**
051     * Get the property from the map.
052     * @param obj the map.
053     * @return map.get(property)
054     */
055    @Override
056    public Object execute(final Object obj) {
057        @SuppressWarnings("unchecked") // ctor only allows Map instances - see discover() method
058        final Map<Object,?> map = (Map<Object, ?>) obj;
059        return map.get(property);
060    }
061
062    /** {@inheritDoc} */
063    @Override
064    public Object tryExecute(final Object obj, Object key) {
065        if (obj != null &&  method != null
066            && objectClass.equals(obj.getClass())
067            && (key == null || property.getClass().equals(key.getClass()))) {
068            @SuppressWarnings("unchecked") // ctor only allows Map instances - see discover() method
069            final Map<Object,?> map = (Map<Object, ?>) obj;
070            return map.get(key);
071        }
072        return TRY_FAILED;
073    }
074
075    /**
076     * Finds the method to perform 'get' on a map.
077     * @param clazz the class to introspect
078     * @return a marker method, map.get
079     */
080    static java.lang.reflect.Method discover(Class<?> clazz) {
081        return (Map.class.isAssignableFrom(clazz))? MAP_GET : null;
082    }
083}