
org.dspace.content.ItemComparator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dspace-api Show documentation
Show all versions of dspace-api Show documentation
DSpace core data model and service APIs.
The newest version!
/**
* 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.content;
import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.ItemService;
import org.dspace.sort.OrderFormat;
/**
* Compare two Items by their DCValues.
*
* The DCValues to be compared are specified by the element, qualifier and
* language parameters to the constructor. If the Item has more than one
* matching Metadatum, then the max parameter to the constructor specifies whether
* the maximum or minimum lexicographic value will be used.
*
* @author Peter Breton
* @version $Revision$
*/
public class ItemComparator implements Comparator, Serializable {
/**
* Dublin Core element
*/
protected String element;
/**
* Dublin Core qualifier
*/
protected String qualifier;
/**
* Language
*/
protected String language;
/**
* Whether maximum or minimum value will be used
*/
protected boolean max;
protected transient ItemService itemService
= ContentServiceFactory.getInstance().getItemService();
/**
* Constructor.
*
* @param element The Dublin Core element
* @param qualifier The Dublin Core qualifier
* @param language The language for the DCValues
* @param max If true, and there is more than one Metadatum for element,
* qualifier and language, then use the maximum value
* lexicographically; otherwise use the minimum value.
*/
public ItemComparator(String element, String qualifier, String language,
boolean max) {
this.element = element;
this.qualifier = qualifier;
this.language = language;
this.max = max;
}
/**
* Compare two Items by checking their DCValues for element, qualifier, and
* language.
*
*
* Return greater than or equal to 1 if the first is lexicographically greater than the second;
* less than or equal to -1 if the second is lexicographically greater than the first, and 0
* otherwise.
*
*
* @param first The first object to compare. Must be an object of type
* org.dspace.content.Item.
* @param second The second object to compare. Must be an object of type
* org.dspace.content.Item.
* @return greater than or equal 1 if the first is lexicographically greater than the second;
* less than or equal -1 if the second is lexicographically greater than the first, and
* 0 otherwise.
*/
@Override
public int compare(Object first, Object second) {
if ((!(first instanceof Item)) || (!(second instanceof Item))) {
throw new IllegalArgumentException("Arguments must be Items");
}
// Retrieve a chosen value from the array for comparison
String firstValue = getValue((Item) first);
String secondValue = getValue((Item) second);
if (firstValue == null && secondValue == null) {
return 0;
}
if (firstValue == null) {
return -1;
}
if (secondValue == null) {
return 1;
}
// See the javadoc for java.lang.String for an explanation
// of the return value.
return firstValue.compareTo(secondValue);
}
/**
* Return true if the object is equal to this one, false otherwise. Another
* object is equal to this one if it is also an ItemComparator, and has the
* same values for element, qualifier, language, and max.
*
* @param obj The object to compare to.
* @return True if the other object is equal to this one, false otherwise.
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ItemComparator)) {
return false;
}
ItemComparator other = (ItemComparator) obj;
return equalsWithNull(element, other.element)
&& equalsWithNull(qualifier, other.qualifier)
&& equalsWithNull(language, other.language) && (max == other.max);
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(element).append(qualifier).append(language).append(max).toHashCode();
}
/**
* @param first first operand
* @param second second operand
* @return true if the first string is equal to the second. Either or both
* may be null.
*/
protected boolean equalsWithNull(String first, String second) {
if (first == null && second == null) {
return true;
}
if (first == null || second == null) {
return false;
}
return first.equals(second);
}
/**
* Choose the canonical value from an item for comparison. If there are no
* values, null is returned. If there is exactly one value, then it is
* returned. Otherwise, either the maximum or minimum lexicographical value
* is returned; the parameter to the constructor says which.
*
* @param item The item to check
* @return The chosen value, or null
*/
protected String getValue(Item item) {
// The overall array and each element are guaranteed non-null
List dcvalues = itemService
.getMetadata(item, MetadataSchemaEnum.DC.getName(), element, qualifier, language);
if (dcvalues.isEmpty()) {
return null;
}
if (dcvalues.size() == 1) {
return normalizeTitle(dcvalues.get(0));
}
// We want to sort using Strings, but also keep track of
// which Metadatum the value came from.
Map values = new HashMap<>();
for (int i = 0; i < dcvalues.size(); i++) {
String value = dcvalues.get(i).getValue();
if (value != null) {
values.put(value, i);
}
}
if (values.isEmpty()) {
return null;
}
Set valueSet = values.keySet();
String chosen = max ? Collections.max(valueSet)
: Collections.min(valueSet);
int index = values.get(chosen);
return normalizeTitle(dcvalues.get(index));
}
/**
* Normalize the title of a Metadatum.
*
* @param value metadata value
* @return normalized title
*/
protected String normalizeTitle(MetadataValue value) {
if (!"title".equals(element)) {
return value.getValue();
}
return OrderFormat.makeSortString(value.getValue(), value.getLanguage(), OrderFormat.TITLE);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy