separate the DirectlyAddressableRestModel from the base RestModel

This commit is contained in:
Andrea Bollini
2017-11-14 18:34:23 +01:00
parent 6e3395a997
commit 84f0810fc7
31 changed files with 138 additions and 101 deletions

View File

@@ -30,6 +30,7 @@ import org.dspace.app.rest.exception.RepositorySearchMethodNotFoundException;
import org.dspace.app.rest.exception.RepositorySearchNotFoundException; import org.dspace.app.rest.exception.RepositorySearchNotFoundException;
import org.dspace.app.rest.model.LinkRest; import org.dspace.app.rest.model.LinkRest;
import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.RestModel;
import org.dspace.app.rest.model.DirectlyAddressableRestModel;
import org.dspace.app.rest.model.hateoas.DSpaceResource; import org.dspace.app.rest.model.hateoas.DSpaceResource;
import org.dspace.app.rest.model.hateoas.EmbeddedPage; import org.dspace.app.rest.model.hateoas.EmbeddedPage;
import org.dspace.app.rest.repository.DSpaceRestRepository; import org.dspace.app.rest.repository.DSpaceRestRepository;
@@ -108,30 +109,30 @@ public class RestResourceController implements InitializingBean {
@RequestMapping(method = RequestMethod.GET, value = "/{id:\\d+}") @RequestMapping(method = RequestMethod.GET, value = "/{id:\\d+}")
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public DSpaceResource<RestModel> findOne(@PathVariable String apiCategory, @PathVariable String model, public DSpaceResource<DirectlyAddressableRestModel> findOne(@PathVariable String apiCategory, @PathVariable String model,
@PathVariable Integer id, @RequestParam(required = false) String projection) { @PathVariable Integer id, @RequestParam(required = false) String projection) {
return findOneInternal(apiCategory, model, id, projection); return findOneInternal(apiCategory, model, id, projection);
} }
@RequestMapping(method = RequestMethod.GET, value = "/{id:^(?!^\\d+$)[A-z0-9]+$+}") @RequestMapping(method = RequestMethod.GET, value = "/{id:^(?!^\\d+$)[A-z0-9]+$+}")
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public DSpaceResource<RestModel> findOne(@PathVariable String apiCategory, @PathVariable String model, public DSpaceResource<DirectlyAddressableRestModel> findOne(@PathVariable String apiCategory, @PathVariable String model,
@PathVariable String id, @RequestParam(required = false) String projection) { @PathVariable String id, @RequestParam(required = false) String projection) {
return findOneInternal(apiCategory, model, id, projection); return findOneInternal(apiCategory, model, id, projection);
} }
@RequestMapping(method = RequestMethod.GET, value = "/{uuid:[0-9a-fxA-FX]{8}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{12}}") @RequestMapping(method = RequestMethod.GET, value = "/{uuid:[0-9a-fxA-FX]{8}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{4}-[0-9a-fxA-FX]{12}}")
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public DSpaceResource<RestModel> findOne(@PathVariable String apiCategory, @PathVariable String model, public DSpaceResource<DirectlyAddressableRestModel> findOne(@PathVariable String apiCategory, @PathVariable String model,
@PathVariable UUID uuid, @RequestParam(required = false) String projection) { @PathVariable UUID uuid, @RequestParam(required = false) String projection) {
return findOneInternal(apiCategory, model, uuid, projection); return findOneInternal(apiCategory, model, uuid, projection);
} }
private <ID extends Serializable> DSpaceResource<RestModel> findOneInternal(String apiCategory, String model, ID id, private <ID extends Serializable> DSpaceResource<DirectlyAddressableRestModel> findOneInternal(String apiCategory, String model, ID id,
String projection) { String projection) {
checkModelPluralForm(apiCategory, model); checkModelPluralForm(apiCategory, model);
DSpaceRestRepository<RestModel, ID> repository = utils.getResourceRepository(apiCategory, model); DSpaceRestRepository<DirectlyAddressableRestModel, ID> repository = utils.getResourceRepository(apiCategory, model);
RestModel modelObject = null; DirectlyAddressableRestModel modelObject = null;
try { try {
modelObject = repository.findOne(id); modelObject = repository.findOne(id);
} catch (ClassCastException e) { } catch (ClassCastException e) {
@@ -181,8 +182,8 @@ public class RestResourceController implements InitializingBean {
public <ID extends Serializable> ResponseEntity<ResourceSupport> postInternal(HttpServletRequest request, String apiCategory, public <ID extends Serializable> ResponseEntity<ResourceSupport> postInternal(HttpServletRequest request, String apiCategory,
String model) throws HttpRequestMethodNotSupportedException { String model) throws HttpRequestMethodNotSupportedException {
checkModelPluralForm(apiCategory, model); checkModelPluralForm(apiCategory, model);
DSpaceRestRepository<RestModel, ID> repository = utils.getResourceRepository(apiCategory, model); DSpaceRestRepository<DirectlyAddressableRestModel, ID> repository = utils.getResourceRepository(apiCategory, model);
RestModel modelObject = null; DirectlyAddressableRestModel modelObject = null;
try { try {
modelObject = repository.createAndReturn(); modelObject = repository.createAndReturn();
} catch (ClassCastException e) { } catch (ClassCastException e) {
@@ -215,7 +216,7 @@ public class RestResourceController implements InitializingBean {
private <ID extends Serializable> List<Serializable> uploadInternal(HttpServletRequest request, String apiCategory, String model, ID id, private <ID extends Serializable> List<Serializable> uploadInternal(HttpServletRequest request, String apiCategory, String model, ID id,
String extraField, MultipartFile... uploadfiles) { String extraField, MultipartFile... uploadfiles) {
DSpaceRestRepository<RestModel, ID> repository = utils.getResourceRepository(apiCategory, model); DSpaceRestRepository<DirectlyAddressableRestModel, ID> repository = utils.getResourceRepository(apiCategory, model);
// Get file name // Get file name
// String uploadedFileName = Arrays.stream(uploadfiles).map(x -> x.getOriginalFilename()) // String uploadedFileName = Arrays.stream(uploadfiles).map(x -> x.getOriginalFilename())
@@ -256,8 +257,8 @@ public class RestResourceController implements InitializingBean {
private <ID extends Serializable> ResourceSupport findRelEntryInternal(HttpServletRequest request, String apiCategory, String model, private <ID extends Serializable> ResourceSupport findRelEntryInternal(HttpServletRequest request, String apiCategory, String model,
String id, String rel, String relid, Pageable page, PagedResourcesAssembler assembler, String projection) { String id, String rel, String relid, Pageable page, PagedResourcesAssembler assembler, String projection) {
checkModelPluralForm(apiCategory, model); checkModelPluralForm(apiCategory, model);
DSpaceRestRepository<RestModel, ID> repository = utils.getResourceRepository(apiCategory, model); DSpaceRestRepository<DirectlyAddressableRestModel, ID> repository = utils.getResourceRepository(apiCategory, model);
Class<RestModel> domainClass = repository.getDomainClass(); Class<DirectlyAddressableRestModel> domainClass = repository.getDomainClass();
LinkRest linkRest = utils.getLinkRest(rel, domainClass); LinkRest linkRest = utils.getLinkRest(rel, domainClass);
if (linkRest != null) { if (linkRest != null) {
@@ -270,7 +271,7 @@ public class RestResourceController implements InitializingBean {
.slash(rel).withSelfRel(); .slash(rel).withSelfRel();
List result = new ArrayList(); List result = new ArrayList();
result.add(object); result.add(object);
PageImpl<RestModel> pageResult = new PageImpl(result, page, 1); PageImpl<DirectlyAddressableRestModel> pageResult = new PageImpl(result, page, 1);
return assembler.toResource(pageResult.map(linkRepository::wrapResource),link); return assembler.toResource(pageResult.map(linkRepository::wrapResource),link);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e.getMessage(), e); throw new RuntimeException(e.getMessage(), e);
@@ -282,8 +283,8 @@ public class RestResourceController implements InitializingBean {
private <ID extends Serializable> ResourceSupport findRelInternal(HttpServletRequest request, String apiCategory, private <ID extends Serializable> ResourceSupport findRelInternal(HttpServletRequest request, String apiCategory,
String model, ID uuid, String rel, Pageable page, PagedResourcesAssembler assembler, String projection) { String model, ID uuid, String rel, Pageable page, PagedResourcesAssembler assembler, String projection) {
checkModelPluralForm(apiCategory, model); checkModelPluralForm(apiCategory, model);
DSpaceRestRepository<RestModel, ID> repository = utils.getResourceRepository(apiCategory, model); DSpaceRestRepository<DirectlyAddressableRestModel, ID> repository = utils.getResourceRepository(apiCategory, model);
Class<RestModel> domainClass = repository.getDomainClass(); Class<DirectlyAddressableRestModel> domainClass = repository.getDomainClass();
LinkRest linkRest = utils.getLinkRest(rel, domainClass); LinkRest linkRest = utils.getLinkRest(rel, domainClass);
@@ -298,7 +299,7 @@ public class RestResourceController implements InitializingBean {
else { else {
try { try {
if ( Page.class.isAssignableFrom( linkMethod.getReturnType()) ){ if ( Page.class.isAssignableFrom( linkMethod.getReturnType()) ){
Page<? extends Serializable> pageResult = (Page<? extends RestModel>) linkMethod Page<? extends RestModel> pageResult = (Page<? extends DirectlyAddressableRestModel>) linkMethod
.invoke(linkRepository, request, uuid, page, projection); .invoke(linkRepository, request, uuid, page, projection);
Link link = linkTo(this.getClass(), apiCategory, model).slash(uuid) Link link = linkTo(this.getClass(), apiCategory, model).slash(uuid)
.slash(rel).withSelfRel(); .slash(rel).withSelfRel();
@@ -307,7 +308,7 @@ public class RestResourceController implements InitializingBean {
return result; return result;
} }
else { else {
Serializable object = (Serializable) linkMethod.invoke(linkRepository, request, uuid, page, RestModel object = (RestModel) linkMethod.invoke(linkRepository, request, uuid, page,
projection); projection);
Link link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(rel) Link link = linkTo(this.getClass(), apiCategory, model).slash(uuid).slash(rel)
.withSelfRel(); .withSelfRel();
@@ -320,7 +321,7 @@ public class RestResourceController implements InitializingBean {
} }
} }
} }
RestModel modelObject = repository.findOne(uuid); DirectlyAddressableRestModel modelObject = repository.findOne(uuid);
DSpaceResource result = repository.wrapResource(modelObject, rel); DSpaceResource result = repository.wrapResource(modelObject, rel);
if (result.getLink(rel) == null) { if (result.getLink(rel) == null) {
// TODO create a custom exception // TODO create a custom exception
@@ -333,14 +334,14 @@ public class RestResourceController implements InitializingBean {
// if we really want to implement pagination we should implement a // if we really want to implement pagination we should implement a
// link repository so to fall in the previous block code // link repository so to fall in the previous block code
EmbeddedPage ep = (EmbeddedPage) result.getEmbedded().get(rel); EmbeddedPage ep = (EmbeddedPage) result.getEmbedded().get(rel);
List<? extends RestModel> fullList = ep.getFullList(); List<? extends DirectlyAddressableRestModel> fullList = ep.getFullList();
if (fullList == null || fullList.size() == 0) if (fullList == null || fullList.size() == 0)
return null; return null;
int start = page.getOffset(); int start = page.getOffset();
int end = (start + page.getPageSize()) > fullList.size() ? fullList.size() : (start + page.getPageSize()); int end = (start + page.getPageSize()) > fullList.size() ? fullList.size() : (start + page.getPageSize());
DSpaceRestRepository<RestModel, ?> resourceRepository = utils DSpaceRestRepository<DirectlyAddressableRestModel, ?> resourceRepository = utils
.getResourceRepository(fullList.get(0).getCategory(), fullList.get(0).getType()); .getResourceRepository(fullList.get(0).getCategory(), fullList.get(0).getType());
PageImpl<RestModel> pageResult = new PageImpl(fullList.subList(start, end), page, fullList.size()); PageImpl<DirectlyAddressableRestModel> pageResult = new PageImpl(fullList.subList(start, end), page, fullList.size());
return assembler.toResource(pageResult.map(resourceRepository::wrapResource)); return assembler.toResource(pageResult.map(resourceRepository::wrapResource));
} else { } else {
ResourceSupport resu = (ResourceSupport) result.getEmbedded().get(rel); ResourceSupport resu = (ResourceSupport) result.getEmbedded().get(rel);
@@ -350,7 +351,7 @@ public class RestResourceController implements InitializingBean {
@RequestMapping(method = RequestMethod.GET) @RequestMapping(method = RequestMethod.GET)
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends RestModel> PagedResources<DSpaceResource<T>> findAll(@PathVariable String apiCategory, public <T extends DirectlyAddressableRestModel> PagedResources<DSpaceResource<T>> findAll(@PathVariable String apiCategory,
@PathVariable String model, Pageable page, PagedResourcesAssembler assembler, @PathVariable String model, Pageable page, PagedResourcesAssembler assembler,
@RequestParam(required = false) String projection) { @RequestParam(required = false) String projection) {
DSpaceRestRepository<T, ?> repository = utils.getResourceRepository(apiCategory, model); DSpaceRestRepository<T, ?> repository = utils.getResourceRepository(apiCategory, model);
@@ -402,7 +403,7 @@ public class RestResourceController implements InitializingBean {
@RequestMapping(method = RequestMethod.GET, value = "/search/{searchMethodName}") @RequestMapping(method = RequestMethod.GET, value = "/search/{searchMethodName}")
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends RestModel> ResourceSupport executeSearchMethods(@PathVariable String apiCategory, public <T extends DirectlyAddressableRestModel> ResourceSupport executeSearchMethods(@PathVariable String apiCategory,
@PathVariable String model, @PathVariable String searchMethodName, Pageable pageable, Sort sort, @PathVariable String model, @PathVariable String searchMethodName, Pageable pageable, Sort sort,
PagedResourcesAssembler assembler, @RequestParam MultiValueMap<String, Object> parameters) PagedResourcesAssembler assembler, @RequestParam MultiValueMap<String, Object> parameters)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {

View File

@@ -10,8 +10,6 @@ package org.dspace.app.rest.model;
import java.util.Date; import java.util.Date;
import java.util.UUID; import java.util.UUID;
import org.dspace.app.rest.RestResourceController;
/** /**
* The Access Condition (ResourcePolicy) REST Resource * The Access Condition (ResourcePolicy) REST Resource
* *
@@ -20,7 +18,7 @@ import org.dspace.app.rest.RestResourceController;
*/ */
public class AccessConditionOptionRest { public class AccessConditionOptionRest {
private String type; private String policyType;
private UUID groupUUID; private UUID groupUUID;
@@ -38,8 +36,8 @@ public class AccessConditionOptionRest {
this.groupUUID = groupUuid; this.groupUUID = groupUuid;
} }
public void setType(String type) { public void setPolicyType(String type) {
this.type = type; this.policyType = type;
} }
public UUID getSelectGroupUUID() { public UUID getSelectGroupUUID() {
@@ -66,8 +64,8 @@ public class AccessConditionOptionRest {
this.maxEndDate = maxEndDate; this.maxEndDate = maxEndDate;
} }
public String getType() { public String getPolicyType() {
return type; return policyType;
} }
} }

View File

@@ -18,7 +18,7 @@ import java.util.UUID;
* @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it)
* *
*/ */
public class AccessConditionRest implements Serializable { public class AccessConditionRest implements RestModel {
public static final String NAME = "accessCondition"; public static final String NAME = "accessCondition";
@@ -47,5 +47,13 @@ public class AccessConditionRest implements Serializable {
public void setPolicyType(String type) { public void setPolicyType(String type) {
this.policyType = type; this.policyType = type;
} }
public String getPolicyType() {
return policyType;
}
@Override
public String getType() {
return NAME;
}
} }

View File

@@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
* @author Andrea Bollini (andrea.bollini at 4science.it) * @author Andrea Bollini (andrea.bollini at 4science.it)
* *
*/ */
public class AuthorityEntryRest implements RestModel { public class AuthorityEntryRest implements DirectlyAddressableRestModel {
public static final String NAME = "authorityEntry"; public static final String NAME = "authorityEntry";
private String id; private String id;
private String display; private String display;

View File

@@ -22,7 +22,7 @@ import org.dspace.app.rest.RestResourceController;
public class AuthorityRest extends BaseObjectRest<String> { public class AuthorityRest extends BaseObjectRest<String> {
public static final String NAME = "authority"; public static final String NAME = "authority";
public static final String CATEGORY = RestModel.INTEGRATION; public static final String CATEGORY = DirectlyAddressableRestModel.INTEGRATION;
public static final String ENTRIES = "entries"; public static final String ENTRIES = "entries";
public static final String ENTRY = "entryValues"; public static final String ENTRY = "entryValues";

View File

@@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
* @param <T> * @param <T>
* the class of the resource identifier * the class of the resource identifier
*/ */
public abstract class BaseObjectRest<T extends Serializable> implements Identifiable<T>, RestModel { public abstract class BaseObjectRest<T extends Serializable> implements Identifiable<T>, DirectlyAddressableRestModel {
protected T id; protected T id;

View File

@@ -22,7 +22,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
public class BitstreamFormatRest extends BaseObjectRest<Integer> { public class BitstreamFormatRest extends BaseObjectRest<Integer> {
public static final String NAME = "bitstreamformat"; public static final String NAME = "bitstreamformat";
public static final String CATEGORY = RestModel.CORE; public static final String CATEGORY = DirectlyAddressableRestModel.CORE;
private String shortDescription; private String shortDescription;

View File

@@ -18,7 +18,7 @@ import com.fasterxml.jackson.annotation.JsonProperty.Access;
public class BitstreamRest extends DSpaceObjectRest { public class BitstreamRest extends DSpaceObjectRest {
public static final String PLURAL_NAME = "bitstreams"; public static final String PLURAL_NAME = "bitstreams";
public static final String NAME = "bitstream"; public static final String NAME = "bitstream";
public static final String CATEGORY = RestModel.CORE; public static final String CATEGORY = DirectlyAddressableRestModel.CORE;
private String bundleName; private String bundleName;
// avoid to serialize this object inline as we want a full resource embedded // avoid to serialize this object inline as we want a full resource embedded

View File

@@ -17,7 +17,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
* @author Andrea Bollini (andrea.bollini at 4science.it) * @author Andrea Bollini (andrea.bollini at 4science.it)
* *
*/ */
public class BrowseEntryRest implements Serializable { public class BrowseEntryRest implements RestModel {
private static final long serialVersionUID = -3415049466402327251L; private static final long serialVersionUID = -3415049466402327251L;
public static final String NAME = "browseEntry"; public static final String NAME = "browseEntry";
private String authority; private String authority;
@@ -67,4 +67,9 @@ public class BrowseEntryRest implements Serializable {
public void setBrowseIndex(BrowseIndexRest browseIndex) { public void setBrowseIndex(BrowseIndexRest browseIndex) {
this.browseIndex = browseIndex; this.browseIndex = browseIndex;
} }
@Override
public String getType() {
return NAME;
}
} }

View File

@@ -29,7 +29,7 @@ public class BrowseIndexRest extends BaseObjectRest<String> {
public static final String NAME = "browse"; public static final String NAME = "browse";
public static final String CATEGORY = RestModel.DISCOVER; public static final String CATEGORY = DirectlyAddressableRestModel.DISCOVER;
public static final String ITEMS = "items"; public static final String ITEMS = "items";
public static final String ENTRIES = "entries"; public static final String ENTRIES = "entries";

View File

@@ -23,7 +23,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
}) })
public class CollectionRest extends DSpaceObjectRest { public class CollectionRest extends DSpaceObjectRest {
public static final String NAME = "collection"; public static final String NAME = "collection";
public static final String CATEGORY = RestModel.CORE; public static final String CATEGORY = DirectlyAddressableRestModel.CORE;
public static final String LICENSE = "license"; public static final String LICENSE = "license";
public static final String DEFAULT_ACCESS_CONDITIONS = "defaultAccessConditions"; public static final String DEFAULT_ACCESS_CONDITIONS = "defaultAccessConditions";
@JsonIgnore @JsonIgnore

View File

@@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
*/ */
public class CommunityRest extends DSpaceObjectRest { public class CommunityRest extends DSpaceObjectRest {
public static final String NAME = "community"; public static final String NAME = "community";
public static final String CATEGORY = RestModel.CORE; public static final String CATEGORY = DirectlyAddressableRestModel.CORE;
@JsonIgnore @JsonIgnore
private BitstreamRest logo; private BitstreamRest logo;

View File

@@ -0,0 +1,31 @@
/**
* 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;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* A directly addressable REST resource
*
* @author Andrea Bollini (andrea.bollini at 4science.it)
*
*/
public interface DirectlyAddressableRestModel extends RestModel {
public static final String CORE = "core";
public static final String EPERSON = "eperson";
public static final String DISCOVER = "discover";
public static final String CONFIGURATION = "config";
public static final String INTEGRATION = "integration";
public static final String SUBMISSION = "submission";
@JsonIgnore
public String getCategory();
@JsonIgnore
public Class getController();
}

View File

@@ -20,7 +20,7 @@ import org.dspace.app.rest.RestResourceController;
*/ */
public class EPersonRest extends DSpaceObjectRest { public class EPersonRest extends DSpaceObjectRest {
public static final String NAME = "eperson"; public static final String NAME = "eperson";
public static final String CATEGORY = RestModel.EPERSON; public static final String CATEGORY = DirectlyAddressableRestModel.EPERSON;
private String netid; private String netid;
private Date lastActive; private Date lastActive;

View File

@@ -22,7 +22,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
public class GroupRest extends DSpaceObjectRest { public class GroupRest extends DSpaceObjectRest {
public static final String NAME = "group"; public static final String NAME = "group";
public static final String CATEGORY = RestModel.EPERSON; public static final String CATEGORY = DirectlyAddressableRestModel.EPERSON;
private String name; private String name;

View File

@@ -22,7 +22,7 @@ import com.fasterxml.jackson.annotation.JsonProperty.Access;
*/ */
public class ItemRest extends DSpaceObjectRest { public class ItemRest extends DSpaceObjectRest {
public static final String NAME = "item"; public static final String NAME = "item";
public static final String CATEGORY = RestModel.CORE; public static final String CATEGORY = DirectlyAddressableRestModel.CORE;
private boolean inArchive = false; private boolean inArchive = false;
private boolean discoverable = false; private boolean discoverable = false;
private boolean withdrawn = false; private boolean withdrawn = false;

View File

@@ -15,7 +15,7 @@ import java.io.Serializable;
* @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it) * @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it)
* *
*/ */
public class LicenseRest implements Serializable { public class LicenseRest implements RestModel {
public static final String NAME = "license"; public static final String NAME = "license";
private boolean custom = false; private boolean custom = false;
private String text; private String text;
@@ -35,5 +35,9 @@ public class LicenseRest implements Serializable {
public void setText(String text) { public void setText(String text) {
this.text = text; this.text = text;
} }
@Override
public String getType() {
return NAME;
}
} }

View File

@@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
*/ */
public class MetadataFieldRest extends BaseObjectRest<Integer> { public class MetadataFieldRest extends BaseObjectRest<Integer> {
public static final String NAME = "metadatafield"; public static final String NAME = "metadatafield";
public static final String CATEGORY = RestModel.CORE; public static final String CATEGORY = DirectlyAddressableRestModel.CORE;
@JsonIgnore @JsonIgnore
private MetadataSchemaRest schema; private MetadataSchemaRest schema;

View File

@@ -17,7 +17,7 @@ import org.dspace.app.rest.RestResourceController;
*/ */
public class MetadataSchemaRest extends BaseObjectRest<Integer> { public class MetadataSchemaRest extends BaseObjectRest<Integer> {
public static final String NAME = "metadataschema"; public static final String NAME = "metadataschema";
public static final String CATEGORY = RestModel.CORE; public static final String CATEGORY = DirectlyAddressableRestModel.CORE;
private String prefix; private String prefix;

View File

@@ -9,27 +9,13 @@ package org.dspace.app.rest.model;
import java.io.Serializable; import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonIgnore;
/** /**
* Methods to implement to make a REST resource addressable * A REST resource directly or indirectly (in a collection) exposed must have at
* least a type attribute to facilitate deserialization
* *
* @author Andrea Bollini (andrea.bollini at 4science.it) * @author Andrea Bollini (andrea.bollini at 4science.it)
* *
*/ */
public interface RestModel extends Serializable { public interface RestModel extends Serializable {
public static final String CORE = "core";
public static final String EPERSON = "eperson";
public static final String DISCOVER = "discover";
public static final String CONFIGURATION = "config";
public static final String INTEGRATION = "integration";
public static final String SUBMISSION = "submission";
@JsonIgnore
public String getCategory();
public String getType(); public String getType();
@JsonIgnore
public Class getController();
} }

View File

@@ -15,7 +15,7 @@ package org.dspace.app.rest.model;
*/ */
public class SiteRest extends DSpaceObjectRest { public class SiteRest extends DSpaceObjectRest {
public static final String NAME = "site"; public static final String NAME = "site";
public static final String CATEGORY = RestModel.CORE; public static final String CATEGORY = DirectlyAddressableRestModel.CORE;
@Override @Override
public String getCategory() { public String getCategory() {

View File

@@ -24,7 +24,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
public class SubmissionDefinitionRest extends BaseObjectRest<String> { public class SubmissionDefinitionRest extends BaseObjectRest<String> {
public static final String NAME = "submissiondefinition"; public static final String NAME = "submissiondefinition";
public static final String CATEGORY = RestModel.CONFIGURATION; public static final String CATEGORY = DirectlyAddressableRestModel.CONFIGURATION;
private String name; private String name;

View File

@@ -21,8 +21,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
*/ */
public class SubmissionFormRest extends BaseObjectRest<String> { public class SubmissionFormRest extends BaseObjectRest<String> {
public static final String NAME = "submissionform"; public static final String NAME = "submissionform";
public static final String NAME_LINK_ON_PANEL = RestModel.CONFIGURATION; public static final String NAME_LINK_ON_PANEL = DirectlyAddressableRestModel.CONFIGURATION;
public static final String CATEGORY = RestModel.CONFIGURATION; public static final String CATEGORY = DirectlyAddressableRestModel.CONFIGURATION;
private String name; private String name;

View File

@@ -25,8 +25,8 @@ import com.fasterxml.jackson.annotation.JsonProperty;
public class SubmissionUploadRest extends BaseObjectRest<String> { public class SubmissionUploadRest extends BaseObjectRest<String> {
public static final String NAME = "submissionupload"; public static final String NAME = "submissionupload";
public static final String NAME_LINK_ON_PANEL = RestModel.CONFIGURATION; public static final String NAME_LINK_ON_PANEL = DirectlyAddressableRestModel.CONFIGURATION;
public static final String CATEGORY = RestModel.CONFIGURATION; public static final String CATEGORY = DirectlyAddressableRestModel.CONFIGURATION;
private String name; private String name;
@@ -68,14 +68,14 @@ public class SubmissionUploadRest extends BaseObjectRest<String> {
} }
public List<AccessConditionOptionRest> getAccessConditions() { public List<AccessConditionOptionRest> getAccessConditions() {
if(accessConditions==null) { if(accessConditionOptions==null) {
accessConditions = new ArrayList<>(); accessConditionOptions = new ArrayList<>();
} }
return accessConditions; return accessConditionOptions;
} }
public void setAccessConditions(List<AccessConditionOptionRest> accessConditions) { public void setAccessConditions(List<AccessConditionOptionRest> accessConditions) {
this.accessConditions = accessConditions; this.accessConditionOptions = accessConditions;
} }
public boolean isRequired() { public boolean isRequired() {
@@ -94,11 +94,11 @@ public class SubmissionUploadRest extends BaseObjectRest<String> {
this.maxSize = maxSize; this.maxSize = maxSize;
} }
public List<SubmissionFormFieldRest> getMetadata() { public SubmissionFormRest getMetadata() {
return metadata; return metadata;
} }
public void setMetadata(List<SubmissionFormFieldRest> metadata) { public void setMetadata(SubmissionFormRest metadata) {
this.metadata = metadata; this.metadata = metadata;
} }
} }

View File

@@ -26,7 +26,7 @@ import com.fasterxml.jackson.annotation.JsonUnwrapped;
*/ */
public class WorkspaceItemRest extends BaseObjectRest<Integer> { public class WorkspaceItemRest extends BaseObjectRest<Integer> {
public static final String NAME = "workspaceitem"; public static final String NAME = "workspaceitem";
public static final String CATEGORY = RestModel.SUBMISSION; public static final String CATEGORY = DirectlyAddressableRestModel.SUBMISSION;
private Date lastModified = new Date(); private Date lastModified = new Date();

View File

@@ -22,7 +22,7 @@ import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.BaseObjectRest; import org.dspace.app.rest.model.BaseObjectRest;
import org.dspace.app.rest.model.LinkRest; import org.dspace.app.rest.model.LinkRest;
import org.dspace.app.rest.model.LinksRest; import org.dspace.app.rest.model.LinksRest;
import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.DirectlyAddressableRestModel;
import org.dspace.app.rest.repository.DSpaceRestRepository; import org.dspace.app.rest.repository.DSpaceRestRepository;
import org.dspace.app.rest.repository.LinkRestRepository; import org.dspace.app.rest.repository.LinkRestRepository;
import org.dspace.app.rest.utils.Utils; import org.dspace.app.rest.utils.Utils;
@@ -45,7 +45,7 @@ import com.fasterxml.jackson.annotation.JsonUnwrapped;
* @author Andrea Bollini (andrea.bollini at 4science.it) * @author Andrea Bollini (andrea.bollini at 4science.it)
* *
*/ */
public abstract class DSpaceResource<T extends RestModel> extends ResourceSupport { public abstract class DSpaceResource<T extends DirectlyAddressableRestModel> extends ResourceSupport {
@JsonUnwrapped @JsonUnwrapped
private final T data; private final T data;
@@ -81,7 +81,7 @@ public abstract class DSpaceResource<T extends RestModel> extends ResourceSuppor
for (Method m : methods) { for (Method m : methods) {
if (StringUtils.equals(m.getName(), linkAnnotation.method())) { if (StringUtils.equals(m.getName(), linkAnnotation.method())) {
// TODO add support for single linked object other than for collections // TODO add support for single linked object other than for collections
Page<? extends Serializable> pageResult = (Page<? extends RestModel>) m.invoke(linkRepository, null, ((BaseObjectRest) data).getId(), null, null); Page<? extends Serializable> pageResult = (Page<? extends DirectlyAddressableRestModel>) m.invoke(linkRepository, null, ((BaseObjectRest) data).getId(), null, null);
EmbeddedPage ep = new EmbeddedPage(linkToSubResource.getHref(), pageResult, null); EmbeddedPage ep = new EmbeddedPage(linkToSubResource.getHref(), pageResult, null);
embedded.put(name, ep); embedded.put(name, ep);
found = true; found = true;
@@ -113,24 +113,24 @@ public abstract class DSpaceResource<T extends RestModel> extends ResourceSuppor
this.add(linkToSubResource); this.add(linkToSubResource);
Object linkedObject = readMethod.invoke(data); Object linkedObject = readMethod.invoke(data);
Object wrapObject = linkedObject; Object wrapObject = linkedObject;
if (linkedObject instanceof RestModel) { if (linkedObject instanceof DirectlyAddressableRestModel) {
RestModel linkedRM = (RestModel) linkedObject; DirectlyAddressableRestModel linkedRM = (DirectlyAddressableRestModel) linkedObject;
wrapObject = utils.getResourceRepository(linkedRM.getCategory(), linkedRM.getType()) wrapObject = utils.getResourceRepository(linkedRM.getCategory(), linkedRM.getType())
.wrapResource(linkedRM); .wrapResource(linkedRM);
} }
else { else {
if (linkedObject instanceof List) { if (linkedObject instanceof List) {
List<RestModel> linkedRMList = (List<RestModel>) linkedObject; List<DirectlyAddressableRestModel> linkedRMList = (List<DirectlyAddressableRestModel>) linkedObject;
if (linkedRMList.size() > 0) { if (linkedRMList.size() > 0) {
DSpaceRestRepository<RestModel, ?> resourceRepository = utils.getResourceRepository(linkedRMList.get(0).getCategory(), linkedRMList.get(0).getType()); DSpaceRestRepository<DirectlyAddressableRestModel, ?> resourceRepository = utils.getResourceRepository(linkedRMList.get(0).getCategory(), linkedRMList.get(0).getType());
// TODO should we force pagination also of embedded resource? // TODO should we force pagination also of embedded resource?
// This will force a pagination with size 10 for embedded collections as well // This will force a pagination with size 10 for embedded collections as well
// int pageSize = 1; // int pageSize = 1;
// PageImpl<RestModel> page = new PageImpl( // PageImpl<RestModel> page = new PageImpl(
// linkedRMList.subList(0, // linkedRMList.subList(0,
// linkedRMList.size() > pageSize ? pageSize : linkedRMList.size()), new PageRequest(0, pageSize), linkedRMList.size()); // linkedRMList.size() > pageSize ? pageSize : linkedRMList.size()), new PageRequest(0, pageSize), linkedRMList.size());
PageImpl<RestModel> page = new PageImpl(linkedRMList); PageImpl<DirectlyAddressableRestModel> page = new PageImpl(linkedRMList);
wrapObject = new EmbeddedPage(linkToSubResource.getHref(), page.map(resourceRepository::wrapResource), linkedRMList); wrapObject = new EmbeddedPage(linkToSubResource.getHref(), page.map(resourceRepository::wrapResource), linkedRMList);
} }
else { else {
@@ -158,12 +158,12 @@ public abstract class DSpaceResource<T extends RestModel> extends ResourceSuppor
for (Method m : methods) { for (Method m : methods) {
if (StringUtils.equals(m.getName(), linkAnnotation.method())) { if (StringUtils.equals(m.getName(), linkAnnotation.method())) {
if ( Page.class.isAssignableFrom( m.getReturnType()) ){ if ( Page.class.isAssignableFrom( m.getReturnType()) ){
Page<? extends Serializable> pageResult = (Page<? extends RestModel>) m.invoke(linkRepository, null, ((BaseObjectRest) data).getId(), null, null); Page<? extends Serializable> pageResult = (Page<? extends DirectlyAddressableRestModel>) m.invoke(linkRepository, null, ((BaseObjectRest) data).getId(), null, null);
EmbeddedPage ep = new EmbeddedPage(linkToSubResource.getHref(), pageResult, null); EmbeddedPage ep = new EmbeddedPage(linkToSubResource.getHref(), pageResult, null);
embedded.put(name, ep); embedded.put(name, ep);
} }
else { else {
RestModel object = (RestModel)m.invoke(linkRepository, null, ((BaseObjectRest) data).getId(), null, null); DirectlyAddressableRestModel object = (DirectlyAddressableRestModel)m.invoke(linkRepository, null, ((BaseObjectRest) data).getId(), null, null);
ResourceSupport ep = linkRepository.wrapResource(object, linkToSubResource.getHref()); ResourceSupport ep = linkRepository.wrapResource(object, linkToSubResource.getHref());
embedded.put(name, ep); embedded.put(name, ep);
} }
@@ -180,10 +180,10 @@ public abstract class DSpaceResource<T extends RestModel> extends ResourceSuppor
} }
} }
} }
else if (RestModel.class.isAssignableFrom(readMethod.getReturnType())) { else if (DirectlyAddressableRestModel.class.isAssignableFrom(readMethod.getReturnType())) {
Link linkToSubResource = utils.linkToSubResource(data, name); Link linkToSubResource = utils.linkToSubResource(data, name);
this.add(linkToSubResource); this.add(linkToSubResource);
RestModel linkedObject = (RestModel) readMethod.invoke(data); DirectlyAddressableRestModel linkedObject = (DirectlyAddressableRestModel) readMethod.invoke(data);
if (linkedObject != null) { if (linkedObject != null) {
embedded.put(name, embedded.put(name,
utils.getResourceRepository(linkedObject.getCategory(), linkedObject.getType()) utils.getResourceRepository(linkedObject.getCategory(), linkedObject.getType())

View File

@@ -15,7 +15,7 @@ import java.util.List;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.DirectlyAddressableRestModel;
import org.dspace.app.rest.model.hateoas.DSpaceResource; import org.dspace.app.rest.model.hateoas.DSpaceResource;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@@ -32,7 +32,7 @@ import org.springframework.web.multipart.MultipartFile;
* @author Andrea Bollini (andrea.bollini at 4science.it) * @author Andrea Bollini (andrea.bollini at 4science.it)
* *
*/ */
public abstract class DSpaceRestRepository<T extends RestModel, ID extends Serializable> public abstract class DSpaceRestRepository<T extends DirectlyAddressableRestModel, ID extends Serializable>
extends AbstractDSpaceRestRepository extends AbstractDSpaceRestRepository
implements PagingAndSortingRepository<T, ID> { implements PagingAndSortingRepository<T, ID> {

View File

@@ -9,6 +9,7 @@ package org.dspace.app.rest.repository;
import java.io.Serializable; import java.io.Serializable;
import org.dspace.app.rest.model.RestModel;
import org.springframework.hateoas.ResourceSupport; import org.springframework.hateoas.ResourceSupport;
/** /**
@@ -17,7 +18,7 @@ import org.springframework.hateoas.ResourceSupport;
* @author Andrea Bollini (andrea.bollini at 4science.it) * @author Andrea Bollini (andrea.bollini at 4science.it)
* *
*/ */
public interface LinkRestRepository<L extends Serializable> { public interface LinkRestRepository<L extends RestModel> {
public abstract ResourceSupport wrapResource(L model, String... rels); public abstract ResourceSupport wrapResource(L model, String... rels);
public default boolean isEmbeddableRelation(Object data, String name) { public default boolean isEmbeddableRelation(Object data, String name) {

View File

@@ -49,6 +49,9 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository<Submiss
private SubmissionConfigReader submissionConfigReader; private SubmissionConfigReader submissionConfigReader;
@Autowired
private SubmissionFormRestRepository submissionFormRestRepository;
@Autowired @Autowired
private UploadConfigurationService uploadConfigurationService; private UploadConfigurationService uploadConfigurationService;
@@ -80,7 +83,7 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository<Submiss
for (SubmissionConfig config : subConfs) { for (SubmissionConfig config : subConfs) {
for (int i = 0; i < config.getNumberOfSteps(); i++) { for (int i = 0; i < config.getNumberOfSteps(); i++) {
SubmissionStepConfig step = config.getStep(i); SubmissionStepConfig step = config.getStep(i);
if (SubmissionStepConfig.UPLOAD_STEP_NAME.equals(step.getId())) { if (SubmissionStepConfig.UPLOAD_STEP_NAME.equals(step.getType())) {
UploadConfiguration uploadConfig = uploadConfigurationService.getMap().get(step.getId()); UploadConfiguration uploadConfig = uploadConfigurationService.getMap().get(step.getId());
if (uploadConfig != null) { if (uploadConfig != null) {
try { try {
@@ -121,10 +124,10 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository<Submiss
if(StringUtils.isNotBlank(option.getDateLimit())) { if(StringUtils.isNotBlank(option.getDateLimit())) {
optionRest.setMaxEndDate(dateMathParser.parseMath(option.getDateLimit())); optionRest.setMaxEndDate(dateMathParser.parseMath(option.getDateLimit()));
} }
optionRest.setType(option.getPolicyType()); optionRest.setPolicyType(option.getPolicyType());
result.getAccessConditions().add(optionRest); result.getAccessConditions().add(optionRest);
} }
result.setMetadata(config.getMetadata()); result.setMetadata(submissionFormRestRepository.findOne(config.getMetadata()));
result.setMaxSize(config.getMaxSize()); result.setMaxSize(config.getMaxSize());
result.setRequired(config.isRequired()); result.setRequired(config.isRequired());
result.setName(config.getName()); result.setName(config.getName());

View File

@@ -12,7 +12,7 @@ import java.util.List;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.app.rest.model.MetadataValueRest; import org.dspace.app.rest.model.MetadataValueRest;
import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.DirectlyAddressableRestModel;
import org.dspace.app.rest.model.step.DataDescribe; import org.dspace.app.rest.model.step.DataDescribe;
import org.dspace.app.rest.model.step.SectionData; import org.dspace.app.rest.model.step.SectionData;
import org.dspace.app.rest.submit.AbstractRestProcessingStep; import org.dspace.app.rest.submit.AbstractRestProcessingStep;

View File

@@ -20,7 +20,7 @@ import org.dspace.app.rest.model.CommunityRest;
import org.dspace.app.rest.model.LinkRest; import org.dspace.app.rest.model.LinkRest;
import org.dspace.app.rest.model.LinksRest; import org.dspace.app.rest.model.LinksRest;
import org.dspace.app.rest.model.MetadataFieldRest; import org.dspace.app.rest.model.MetadataFieldRest;
import org.dspace.app.rest.model.RestModel; import org.dspace.app.rest.model.DirectlyAddressableRestModel;
import org.dspace.app.rest.model.hateoas.DSpaceResource; import org.dspace.app.rest.model.hateoas.DSpaceResource;
import org.dspace.app.rest.repository.DSpaceRestRepository; import org.dspace.app.rest.repository.DSpaceRestRepository;
import org.dspace.app.rest.repository.LinkRestRepository; import org.dspace.app.rest.repository.LinkRestRepository;
@@ -60,20 +60,20 @@ public class Utils {
} }
public Link linkToSingleResource(DSpaceResource r, String rel) { public Link linkToSingleResource(DSpaceResource r, String rel) {
RestModel data = r.getData(); DirectlyAddressableRestModel data = r.getData();
return linkToSingleResource(data, rel); return linkToSingleResource(data, rel);
} }
public Link linkToSingleResource(RestModel data, String rel) { public Link linkToSingleResource(DirectlyAddressableRestModel data, String rel) {
return linkTo(data.getController(), data.getCategory(), English.plural(data.getType())).slash(data) return linkTo(data.getController(), data.getCategory(), English.plural(data.getType())).slash(data)
.withRel(rel); .withRel(rel);
} }
public Link linkToSubResource(RestModel data, String rel) { public Link linkToSubResource(DirectlyAddressableRestModel data, String rel) {
return linkToSubResource(data, rel, rel); return linkToSubResource(data, rel, rel);
} }
public Link linkToSubResource(RestModel data, String rel, String path) { public Link linkToSubResource(DirectlyAddressableRestModel data, String rel, String path) {
return linkTo(data.getController(), data.getCategory(), English.plural(data.getType())).slash(data).slash(path) return linkTo(data.getController(), data.getCategory(), English.plural(data.getType())).slash(data).slash(path)
.withRel(rel); .withRel(rel);
} }
@@ -131,7 +131,7 @@ public class Utils {
* @return the LinkRest annotation corresponding to the specified rel in the * @return the LinkRest annotation corresponding to the specified rel in the
* domainClass. Null if not found * domainClass. Null if not found
*/ */
public LinkRest getLinkRest(String rel, Class<RestModel> domainClass) { public LinkRest getLinkRest(String rel, Class<DirectlyAddressableRestModel> domainClass) {
LinkRest linkRest = null; LinkRest linkRest = null;
LinksRest linksAnnotation = domainClass.getDeclaredAnnotation(LinksRest.class); LinksRest linksAnnotation = domainClass.getDeclaredAnnotation(LinksRest.class);
if (linksAnnotation != null) { if (linksAnnotation != null) {