diff --git a/dspace-api/src/main/java/org/dspace/authority/indexer/DSpaceAuthorityIndexer.java b/dspace-api/src/main/java/org/dspace/authority/indexer/DSpaceAuthorityIndexer.java index 2cb12f6e3e..2065cf67e4 100644 --- a/dspace-api/src/main/java/org/dspace/authority/indexer/DSpaceAuthorityIndexer.java +++ b/dspace-api/src/main/java/org/dspace/authority/indexer/DSpaceAuthorityIndexer.java @@ -107,7 +107,7 @@ public class DSpaceAuthorityIndexer implements AuthorityIndexerInterface { // 1. iterate over the metadata values String metadataField = metadataFields.get(currentFieldIndex); - DCValue[] values = currentItem.getMetadata(metadataField); + DCValue[] values = currentItem.getMetadataByMetadataString(metadataField); if (currentMetadataIndex < values.length) { prepareNextValue(metadataField, values[currentMetadataIndex]); diff --git a/dspace-api/src/main/java/org/dspace/content/DSpaceObject.java b/dspace-api/src/main/java/org/dspace/content/DSpaceObject.java index b30ab05fdb..4635ef7183 100644 --- a/dspace-api/src/main/java/org/dspace/content/DSpaceObject.java +++ b/dspace-api/src/main/java/org/dspace/content/DSpaceObject.java @@ -9,6 +9,8 @@ package org.dspace.content; import java.sql.SQLException; import java.util.*; + +import org.apache.commons.lang.ArrayUtils; import org.apache.log4j.Logger; import org.apache.commons.lang.StringUtils; @@ -717,6 +719,86 @@ public abstract class DSpaceObject return null; } + public List getMetadata(String mdString, String authority) { + String[] elements = getElements(mdString); + return getMetadata(elements[0], elements[1], elements[2], elements[3], authority); + } + + public List getMetadata(String schema, String element, String qualifier, String lang, String authority) { + DCValue[] metadata = getMetadata(schema, element, qualifier, lang); + List dcValues = Arrays.asList(metadata); + if (!authority.equals(Item.ANY)) { + Iterator iterator = dcValues.iterator(); + while (iterator.hasNext()) { + DCValue dcValue = iterator.next(); + if (!authority.equals(dcValue.authority)) { + iterator.remove(); + } + } + } + return dcValues; + } + + + /** + * Splits "schema.element.qualifier.language" into an array. + *

+ * The returned array will always have length >= 4 + *

+ * Values in the returned array can be empty or null. + */ + public static String[] getElements(String fieldName) { + String[] tokens = StringUtils.split(fieldName, "."); + + int add = 4 - tokens.length; + if (add > 0) { + tokens = (String[]) ArrayUtils.addAll(tokens, new String[add]); + } + + return tokens; + } + + /** + * Splits "schema.element.qualifier.language" into an array. + *

+ * The returned array will always have length >= 4 + *

+ * When @param fill is true, elements that would be empty or null are replaced by Item.ANY + */ + public static String[] getElementsFilled(String fieldName) { + String[] elements = getElements(fieldName); + for (int i = 0; i < elements.length; i++) { + if (StringUtils.isBlank(elements[i])) { + elements[i] = Item.ANY; + } + } + return elements; + } + + public void replaceMetadataValue(DCValue oldValue, DCValue newValue) + { + // check both dcvalues are for the same field + if (oldValue.hasSameFieldAs(newValue)) { + + String schema = oldValue.schema; + String element = oldValue.element; + String qualifier = oldValue.qualifier; + + // Save all metadata for this field + DCValue[] dcvalues = getMetadata(schema, element, qualifier, Item.ANY); + clearMetadata(schema, element, qualifier, Item.ANY); + for (DCValue dcvalue : dcvalues) { + if (dcvalue.equals(oldValue)) { + addMetadata(schema, element, qualifier, newValue.language, newValue.value, newValue.authority, newValue.confidence); + } else { + addMetadata(schema, element, qualifier, dcvalue.language, dcvalue.value, dcvalue.authority, dcvalue.confidence); + } + } + } + } + + + /** * Add Dublin Core metadata fields. These are appended to existing values. * Use clearDC to remove values. The ordering of values diff --git a/dspace-api/src/main/java/org/dspace/content/Item.java b/dspace-api/src/main/java/org/dspace/content/Item.java index decc14b0b0..2efbf81f96 100644 --- a/dspace-api/src/main/java/org/dspace/content/Item.java +++ b/dspace-api/src/main/java/org/dspace/content/Item.java @@ -24,9 +24,6 @@ import org.dspace.authorize.AuthorizeManager; import org.dspace.authorize.ResourcePolicy; import org.dspace.browse.BrowseException; import org.dspace.browse.IndexBrowse; -import org.dspace.content.authority.ChoiceAuthorityManager; -import org.dspace.content.authority.Choices; -import org.dspace.content.authority.MetadataAuthorityManager; import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.core.LogManager; @@ -35,7 +32,6 @@ import org.dspace.content.authority.ChoiceAuthorityManager; import org.dspace.event.Event; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; -import org.dspace.event.Event; import org.dspace.handle.HandleManager; import org.dspace.identifier.IdentifierException; import org.dspace.identifier.IdentifierService; @@ -45,12 +41,6 @@ import org.dspace.storage.rdbms.TableRowIterator; import org.dspace.utils.DSpace; import org.dspace.versioning.VersioningService; -import java.io.IOException; -import java.io.InputStream; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.util.*; - /** * Class representing an item in DSpace. *

@@ -254,6 +244,32 @@ public class Item extends DSpaceObject return new ItemIterator(context, rows); } + public static ItemIterator findByMetadataFieldAuthority(Context context, String mdString, String authority) throws SQLException, AuthorizeException, IOException { + String[] elements = getElementsFilled(mdString); + String schema = elements[0], element = elements[1], qualifier = elements[2]; + MetadataSchema mds = MetadataSchema.find(context, schema); + if (mds == null) { + throw new IllegalArgumentException("No such metadata schema: " + schema); + } + MetadataField mdf = MetadataField.findByElement(context, mds.getSchemaID(), element, qualifier); + if (mdf == null) { + throw new IllegalArgumentException( + "No such metadata field: schema=" + schema + ", element=" + element + ", qualifier=" + qualifier); + } + + String query = "SELECT item.* FROM metadatavalue,item WHERE item.in_archive='1' " + + "AND item.item_id = metadatavalue.item_id AND metadata_field_id = ?"; + TableRowIterator rows = null; + if (Item.ANY.equals(authority)) { + rows = DatabaseManager.queryTable(context, "item", query, mdf.getFieldID()); + } else { + query += " AND metadatavalue.authority = ?"; + rows = DatabaseManager.queryTable(context, "item", query, mdf.getFieldID(), authority); + } + return new ItemIterator(context, rows); + } + + /** * Get the internal ID of this item. In general, this shouldn't be exposed * to users