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