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