use of org.dspace.content.MetadataValue in project DSpace by DSpace.
the class ItemIndexFactoryImpl method addDiscoveryFields.
@Override
public void addDiscoveryFields(SolrInputDocument doc, Context context, Item item, List<DiscoveryConfiguration> discoveryConfigurations) throws SQLException, IOException {
// use the item service to retrieve the owning collection also for inprogress submission
Collection collection = (Collection) itemService.getParentObject(context, item);
// Keep a list of our sort values which we added, sort values can only be added once
List<String> sortFieldsAdded = new ArrayList<>();
Map<String, List<DiscoverySearchFilter>> searchFilters = new HashMap<>();
Set<String> hitHighlightingFields = new HashSet<>();
try {
// A map used to save each sidebarFacet config by the metadata fields
Map<String, DiscoverySortFieldConfiguration> sortFields = new HashMap<>();
Map<String, DiscoveryRecentSubmissionsConfiguration> recentSubmissionsConfigurationMap = new HashMap<>();
Set<String> moreLikeThisFields = new HashSet<>();
// some configuration are returned multiple times, skip them to save CPU cycles
Set<String> appliedConf = new HashSet<>();
// it is common to have search filter shared between multiple configurations
Set<String> appliedDiscoverySearchFilter = new HashSet<>();
for (DiscoveryConfiguration discoveryConfiguration : discoveryConfigurations) {
if (appliedConf.contains(discoveryConfiguration.getId())) {
continue;
} else {
appliedConf.add(discoveryConfiguration.getId());
}
for (int i = 0; i < discoveryConfiguration.getSearchFilters().size(); i++) {
if (appliedDiscoverySearchFilter.contains(discoveryConfiguration.getSearchFilters().get(i).getIndexFieldName())) {
continue;
} else {
appliedDiscoverySearchFilter.add(discoveryConfiguration.getSearchFilters().get(i).getIndexFieldName());
}
List<MetadataValue> metadataValueList = new LinkedList<>();
boolean shouldExposeMinMax = false;
DiscoverySearchFilter discoverySearchFilter = discoveryConfiguration.getSearchFilters().get(i);
if (StringUtils.equalsIgnoreCase(discoverySearchFilter.getFilterType(), "facet")) {
if (((DiscoverySearchFilterFacet) discoverySearchFilter).exposeMinAndMaxValue()) {
shouldExposeMinMax = true;
}
}
for (int j = 0; j < discoverySearchFilter.getMetadataFields().size(); j++) {
String metadataField = discoverySearchFilter.getMetadataFields().get(j);
List<DiscoverySearchFilter> resultingList;
if (searchFilters.get(metadataField) != null) {
resultingList = searchFilters.get(metadataField);
} else {
// New metadata field, create a new list for it
resultingList = new ArrayList<>();
}
if (shouldExposeMinMax) {
String[] splittedMetadataField = metadataField.split("\\.");
String schema = splittedMetadataField[0];
String element = splittedMetadataField.length > 1 ? splittedMetadataField[1] : null;
String qualifier = splittedMetadataField.length > 2 ? splittedMetadataField[2] : null;
metadataValueList.addAll(itemService.getMetadata(item, schema, element, qualifier, Item.ANY));
}
resultingList.add(discoverySearchFilter);
searchFilters.put(metadataField, resultingList);
}
if (!metadataValueList.isEmpty() && shouldExposeMinMax) {
metadataValueList.sort((mdv1, mdv2) -> mdv1.getValue().compareTo(mdv2.getValue()));
MetadataValue firstMetadataValue = metadataValueList.get(0);
MetadataValue lastMetadataValue = metadataValueList.get(metadataValueList.size() - 1);
doc.addField(discoverySearchFilter.getIndexFieldName() + "_min", firstMetadataValue.getValue());
doc.addField(discoverySearchFilter.getIndexFieldName() + "_min_sort", firstMetadataValue.getValue());
doc.addField(discoverySearchFilter.getIndexFieldName() + "_max", lastMetadataValue.getValue());
doc.addField(discoverySearchFilter.getIndexFieldName() + "_max_sort", lastMetadataValue.getValue());
}
}
DiscoverySortConfiguration sortConfiguration = discoveryConfiguration.getSearchSortConfiguration();
if (sortConfiguration != null) {
for (DiscoverySortFieldConfiguration discoverySortConfiguration : sortConfiguration.getSortFields()) {
sortFields.put(discoverySortConfiguration.getMetadataField(), discoverySortConfiguration);
}
}
DiscoveryRecentSubmissionsConfiguration recentSubmissionConfiguration = discoveryConfiguration.getRecentSubmissionConfiguration();
if (recentSubmissionConfiguration != null) {
recentSubmissionsConfigurationMap.put(recentSubmissionConfiguration.getMetadataSortField(), recentSubmissionConfiguration);
}
DiscoveryHitHighlightingConfiguration hitHighlightingConfiguration = discoveryConfiguration.getHitHighlightingConfiguration();
if (hitHighlightingConfiguration != null) {
List<DiscoveryHitHighlightFieldConfiguration> fieldConfigurations = hitHighlightingConfiguration.getMetadataFields();
for (DiscoveryHitHighlightFieldConfiguration fieldConfiguration : fieldConfigurations) {
hitHighlightingFields.add(fieldConfiguration.getField());
}
}
DiscoveryMoreLikeThisConfiguration moreLikeThisConfiguration = discoveryConfiguration.getMoreLikeThisConfiguration();
if (moreLikeThisConfiguration != null) {
for (String metadataField : moreLikeThisConfiguration.getSimilarityMetadataFields()) {
moreLikeThisFields.add(metadataField);
}
}
}
List<String> toProjectionFields = new ArrayList<>();
String[] projectionFields = DSpaceServicesFactory.getInstance().getConfigurationService().getArrayProperty("discovery.index.projection");
if (projectionFields != null) {
for (String field : projectionFields) {
toProjectionFields.add(field.trim());
}
}
List<String> toIgnoreMetadataFields = SearchUtils.getIgnoredMetadataFields(item.getType());
List<MetadataValue> mydc = itemService.getMetadata(item, Item.ANY, Item.ANY, Item.ANY, Item.ANY);
for (MetadataValue meta : mydc) {
MetadataField metadataField = meta.getMetadataField();
MetadataSchema metadataSchema = metadataField.getMetadataSchema();
String field = metadataSchema.getName() + "." + metadataField.getElement();
String unqualifiedField = field;
String value = meta.getValue();
if (value == null) {
continue;
}
if (metadataField.getQualifier() != null && !metadataField.getQualifier().trim().equals("")) {
field += "." + metadataField.getQualifier();
}
// We are not indexing provenance, this is useless
if (toIgnoreMetadataFields != null && (toIgnoreMetadataFields.contains(field) || toIgnoreMetadataFields.contains(unqualifiedField + "." + Item.ANY))) {
continue;
}
String authority = null;
String preferedLabel = null;
List<String> variants = null;
boolean isAuthorityControlled = metadataAuthorityService.isAuthorityControlled(metadataField);
int minConfidence = isAuthorityControlled ? metadataAuthorityService.getMinConfidence(metadataField) : Choices.CF_ACCEPTED;
if (isAuthorityControlled && meta.getAuthority() != null && meta.getConfidence() >= minConfidence) {
boolean ignoreAuthority = DSpaceServicesFactory.getInstance().getConfigurationService().getPropertyAsType("discovery.index.authority.ignore." + field, DSpaceServicesFactory.getInstance().getConfigurationService().getPropertyAsType("discovery.index.authority.ignore", Boolean.FALSE), true);
if (!ignoreAuthority) {
authority = meta.getAuthority();
boolean ignorePrefered = DSpaceServicesFactory.getInstance().getConfigurationService().getPropertyAsType("discovery.index.authority.ignore-prefered." + field, DSpaceServicesFactory.getInstance().getConfigurationService().getPropertyAsType("discovery.index.authority.ignore-prefered", Boolean.FALSE), true);
if (!ignorePrefered) {
try {
preferedLabel = choiceAuthorityService.getLabel(meta, collection, meta.getLanguage());
} catch (Exception e) {
log.warn("Failed to get preferred label for " + field, e);
}
}
boolean ignoreVariants = DSpaceServicesFactory.getInstance().getConfigurationService().getPropertyAsType("discovery.index.authority.ignore-variants." + field, DSpaceServicesFactory.getInstance().getConfigurationService().getPropertyAsType("discovery.index.authority.ignore-variants", Boolean.FALSE), true);
if (!ignoreVariants) {
try {
variants = choiceAuthorityService.getVariants(meta, collection);
} catch (Exception e) {
log.warn("Failed to get variants for " + field, e);
}
}
}
}
if ((searchFilters.get(field) != null || searchFilters.get(unqualifiedField + "." + Item.ANY) != null)) {
List<DiscoverySearchFilter> searchFilterConfigs = searchFilters.get(field);
if (searchFilterConfigs == null) {
searchFilterConfigs = searchFilters.get(unqualifiedField + "." + Item.ANY);
}
for (DiscoverySearchFilter searchFilter : searchFilterConfigs) {
Date date = null;
String separator = DSpaceServicesFactory.getInstance().getConfigurationService().getProperty("discovery.solr.facets.split.char");
if (separator == null) {
separator = SearchUtils.FILTER_SEPARATOR;
}
if (searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_DATE)) {
// For our search filters that are dates we format them properly
date = MultiFormatDateParser.parse(value);
if (date != null) {
// TODO: make this date format configurable !
value = DateFormatUtils.formatUTC(date, "yyyy-MM-dd");
}
}
doc.addField(searchFilter.getIndexFieldName(), value);
doc.addField(searchFilter.getIndexFieldName() + "_keyword", value);
if (authority != null && preferedLabel == null) {
doc.addField(searchFilter.getIndexFieldName() + "_keyword", value + SearchUtils.AUTHORITY_SEPARATOR + authority);
doc.addField(searchFilter.getIndexFieldName() + "_authority", authority);
doc.addField(searchFilter.getIndexFieldName() + "_acid", value.toLowerCase() + separator + value + SearchUtils.AUTHORITY_SEPARATOR + authority);
}
if (preferedLabel != null) {
doc.addField(searchFilter.getIndexFieldName(), preferedLabel);
doc.addField(searchFilter.getIndexFieldName() + "_keyword", preferedLabel);
doc.addField(searchFilter.getIndexFieldName() + "_keyword", preferedLabel + SearchUtils.AUTHORITY_SEPARATOR + authority);
doc.addField(searchFilter.getIndexFieldName() + "_authority", authority);
doc.addField(searchFilter.getIndexFieldName() + "_acid", preferedLabel.toLowerCase() + separator + preferedLabel + SearchUtils.AUTHORITY_SEPARATOR + authority);
}
if (variants != null) {
for (String var : variants) {
doc.addField(searchFilter.getIndexFieldName() + "_keyword", var);
doc.addField(searchFilter.getIndexFieldName() + "_acid", var.toLowerCase() + separator + var + SearchUtils.AUTHORITY_SEPARATOR + authority);
}
}
// Add a dynamic fields for auto complete in search
doc.addField(searchFilter.getIndexFieldName() + "_ac", value.toLowerCase() + separator + value);
if (preferedLabel != null) {
doc.addField(searchFilter.getIndexFieldName() + "_ac", preferedLabel.toLowerCase() + separator + preferedLabel);
}
if (variants != null) {
for (String var : variants) {
doc.addField(searchFilter.getIndexFieldName() + "_ac", var.toLowerCase() + separator + var);
}
}
if (searchFilter.getFilterType().equals(DiscoverySearchFilterFacet.FILTER_TYPE_FACET)) {
if (searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_TEXT)) {
// Solr has issues with facet prefix and cases
if (authority != null) {
String facetValue = preferedLabel != null ? preferedLabel : value;
doc.addField(searchFilter.getIndexFieldName() + "_filter", facetValue.toLowerCase() + separator + facetValue + SearchUtils.AUTHORITY_SEPARATOR + authority);
} else {
doc.addField(searchFilter.getIndexFieldName() + "_filter", value.toLowerCase() + separator + value);
}
} else if (searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_DATE)) {
if (date != null) {
String indexField = searchFilter.getIndexFieldName() + ".year";
String yearUTC = DateFormatUtils.formatUTC(date, "yyyy");
doc.addField(searchFilter.getIndexFieldName() + "_keyword", yearUTC);
// add the year to the autocomplete index
doc.addField(searchFilter.getIndexFieldName() + "_ac", yearUTC);
doc.addField(indexField, yearUTC);
if (yearUTC.startsWith("0")) {
doc.addField(searchFilter.getIndexFieldName() + "_keyword", yearUTC.replaceFirst("0*", ""));
// add date without starting zeros for autocomplete e filtering
doc.addField(searchFilter.getIndexFieldName() + "_ac", yearUTC.replaceFirst("0*", ""));
doc.addField(searchFilter.getIndexFieldName() + "_ac", value.replaceFirst("0*", ""));
doc.addField(searchFilter.getIndexFieldName() + "_keyword", value.replaceFirst("0*", ""));
}
// & lower bound year of our facet
if (doc.getField(indexField + "_sort") == null) {
// We can only add one year so take the first one
doc.addField(indexField + "_sort", yearUTC);
}
}
} else if (searchFilter.getType().equals(DiscoveryConfigurationParameters.TYPE_HIERARCHICAL)) {
HierarchicalSidebarFacetConfiguration hierarchicalSidebarFacetConfiguration = (HierarchicalSidebarFacetConfiguration) searchFilter;
String[] subValues = value.split(hierarchicalSidebarFacetConfiguration.getSplitter());
if (hierarchicalSidebarFacetConfiguration.isSkipFirstNodeLevel() && 1 < subValues.length) {
// Remove the first element of our array
subValues = (String[]) ArrayUtils.subarray(subValues, 1, subValues.length);
}
for (int i = 0; i < subValues.length; i++) {
StringBuilder valueBuilder = new StringBuilder();
for (int j = 0; j <= i; j++) {
valueBuilder.append(subValues[j]);
if (j < i) {
valueBuilder.append(hierarchicalSidebarFacetConfiguration.getSplitter());
}
}
String indexValue = valueBuilder.toString().trim();
doc.addField(searchFilter.getIndexFieldName() + "_tax_" + i + "_filter", indexValue.toLowerCase() + separator + indexValue);
// We add the field x times that it has occurred
for (int j = i; j < subValues.length; j++) {
doc.addField(searchFilter.getIndexFieldName() + "_filter", indexValue.toLowerCase() + separator + indexValue);
doc.addField(searchFilter.getIndexFieldName() + "_keyword", indexValue);
}
}
}
}
}
}
if ((sortFields.get(field) != null || recentSubmissionsConfigurationMap.get(field) != null) && !sortFieldsAdded.contains(field)) {
// Only add sort value once
String type;
if (sortFields.get(field) != null) {
type = sortFields.get(field).getType();
} else {
type = recentSubmissionsConfigurationMap.get(field).getType();
}
if (type.equals(DiscoveryConfigurationParameters.TYPE_DATE)) {
Date date = MultiFormatDateParser.parse(value);
if (date != null) {
String stringDate = SolrUtils.getDateFormatter().format(date);
doc.addField(field + "_dt", stringDate);
} else {
log.warn("Error while indexing sort date field, item: " + item.getHandle() + " metadata field: " + field + " date value: " + date);
}
} else {
doc.addField(field + "_sort", value);
}
sortFieldsAdded.add(field);
}
if (hitHighlightingFields.contains(field) || hitHighlightingFields.contains("*") || hitHighlightingFields.contains(unqualifiedField + "." + Item.ANY)) {
if (authority != null) {
doc.addField(field + "_hl", value + SearchUtils.AUTHORITY_SEPARATOR + authority);
} else {
doc.addField(field + "_hl", value);
}
}
if (moreLikeThisFields.contains(field) || moreLikeThisFields.contains(unqualifiedField + "." + Item.ANY)) {
doc.addField(field + "_mlt", value);
}
doc.addField(field, value);
if (authority != null) {
doc.addField(field + "_authority", authority);
}
if (toProjectionFields.contains(field) || toProjectionFields.contains(unqualifiedField + "." + Item.ANY)) {
StringBuffer variantsToStore = new StringBuffer();
if (variants != null) {
for (String var : variants) {
variantsToStore.append(VARIANTS_STORE_SEPARATOR);
variantsToStore.append(var);
}
}
doc.addField(field + "_stored", value + STORE_SEPARATOR + preferedLabel + STORE_SEPARATOR + (variantsToStore.length() > VARIANTS_STORE_SEPARATOR.length() ? variantsToStore.substring(VARIANTS_STORE_SEPARATOR.length()) : "null") + STORE_SEPARATOR + authority + STORE_SEPARATOR + meta.getLanguage());
}
if (meta.getLanguage() != null && !meta.getLanguage().trim().equals("")) {
String langField = field + "." + meta.getLanguage();
doc.addField(langField, value);
}
}
} catch (Exception e) {
log.error(LogHelper.getHeader(context, "item_metadata_discovery_error", "Item identifier: " + item.getID()), e);
}
log.debug(" Added Metadata");
try {
List<MetadataValue> values = itemService.getMetadataByMetadataString(item, "dc.relation.ispartof");
if (values != null && values.size() > 0 && values.get(0) != null && values.get(0).getValue() != null) {
// group on parent
String handlePrefix = handleService.getCanonicalPrefix();
doc.addField("publication_grp", values.get(0).getValue().replaceFirst(handlePrefix, ""));
} else {
// group on self
doc.addField("publication_grp", item.getHandle());
}
} catch (Exception e) {
log.error(LogHelper.getHeader(context, "item_publication_group_discovery_error", "Item identifier: " + item.getID()), e);
}
log.debug(" Added Grouping");
}
use of org.dspace.content.MetadataValue in project DSpace by DSpace.
the class CitationDocumentServiceImpl method getAllMetadataSeparated.
@Override
public String getAllMetadataSeparated(Item item, String metadataKey) {
List<MetadataValue> dcValues = itemService.getMetadataByMetadataString(item, metadataKey);
ArrayList<String> valueArray = new ArrayList<>();
for (MetadataValue dcValue : dcValues) {
if (StringUtils.isNotBlank(dcValue.getValue())) {
valueArray.add(dcValue.getValue());
}
}
return StringUtils.join(valueArray.toArray(), "; ");
}
use of org.dspace.content.MetadataValue in project DSpace by DSpace.
the class EmbargoServiceImpl method getEmbargoTermsAsDate.
@Override
public DCDate getEmbargoTermsAsDate(Context context, Item item) throws SQLException, AuthorizeException {
List<MetadataValue> terms = itemService.getMetadata(item, terms_schema, terms_element, terms_qualifier, Item.ANY);
DCDate result = null;
// Its poor form to blindly use an object that could be null...
if (terms == null) {
return null;
}
result = setter.parseTerms(context, item, terms.size() > 0 ? terms.get(0).getValue() : null);
if (result == null) {
return null;
}
// new DCDate(non-date String) means toDate() will return null
Date liftDate = result.toDate();
if (liftDate == null) {
throw new IllegalArgumentException("Embargo lift date is uninterpretable: " + result.toString());
}
/*
* NOTE: We do not check here for past dates as it can result in errors during AIP restoration.
* Therefore, UIs should perform any such date validation on input. See DS-3348
*/
return result;
}
use of org.dspace.content.MetadataValue in project DSpace by DSpace.
the class LogicalFilterTest method testMetadataValueMatchCondition.
/**
* Test a simple filter with a single logical statement: the MetadataValueMatchCondition
* looking for a dc.title field beginning with "TEST", and an item that doesn't match this test
*/
@Test
public void testMetadataValueMatchCondition() {
try {
MetadataValue metadataValueOne = metadataValueService.create(context, itemOne, metadataField);
MetadataValue metadataValueTwo = metadataValueService.create(context, itemTwo, metadataField);
metadataValueOne.setValue("TEST title should match the condition");
metadataValueTwo.setValue("This title should not match the condition");
} catch (SQLException e) {
fail("Encountered SQL error creating metadata value on item: " + e.getMessage());
}
// Instantiate new filter for testing this condition
DefaultFilter filter = new DefaultFilter();
// Create condition to match pattern on dc.title metadata
Condition condition = new MetadataValueMatchCondition();
condition.setItemService(ContentServiceFactory.getInstance().getItemService());
Map<String, Object> parameters = new HashMap<>();
// Match on the dc.title field
parameters.put("field", "dc.title");
// "Starts with "TEST" (case sensitive)
parameters.put("pattern", "^TEST");
// Set up condition with these parameters and add it as the sole statement to the metadata filter
try {
condition.setParameters(parameters);
filter.setStatement(condition);
// Test the filter on the first item - expected outcome is true
assertTrue("itemOne unexpectedly did not match the 'dc.title starts with TEST' test", filter.getResult(context, itemOne));
// Test the filter on the second item - expected outcome is false
assertFalse("itemTwo unexpectedly matched the 'dc.title starts with TEST' test", filter.getResult(context, itemTwo));
} catch (LogicalStatementException e) {
log.error(e.getMessage());
fail("LogicalStatementException thrown testing the MetadataValueMatchCondition filter" + e.getMessage());
}
}
use of org.dspace.content.MetadataValue in project DSpace by DSpace.
the class CollectedTest method testGetValues.
@Test
public void testGetValues() {
// Setup objects utilized in unit test
List<String> list = new ArrayList<>();
List<String> valueList = new ArrayList<>();
List<MetadataValue> metadataValueList = new ArrayList<>();
MetadataValue metadataValue = mock(MetadataValue.class);
Item item = mock(Item.class);
metadataValueList.add(metadataValue);
String s = "dc.title";
list.add(s);
List<String> splittedString = Splitter.on('.').splitToList(s);
collected.setFields(list);
valueList.add("TestValue");
// Mock the state of objects utilized in getValues() to meet the success criteria of an invocation
when(itemService.getMetadata(item, splittedString.size() > 0 ? splittedString.get(0) : null, splittedString.size() > 1 ? splittedString.get(1) : null, splittedString.size() > 2 ? splittedString.get(2) : null, Item.ANY, false)).thenReturn(metadataValueList);
when(metadataValue.getValue()).thenReturn("TestValue");
// The reported value(s) should match our valueList
assertEquals("TestGetValues 0", valueList, collected.getValues(context, item));
}
Aggregations