All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazonaws.hal.client.MapBackedInvocationHandler Maven / Gradle / Ivy

/*
 * Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

package com.amazonaws.hal.client;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;

import static com.amazonaws.hal.client.ConversionUtil.convert;
import static com.amazonaws.hal.client.ConversionUtil.getPropertyName;


class MapBackedInvocationHandler
        implements InvocationHandler {

    //-------------------------------------------------------------
    // Variables - Private
    //-------------------------------------------------------------

    private Type type;
    private Map map;


    //-------------------------------------------------------------
    // Constructors
    //-------------------------------------------------------------

    MapBackedInvocationHandler(Type type, Map map) {
        this.type = type;
        this.map = map;
    }


    //-------------------------------------------------------------
    // Implementation - InvocationHandler
    //-------------------------------------------------------------

    /**
     */
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        if (method.getName().startsWith("get")) {
            String propertyName = getPropertyName(method.getName());
            Object property = map.get(propertyName);
            Type returnType = method.getGenericReturnType();

            // When a value is accessed, it's intended type can either be a
            // class or some other type (like a ParameterizedType).
            //
            // If the target type is a class and the value is of that type,
            // we return it.  If the value is not of that type, we convert
            // it and store the converted value (trusting it was converted
            // properly) back to the backing store.
            //
            // If the target type is not a class, it may be ParameterizedType
            // like List or Map.  We check if the value is already
            // a converting type and if so, we return it.  If the value is
            // not, we convert it and if it's now a converting type, we store
            // the new value in the backing store.

            if (returnType instanceof Class) {
                if (!((Class) returnType).isInstance(property)) {
                    property = convert(returnType, property);

                    //noinspection unchecked
                    map.put(propertyName, property);
                }
            } else {
                if (!(property instanceof ConvertingMap) && !(property instanceof ConvertingList)) {
                    property = convert(returnType, property);

                    if (property instanceof ConvertingMap || property instanceof ConvertingList) {
                        //noinspection unchecked
                        map.put(propertyName, property);
                    }
                }
            }

            return property;
        } else if (method.getName().equals("toString")) {
            return "Proxy for type: " + type;
        }
        // TODO: equals() and hashCode()?

        throw new UnsupportedOperationException("Don't know how to handle '" + method.getName() + "'");
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy