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    
020    import java.util.Map;
021    
022     /**
023     * Specialized executor to get a property from a Map.
024      * @since 2.0
025     */
026    public 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    }