Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement tools #312

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0615e64
name enhancer for person entity
floriangantner Feb 3, 2023
4b8e3e3
item enhancer for collections and entity type
floriangantner Feb 3, 2023
13677d8
item enhancer for collections and entity type and modifiedDate using …
floriangantner Feb 3, 2023
05cd10f
enhancer using mapconverter result
floriangantner Feb 3, 2023
c42703b
clean up code and some fixes
floriangantner Jul 3, 2023
b2912ca
Merge branch 'dspace-cris-7' into dspace-cris-7-enhancement
floriangantner Jul 3, 2023
4b51093
fix missing license header
floriangantner Jul 11, 2023
ee91399
fix a bunch of dspace checkstyle issues
floriangantner Aug 8, 2023
a4e7728
fix another dspace checkstyle issues
floriangantner Aug 8, 2023
fd79222
common itemenhancer integration tests
floriangantner Aug 22, 2023
7b10626
Merge branch 'dspace-cris-7' into dspace-cris-7-enhancement
floriangantner Aug 28, 2023
fa1c3f0
fix wrong config property breaking tests
floriangantner Aug 28, 2023
742ab6a
refactor item enhancement entity type script
floriangantner Aug 30, 2023
cad9330
refactor item enhancement by date script
floriangantner Aug 30, 2023
7c045ef
Merge branch 'dspace-cris-7' into dspace-cris-7-enhancement
floriangantner Oct 13, 2023
8103547
[maven-release-plugin] prepare release dspace-cris-2023.02.02
atarix83 Feb 9, 2024
d46630f
Merge tag 'dspace-cris-2023.02.02' into dspace-cris-7-enhancement
floriangantner Feb 20, 2024
2c10042
align enhancer scripts to new deepMode force enhancement
floriangantner Feb 20, 2024
9c46991
implement deepMode in NameEnhancer
floriangantner Feb 20, 2024
5ab97e4
implement deepMode in MapConverterValueEnhancer
floriangantner Feb 20, 2024
81aa4a4
align enhancer integration tests
floriangantner Feb 22, 2024
dfa2a91
integration tests for enhancer
floriangantner Feb 23, 2024
8600d1b
integration test for nameenhancer
floriangantner Feb 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dspace-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<parent>
<groupId>org.dspace</groupId>
<artifactId>dspace-parent</artifactId>
<version>cris-2023.02.02-SNAPSHOT</version>
<version>cris-2023.02.02</version>
<relativePath>..</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/**
* 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.enhancer.impl;

import java.sql.SQLException;
import java.util.Objects;

import org.apache.commons.lang.StringUtils;
import org.dspace.content.Item;
import org.dspace.content.MetadataField;
import org.dspace.content.enhancer.AbstractItemEnhancer;
import org.dspace.content.enhancer.ItemEnhancer;
import org.dspace.content.service.ItemService;
import org.dspace.content.service.MetadataFieldService;
import org.dspace.core.Context;
import org.dspace.services.ConfigurationService;
import org.dspace.util.SimpleMapConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
* Implementation of {@link ItemEnhancer} that add metadata values on the given
* item from the result of some mapConverter
* Only consider 1 to 1 value enhancement and no additional security/authority/language settings form the origin value.
* e.g. dc.type (dspace) -> dc.type (coar)
*
* @author Florian Gantner ([email protected])
*
*/
public class MapConverterValueEnhancer extends AbstractItemEnhancer {

private static final Logger LOGGER = LoggerFactory.getLogger(MapConverterValueEnhancer.class);

@Autowired
private ItemService itemService;

@Autowired
private MetadataFieldService metadatafieldService;

@Autowired
private ConfigurationService configurationService;

private String sourceEntityType;

private String sourceItemMetadataField;
private String targetItemMetadataField;

private boolean useDefaultLanguage;

private SimpleMapConverter converter;

@Override
public boolean canEnhance(Context context, Item item) {
return sourceEntityType == null || sourceEntityType.equals(itemService.getEntityType(item));
}

@Override
public boolean enhance(Context context, Item item, boolean deepMode) {
try {
if (StringUtils.isBlank(sourceItemMetadataField) || Objects.isNull(converter) ||
StringUtils.isBlank(targetItemMetadataField)) {
return false;
}
String sourceval;
String targetval;
String calculatedval;
sourceval = itemService.getMetadata(item, sourceItemMetadataField);
targetval = itemService.getMetadata(item, targetItemMetadataField);
if (StringUtils.isNotBlank(sourceval)) {
calculatedval = converter.getValue(sourceval);
if (StringUtils.isNotBlank(targetval) && !targetval.contentEquals(calculatedval)) {
// replace mdv if it's different
removeTargetMetadata(context, item);
addTargetMetadata(context, item, calculatedval);
return true;
} else if (StringUtils.isBlank(targetval)) {
// set new value
addTargetMetadata(context, item, calculatedval);
return true;
} else if (StringUtils.isNotBlank(sourceval) && StringUtils.isNotBlank(targetval)
&& sourceval.contentEquals(targetval) && deepMode) {
//When both values are equal and deepMode is active, recalculate the value
removeTargetMetadata(context, item);
addTargetMetadata(context, item, calculatedval);
return true;
}
} else if (StringUtils.isBlank(sourceval) && StringUtils.isNotBlank(targetval)) {
// remove value
removeTargetMetadata(context, item);
return true;
}
} catch (Exception e) {
LOGGER.error("An error occurs enhancing item with id {}: {}", item.getID(), e.getMessage(), e);
//throw new SQLRuntimeException(e);
}
return false;
}
private void addTargetMetadata(Context context, Item item, String value) throws Exception {
MetadataField targetmd = metadatafieldService.findByString(context, targetItemMetadataField, '.');
if (targetmd != null) {
String lang = (this.useDefaultLanguage) ? this.configurationService.getProperty("default.language") : null;
itemService.addMetadata(context, item, targetmd, lang, value);
} else {
LOGGER.error("No valid metadatavalue to enhance specified");
}
}

private void removeTargetMetadata(Context context, Item item) throws SQLException {
MetadataField targetmd = metadatafieldService.findByString(context, targetItemMetadataField, '.');
if (targetmd != null) {
itemService.clearMetadata(context, item, targetmd.getMetadataSchema().getName(),
targetmd.getElement(), targetmd.getQualifier(), Item.ANY);
} else {
LOGGER.error("No valid metadatavalue to enhance specified");
}
}

public void setSourceEntityType(String sourceEntityType) {
this.sourceEntityType = sourceEntityType;
}

public void setTargetItemMetadataField(String targetItemMetadataField) {
this.targetItemMetadataField = targetItemMetadataField;
}

public void setSourceItemMetadataField(String sourceItemMetadataField) {
this.sourceItemMetadataField = sourceItemMetadataField;
}

public void setConverter(SimpleMapConverter converter) {
this.converter = converter;
}

public void setUseDefaultLanguage(boolean useDefaultLanguage) {
this.useDefaultLanguage = useDefaultLanguage;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/**
* 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.enhancer.impl;

import java.sql.SQLException;
import java.util.List;
import java.util.Objects;

import org.apache.commons.lang.StringUtils;
import org.dspace.content.Item;
import org.dspace.content.MetadataField;
import org.dspace.content.MetadataValue;
import org.dspace.content.enhancer.AbstractItemEnhancer;
import org.dspace.content.enhancer.ItemEnhancer;
import org.dspace.content.service.ItemService;
import org.dspace.content.service.MetadataFieldService;
import org.dspace.core.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
* Implementation of {@link ItemEnhancer} that add metadata values on the given
* item from a list of other metadatavalues .
* The first value of the list that is not null matches and overwrites the existing value.
* Some default value can be specified if no fields were found
*
* @author Florian Gantner ([email protected])
*
*/
public class NameEnhancer extends AbstractItemEnhancer {

private static final Logger LOGGER = LoggerFactory.getLogger(NameEnhancer.class);

@Autowired
private ItemService itemService;

@Autowired
private MetadataFieldService metadatafieldService;

private String sourceEntityType;

private String targetItemMetadataField;

private List<String> relatedItemMetadataFields;
private String defaultValue;

@Override
public boolean canEnhance(Context context, Item item) {
return sourceEntityType == null || sourceEntityType.equals(itemService.getEntityType(item));
}

@Override
public boolean enhance(Context context, Item item, boolean deepMode) {
try {
if (Objects.isNull(relatedItemMetadataFields) || relatedItemMetadataFields.isEmpty() ||
StringUtils.isBlank(targetItemMetadataField)) {
return false;
}
return checkNames(context, item, deepMode);
} catch (Exception e) {
LOGGER.error("An error occurs enhancing item with id {}: {}", item.getID(), e.getMessage(), e);
//Exception handling not supported by ItemEnhancerService. Thus, just log to continue other enhancers
//throw new SQLRuntimeException(e);
}
return false;
}

/**
* Check the names/values from the specified metadatafield and compare the first value found
* with the target metadatafield. Updates the target metadatafield when the value is different
* or when deepMode is set.
* When the target metadatafield has not been set before, then set this value.
* @param context current Context
* @param item current item
* @param deepMode boolean
* @return boolean value if some change/update has happened
* @throws Exception when some error occurs
*/
private boolean checkNames(Context context, Item item, boolean deepMode) throws Exception {
// ignore languages of Metadata here. Assume main title is not repeated
// Could be more simplified
List<MetadataValue> currentnames = itemService.getMetadataByMetadataString(item, targetItemMetadataField);

if (!currentnames.isEmpty()) {
// some name is assigned yet
for (MetadataValue currentname : currentnames) {
String val = currentname.getValue();
for (String field : relatedItemMetadataFields) {
List<MetadataValue> fieldnames =
itemService.getMetadataByMetadataString(item, field);
if (fieldnames.isEmpty()) {
continue ; //No Values, try next loop
}
for (MetadataValue fieldname : fieldnames) {
if (StringUtils.isNotBlank(fieldname.getValue())
&& fieldname.getValue().contentEquals(val)) {
//Values are the same. No Update necessary
if (deepMode) {
// value is recalculated in deepMode
return updateTargetMetadata(context, item, fieldname.getValue(), true);
}
return false;
} else {
//values differ. We must update the value
return updateTargetMetadata(context, item, fieldname.getValue(), true);
}
}
}
}
if (StringUtils.isNotBlank(defaultValue)
&& !currentnames.get(0).getValue().contentEquals(defaultValue)) {
// None of the names above matches. Set Default-Value, if it exists. Otherwise, do nothing
return updateTargetMetadata(context, item, defaultValue, true);
}

} else {
// No Name assigned yet
// Check existing names
for (String field : relatedItemMetadataFields) {
List<MetadataValue> fieldnames = itemService.getMetadataByMetadataString(item, field);
if (fieldnames.isEmpty()) {
continue; //No Values, try next loop
}
for (MetadataValue fieldname : fieldnames) {
if (StringUtils.isNotBlank(fieldname.getValue())) {
//Got some value
return updateTargetMetadata(context, item, fieldname.getValue(), false);
}
}
}
// If no name exist, set defaultvalue
if (StringUtils.isNotBlank(defaultValue)) {
return updateTargetMetadata(context, item, defaultValue, false);
}
// otherwise do not assign any value
}
return false;
}

/**
* Update/Set the target metadata with option to clear/delete previous metadatavalues
* @param context current Context
* @param item item to set metadatavalue
* @param value value to set
* @param clear clear/delete existing values byfore
* @return boolean value if the value has been updated successfully
* @throws SQLException when some error occurs
*/
private boolean updateTargetMetadata(Context context, Item item, String value, boolean clear) throws SQLException {
MetadataField targetmd = metadatafieldService.findByString(context, targetItemMetadataField, '.');
if (targetmd != null) {
if (clear) {
itemService.clearMetadata(context, item, targetmd.getMetadataSchema().getName(), targetmd.getElement(),
targetmd.getQualifier(), Item.ANY);
}
itemService.addMetadata(context, item, targetmd, null, value);
return true;
} else {
LOGGER.error("No valid metadatavalue to enhance specified");
}
return false;
}

public void setSourceEntityType(String sourceEntityType) {
this.sourceEntityType = sourceEntityType;
}

public void setTargetItemMetadataField(String targetItemMetadataField) {
this.targetItemMetadataField = targetItemMetadataField;
}

public void setRelatedItemMetadataFields(List<String> relatedItemMetadataFields) {
this.relatedItemMetadataFields = relatedItemMetadataFields;
}

public void setDefaultValue(String defaultvalue) {
this.defaultValue = defaultvalue;
}

}

Loading