se.l4.vibe.internal.service.ServiceImpl Maven / Gradle / Ivy
package se.l4.vibe.internal.service;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* Implementation of {@link Service} that uses reflection.
*
* @author Andreas Holstenson
*
*/
public class ServiceImpl
implements Service
{
private final Object object;
private final ConcurrentMap attributes;
public ServiceImpl(Object object)
{
this.object = object;
attributes = new ConcurrentHashMap();
buildAttributes(attributes, object.getClass());
}
private void buildAttributes(ConcurrentMap attributes, Class> type)
{
while(type != Object.class)
{
for(Field field : type.getDeclaredFields())
{
if(field.isAnnotationPresent(ExposeAsAttribute.class))
{
Attribute attr = new AttributeViaField(field);
if(attributes.containsKey(attr.getName()))
{
throw new IllegalArgumentException("Attribute named "
+ attr.getName() + " already exists; Declared via "
+ attributes.get(attr.getName()));
}
attributes.put(attr.getName(), attr);
}
}
for(Method method : type.getDeclaredMethods())
{
if(method.isAnnotationPresent(ExposeAsAttribute.class))
{
Attribute attr = new AttributeViaMethod(method);
if(attributes.containsKey(attr.getName()))
{
throw new IllegalArgumentException("Attribute named "
+ attr.getName() + " already exists; Declared via "
+ attributes.get(attr.getName()));
}
attributes.put(attr.getName(), attr);
}
}
type = type.getSuperclass();
}
}
@Override
public Collection getAttributes()
{
return attributes.values();
}
@Override
public Attribute getAttribute(String attribute)
{
return attributes.get(attribute);
}
private class AttributeViaField
implements Attribute
{
private final Field field;
private final String name;
public AttributeViaField(Field field)
{
this.field = field;
field.setAccessible(true);
ExposeAsAttribute annotation = field.getAnnotation(ExposeAsAttribute.class);
this.name = annotation.value().equals("") ? field.getName() : annotation.value();
}
@Override
public String getName()
{
return name;
}
@Override
public Class> getType()
{
return field.getType();
}
@Override
public Object getValue()
{
try
{
return field.get(object);
}
catch(IllegalArgumentException e)
{
throw new RuntimeException("Unable to get value of field " + field + "; " + e.getMessage(), e);
}
catch(IllegalAccessException e)
{
throw new RuntimeException("Unable to get value of field " + field + "; " + e.getMessage(), e);
}
}
@Override
public String toString()
{
return "AttributeViaField[" + field + "]";
}
}
private class AttributeViaMethod
implements Attribute
{
private final Method method;
private final String name;
public AttributeViaMethod(Method method)
{
this.method = method;
method.setAccessible(true);
if(method.getParameterTypes().length != 0)
{
throw new IllegalArgumentException("Method " + method + " must not have any parameters");
}
if(method.getReturnType() == void.class)
{
throw new IllegalArgumentException("Method " + method + " must not have a non void return type");
}
ExposeAsAttribute annotation = method.getAnnotation(ExposeAsAttribute.class);
this.name = annotation.value().equals("") ? method.getName() : annotation.value();
}
@Override
public String getName()
{
return name;
}
@Override
public Class> getType()
{
return method.getReturnType();
}
@Override
public Object getValue()
{
try
{
return method.invoke(object);
}
catch(IllegalArgumentException e)
{
throw new RuntimeException("Unable to get value; " + e.getMessage(), e);
}
catch(IllegalAccessException e)
{
throw new RuntimeException("Unable to get value; " + e.getMessage(), e);
}
catch(InvocationTargetException e)
{
throw new RuntimeException("Unable to get value; " + e.getCause().getMessage(), e.getCause());
}
}
@Override
public String toString()
{
return "AttributeViaMethod[" + method + "]";
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy