Skip to content
Merged
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 @@ -70,6 +70,7 @@ protected void runSchematron(String lang, Path schemaDir, List<MetadataValidatio
params.put("lang", lang);
params.put("rule", ruleId);
params.put("thesaurusDir", thesaurusManager.getThesauriDirectory().toString());
params.put("metadataId", metadataId);

Path file = schemaDir.resolve(SCHEMATRON_DIR).resolve(schematron.getFile());
Element xmlReport = Xml.transform(md, file, params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public Element applyCustomSchematronRules(String schema, Element md,
List<ApplicableSchematron> applicableSchematron = getApplicableSchematronList(md, metadataSchema, groupOwnerId);

for (ApplicableSchematron applicable : applicableSchematron) {
// Pass -1 as metadataId for external validation since the metadata is not in the database.
// Schematron rules can reference the metadataId parameter, but attempting to look up metadata
// using -1 will return empty results.
runSchematron(lang, schemaDir, validations, schemaTronXmlOut, -1, md, applicable);
}
} catch (Throwable e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,18 @@
import org.fao.geonet.exceptions.ResourceNotFoundEx;
import org.fao.geonet.utils.Xml;
import org.jdom.Element;
import org.mockito.ArgumentCaptor;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

import org.junit.Test;
import org.springframework.context.ConfigurableApplicationContext;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import static org.junit.Assert.assertEquals;
Expand Down Expand Up @@ -127,4 +130,51 @@ public void testRunSchematronLocalizedExceptionHandling() {
assertEquals(MetadataValidationStatus.NEVER_CALCULATED, validations.get(0).getStatus());
}
}

@Test
public void testRunSchematronPassesMetadataIdParam() throws Exception {
ConfigurableApplicationContext mockContext = Mockito.mock(ConfigurableApplicationContext.class);
try (MockedStatic<ApplicationContextHolder> mockedHolder = Mockito.mockStatic(ApplicationContextHolder.class);
MockedStatic<Xml> mockedXml = Mockito.mockStatic(Xml.class)) {

mockedHolder.when(ApplicationContextHolder::get).thenReturn(mockContext);
ThesaurusManager mockThesaurusManager = Mockito.mock(ThesaurusManager.class);
Mockito.when(mockContext.getBean(ThesaurusManager.class)).thenReturn(mockThesaurusManager);

Path thesaurusDir = Paths.get("/thesaurus");
Mockito.when(mockThesaurusManager.getThesauriDirectory()).thenReturn(thesaurusDir);

// Capture the params passed to Xml.transform
@SuppressWarnings("unchecked")
ArgumentCaptor<Map<String, Object>> paramsCaptor = ArgumentCaptor.forClass(Map.class);
mockedXml.when(() -> Xml.transform(Mockito.any(), Mockito.any(Path.class), paramsCaptor.capture()))
.thenReturn(new Element("output"));

AbstractSchematronValidator validator = new AbstractSchematronValidator();
int expectedMetadataId = 42;
Path schemaDir = Mockito.mock(Path.class);
Path schematronFile = Mockito.mock(Path.class);
Mockito.when(schemaDir.resolve(Mockito.anyString())).thenReturn(schematronFile);
Mockito.when(schematronFile.resolve(Mockito.anyString())).thenReturn(schematronFile);

List<MetadataValidation> validations = new ArrayList<>();
Element schemaTronXmlOut = new Element("schemaTronXmlOut");
Element md = new Element("metadata");
ApplicableSchematron applicable = Mockito.mock(ApplicableSchematron.class);

Schematron schematron = new Schematron();
schematron.setSchemaName("testSchemaName");
schematron.setFile("schematron-rules-test.xsl");

Mockito.when(applicable.getSchematron()).thenReturn(schematron);
Mockito.when(applicable.getRequirement()).thenReturn(SchematronRequirement.REQUIRED);

validator.runSchematron("eng", schemaDir, validations, schemaTronXmlOut, expectedMetadataId, md, applicable);

Map<String, Object> capturedParams = paramsCaptor.getValue();
assertNotNull("params map should not be null", capturedParams);
assertEquals("metadataId should be passed to the schematron XSL transform",
expectedMetadataId, capturedParams.get("metadataId"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,17 @@ As for most of GeoNetwork, the output of this rule can be localized to different
</strings>
```

##### Available parameters in schematron rules

When GeoNetwork executes a compiled schematron, the following parameters are automatically passed to the XSL and can be referenced inside `<sch:rule>` blocks using `$paramName`:

| Parameter | Type | Description |
|-----------------|---------|-----------------------------------------------------------------------------|
| `lang` | string | The two or three letter language code of the current user session (e.g. `eng`). Use this to return localised messages. |
| `rule` | string | The file name of the compiled schematron XSL (e.g. `schematron-rules-iso.xsl`). |
| `thesaurusDir` | string | Absolute path to the GeoNetwork thesaurus directory. Useful for rules that need to validate against controlled vocabularies. |
| `metadataId` | integer | The internal database identifier of the metadata record being validated. Useful for rules that need to look up related information. **Note:** When validating external metadata (metadata not saved to the database), this parameter is set to `-1`. Attempts to query the database using this value will return empty results. |

Procedure for adding schematron rules, working within the schematrons directory:

1. Place your schematron rules in 'rules'. Naming convention is 'schematron-rules-<suffix>.sch' eg. `schematron-rules-iso-mcp.sch`. Place localized strings for the rule assertions into 'rules/loc/<language_prefix>'.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@
<axsl:param name="lang"/>
<axsl:param name="thesaurusDir"/>
<axsl:param name="rule"/>
<axsl:param name="metadataId"/>

<!-- Retrieve localisation entries (one file specific to the rule, the other file is shared by all schematron). Fallback language is English. -->
<axsl:variable name="loc">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ protected Pair<Element, Path> compileSchematron(Path sourceFile) {
params.put("lang", "eng");
params.put("thesaurusDir", THESAURUS_DIR.toAbsolutePath().toString().replace("\\", "/"));
params.put("rule", ruleName + ".xsl");
params.put("metadataId", "0");

Path outputFile = temporaryFolder.getRoot().toPath().resolve("path/requiredtoFind/utilsfile/" + ruleName + ".xsl");
Files.createDirectories(outputFile.getParent());
Expand Down
Loading