Skip to content

Commit

Permalink
relation inside metadata group in refer crosswalk
Browse files Browse the repository at this point in the history
  • Loading branch information
floriangantner committed Sep 8, 2023
1 parent 5766d8c commit 8b801dc
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 4 deletions.
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 @@ -68,6 +70,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 @@ -91,6 +94,9 @@ public class ReferCrosswalk implements ItemExportCrosswalk {
@Autowired
private ConditionEvaluatorMapper conditionEvaluatorMapper;

@Autowired
private MetadataValueConditionEvaluatorMapper metadataconditionEvaluatorMapper;

@Autowired
private MetadataSecurityService metadataSecurityService;

Expand Down Expand Up @@ -233,7 +239,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 @@ -325,6 +332,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 @@ -334,17 +359,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 @@ -387,6 +466,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 @@ -399,7 +500,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 @@ -709,6 +709,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

0 comments on commit 8b801dc

Please sign in to comment.