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

Draft: relation inside metadata group in refer crosswalk #387

Draft
wants to merge 4 commits into
base: dspace-cris-2023_02_x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
import org.dspace.content.crosswalk.CrosswalkObjectNotSupported;
import org.dspace.content.integration.crosswalks.evaluators.ConditionEvaluator;
import org.dspace.content.integration.crosswalks.evaluators.ConditionEvaluatorMapper;
import org.dspace.content.integration.crosswalks.evaluators.MetadataValueConditionEvaluator;
import org.dspace.content.integration.crosswalks.evaluators.MetadataValueConditionEvaluatorMapper;
import org.dspace.content.integration.crosswalks.model.TemplateLine;
import org.dspace.content.integration.crosswalks.virtualfields.VirtualField;
import org.dspace.content.integration.crosswalks.virtualfields.VirtualFieldMapper;
Expand All @@ -71,6 +73,7 @@
* Item starting from a template.
*
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
* @author Florian Gantner ([email protected])
*
*/
public class ReferCrosswalk implements ItemExportCrosswalk {
Expand All @@ -94,6 +97,9 @@ public class ReferCrosswalk implements ItemExportCrosswalk {
@Autowired
private ConditionEvaluatorMapper conditionEvaluatorMapper;

@Autowired
private MetadataValueConditionEvaluatorMapper metadataconditionEvaluatorMapper;

@Autowired
private MetadataSecurityService metadataSecurityService;

Expand Down Expand Up @@ -264,7 +270,8 @@ private TemplateLine buildTemplateLine(String templateLine) {

if (templateLineObj.isIfGroupField()) {
String conditionName = templateLineObj.getIfConditionName();
if (!conditionEvaluatorMapper.contains(conditionName)) {
if (!conditionEvaluatorMapper.contains(conditionName)
&& !metadataconditionEvaluatorMapper.contains(conditionName)) {
throw new IllegalStateException("Unknown condition evaluator found in the template '" + templateFileName
+ "': " + conditionName);
}
Expand Down Expand Up @@ -356,6 +363,24 @@ private List<String> getMetadataValuesForLine(Context context, TemplateLine line

}

private List<String> getMetadataValuesForField(Context context, String field, Item item) {
if (field.contains("-")) {
field = field.replaceAll("-",".");
}
if (field.contains("_")) {
String[] langs = field.split("_");
String lang = langs[1];
field = langs[0];
return metadataSecurityService.getPermissionFilteredMetadataValues(context, item, field).stream()
.filter(md -> md.getLanguage() != null && md.getLanguage().startsWith(lang))
.map(MetadataValue::getValue)
.collect(Collectors.toList());
}
return metadataSecurityService.getPermissionFilteredMetadataValues(context, item, field).stream()
.map(MetadataValue::getValue)
.collect(Collectors.toList());
}

private void handleMetadataGroup(Context context, Item item, Iterator<TemplateLine> iterator, String groupName,
List<String> lines) throws IOException {

Expand All @@ -365,17 +390,71 @@ private void handleMetadataGroup(Context context, Item item, Iterator<TemplateLi
Map<String, List<String>> metadataValues = new HashMap<>();

for (int i = 0; i < groupSize; i++) {
String ifgroup = null;
boolean ifconditionresult = false;
String currentrelationname = null;

for (int gi = 0; gi < groupLines.size(); gi++) {
TemplateLine line = groupLines.get(gi);
// Uniba Added Check for relations
if (currentrelationname != null && !line.isRelationGroupEndField(currentrelationname)) {
continue; // if within relation, Skip line until end of relation
}

if (currentrelationname != null && line.isRelationGroupEndField(currentrelationname)) {
currentrelationname = null;
continue;
}

if (ifgroup != null && !line.isIfGroupEndField(ifgroup) && !ifconditionresult) {
continue;
}

for (TemplateLine line : groupLines) {
// Uniba added checks for one single if condition inside metadatagroup to check the metadatavalue
// at the specific position. Nested Conditions are more complex and not supported (yet)
if (line.isIfGroupStartField()) {
ifgroup = line.getIfCondition();
//Perhaps create some own method?
String fieldname = line.getIfConditionValue();
String metadatatocheck = null;
List<String> metadatastocheck = getMetadataValuesForField(context, fieldname, item);
if (metadatastocheck != null && !metadatastocheck.isEmpty() && (i < metadatastocheck.size())) {
metadatatocheck = metadatastocheck.get(i);
}

if (!metadataconditionEvaluatorMapper.contains(line.getIfConditionName())) {
throw new IllegalStateException("Unknown condition evaluator found in the template '"
+ templateFileName + "': " + line.getIfConditionName());
}
MetadataValueConditionEvaluator evaluator =
metadataconditionEvaluatorMapper.getConditionEvaluator(line.getIfConditionName());
ifconditionresult = evaluator.test(context, metadatatocheck, line.getIfCondition());
continue; //otherwise field is being requested
}

if (ifgroup != null && line.isIfGroupEndField(ifgroup)) {
ifgroup = null;
ifconditionresult = false;
continue;
}
String field = line.getField();

if (line.isRelationGroupStartField()) {
//this considers the whole item
//Should only handle the item at position gi+1
List<TemplateLine> relatedgroup = groupLines.subList(gi + 1, groupLines.size());
handleRelationWithinGroup(context, item,relatedgroup.iterator(), line.getRelationName(), lines,
true, i);
currentrelationname = line.getRelationName();
continue;
}

if (StringUtils.isBlank(line.getField())) {
lines.add(line.getBeforeField());
continue;
}

List<String> metadata = null;
List<String> metadata;
if (metadataValues.containsKey(field)) {
metadata = metadataValues.get(field);
} else {
Expand Down Expand Up @@ -418,6 +497,28 @@ private void handleRelationGroup(Context context, Item item, Iterator<TemplateLi

}

private void handleRelationWithinGroup(Context context, Item item, Iterator<TemplateLine> iterator,
String relationName, List<String> lines, boolean findRelatedItems, int position) throws IOException {

List<TemplateLine> groupLines = getGroupLines(iterator, line -> line.isRelationGroupEndField(relationName));

if (!findRelatedItems) {
return;
}

Iterator<Item> relatedItems = findRelatedItems(context, item, relationName);
int cnt = 0;
while (relatedItems.hasNext()) {
Item relatedItem = relatedItems.next();
if (cnt == position) {
Iterator<TemplateLine> lineIterator = groupLines.iterator();
appendLines(context, relatedItem, lineIterator, lines, findRelatedItems);
}
cnt++;
}

}

private void handleIfGroup(Context context, Item item, Iterator<TemplateLine> iterator, TemplateLine conditionLine,
List<String> lines, boolean findRelatedItems) throws IOException {

Expand All @@ -430,7 +531,6 @@ private void handleIfGroup(Context context, Item item, Iterator<TemplateLine> it
if (evaluator.test(context, item, condition)) {
appendLines(context, item, groupLines.iterator(), lines, findRelatedItems);
}

}

private List<TemplateLine> getGroupLines(Iterator<TemplateLine> iterator, Predicate<TemplateLine> breakPredicate) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* 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.integration.crosswalks.evaluators;

import org.apache.commons.lang3.StringUtils;
import org.dspace.core.Context;

/**
* Class that can be extended to evaluate a given condition on some metadatavalue.
*
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
* @author Florian Gantner ([email protected])
*
*/
public abstract class MetadataValueConditionEvaluator {

/**
* Test the given condition on the given metadtavalue.
* The condition should have the format [not].evaluatorIdentifier.value,
* where:
* <ul>
* <li> not can be used to negate the result of the condition
* <li> evaluatorIdentifier is the unique identifier of the evaluator
* <li> value can be any string useful to the evaluator
* </ul>
*
* @param context the DSpace Context
* @param value the item to evaluate
* @param condition the condition to evaluate
* @return the evaluation result
*/
public final boolean test(Context context, String value, String condition) {
if (StringUtils.isBlank(condition)) {
return false;
}

if (condition.startsWith("not.")) {
return !doTest(context, value, condition.substring("not.".length()));
}

return doTest(context, value, condition);

}

/**
* Test the given condition on the given item.
* The condition should have the format evaluatorIdentifier.value, where:
* <ul>
* <li> evaluatorIdentifier is the unique identifier of the evaluator
* <li> value can be any string useful to the evaluator
* </ul>
*
* @param context the DSpace Context
* @param value the metadatavalue to evaluate
* @param condition the condition to evaluate
* @return the evaluation result
*/
protected abstract boolean doTest(Context context, String value, String condition);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* 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.integration.crosswalks.evaluators;

import java.util.Map;
import java.util.Set;

/**
* A Mapper between instances of {@link MetadataValueConditionEvaluator} and their identifiers.
*
* @author Luca Giamminonni (luca.giamminonni at 4science.it)
* @author Florian Gantner ([email protected])
*
*/
public class MetadataValueConditionEvaluatorMapper {

private final Map<String, MetadataValueConditionEvaluator> conditionEvaluators;

public MetadataValueConditionEvaluatorMapper(Map<String, MetadataValueConditionEvaluator> conditionEvaluators) {
this.conditionEvaluators = conditionEvaluators;
}

public Set<String> getConditionEvaluatorNames() {
return conditionEvaluators.keySet();
}

public MetadataValueConditionEvaluator getConditionEvaluator(String name) {
return conditionEvaluators.get(name);
}

public boolean contains(String name) {
return conditionEvaluators.containsKey(name);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* 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.integration.crosswalks.evaluators;

import org.dspace.core.Context;
import org.dspace.core.CrisConstants;

/**
* Implementation of {@link MetadataValueConditionEvaluator} to evaluate
* if the given Metadata Value is null or some Placeholder Value
*
* @author Florian Gantner ([email protected])
*
*/
public class MetadataValuePlaceholderOrNullCondition extends MetadataValueConditionEvaluator {

@Override
protected boolean doTest(Context context, String value, String condition) {
return value == null || value.contentEquals(CrisConstants.PLACEHOLDER_PARENT_METADATA_VALUE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ public String getIfCondition() {

}

public String getIfConditionValue() {
return isIfGroupField() ?
join(".", Arrays.copyOfRange(fieldBits, (fieldBits[1].equals("not")) ? 3 : 2, fieldBits.length - 1)) : null;

}

public String getIfConditionName() {
if (!isIfGroupField()) {
return null;
Expand Down
14 changes: 14 additions & 0 deletions dspace/config/spring/api/crosswalks.xml
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,20 @@
<bean class="org.dspace.content.integration.crosswalks.evaluators.AuthorityNotBlankCondition" id="authorityConditionEvaluator"/>
<bean class="org.dspace.content.integration.crosswalks.evaluators.HasMetadataCondition" id="metadataConditionEvaluator"/>

<!-- MetadataValue Evaluators Configuration -->
<bean class="org.dspace.content.integration.crosswalks.evaluators.MetadataValueConditionEvaluatorMapper"
id="metadatavalueconditionEvaluatorMapper">
<constructor-arg name="conditionEvaluators">
<map>
<entry key="nullorplaceholder" value-ref="metadataValueNullOrPlaceholderConditionEvaluator" />
</map>
</constructor-arg>
</bean>

<bean class="org.dspace.content.integration.crosswalks.evaluators.MetadataValuePlaceholderOrNullCondition"
id="metadataValueNullOrPlaceholderConditionEvaluator"/>


<!-- Item export format SERVICE -->
<bean class="org.dspace.content.integration.crosswalks.service.ItemExportFormatServiceImpl"/>
<bean class="org.dspace.discovery.configuration.DiscoveryConfigurationUtilsService"/>
Expand Down