When moving metadata, make sure virtual metadata is handled correctly

This commit is contained in:
Ben Bosman
2020-02-18 12:50:55 +01:00
parent 205cb103dc
commit b8bca78e50
4 changed files with 107 additions and 59 deletions

View File

@@ -207,8 +207,8 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
} }
@Override @Override
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang, public List<MetadataValue> addMetadata(Context context, T dso, String schema, String element, String qualifier,
List<String> values) throws SQLException { String lang, List<String> values) throws SQLException {
MetadataField metadataField = metadataFieldService.findByElement(context, schema, element, qualifier); MetadataField metadataField = metadataFieldService.findByElement(context, schema, element, qualifier);
if (metadataField == null) { if (metadataField == null) {
throw new SQLException( throw new SQLException(
@@ -216,12 +216,12 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
"exist!"); "exist!");
} }
addMetadata(context, dso, metadataField, lang, values); return addMetadata(context, dso, metadataField, lang, values);
} }
@Override @Override
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang, public List<MetadataValue> addMetadata(Context context, T dso, String schema, String element, String qualifier,
List<String> values, List<String> authorities, List<Integer> confidences) String lang, List<String> values, List<String> authorities, List<Integer> confidences)
throws SQLException { throws SQLException {
// We will not verify that they are valid entries in the registry // We will not verify that they are valid entries in the registry
// until update() is called. // until update() is called.
@@ -231,15 +231,16 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
"bad_dublin_core schema=" + schema + "." + element + "." + qualifier + ". Metadata field does not " + "bad_dublin_core schema=" + schema + "." + element + "." + qualifier + ". Metadata field does not " +
"exist!"); "exist!");
} }
addMetadata(context, dso, metadataField, lang, values, authorities, confidences); return addMetadata(context, dso, metadataField, lang, values, authorities, confidences);
} }
@Override @Override
public void addMetadata(Context context, T dso, MetadataField metadataField, String lang, List<String> values, public List<MetadataValue> addMetadata(Context context, T dso, MetadataField metadataField, String lang,
List<String> authorities, List<Integer> confidences) List<String> values, List<String> authorities, List<Integer> confidences)
throws SQLException { throws SQLException {
boolean authorityControlled = metadataAuthorityService.isAuthorityControlled(metadataField); boolean authorityControlled = metadataAuthorityService.isAuthorityControlled(metadataField);
boolean authorityRequired = metadataAuthorityService.isAuthorityRequired(metadataField); boolean authorityRequired = metadataAuthorityService.isAuthorityRequired(metadataField);
List<MetadataValue> newMetadata = new ArrayList<>(values.size());
// We will not verify that they are valid entries in the registry // We will not verify that they are valid entries in the registry
// until update() is called. // until update() is called.
for (int i = 0; i < values.size(); i++) { for (int i = 0; i < values.size(); i++) {
@@ -250,6 +251,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
} }
} }
MetadataValue metadataValue = metadataValueService.create(context, dso, metadataField); MetadataValue metadataValue = metadataValueService.create(context, dso, metadataField);
newMetadata.add(metadataValue);
//Set place to list length of all metadatavalues for the given schema.element.qualifier combination. //Set place to list length of all metadatavalues for the given schema.element.qualifier combination.
// Subtract one to adhere to the 0 as first element rule // Subtract one to adhere to the 0 as first element rule
metadataValue.setPlace( metadataValue.setPlace(
@@ -304,29 +306,31 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
// metadataValueService.update(context, metadataValue); // metadataValueService.update(context, metadataValue);
dso.addDetails(metadataField.toString()); dso.addDetails(metadataField.toString());
} }
return newMetadata;
} }
@Override @Override
public void addMetadata(Context context, T dso, MetadataField metadataField, String language, String value, public MetadataValue addMetadata(Context context, T dso, MetadataField metadataField, String language,
String authority, int confidence) throws SQLException { String value, String authority, int confidence) throws SQLException {
addMetadata(context, dso, metadataField, language, Arrays.asList(value), Arrays.asList(authority), return addMetadata(context, dso, metadataField, language, Arrays.asList(value), Arrays.asList(authority),
Arrays.asList(confidence)); Arrays.asList(confidence)).get(0);
} }
@Override @Override
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang, public MetadataValue addMetadata(Context context, T dso, String schema, String element, String qualifier,
String value) throws SQLException { String lang, String value) throws SQLException {
addMetadata(context, dso, schema, element, qualifier, lang, Arrays.asList(value)); return addMetadata(context, dso, schema, element, qualifier, lang, Arrays.asList(value)).get(0);
} }
@Override @Override
public void addMetadata(Context context, T dso, MetadataField metadataField, String language, String value) public MetadataValue addMetadata(Context context, T dso, MetadataField metadataField, String language, String value)
throws SQLException { throws SQLException {
addMetadata(context, dso, metadataField, language, Arrays.asList(value)); return addMetadata(context, dso, metadataField, language, Arrays.asList(value)).get(0);
} }
@Override @Override
public void addMetadata(Context context, T dso, MetadataField metadataField, String language, List<String> values) public List<MetadataValue> addMetadata(Context context, T dso, MetadataField metadataField, String language,
List<String> values)
throws SQLException { throws SQLException {
if (metadataField != null) { if (metadataField != null) {
String fieldKey = metadataAuthorityService String fieldKey = metadataAuthorityService
@@ -343,18 +347,19 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
getAuthoritiesAndConfidences(fieldKey, null, values, authorities, confidences, i); getAuthoritiesAndConfidences(fieldKey, null, values, authorities, confidences, i);
} }
} }
addMetadata(context, dso, metadataField, language, values, authorities, confidences); return addMetadata(context, dso, metadataField, language, values, authorities, confidences);
} else { } else {
addMetadata(context, dso, metadataField, language, values, null, null); return addMetadata(context, dso, metadataField, language, values, null, null);
} }
} }
return new ArrayList<>(0);
} }
@Override @Override
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang, public MetadataValue addMetadata(Context context, T dso, String schema, String element, String qualifier,
String value, String authority, int confidence) throws SQLException { String lang, String value, String authority, int confidence) throws SQLException {
addMetadata(context, dso, schema, element, qualifier, lang, Arrays.asList(value), Arrays.asList(authority), return addMetadata(context, dso, schema, element, qualifier, lang, Arrays.asList(value),
Arrays.asList(confidence)); Arrays.asList(authority), Arrays.asList(confidence)).get(0);
} }
@Override @Override
@@ -664,18 +669,20 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
List<MetadataValue> list = getMetadata(dso, schema, element, qualifier); List<MetadataValue> list = getMetadata(dso, schema, element, qualifier);
clearMetadata(context, dso, schema, element, qualifier, Item.ANY);
int idx = 0; int idx = 0;
int place = 0;
boolean last = true; boolean last = true;
for (MetadataValue rr : list) { for (MetadataValue rr : list) {
if (idx == index) { if (idx == index) {
addMetadata(context, dso, schema, element, qualifier, MetadataValue newMetadata = addMetadata(context, dso, schema, element, qualifier,
lang, value, authority, confidence); lang, value, authority, confidence);
moveSingleMetadataValue(context, dso, schema, element, qualifier, place, newMetadata);
place++;
last = false; last = false;
} }
addMetadata(context, dso, schema, element, qualifier, moveSingleMetadataValue(context, dso, schema, element, qualifier, place, rr);
rr.getLanguage(), rr.getValue(), rr.getAuthority(), rr.getConfidence()); place++;
idx++; idx++;
} }
if (last) { if (last) {
@@ -699,8 +706,6 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
"The \"from\" location MUST exist for the operation to be successful. Idx:" + from); "The \"from\" location MUST exist for the operation to be successful. Idx:" + from);
} }
clearMetadata(context, dso, schema, element, qualifier, Item.ANY);
int idx = 0; int idx = 0;
MetadataValue moved = null; MetadataValue moved = null;
for (MetadataValue md : list) { for (MetadataValue md : list) {
@@ -712,30 +717,39 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
} }
idx = 0; idx = 0;
int place = 0;
boolean last = true; boolean last = true;
for (MetadataValue rr : list) { for (MetadataValue rr : list) {
if (idx == to && to < from) { if (idx == to && to < from) {
addMetadata(context, dso, schema, element, qualifier, moved.getLanguage(), moved.getValue(), moveSingleMetadataValue(context, dso, schema, element, qualifier, place, moved);
moved.getAuthority(), moved.getConfidence()); place++;
last = false; last = false;
} }
if (idx != from) { if (idx != from) {
addMetadata(context, dso, schema, element, qualifier, rr.getLanguage(), rr.getValue(), moveSingleMetadataValue(context, dso, schema, element, qualifier, place, rr);
rr.getAuthority(), rr.getConfidence()); place++;
} }
if (idx == to && to > from) { if (idx == to && to > from) {
addMetadata(context, dso, schema, element, qualifier, moved.getLanguage(), moved.getValue(), moveSingleMetadataValue(context, dso, schema, element, qualifier, place, moved);
moved.getAuthority(), moved.getConfidence()); place++;
last = false; last = false;
} }
idx++; idx++;
} }
if (last) { if (last) {
addMetadata(context, dso, schema, element, qualifier, moved.getLanguage(), moved.getValue(), moveSingleMetadataValue(context, dso, schema, element, qualifier, place, moved);
moved.getAuthority(), moved.getConfidence());
} }
} }
/**
* Supports moving metadata by updating the place of the metadata value
*/
protected void moveSingleMetadataValue(Context context, T dso, String schema, String element,
String qualifier, int place, MetadataValue rr) throws SQLException {
//just move the metadata
rr.setPlace(place);
}
@Override @Override
public void replaceMetadata(Context context, T dso, String schema, String element, String qualifier, String lang, public void replaceMetadata(Context context, T dso, String schema, String element, String qualifier, String lang,
String value, String authority, int confidence, int index) throws SQLException { String value, String authority, int confidence, int index) throws SQLException {

View File

@@ -1372,6 +1372,33 @@ prevent the generation of resource policy entry values with null dspace_object a
} }
/**
* Supports moving metadata by adding the metadata value or updating the place of the relationship
*/
@Override
protected void moveSingleMetadataValue(Context context, Item dso, String schema, String element,
String qualifier, int place, MetadataValue rr) throws SQLException {
if (rr instanceof RelationshipMetadataValue) {
try {
//Retrieve the applicable relationship
Relationship rs = relationshipService.find(context,
((RelationshipMetadataValue) rr).getRelationshipId());
if (rs.getLeftItem() == dso) {
rs.setLeftPlace(place);
} else {
rs.setRightPlace(place);
}
relationshipService.update(context, rs);
} catch (Exception e) {
//should not occur, otherwise metadata can't be updated either
log.error("An error occurred while moving " + rr.getAuthority() + " for item " + dso.getID(), e);
}
} else {
//just move the metadata
rr.setPlace(place);
}
}
/** /**
* This method will sort the List of MetadataValue objects based on the MetadataSchema, MetadataField Element, * This method will sort the List of MetadataValue objects based on the MetadataSchema, MetadataField Element,
* MetadataField Qualifier and MetadataField Place in that order. * MetadataField Qualifier and MetadataField Place in that order.

View File

@@ -7,6 +7,8 @@
*/ */
package org.dspace.content; package org.dspace.content;
import org.dspace.core.Constants;
/** /**
* This class is used as a representation of MetadataValues for the MetadataValues that are derived from the * This class is used as a representation of MetadataValues for the MetadataValues that are derived from the
* Relationships that the item has. This includes the useForPlace property which we'll have to use to determine * Relationships that the item has. This includes the useForPlace property which we'll have to use to determine
@@ -57,4 +59,8 @@ public class RelationshipMetadataValue extends MetadataValue {
} }
return super.equals(obj); return super.equals(obj);
} }
public int getRelationshipId() {
return Integer.parseInt(getAuthority().substring(Constants.VIRTUAL_AUTHORITY_PREFIX.length()));
}
} }

View File

@@ -202,8 +202,8 @@ public interface DSpaceObjectService<T extends DSpaceObject> {
* @param values the values to add. * @param values the values to add.
* @throws SQLException if database error * @throws SQLException if database error
*/ */
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang, public List<MetadataValue> addMetadata(Context context, T dso, String schema, String element, String qualifier,
List<String> values) throws SQLException; String lang, List<String> values) throws SQLException;
/** /**
* Add metadata fields. These are appended to existing values. * Add metadata fields. These are appended to existing values.
@@ -225,8 +225,8 @@ public interface DSpaceObjectService<T extends DSpaceObject> {
* @param confidences the authority confidence (default 0) * @param confidences the authority confidence (default 0)
* @throws SQLException if database error * @throws SQLException if database error
*/ */
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang, public List<MetadataValue> addMetadata(Context context, T dso, String schema, String element, String qualifier,
List<String> values, List<String> authorities, List<Integer> confidences) String lang, List<String> values, List<String> authorities, List<Integer> confidences)
throws SQLException; throws SQLException;
/** /**
@@ -244,9 +244,10 @@ public interface DSpaceObjectService<T extends DSpaceObject> {
* @param authorities the external authority key for this value (or null) * @param authorities the external authority key for this value (or null)
* @param confidences the authority confidence (default 0) * @param confidences the authority confidence (default 0)
* @throws SQLException if database error * @throws SQLException if database error
* @return
*/ */
public void addMetadata(Context context, T dso, MetadataField metadataField, String lang, List<String> values, public List<MetadataValue> addMetadata(Context context, T dso, MetadataField metadataField, String lang,
List<String> authorities, List<Integer> confidences) throws SQLException; List<String> values, List<String> authorities, List<Integer> confidences) throws SQLException;
/** /**
* Shortcut for {@link #addMetadata(Context, DSpaceObject, MetadataField, String, List, List, List)} when a single * Shortcut for {@link #addMetadata(Context, DSpaceObject, MetadataField, String, List, List, List)} when a single
@@ -261,14 +262,14 @@ public interface DSpaceObjectService<T extends DSpaceObject> {
* @param confidence * @param confidence
* @throws SQLException * @throws SQLException
*/ */
public void addMetadata(Context context, T dso, MetadataField metadataField, String language, String value, public MetadataValue addMetadata(Context context, T dso, MetadataField metadataField, String language,
String authority, int confidence) throws SQLException; String value, String authority, int confidence) throws SQLException;
public void addMetadata(Context context, T dso, MetadataField metadataField, String language, String value) public MetadataValue addMetadata(Context context, T dso, MetadataField metadataField, String language, String value)
throws SQLException; throws SQLException;
public void addMetadata(Context context, T dso, MetadataField metadataField, String language, List<String> values) public List<MetadataValue> addMetadata(Context context, T dso, MetadataField metadataField, String language,
throws SQLException; List<String> values) throws SQLException;
/** /**
* Add a single metadata field. This is appended to existing * Add a single metadata field. This is appended to existing
@@ -287,8 +288,8 @@ public interface DSpaceObjectService<T extends DSpaceObject> {
* @param value the value to add. * @param value the value to add.
* @throws SQLException if database error * @throws SQLException if database error
*/ */
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang, public MetadataValue addMetadata(Context context, T dso, String schema, String element, String qualifier,
String value) throws SQLException; String lang, String value) throws SQLException;
/** /**
* Add a single metadata field. This is appended to existing * Add a single metadata field. This is appended to existing
@@ -309,8 +310,8 @@ public interface DSpaceObjectService<T extends DSpaceObject> {
* @param confidence the authority confidence (default 0) * @param confidence the authority confidence (default 0)
* @throws SQLException if database error * @throws SQLException if database error
*/ */
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang, public MetadataValue addMetadata(Context context, T dso, String schema, String element, String qualifier,
String value, String authority, int confidence) throws SQLException; String lang, String value, String authority, int confidence) throws SQLException;
/** /**
* Clear metadata values. As with <code>getDC</code> above, * Clear metadata values. As with <code>getDC</code> above,