D4CRIS-338 refactoring to implement PATCH operation model; manage upload section operation;

This commit is contained in:
Luigi Andrea Pascarelli
2017-11-15 19:50:12 +01:00
parent c9b4270af2
commit 4870d75afa
36 changed files with 887 additions and 195 deletions

View File

@@ -210,7 +210,7 @@ public class AddBitstreamsAction extends UpdateBitstreamsAction {
if (group != null)
{
authorizeService.removeAllPolicies(context, bs); // remove the default policy
authorizeService.createResourcePolicy(context, bs, group, null, ce.permissionsActionId, null);
authorizeService.createResourcePolicy(context, bs, group, null, ce.permissionsActionId, null, null, null, null);
}
}

View File

@@ -530,21 +530,21 @@ public class AuthorizeServiceImpl implements AuthorizeService
public void addPolicy(Context context, DSpaceObject o, int actionID,
EPerson e, String type) throws SQLException, AuthorizeException
{
createResourcePolicy(context, o, null, e, actionID, type);
createResourcePolicy(context, o, null, e, actionID, type, null, null, null);
}
@Override
public void addPolicy(Context c, DSpaceObject o, int actionID,
Group g) throws SQLException, AuthorizeException
{
createResourcePolicy(c, o, g, null, actionID, null);
createResourcePolicy(c, o, g, null, actionID, null, null, null, null);
}
@Override
public void addPolicy(Context c, DSpaceObject o, int actionID,
Group g, String type) throws SQLException, AuthorizeException
{
createResourcePolicy(c, o, g, null, actionID, type);
createResourcePolicy(c, o, g, null, actionID, type, null, null, null);
}
@Override
@@ -777,7 +777,7 @@ public class AuthorizeServiceImpl implements AuthorizeService
}
@Override
public ResourcePolicy createResourcePolicy(Context context, DSpaceObject dso, Group group, EPerson eperson, int type, String rpType) throws SQLException, AuthorizeException {
public ResourcePolicy createResourcePolicy(Context context, DSpaceObject dso, Group group, EPerson eperson, int type, String rpType, String rpName, Date startDate, Date endDate) throws SQLException, AuthorizeException {
if (group == null && eperson == null)
{
throw new IllegalArgumentException("We need at least an eperson or a group in order to create a resource policy.");
@@ -789,6 +789,9 @@ public class AuthorizeServiceImpl implements AuthorizeService
myPolicy.setGroup(group);
myPolicy.setEPerson(eperson);
myPolicy.setRpType(rpType);
myPolicy.setRpName(rpName);
myPolicy.setEndDate(endDate);
myPolicy.setStartDate(startDate);
resourcePolicyService.update(context, myPolicy);
return myPolicy;
@@ -819,7 +822,7 @@ public class AuthorizeServiceImpl implements AuthorizeService
if (policy == null)
{
policy = createResourcePolicy(context, dso, group, ePerson, action, ResourcePolicy.TYPE_CUSTOM);
policy = createResourcePolicy(context, dso, group, ePerson, action, ResourcePolicy.TYPE_CUSTOM, null, null, null);
}
policy.setGroup(group);
policy.setEPerson(ePerson);

View File

@@ -471,7 +471,7 @@ public interface AuthorizeService {
*/
public void generateAutomaticPolicies(Context context, Date embargoDate, String reason, DSpaceObject dso, Collection owningCollection) throws SQLException, AuthorizeException;
public ResourcePolicy createResourcePolicy(Context context, DSpaceObject dso, Group group, EPerson eperson, int type, String rpType) throws SQLException, AuthorizeException;
public ResourcePolicy createResourcePolicy(Context context, DSpaceObject dso, Group group, EPerson eperson, int type, String rpType, String rpName, Date startDate, Date endDate) throws SQLException, AuthorizeException;
public ResourcePolicy createOrModifyPolicy(ResourcePolicy policy, Context context, String name, Group group, EPerson ePerson, Date embargoDate, int action, String reason, DSpaceObject dso) throws AuthorizeException, SQLException;

View File

@@ -106,10 +106,10 @@ public class CollectionServiceImpl extends DSpaceObjectServiceImpl<Collection> i
Group anonymousGroup = groupService.findByName(context, Group.ANONYMOUS);
authorizeService.createResourcePolicy(context, newCollection, anonymousGroup, null, Constants.READ, null);
authorizeService.createResourcePolicy(context, newCollection, anonymousGroup, null, Constants.READ, null, null, null, null);
// now create the default policies for submitted items
authorizeService.createResourcePolicy(context, newCollection, anonymousGroup, null, Constants.DEFAULT_ITEM_READ, null);
authorizeService.createResourcePolicy(context, newCollection, anonymousGroup, null, Constants.DEFAULT_BITSTREAM_READ, null);
authorizeService.createResourcePolicy(context, newCollection, anonymousGroup, null, Constants.DEFAULT_ITEM_READ, null, null, null, null);
authorizeService.createResourcePolicy(context, newCollection, anonymousGroup, null, Constants.DEFAULT_BITSTREAM_READ, null, null, null, null);

View File

@@ -108,7 +108,7 @@ public class CommunityServiceImpl extends DSpaceObjectServiceImpl<Community> imp
// of 'anonymous' READ
Group anonymousGroup = groupService.findByName(context, Group.ANONYMOUS);
authorizeService.createResourcePolicy(context, newCommunity, anonymousGroup, null, Constants.READ, null);
authorizeService.createResourcePolicy(context, newCommunity, anonymousGroup, null, Constants.READ, null, null, null, null);
communityDAO.save(context, newCommunity);

View File

@@ -14,10 +14,9 @@ import org.dspace.services.ConfigurationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* Converter to translate ResourcePolicy into human readable value configuration.
* Converter to translate ResourcePolicy into human readable value
* configuration.
*
* @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it)
*/
@@ -26,29 +25,22 @@ public class AccessConditionsConverter extends DSpaceConverter<ResourcePolicy, A
@Autowired
ConfigurationService configurationService;
@Override
public AccessConditionRest fromModel(ResourcePolicy obj) {
AccessConditionRest model = new AccessConditionRest();
model.setPolicyType("openaccess");
model.setPolicyType(obj.getRpName());
if (obj.getGroup() != null) {
model.setGroupUUID(obj.getGroup().getID());
if (Group.ADMIN.equals(obj.getGroup().getName())) {
model.setPolicyType("administrator");
}
else {
if(obj.getStartDate()!=null) {
model.setPolicyType("embargo");
model.setEndDate(obj.getStartDate());
}
else {
if(obj.getEndDate()!=null) {
model.setPolicyType("lease");
model.setEndDate(obj.getEndDate());
}
model.setGroupUUID(obj.getGroup().getID());
if (obj.getStartDate() != null) {
model.setEndDate(obj.getStartDate());
} else {
if (obj.getEndDate() != null) {
model.setEndDate(obj.getEndDate());
}
}
}
return model;
}

View File

@@ -7,7 +7,6 @@
*/
package org.dspace.app.rest.model;
import java.io.Serializable;
import java.util.Date;
import java.util.UUID;

View File

@@ -7,8 +7,6 @@
*/
package org.dspace.app.rest.model;
import java.io.Serializable;
/**
* The License text REST resource.
*

View File

@@ -1,28 +1,24 @@
package org.dspace.app.rest.model.step;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.dspace.app.rest.model.AccessConditionRest;
import org.dspace.app.rest.model.CheckSumRest;
import org.dspace.app.rest.model.MetadataEntryRest;
import org.springframework.hateoas.ResourceSupport;
import org.dspace.app.rest.model.MetadataValueRest;
public class UploadBitstreamRest extends UploadStatusResponse {
private UUID uuid;
private List<MetadataEntryRest> metadata;
private Map<String, List<MetadataValueRest>> metadata = new HashMap<>();
private List<AccessConditionRest> accessConditions;
private Long sizeBytes;
private CheckSumRest checkSum;
private String url;
public List<MetadataEntryRest> getMetadata() {
return metadata;
}
public void setMetadata(List<MetadataEntryRest> metadata) {
this.metadata = metadata;
}
public Long getSizeBytes() {
return sizeBytes;
}
@@ -54,4 +50,23 @@ public class UploadBitstreamRest extends UploadStatusResponse {
public void setUuid(UUID uuid) {
this.uuid = uuid;
}
public Map<String, List<MetadataValueRest>> getMetadata() {
return metadata;
}
public void setMetadata(Map<String, List<MetadataValueRest>> metadata) {
this.metadata = metadata;
}
public List<AccessConditionRest> getAccessConditions() {
if(accessConditions==null) {
accessConditions = new ArrayList<>();
}
return accessConditions;
}
public void setAccessConditions(List<AccessConditionRest> accessConditions) {
this.accessConditions = accessConditions;
}
}

View File

@@ -26,7 +26,6 @@ import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.ResourceSupport;
import org.springframework.stereotype.Component;

View File

@@ -243,23 +243,19 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
WorkspaceItem source = wis.find(context, id);
for(PatchOperation op : operations) {
//the value in the position 0 is a null value
String[] path = op.getPath().split("/");
if("sections".equals(path[1])) {
String section = path[2];
String target = path[3];
String index = "";
if(path.length>4) {
index = path[4];
}
String[] path = op.getPath().substring(1).split("/",3);
if("sections".equals(path[0])) {
String section = path[1];
String absolutePath = path[2];
String operation = op.getOp();
evaluatePatch(context, request, source, wsi, operation, section, target, index, op.getValue());
evaluatePatch(context, request, source, wsi, operation, section, absolutePath, op.getValue());
}
}
wis.update(context, source);
}
private void evaluatePatch(Context context, HttpServletRequest request, WorkspaceItem source, WorkspaceItemRest wsi, String operation, String section, String target, String index,
private void evaluatePatch(Context context, HttpServletRequest request, WorkspaceItem source, WorkspaceItemRest wsi, String operation, String section, String path,
Object value) throws Exception {
SubmissionConfig submissionConfig = submissionConfigReader.getSubmissionConfigByName(wsi.getSubmissionDefinition().getName());
for(int stepNum = 0; stepNum<submissionConfig.getNumberOfSteps(); stepNum++) {
@@ -282,7 +278,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
// load the JSPStep interface for this step
AbstractRestProcessingStep stepProcessing = (AbstractRestProcessingStep) stepClass
.newInstance();
stepProcessing.doPatchProcessing(context, getRequestService().getCurrentRequest(), source, operation, target, index, value);
stepProcessing.doPatchProcessing(context, getRequestService().getCurrentRequest(), source, operation, path, value);
} else {
throw new Exception("The submission step class specified by '"
+ stepConfig.getProcessingClassName()

View File

@@ -26,7 +26,7 @@ public interface AbstractRestProcessingStep {
public <T extends Serializable> T getData(WorkspaceItem obj, SubmissionStepConfig config) throws Exception;
public void doPatchProcessing(Context context, Request currentRequest, WorkspaceItem source, String operation,
String target, String index, Object value) throws Exception;
String path, Object value) throws Exception;
}

View File

@@ -0,0 +1,19 @@
package org.dspace.app.rest.submit;
import java.util.Map;
import org.dspace.app.rest.submit.factory.impl.PatchOperation;
public class PatchConfigurationService {
private Map<String, Map<String, PatchOperation>> map;
public Map<String, Map<String, PatchOperation>> getMap() {
return map;
}
public void setMap(Map<String, Map<String, PatchOperation>> map) {
this.map = map;
}
}

View File

@@ -14,10 +14,13 @@ import java.util.UUID;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.atteo.evo.inflector.English;
import org.dspace.app.rest.converter.AccessConditionsConverter;
import org.dspace.app.rest.model.AccessConditionRest;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.CheckSumRest;
import org.dspace.app.rest.model.MetadataEntryRest;
import org.dspace.app.rest.model.MetadataValueRest;
import org.dspace.app.rest.model.step.UploadBitstreamRest;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.content.Bitstream;
import org.dspace.content.Collection;
import org.dspace.content.MetadataValue;
@@ -25,6 +28,7 @@ import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.WorkspaceItemService;
import org.dspace.core.Context;
import org.dspace.core.Utils;
import org.dspace.services.ConfigurationService;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
@@ -84,24 +88,43 @@ public class SubmissionService {
public static UploadBitstreamRest buildUploadBitstream(ConfigurationService configurationService, Bitstream source) {
UploadBitstreamRest b = new UploadBitstreamRest();
List<MetadataEntryRest> metadata = new ArrayList<MetadataEntryRest>();
for (MetadataValue mv : source.getMetadata()) {
MetadataEntryRest me = new MetadataEntryRest();
me.setKey(mv.getMetadataField().toString('.'));
me.setValue(mv.getValue());
me.setLanguage(mv.getLanguage());
metadata.add(me);
UploadBitstreamRest data = new UploadBitstreamRest();
for (MetadataValue md : source.getMetadata()) {
MetadataValueRest dto = new MetadataValueRest();
dto.setAuthority(md.getAuthority());
dto.setConfidence(md.getConfidence());
dto.setLanguage(md.getLanguage());
dto.setPlace(md.getPlace());
dto.setValue(md.getValue());
String[] metadataToCheck = Utils.tokenize(md.getMetadataField().toString());
if(data.getMetadata().containsKey(Utils.standardize(metadataToCheck[0], metadataToCheck[1], metadataToCheck[2], "."))) {
data.getMetadata().get(Utils.standardize(md.getMetadataField().getMetadataSchema().getName(), md.getMetadataField().getElement(), md.getMetadataField().getQualifier(), ".")).add(dto);
}
else {
List<MetadataValueRest> listDto = new ArrayList<>();
listDto.add(dto);
data.getMetadata().put(Utils.standardize(md.getMetadataField().getMetadataSchema().getName(), md.getMetadataField().getElement(), md.getMetadataField().getQualifier(), "."), listDto);
}
}
b.setMetadata(metadata);
b.setUuid(source.getID());
AccessConditionsConverter aCConverter = new AccessConditionsConverter();
for(ResourcePolicy rp : source.getResourcePolicies()) {
AccessConditionRest accessConditionRest = aCConverter.convert(rp);
data.getAccessConditions().add(accessConditionRest);
}
data.setUuid(source.getID());
CheckSumRest checksum = new CheckSumRest();
checksum.setCheckSumAlgorithm(source.getChecksumAlgorithm());
checksum.setValue(source.getChecksum());
b.setCheckSum(checksum);
b.setSizeBytes(source.getSize());
b.setUrl(configurationService.getProperty("dspace.url")+"/api/"+BitstreamRest.CATEGORY +"/"+ English.plural(BitstreamRest.NAME) + "/" + source.getID() + "/content");
return b;
data.setCheckSum(checksum);
data.setSizeBytes(source.getSize());
data.setUrl(configurationService.getProperty("dspace.url")+"/api/"+BitstreamRest.CATEGORY +"/"+ English.plural(BitstreamRest.NAME) + "/" + source.getID() + "/content");
return data;
}
}

View File

@@ -0,0 +1,31 @@
package org.dspace.app.rest.submit.factory;
import org.dspace.app.rest.submit.PatchConfigurationService;
import org.dspace.app.rest.submit.factory.impl.PatchOperation;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.utils.DSpace;
import org.springframework.beans.factory.annotation.Autowired;
public class PatchOperationFactory {
private PatchConfigurationService patchConfigurationService;
public PatchOperation instanceOf(String instance, String operation) {
PatchOperation result = getPatchConfigurationService().getMap().get(operation).get(instance);
if(result==null) {
throw new RuntimeException("Operation "+operation+" not yet implemented for " + instance);
}
return result;
}
public PatchConfigurationService getPatchConfigurationService() {
if(patchConfigurationService==null) {
patchConfigurationService = DSpaceServicesFactory.getInstance().getServiceManager().getServiceByName("patchConfigurationService", PatchConfigurationService.class);
}
return patchConfigurationService;
}
public void setPatchConfigurationService(PatchConfigurationService patchOperationService) {
this.patchConfigurationService = patchOperationService;
}
}

View File

@@ -0,0 +1,49 @@
package org.dspace.app.rest.submit.factory.impl;
import java.util.List;
import org.dspace.app.rest.model.AccessConditionRest;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
public class AccessConditionRemovePatchOperation extends RemovePatchOperation<AccessConditionRest> {
@Autowired
ItemService itemService;
@Autowired
AuthorizeService authorizeService;
@Override
void remove(Context context, Request currentRequest, WorkspaceItem source, String path, Object value)
throws Exception {
String[] split = path.split("/");
Item item = source.getItem();
List<Bundle> bundle = itemService.getBundles(item, "ORIGINAL");
;
for (Bundle bb : bundle) {
int idx = 0;
for (Bitstream b : bb.getBitstreams()) {
if (idx == Integer.parseInt(split[0])) {
authorizeService.removeAllPolicies(context, b);
}
idx++;
}
}
}
@Override
protected Class<AccessConditionRest[]> getClassForEvaluation() {
return AccessConditionRest[].class;
}
}

View File

@@ -0,0 +1,77 @@
package org.dspace.app.rest.submit.factory.impl;
import java.util.Date;
import java.util.List;
import org.dspace.app.rest.model.AccessConditionRest;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.BitstreamService;
import org.dspace.content.service.ItemService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.json.patch.LateObjectEvaluator;
public class AccessConditionReplacePatchOperation extends ReplacePatchOperation<AccessConditionRest> {
@Autowired
BitstreamService bitstreamService;
@Autowired
ItemService itemService;
@Autowired
AuthorizeService authorizeService;
@Autowired
GroupService groupService;
@Override
void replace(Context context, Request currentRequest, WorkspaceItem source, String path, Object value)
throws Exception {
String[] split = path.split("/");
Item item = source.getItem();
List<Bundle> bundle = itemService.getBundles(item, "ORIGINAL");
;
for (Bundle bb : bundle) {
int idx = 0;
for (Bitstream b : bb.getBitstreams()) {
if (idx == Integer.parseInt(split[0])) {
authorizeService.removeAllPolicies(context, b);
AccessConditionRest[] newAccessConditions = evaluateObject((LateObjectEvaluator) value);
for (AccessConditionRest newAccessCondition : newAccessConditions) {
String name = newAccessCondition.getPolicyType();
Group group = groupService.find(context, newAccessCondition.getGroupUUID());
//TODO manage error on select group
Date startDate = null;
Date endDate = null;
if("embargo".equals(newAccessCondition.getPolicyType())) {
startDate = newAccessCondition.getEndDate();
}
if("lease".equals(newAccessCondition.getPolicyType())) {
endDate = newAccessCondition.getEndDate();
}
authorizeService.createResourcePolicy(context, b, group, null, Constants.READ, ResourcePolicy.TYPE_CUSTOM, name, startDate, endDate);
// TODO manage duplicate policy
}
}
idx++;
}
}
}
@Override
protected Class<AccessConditionRest[]> getClassForEvaluation() {
return AccessConditionRest[].class;
}
}

View File

@@ -0,0 +1,16 @@
package org.dspace.app.rest.submit.factory.impl;
import org.dspace.content.WorkspaceItem;
import org.dspace.core.Context;
import org.dspace.services.model.Request;
public abstract class AddPatchOperation<T extends Object> extends PatchOperation<T> {
@Override
public void perform(Context context, Request currentRequest, WorkspaceItem source, String string, Object value) throws Exception {
add(context, currentRequest, source, string, value);
}
abstract void add(Context context,Request currentRequest,WorkspaceItem source,String string,Object value) throws Exception;
}

View File

@@ -0,0 +1,55 @@
package org.dspace.app.rest.submit.factory.impl;
import java.sql.SQLException;
import java.util.List;
import org.dspace.app.rest.model.MetadataValueRest;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.BitstreamService;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.core.Utils;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.json.patch.LateObjectEvaluator;
public class BitstreamMetadataValueAddPatchOperation extends AddPatchOperation<MetadataValueRest> {
@Autowired
BitstreamService bitstreamService;
@Autowired
ItemService itemService;
@Override
void add(Context context, Request currentRequest, WorkspaceItem source, String path, Object value) throws Exception {
String[] split = path.split("/");
Item item = source.getItem();
List<Bundle> bundle = itemService.getBundles(item, "ORIGINAL");;
for(Bundle bb : bundle) {
int idx = 0;
for(Bitstream b : bb.getBitstreams()) {
if(idx==Integer.parseInt(split[0])) {
addValue(context, b, split[2], evaluateObject((LateObjectEvaluator)value));
}
idx++;
}
}
}
@Override
protected Class<MetadataValueRest[]> getClassForEvaluation() {
return MetadataValueRest[].class;
}
private void addValue(Context context, Bitstream source, String target, MetadataValueRest[] list) throws SQLException {
String[] metadata = Utils.tokenize(target);
for(MetadataValueRest ll : list) {
bitstreamService.addMetadata(context, source, metadata[0], metadata[1], metadata[2], ll.getLanguage(), ll.getValue(), ll.getAuthority(), ll.getConfidence());
}
}
}

View File

@@ -0,0 +1,64 @@
package org.dspace.app.rest.submit.factory.impl;
import java.sql.SQLException;
import java.util.List;
import org.dspace.app.rest.model.MetadataValueRest;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.Item;
import org.dspace.content.MetadataValue;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.BitstreamService;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.core.Utils;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.json.patch.LateObjectEvaluator;
public class BitstreamMetadataValueRemovePatchOperation extends RemovePatchOperation<MetadataValueRest> {
@Autowired
BitstreamService bitstreamService;
@Autowired
ItemService itemService;
@Override
void remove(Context context, Request currentRequest, WorkspaceItem source, String path, Object value) throws Exception {
String[] split = path.split("/");
Item item = source.getItem();
List<Bundle> bundle = itemService.getBundles(item, "ORIGINAL");;
for(Bundle bb : bundle) {
int idx = 0;
for(Bitstream b : bb.getBitstreams()) {
if(idx==Integer.parseInt(split[0])) {
deleteValue(context, b, split[2], split[3]);
}
idx++;
}
}
}
@Override
protected Class<MetadataValueRest[]> getClassForEvaluation() {
return MetadataValueRest[].class;
}
private void deleteValue(Context context, Bitstream source, String target, String index) throws SQLException {
String[] metadata = Utils.tokenize(target);
List<MetadataValue> mm = bitstreamService.getMetadata(source, metadata[0], metadata[1], metadata[2], Item.ANY);
bitstreamService.clearMetadata(context, source, metadata[0], metadata[1], metadata[2], Item.ANY);
int idx = 0;
for(MetadataValue m : mm) {
Integer toDelete = Integer.parseInt(index);
if(idx != toDelete) {
bitstreamService.addMetadata(context, source, metadata[0], metadata[1], metadata[2], m.getLanguage(), m.getValue(), m.getAuthority(), m.getConfidence());
}
idx++;
}
}
}

View File

@@ -0,0 +1,55 @@
package org.dspace.app.rest.submit.factory.impl;
import java.sql.SQLException;
import java.util.List;
import org.dspace.app.rest.model.MetadataValueRest;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.BitstreamService;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.core.Utils;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.json.patch.LateObjectEvaluator;
public class BitstreamMetadataValueReplacePatchOperation extends ReplacePatchOperation<MetadataValueRest> {
@Autowired
BitstreamService bitstreamService;
@Autowired
ItemService itemService;
@Override
void replace(Context context, Request currentRequest, WorkspaceItem source, String path, Object value) throws Exception {
String[] split = path.split("/");
Item item = source.getItem();
List<Bundle> bundle = itemService.getBundles(item, "ORIGINAL");;
for(Bundle bb : bundle) {
int idx = 0;
for(Bitstream b : bb.getBitstreams()) {
if(idx==Integer.parseInt(split[0])) {
replaceValue(context, b, split[2], evaluateObject((LateObjectEvaluator)value));
}
idx++;
}
}
}
@Override
protected Class<MetadataValueRest[]> getClassForEvaluation() {
return MetadataValueRest[].class;
}
private void replaceValue(Context context, Bitstream source, String target, MetadataValueRest[] list) throws SQLException {
String[] metadata = Utils.tokenize(target);
bitstreamService.clearMetadata(context, source, metadata[0], metadata[1], metadata[2], Item.ANY);
for(MetadataValueRest ll : list) {
bitstreamService.addMetadata(context, source, metadata[0], metadata[1], metadata[2], ll.getLanguage(), ll.getValue(), ll.getAuthority(), ll.getConfidence());
}
}
}

View File

@@ -0,0 +1,63 @@
package org.dspace.app.rest.submit.factory.impl;
import java.util.List;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.BitstreamService;
import org.dspace.content.service.BundleService;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
public class BitstreamRemovePatchOperation extends RemovePatchOperation<String>{
@Autowired
ItemService itemService;
@Autowired
BundleService bundleService;
@Override
void remove(Context context, Request currentRequest, WorkspaceItem source, String path, Object value)
throws Exception {
Item item = source.getItem();
List<Bundle> bbb = itemService.getBundles(item, "ORIGINAL");
Bitstream bitstream = null;
external : for(Bundle bb : bbb) {
int idx = 0;
for(Bitstream b : bb.getBitstreams()) {
if(idx==Integer.parseInt(path)) {
bitstream = b;
break external;
}
idx++;
}
}
// remove bitstream from bundle..
// delete bundle if it's now empty
List<Bundle> bundles = bitstream.getBundles();
Bundle bundle = bundles.get(0);
bundleService.removeBitstream(context, bundle, bitstream);
List<Bitstream> bitstreams = bundle.getBitstreams();
// remove bundle if it's now empty
if (bitstreams.size() < 1)
{
itemService.removeBundle(context, item, bundle);
}
}
@Override
protected Class<String[]> getClassForEvaluation() {
return String[].class;
}
}

View File

@@ -0,0 +1,36 @@
package org.dspace.app.rest.submit.factory.impl;
import java.sql.SQLException;
import org.dspace.app.rest.model.MetadataValueRest;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.core.Utils;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.json.patch.LateObjectEvaluator;
public class ItemMetadataValueAddPatchOperation extends AddPatchOperation<MetadataValueRest> {
@Autowired
ItemService itemService;
@Override
void add(Context context, Request currentRequest, WorkspaceItem source, String path, Object value) throws Exception {
String[] split = path.split("/");
addValue(context, source, split[0], evaluateObject((LateObjectEvaluator)value));
}
@Override
protected Class<MetadataValueRest[]> getClassForEvaluation() {
return MetadataValueRest[].class;
}
private void addValue(Context context, WorkspaceItem source, String target, MetadataValueRest[] list) throws SQLException {
String[] metadata = Utils.tokenize(target);
for(MetadataValueRest ll : list) {
itemService.addMetadata(context, source.getItem(), metadata[0], metadata[1], metadata[2], ll.getLanguage(), ll.getValue(), ll.getAuthority(), ll.getConfidence());
}
}
}

View File

@@ -0,0 +1,46 @@
package org.dspace.app.rest.submit.factory.impl;
import java.sql.SQLException;
import java.util.List;
import org.dspace.app.rest.model.MetadataValueRest;
import org.dspace.content.Item;
import org.dspace.content.MetadataValue;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.core.Utils;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
public class ItemMetadataValueRemovePatchOperation extends RemovePatchOperation<MetadataValueRest> {
@Autowired
ItemService itemService;
@Override
void remove(Context context, Request currentRequest, WorkspaceItem source, String path, Object value) throws Exception {
String[] split = path.split("/");
deleteValue(context, source, split[0], split[1]);
}
@Override
protected Class<MetadataValueRest[]> getClassForEvaluation() {
return MetadataValueRest[].class;
}
private void deleteValue(Context context, WorkspaceItem source, String target, String index) throws SQLException {
String[] metadata = Utils.tokenize(target);
List<MetadataValue> mm = itemService.getMetadata(source.getItem(), metadata[0], metadata[1], metadata[2], Item.ANY);
itemService.clearMetadata(context, source.getItem(), metadata[0], metadata[1], metadata[2], Item.ANY);
int idx = 0;
for(MetadataValue m : mm) {
Integer toDelete = Integer.parseInt(index);
if(idx != toDelete) {
itemService.addMetadata(context, source.getItem(), metadata[0], metadata[1], metadata[2], m.getLanguage(), m.getValue(), m.getAuthority(), m.getConfidence());
}
idx++;
}
}
}

View File

@@ -0,0 +1,38 @@
package org.dspace.app.rest.submit.factory.impl;
import java.sql.SQLException;
import org.dspace.app.rest.model.MetadataValueRest;
import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.core.Utils;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.rest.webmvc.json.patch.LateObjectEvaluator;
public class ItemMetadataValueReplacePatchOperation extends ReplacePatchOperation<MetadataValueRest> {
@Autowired
ItemService itemService;
@Override
void replace(Context context, Request currentRequest, WorkspaceItem source, String path, Object value) throws Exception {
String[] split = path.split("/");
replaceValue(context, source, split[0], evaluateObject((LateObjectEvaluator)value));
}
@Override
protected Class<MetadataValueRest[]> getClassForEvaluation() {
return MetadataValueRest[].class;
}
private void replaceValue(Context context, WorkspaceItem source, String target, MetadataValueRest[] list) throws SQLException {
String[] metadata = Utils.tokenize(target);
itemService.clearMetadata(context, source.getItem(), metadata[0], metadata[1], metadata[2], Item.ANY);
for(MetadataValueRest ll : list) {
itemService.addMetadata(context, source.getItem(), metadata[0], metadata[1], metadata[2], ll.getLanguage(), ll.getValue(), ll.getAuthority(), ll.getConfidence());
}
}
}

View File

@@ -0,0 +1,26 @@
package org.dspace.app.rest.submit.factory.impl;
import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
public class LicenseRemovePatchOperation extends RemovePatchOperation<String> {
@Autowired
ItemService itemService;
@Override
void remove(Context context, Request currentRequest, WorkspaceItem source, String string, Object value) throws Exception {
Item item = source.getItem();
itemService.removeDSpaceLicense(context, item);
}
@Override
protected Class<String[]> getClassForEvaluation() {
return String[].class;
}
}

View File

@@ -0,0 +1,38 @@
package org.dspace.app.rest.submit.factory.impl;
import org.dspace.content.Item;
import org.dspace.content.LicenseUtils;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.ItemService;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.services.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
public class LicenseReplacePatchOperation extends ReplacePatchOperation<String> {
@Autowired
ItemService itemService;
@Override
void replace(Context context, Request currentRequest, WorkspaceItem source, String string, Object value) throws Exception {
Item item = source.getItem();
EPerson submitter = context.getCurrentUser();
// remove any existing DSpace license (just in case the user
// accepted it previously)
itemService.removeDSpaceLicense(context, item);
String license = LicenseUtils.getLicenseText(context.getCurrentLocale(), source.getCollection(), item,
submitter);
LicenseUtils.grantLicense(context, item, license, (String)value);
}
@Override
protected Class<String[]> getClassForEvaluation() {
return String[].class;
}
}

View File

@@ -0,0 +1,23 @@
package org.dspace.app.rest.submit.factory.impl;
import org.dspace.content.WorkspaceItem;
import org.dspace.core.Context;
import org.dspace.services.model.Request;
import org.springframework.data.rest.webmvc.json.patch.LateObjectEvaluator;
public abstract class PatchOperation<T extends Object> {
public abstract void perform(Context context, Request currentRequest, WorkspaceItem source, String path, Object value) throws Exception;
public T[] evaluateObject(LateObjectEvaluator value) {
T[] list = null;
if(value!=null) {
LateObjectEvaluator object = (LateObjectEvaluator)value;
list = (T[])object.evaluate(getClassForEvaluation());
}
return list;
}
protected abstract Class<T[]> getClassForEvaluation();
}

View File

@@ -0,0 +1,16 @@
package org.dspace.app.rest.submit.factory.impl;
import org.dspace.content.WorkspaceItem;
import org.dspace.core.Context;
import org.dspace.services.model.Request;
public abstract class RemovePatchOperation<T extends Object> extends PatchOperation<T> {
@Override
public void perform(Context context, Request currentRequest, WorkspaceItem source, String string, Object value) throws Exception{
remove(context, currentRequest, source, string, value);
}
abstract void remove(Context context,Request currentRequest,WorkspaceItem source,String string,Object value) throws Exception;
}

View File

@@ -0,0 +1,18 @@
package org.dspace.app.rest.submit.factory.impl;
import org.dspace.content.WorkspaceItem;
import org.dspace.core.Context;
import org.dspace.services.model.Request;
public abstract class ReplacePatchOperation<T extends Object> extends PatchOperation<T> {
@Override
public void perform(Context context, Request currentRequest, WorkspaceItem source, String string, Object value)
throws Exception {
replace(context, currentRequest, source, string, value);
}
abstract void replace(Context context, Request currentRequest, WorkspaceItem source, String string, Object value)
throws Exception;
}

View File

@@ -34,7 +34,7 @@ public class CollectionStep extends org.dspace.submit.step.SelectCollectionStep
@Override
public void doPatchProcessing(Context context, Request currentRequest, WorkspaceItem source, String operation,
String target, String index, Object value) {
String path, Object value) {
switch (operation) {
case "move":

View File

@@ -7,7 +7,6 @@
*/
package org.dspace.app.rest.submit.step;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@@ -15,18 +14,18 @@ import org.apache.log4j.Logger;
import org.dspace.app.rest.model.MetadataValueRest;
import org.dspace.app.rest.model.step.DataDescribe;
import org.dspace.app.rest.submit.AbstractRestProcessingStep;
import org.dspace.app.rest.submit.factory.PatchOperationFactory;
import org.dspace.app.rest.submit.factory.impl.PatchOperation;
import org.dspace.app.util.DCInput;
import org.dspace.app.util.DCInputSet;
import org.dspace.app.util.DCInputsReader;
import org.dspace.app.util.DCInputsReaderException;
import org.dspace.app.util.SubmissionStepConfig;
import org.dspace.content.Item;
import org.dspace.content.MetadataValue;
import org.dspace.content.WorkspaceItem;
import org.dspace.core.Context;
import org.dspace.core.Utils;
import org.dspace.services.model.Request;
import org.springframework.data.rest.webmvc.json.patch.LateObjectEvaluator;
/**
* Describe step for DSpace Spring Rest. Handle the exposition of metadata own by the in progress submission.
@@ -78,54 +77,11 @@ public class DescribeStep extends org.dspace.submit.step.DescribeStep implements
@Override
public void doPatchProcessing(Context context, Request currentRequest, WorkspaceItem source, String operation,
String target, String index, Object value) throws Exception {
MetadataValueRest[] list = null;
if(value!=null) {
LateObjectEvaluator object = (LateObjectEvaluator)value;
list = (MetadataValueRest[])object.evaluate(MetadataValueRest[].class);
}
switch (operation) {
case "add":
addValue(context, source, target, list);
break;
case "replace":
replaceValue(context, source, target, list);
break;
case "remove":
deleteValue(context, source, target, index);
break;
default:
throw new RuntimeException("Operation "+operation+" not yet implemented!");
}
}
private void deleteValue(Context context, WorkspaceItem source, String target, String index) throws SQLException {
String[] metadata = Utils.tokenize(target);
List<MetadataValue> mm = itemService.getMetadata(source.getItem(), metadata[0], metadata[1], metadata[2], Item.ANY);
itemService.clearMetadata(context, source.getItem(), metadata[0], metadata[1], metadata[2], Item.ANY);
int idx = 0;
for(MetadataValue m : mm) {
Integer toDelete = Integer.parseInt(index);
if(idx != toDelete) {
itemService.addMetadata(context, source.getItem(), metadata[0], metadata[1], metadata[2], m.getLanguage(), m.getValue(), m.getAuthority(), m.getConfidence());
}
idx++;
}
}
private void replaceValue(Context context, WorkspaceItem source, String target, MetadataValueRest[] list) throws SQLException {
String[] metadata = Utils.tokenize(target);
itemService.clearMetadata(context, source.getItem(), metadata[0], metadata[1], metadata[2], Item.ANY);
for(MetadataValueRest ll : list) {
itemService.addMetadata(context, source.getItem(), metadata[0], metadata[1], metadata[2], ll.getLanguage(), ll.getValue(), ll.getAuthority(), ll.getConfidence());
}
}
private void addValue(Context context, WorkspaceItem source, String target, MetadataValueRest[] list) throws SQLException {
String[] metadata = Utils.tokenize(target);
for(MetadataValueRest ll : list) {
itemService.addMetadata(context, source.getItem(), metadata[0], metadata[1], metadata[2], ll.getLanguage(), ll.getValue(), ll.getAuthority(), ll.getConfidence());
}
String path, Object value) throws Exception {
PatchOperation<MetadataValueRest> patchOperation = new PatchOperationFactory().instanceOf("metadatavalue", operation);
patchOperation.perform(context, currentRequest, source, path, value);
}
}

View File

@@ -7,25 +7,18 @@
*/
package org.dspace.app.rest.submit.step;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import org.atteo.evo.inflector.English;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.step.DataLicense;
import org.dspace.app.rest.submit.AbstractRestProcessingStep;
import org.dspace.app.rest.submit.factory.PatchOperationFactory;
import org.dspace.app.rest.submit.factory.impl.PatchOperation;
import org.dspace.app.util.SubmissionStepConfig;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Bitstream;
import org.dspace.content.Item;
import org.dspace.content.LicenseUtils;
import org.dspace.content.WorkspaceItem;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.services.model.Request;
import org.springframework.data.rest.webmvc.json.patch.LateObjectEvaluator;
/**
* License step for DSpace Spring Rest. Expose the license information about the in progress submission.
@@ -51,29 +44,13 @@ public class LicenseStep extends org.dspace.submit.step.LicenseStep implements A
@Override
public void doPatchProcessing(Context context, Request currentRequest, WorkspaceItem source, String operation,
String target, String index, Object value) throws Exception {
String path, Object value) throws Exception {
if("acceptanceDate".equals(target)) {
Item item = source.getItem();
EPerson submitter = context.getCurrentUser();
switch (operation) {
case "replace":
// remove any existing DSpace license (just in case the user
// accepted it previously)
itemService.removeDSpaceLicense(context, item);
String license = LicenseUtils.getLicenseText(context.getCurrentLocale(), source.getCollection(), item,
submitter);
if("acceptanceDate".equals(path)) {
PatchOperation<String> patchOperation = new PatchOperationFactory().instanceOf(path, operation);
patchOperation.perform(context, currentRequest, source, path, value);
LicenseUtils.grantLicense(context, item, license, (String)value);
break;
case "remove":
itemService.removeDSpaceLicense(context, item);
break;
default:
throw new RuntimeException("Operation " + operation + " not yet implemented!");
}
}
}
}

View File

@@ -9,10 +9,13 @@ package org.dspace.app.rest.submit.step;
import java.util.List;
import org.apache.commons.lang3.math.NumberUtils;
import org.dspace.app.rest.model.step.DataUpload;
import org.dspace.app.rest.model.step.UploadBitstreamRest;
import org.dspace.app.rest.submit.AbstractRestProcessingStep;
import org.dspace.app.rest.submit.SubmissionService;
import org.dspace.app.rest.submit.factory.PatchOperationFactory;
import org.dspace.app.rest.submit.factory.impl.PatchOperation;
import org.dspace.app.util.SubmissionStepConfig;
import org.dspace.content.Bitstream;
import org.dspace.content.Bundle;
@@ -20,45 +23,44 @@ import org.dspace.content.WorkspaceItem;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.services.model.Request;
import org.springframework.data.rest.webmvc.json.patch.LateObjectEvaluator;
/**
* Upload step for DSpace Spring Rest. Expose information about the bitstream uploaded for the in progress submission.
* Upload step for DSpace Spring Rest. Expose information about the bitstream
* uploaded for the in progress submission.
*
* @author Luigi Andrea Pascarelli (luigiandrea.pascarelli at 4science.it)
*
*/
public class UploadStep extends org.dspace.submit.step.UploadStep implements AbstractRestProcessingStep {
@Override
public DataUpload getData(WorkspaceItem obj, SubmissionStepConfig config) throws Exception {
DataUpload result = new DataUpload();
DataUpload result = new DataUpload();
List<Bundle> bundles = itemService.getBundles(obj.getItem(), Constants.CONTENT_BUNDLE_NAME);
for(Bundle bundle : bundles) {
for(Bitstream source : bundle.getBitstreams()) {
for (Bundle bundle : bundles) {
for (Bitstream source : bundle.getBitstreams()) {
UploadBitstreamRest b = SubmissionService.buildUploadBitstream(configurationService, source);
result.getFiles().add(b);
}
}
return result;
return result;
}
@Override
public void doPatchProcessing(Context context, Request currentRequest, WorkspaceItem source, String operation,
String target, String index, Object value) {
switch (operation) {
case "add":
break;
case "replace":
break;
case "remove":
break;
default:
throw new RuntimeException("Operation "+operation+" not yet implemented!");
String path, Object value) throws Exception {
String[] split = path.split("/");
String instance = "";
if("remove".equals(operation) && NumberUtils.isNumber(path)) {
instance = "bitstreamremove";
}
else {
instance = split[1];
}
PatchOperation<?> patchOperation = new PatchOperationFactory().instanceOf(instance, operation);
patchOperation.perform(context, currentRequest, source, path, value);
}
}

View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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/ -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="patchConfigurationService" class="org.dspace.app.rest.submit.PatchConfigurationService">
<property name="map">
<map>
<entry key="add">
<map>
<!-- WARNING do not change "metadatavalue" it is used in the Java logic;
the other key are dynamic discover from PATCH path -->
<entry key="metadatavalue">
<bean
class="org.dspace.app.rest.submit.factory.impl.ItemMetadataValueAddPatchOperation" />
</entry>
<entry key="metadata">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamMetadataValueAddPatchOperation" />
</entry>
</map>
</entry>
<entry key="remove">
<map>
<!-- WARNING do not change "metadatavalue" it is used in the Java logic;
the other key are dynamic discover from PATCH path -->
<entry key="metadatavalue">
<bean
class="org.dspace.app.rest.submit.factory.impl.ItemMetadataValueRemovePatchOperation" />
</entry>
<entry key="metadata">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamMetadataValueRemovePatchOperation" />
</entry>
<entry key="acceptanceDate">
<bean
class="org.dspace.app.rest.submit.factory.impl.LicenseRemovePatchOperation" />
</entry>
<!-- WARNING do not change "bitstreamremove" it is used in the Java
logic -->
<entry key="bitstreamremove">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamRemovePatchOperation" />
</entry>
<entry key="accessConditions">
<bean
class="org.dspace.app.rest.submit.factory.impl.AccessConditionRemovePatchOperation" />
</entry>
</map>
</entry>
<entry key="replace">
<map>
<!-- WARNING do not change "metadatavalue" it is used in the Java logic;
the other key are dynamic discover from PATCH path -->
<entry key="metadatavalue">
<bean
class="org.dspace.app.rest.submit.factory.impl.ItemMetadataValueReplacePatchOperation" />
</entry>
<entry key="metadata">
<bean
class="org.dspace.app.rest.submit.factory.impl.BitstreamMetadataValueReplacePatchOperation" />
</entry>
<entry key="acceptanceDate">
<bean
class="org.dspace.app.rest.submit.factory.impl.LicenseReplacePatchOperation" />
</entry>
<entry key="accessConditions">
<bean
class="org.dspace.app.rest.submit.factory.impl.AccessConditionReplacePatchOperation" />
</entry>
</map>
</entry>
</map>
</property>
</bean>
</beans>

View File

@@ -18,26 +18,7 @@
</list>
</property>
</bean>
<bean id="fieldBitstreamName" class="org.dspace.submit.model.SubmissionFormField">
<property name="selectableMetadata">
<list>
<bean class="org.dspace.submit.model.SelectableMetadata">
<property name="metadata" value="dc.title"></property>
</bean>
</list>
</property>
</bean>
<bean id="fieldBitstreamDescription" class="org.dspace.submit.model.SubmissionFormField">
<property name="selectableMetadata">
<list>
<bean class="org.dspace.submit.model.SelectableMetadata">
<property name="metadata" value="dc.description"></property>
</bean>
</list>
</property>
</bean>
<bean id="openAccess" class="org.dspace.submit.model.AccessConditionOption">
<property name="groupName" value="Anonymous"/>
<property name="policyType" value="openaccess"/>