/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.model.hateoas;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.dspace.app.rest.model.RestModel;
import org.dspace.app.rest.utils.Utils;
import org.springframework.hateoas.Link;
import org.springframework.hateoas.ResourceSupport;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
/**
* A base class for DSpace Rest HAL Resource. The HAL Resource wraps the REST
* Resource adding support for the links and embedded resources. Each property
* of the wrapped REST resource is automatically translated in a link and the
* available information included as embedded resource
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*
*/
public abstract class DSpaceResource<T extends RestModel> extends ResourceSupport {
@JsonUnwrapped
private final T data;
@JsonProperty(value = "_embedded")
@JsonInclude(Include.NON_EMPTY)
private Map<String, Object> embedded = new HashMap<String, Object>();
public DSpaceResource(T data, Utils utils, String... rels) {
this.data = data;
if (data != null) {
try {
for (PropertyDescriptor pd : Introspector.getBeanInfo(data.getClass()).getPropertyDescriptors()) {
Method readMethod = pd.getReadMethod();
if (readMethod != null && !"class".equals(pd.getName())) {
if (RestModel.class.isAssignableFrom(readMethod.getReturnType())) {
this.add(utils.linkToSubResource(data, pd.getName()));
RestModel linkedObject = (RestModel) readMethod.invoke(data);
if (linkedObject != null) {
embedded.put(pd.getName(),
utils.getResourceRepository(linkedObject.getType()).wrapResource(linkedObject));
} else {
embedded.put(pd.getName(), null);
}
Method writeMethod = pd.getWriteMethod();
writeMethod.invoke(data, new Object[] { null });
}
}
}
} catch (IntrospectionException | IllegalArgumentException | IllegalAccessException
| InvocationTargetException e) {
throw new RuntimeException(e.getMessage(), e);
}
this.add(utils.linkToSingleResource(data, Link.REL_SELF));
}
}
public Map<String, Object> getEmbedded() {
return embedded;
}
public T getData() {
return data;
}
}