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
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang,
List<String> values) throws SQLException {
public List<MetadataValue> addMetadata(Context context, T dso, String schema, String element, String qualifier,
String lang, List<String> values) throws SQLException {
MetadataField metadataField = metadataFieldService.findByElement(context, schema, element, qualifier);
if (metadataField == null) {
throw new SQLException(
@@ -216,12 +216,12 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
"exist!");
}
addMetadata(context, dso, metadataField, lang, values);
return addMetadata(context, dso, metadataField, lang, values);
}
@Override
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang,
List<String> values, List<String> authorities, List<Integer> confidences)
public List<MetadataValue> addMetadata(Context context, T dso, String schema, String element, String qualifier,
String lang, List<String> values, List<String> authorities, List<Integer> confidences)
throws SQLException {
// We will not verify that they are valid entries in the registry
// 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 " +
"exist!");
}
addMetadata(context, dso, metadataField, lang, values, authorities, confidences);
return addMetadata(context, dso, metadataField, lang, values, authorities, confidences);
}
@Override
public void addMetadata(Context context, T dso, MetadataField metadataField, String lang, List<String> values,
List<String> authorities, List<Integer> confidences)
public List<MetadataValue> addMetadata(Context context, T dso, MetadataField metadataField, String lang,
List<String> values, List<String> authorities, List<Integer> confidences)
throws SQLException {
boolean authorityControlled = metadataAuthorityService.isAuthorityControlled(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
// until update() is called.
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);
newMetadata.add(metadataValue);
//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
metadataValue.setPlace(
@@ -304,29 +306,31 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
// metadataValueService.update(context, metadataValue);
dso.addDetails(metadataField.toString());
}
return newMetadata;
}
@Override
public void addMetadata(Context context, T dso, MetadataField metadataField, String language, String value,
String authority, int confidence) throws SQLException {
addMetadata(context, dso, metadataField, language, Arrays.asList(value), Arrays.asList(authority),
Arrays.asList(confidence));
public MetadataValue addMetadata(Context context, T dso, MetadataField metadataField, String language,
String value, String authority, int confidence) throws SQLException {
return addMetadata(context, dso, metadataField, language, Arrays.asList(value), Arrays.asList(authority),
Arrays.asList(confidence)).get(0);
}
@Override
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang,
String value) throws SQLException {
addMetadata(context, dso, schema, element, qualifier, lang, Arrays.asList(value));
public MetadataValue addMetadata(Context context, T dso, String schema, String element, String qualifier,
String lang, String value) throws SQLException {
return addMetadata(context, dso, schema, element, qualifier, lang, Arrays.asList(value)).get(0);
}
@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 {
addMetadata(context, dso, metadataField, language, Arrays.asList(value));
return addMetadata(context, dso, metadataField, language, Arrays.asList(value)).get(0);
}
@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 {
if (metadataField != null) {
String fieldKey = metadataAuthorityService
@@ -343,18 +347,19 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
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 {
addMetadata(context, dso, metadataField, language, values, null, null);
return addMetadata(context, dso, metadataField, language, values, null, null);
}
}
return new ArrayList<>(0);
}
@Override
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang,
String value, String authority, int confidence) throws SQLException {
addMetadata(context, dso, schema, element, qualifier, lang, Arrays.asList(value), Arrays.asList(authority),
Arrays.asList(confidence));
public MetadataValue addMetadata(Context context, T dso, String schema, String element, String qualifier,
String lang, String value, String authority, int confidence) throws SQLException {
return addMetadata(context, dso, schema, element, qualifier, lang, Arrays.asList(value),
Arrays.asList(authority), Arrays.asList(confidence)).get(0);
}
@Override
@@ -664,18 +669,20 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
List<MetadataValue> list = getMetadata(dso, schema, element, qualifier);
clearMetadata(context, dso, schema, element, qualifier, Item.ANY);
int idx = 0;
int place = 0;
boolean last = true;
for (MetadataValue rr : list) {
if (idx == index) {
addMetadata(context, dso, schema, element, qualifier,
MetadataValue newMetadata = addMetadata(context, dso, schema, element, qualifier,
lang, value, authority, confidence);
moveSingleMetadataValue(context, dso, schema, element, qualifier, place, newMetadata);
place++;
last = false;
}
addMetadata(context, dso, schema, element, qualifier,
rr.getLanguage(), rr.getValue(), rr.getAuthority(), rr.getConfidence());
moveSingleMetadataValue(context, dso, schema, element, qualifier, place, rr);
place++;
idx++;
}
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);
}
clearMetadata(context, dso, schema, element, qualifier, Item.ANY);
int idx = 0;
MetadataValue moved = null;
for (MetadataValue md : list) {
@@ -712,30 +717,39 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
}
idx = 0;
int place = 0;
boolean last = true;
for (MetadataValue rr : list) {
if (idx == to && to < from) {
addMetadata(context, dso, schema, element, qualifier, moved.getLanguage(), moved.getValue(),
moved.getAuthority(), moved.getConfidence());
moveSingleMetadataValue(context, dso, schema, element, qualifier, place, moved);
place++;
last = false;
}
if (idx != from) {
addMetadata(context, dso, schema, element, qualifier, rr.getLanguage(), rr.getValue(),
rr.getAuthority(), rr.getConfidence());
moveSingleMetadataValue(context, dso, schema, element, qualifier, place, rr);
place++;
}
if (idx == to && to > from) {
addMetadata(context, dso, schema, element, qualifier, moved.getLanguage(), moved.getValue(),
moved.getAuthority(), moved.getConfidence());
moveSingleMetadataValue(context, dso, schema, element, qualifier, place, moved);
place++;
last = false;
}
idx++;
}
if (last) {
addMetadata(context, dso, schema, element, qualifier, moved.getLanguage(), moved.getValue(),
moved.getAuthority(), moved.getConfidence());
moveSingleMetadataValue(context, dso, schema, element, qualifier, place, moved);
}
}
/**
* 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
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 {

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,
* MetadataField Qualifier and MetadataField Place in that order.

View File

@@ -7,6 +7,8 @@
*/
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
* 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);
}
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.
* @throws SQLException if database error
*/
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang,
List<String> values) throws SQLException;
public List<MetadataValue> addMetadata(Context context, T dso, String schema, String element, String qualifier,
String lang, List<String> values) throws SQLException;
/**
* 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)
* @throws SQLException if database error
*/
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang,
List<String> values, List<String> authorities, List<Integer> confidences)
public List<MetadataValue> addMetadata(Context context, T dso, String schema, String element, String qualifier,
String lang, List<String> values, List<String> authorities, List<Integer> confidences)
throws SQLException;
/**
@@ -244,9 +244,10 @@ public interface DSpaceObjectService<T extends DSpaceObject> {
* @param authorities the external authority key for this value (or null)
* @param confidences the authority confidence (default 0)
* @throws SQLException if database error
* @return
*/
public void addMetadata(Context context, T dso, MetadataField metadataField, String lang, List<String> values,
List<String> authorities, List<Integer> confidences) throws SQLException;
public List<MetadataValue> addMetadata(Context context, T dso, MetadataField metadataField, String lang,
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
@@ -261,14 +262,14 @@ public interface DSpaceObjectService<T extends DSpaceObject> {
* @param confidence
* @throws SQLException
*/
public void addMetadata(Context context, T dso, MetadataField metadataField, String language, String value,
String authority, int confidence) throws SQLException;
public MetadataValue addMetadata(Context context, T dso, MetadataField metadataField, String language,
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;
public void addMetadata(Context context, T dso, MetadataField metadataField, String language, List<String> values)
throws SQLException;
public List<MetadataValue> addMetadata(Context context, T dso, MetadataField metadataField, String language,
List<String> values) throws SQLException;
/**
* 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.
* @throws SQLException if database error
*/
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang,
String value) throws SQLException;
public MetadataValue addMetadata(Context context, T dso, String schema, String element, String qualifier,
String lang, String value) throws SQLException;
/**
* 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)
* @throws SQLException if database error
*/
public void addMetadata(Context context, T dso, String schema, String element, String qualifier, String lang,
String value, String authority, int confidence) throws SQLException;
public MetadataValue addMetadata(Context context, T dso, String schema, String element, String qualifier,
String lang, String value, String authority, int confidence) throws SQLException;
/**
* Clear metadata values. As with <code>getDC</code> above,