Package com.theoryinpractise.halbuilder.impl.bytecode

Source Code of com.theoryinpractise.halbuilder.impl.bytecode.InterfaceRenderer

package com.theoryinpractise.halbuilder.impl.bytecode;

import com.google.common.base.Preconditions;
import com.theoryinpractise.halbuilder.api.ReadableRepresentation;
import com.theoryinpractise.halbuilder.api.RepresentationException;

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

import static com.theoryinpractise.halbuilder.impl.bytecode.InterfaceSupport.derivePropertyNameFromMethod;

/**
* Java Interface based "renderer", this will write the resource as a Proxy to a Java interface.
*/
public class InterfaceRenderer<T> {

    private Class<T> anInterface;

    public static <I> InterfaceRenderer<I> newInterfaceRenderer(Class<I> anInterface) {
        return new InterfaceRenderer<I>(anInterface);
    }

    private InterfaceRenderer(Class<T> anInterface) {
        Preconditions.checkArgument(anInterface.isInterface(), "Provided class MUST be an interface.");
        this.anInterface = anInterface;
    }

    public T render(final ReadableRepresentation representation) {
        return render(representation.getProperties());
    }

    public T render(final Map<String, Object> properties) {
        if (InterfaceContract.newInterfaceContract(anInterface).isSatisfiedBy(properties)) {
            T proxy = (T) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {anInterface}, new InvocationHandler() {
                public Object invoke(Object o, Method method, Object[] objects) throws Throwable {

                    String propertyName = derivePropertyNameFromMethod(method);


                    Object propertyValue = properties.get(propertyName);

                    Class<?> returnType = method.getReturnType();

                    Object returnValue;

                    if (propertyValue != null) {
                        returnValue = returnType.getConstructor(propertyValue.getClass()).newInstance(propertyValue);
                    } else {
                        // In this case, we have a null property.
                        returnValue = null;
                    }

                    return returnValue;
                }
            });
            return proxy;
        } else {
            throw new RepresentationException("Unable to write representation to " + anInterface.getName());
        }
    }
}
TOP

Related Classes of com.theoryinpractise.halbuilder.impl.bytecode.InterfaceRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.