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

net.sf.cuf.model.MethodAccessAdapter Maven / Gradle / Ivy

The newest version!
package net.sf.cuf.model;

import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.util.StringTokenizer;

/**
 * This Adapter maps aspect names to a get/set method call.
 */
@SuppressWarnings({"StringContatenationInLoop"})
public class MethodAccessAdapter implements AspectAccessAdapter
{
    /** the getter methods to our aspect, never null, mGetMethods.length>0 */
    private Method[]       mGetMethods;
    /** the set method of our aspect, may be null if the aspect is not mutable */
    private Method         mSetMethod;

    /**
     * Creates a new adapter for a Map-based source.
     * @param pSourceClass the (base) class of the source
     * @param pAspectName the aspect name, may be separated by AspectAdapter.SEPARATOR
     */
    public MethodAccessAdapter(final Class pSourceClass, final String pAspectName)
    {
        // check args
        if (pSourceClass == null)
            throw new IllegalArgumentException("SourceClass must not be null");
        if (pAspectName == null)
            throw new IllegalArgumentException("AspectName must not be null");
        if (pAspectName.length() == 0)
            throw new IllegalArgumentException("AspectName must not be empty");

        // map attributes string to methods
        StringTokenizer st= new StringTokenizer(pAspectName, AspectAdapter.SEPARATOR);
        Class        sourceClass    = pSourceClass;
        Class        lastSourceClass= null;
        String          attribute      = null;
        mGetMethods= new Method[st.countTokens()];
        try
        {
            for (int i= 0; i< mGetMethods.length; i++ )
            {
                attribute= st.nextToken();
                String getterName= "get"+
                                   attribute.substring(0, 1).toUpperCase()+
                                   attribute.substring(1);
                Method getter;
                try
                {
                    getter = sourceClass.getMethod(getterName);
                }
                catch (NoSuchMethodException e)
                {
                    throw new IllegalArgumentException( "Class "+sourceClass+
                                                        " does not have a method "+
                                                        getterName+"()");
                }
                mGetMethods[i]= getter;
                lastSourceClass= sourceClass;
                sourceClass    = getter.getReturnType();
            }
            //noinspection ConstantConditions
            String setterName= "set"+
                               attribute.substring(0, 1).toUpperCase()+
                               attribute.substring(1);
            try
            {
                //noinspection ConstantConditions
                mSetMethod= lastSourceClass.getMethod(setterName, new Class[]{sourceClass});
            }
            catch (NoSuchMethodException e)
            {
                // immutable value
                mSetMethod= null;
            }
        }
        catch (Exception e)
        {
            // this will handle also some NPE's from above
            throw new IllegalArgumentException(e);
        }
    }

    /**
     * Tests if a call to setValue() makes sense.
     * @return false if we have no set method
     */
    public boolean isEditable()
    {
        return (mSetMethod!=null);
    }

    /**
     * Extract the value from the source.
     * @param pSource the source, may be null
     * @return null or the value
     */
    public Object getValue(final Object pSource)
    {
        if (pSource==null)
        {
            return null;
        }

        Object aspect= pSource;
        try
        {
            for (final Method getMethod : mGetMethods)
            {
                try
                {
                    aspect = getMethod.invoke(aspect);
                }
                catch (IllegalArgumentException e)
                {
                    throw new IllegalArgumentException("While invoking method " + getMethod +
                                               " on object of class " + aspect.getClass() + ": " +
                                               e.getMessage(), e);
                }
            }
        }
        catch (IllegalAccessException e)
        {
            // map e to a IllegalArgumentException
            throw new IllegalArgumentException(e.getMessage(), e);
        }
        catch (InvocationTargetException e)
        {
            // map the cause of e to a IllegalArgumentException, if it is
            // not a RuntimeException or an Error
            Throwable cause= e.getTargetException();

            if (cause instanceof RuntimeException)
            {
                throw (RuntimeException) cause;
            }
            if (cause instanceof Error)
            {
                throw (Error) cause;
            }

            throw new IllegalArgumentException(cause!=null ? cause.getMessage() : e.getMessage());
        }
        return aspect;
    }

    /**
     * Sets a value to the source.
     * @param pSource the source, never null
     * @param pValue the new value, may be null
     */
    public void setValue(final Object pSource, final Object pValue)
    {
        try
        {
            Object aspect= pSource;
            for (int i = 0; i < mGetMethods.length-1; i++)
            {
                Method getMethod= mGetMethods[i];
                aspect= getMethod.invoke(aspect);
            }
            mSetMethod.invoke(aspect, pValue);
        }
        catch (IllegalArgumentException e)
        {
            throw new IllegalArgumentException("Error while calling " + mSetMethod +
                                               " (setting value " + pValue + "): " +
                                               e.getMessage(), e);
        }
        catch (IllegalAccessException e)
        {
            // map e to a IllegalArgumentException
            throw new IllegalArgumentException(e.getMessage(), e);
        }
        catch (InvocationTargetException e)
        {
            // map the cause of e to a IllegalArgumentException, if it is
            // not a RuntimeException or an Error
            Throwable cause= e.getTargetException();

            if (cause instanceof RuntimeException)
            {
                throw (RuntimeException) cause;
            }
            if (cause instanceof Error)
            {
                throw (Error) cause;
            }
            IllegalArgumentException ex = new IllegalArgumentException(cause!=null ? cause.getMessage() : e.getMessage());
            if (cause!=null)
            {
                ex.initCause( cause);
            }
            throw ex;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy