use of org.apache.stanbol.enhancer.rdfentities.Rdf in project stanbol by apache.
the class RdfProxyInvocationHandler method invoke.
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//RdfEntity rdfEntity;
if (!(proxy instanceof RdfEntity)) {
throw new IllegalArgumentException("Parsed proxy instance is not of type " + RdfEntity.class + ". This RdfWrapperInvocationHandler implementations only work for proxies implementing this interface!");
}
//implementation of the RffEntity Interface method!
if (method.equals(getIDMethod)) {
return rdfNode;
}
//implement toString
if (method.equals(equals)) {
return args[0] != null && args[0] instanceof RdfEntity && ((RdfEntity) args[0]).getId().equals(rdfNode);
}
//implement hashCode
if (method.equals(hashCode)) {
return rdfNode.toString().hashCode();
}
//implement toString
if (method.equals(toString)) {
return "Proxy for Node " + rdfNode + " and interfaces " + interfaces;
}
Rdf rdf = method.getAnnotation(Rdf.class);
if (rdf == null) {
throw new IllegalStateException("Invoked Method does not have an Rdf annotation!");
}
IRI property;
if (rdf.id().startsWith("http://") || rdf.id().startsWith("urn:")) {
property = new IRI(rdf.id());
} else {
throw new IllegalStateException("The id=\"" + rdf.id() + "\"provided by the rdf annotation is not an valid URI");
}
//check for Write (Setter) Method
if (method.getReturnType().equals(void.class)) {
Type[] parameterTypes = method.getGenericParameterTypes();
//Only methods with a single parameter are supported
if (parameterTypes.length != 1) {
throw new IllegalStateException("Unsupported parameters for Method " + method.toString() + "! Only setter methodes with a singe parameter are supported.");
}
final Type parameterType = parameterTypes[0];
//now check if args != null and has an element
if (args == null) {
throw new IllegalArgumentException("NULL parsed as \"Object[] args\". An array with a single value is expected when calling " + method.toString() + "!");
}
if (args.length < 1) {
throw new IllegalArgumentException("An empty array was parsed as \"Object[] args\". An array with a single value is expected when calling method " + method.toString() + "!");
}
final Object value = args[0];
//Handle Arrays
if (parameterType instanceof Class<?> && ((Class<?>) parameterType).isArray()) {
throw new IllegalStateException("No support for Arrays right now. Use " + Collection.class + " instead");
}
//if null is parsed as value we need to delete all values
if (value == null) {
removeValues(property);
//setter methods are void -> return null
return null;
}
//if a collection is parsed we need to check the generic type
if (Collection.class.isAssignableFrom(value.getClass())) {
Type genericType = null;
if (parameterTypes[0] instanceof ParameterizedType) {
for (Type typeArgument : ((ParameterizedType) parameterTypes[0]).getActualTypeArguments()) {
if (genericType == null) {
genericType = typeArgument;
} else {
//TODO: replace with a warning but for testing start with an exception
throw new IllegalStateException("Multiple generic type definition for method " + method.toString() + " (generic types: " + ((ParameterizedType) parameterTypes[0]).getActualTypeArguments() + ")");
}
}
}
setValues(property, (Collection<?>) value);
return null;
} else {
setValue(property, value);
return null;
}
} else {
//assume an read (getter) method
Class<?> returnType = method.getReturnType();
if (Collection.class.isAssignableFrom(returnType)) {
Type genericType = null;
Type genericReturnType = method.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType) {
ParameterizedType type = (ParameterizedType) genericReturnType;
for (Type typeArgument : type.getActualTypeArguments()) {
if (genericType == null) {
genericType = typeArgument;
} else {
//TODO: replace with a warning but for testing start with an exception
throw new IllegalStateException("Multiple generic type definition for method " + method.toString() + " (generic types: " + type.getActualTypeArguments() + ")");
}
}
}
if (genericType == null) {
throw new IllegalStateException("Generic Type not defined for Collection in Method " + method.toString() + " (generic type is needed to correctly map rdf values for property " + property);
}
return getValues(property, (Class<?>) genericType);
} else {
return getValue(property, returnType);
}
}
}
Aggregations