Skip to content

Commit

Permalink
changed validation checks, updated documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
rsehr committed Dec 4, 2024
1 parent d96f2c8 commit 9144bb3
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 30 deletions.
4 changes: 3 additions & 1 deletion docs/index_de.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,6 @@ Parameter | Erläuterung
`openStepOnError` | Dieser Parameter legt fest, welcher Arbeitsschritt des Workflows erneut geöffnet werden soll, wenn ein Fehler innerhalb der Validierung auftritt. Wird dieser Parameter nicht verwendet, so aktiviert das Plugin stattdessen einfach den vorherigen Arbeitsschritt des Validierungsschritts.
`lockAllStepsBetween` | Mit diesem Parameter wird festgelegt, ob die Arbeitsschritte des Workflows zwischen dem Validierungsschritt und demjenigen, der innerhalb des Parameters `openStepOnError` angegeben wurde, wieder auf auf den Status gesperrt gesetzt werden sollen, so dass diese Arbeitsschritte ein erneutes Mal durchlaufen (`true`) werden müssen. Wird der Wert hingegen auf `false` gesetzt, so wird der Status der dazwischen liegenden Schritte nicht verändert, so dass die Arbeitsschritte auch nicht noch einmal durchlaufen werden.
`jhoveConfiguration` | Mit diesem Parameter wird angegeben, wo sich die Konfigurationsdatei für JHove befindet.
`check` | Innerhalb eines jeden Elements check wird festgelegt, was JHove genau validieren soll. Hier wird beispielsweise festgelegt, welches Dateiformat erwartet wird. Für den erwarteten Wert kann innerhalb des Elements `<wanted>` eine direkte Eingabe auch als Bereich erfasst werden. Ebenso ist es hier auch möglich, eine Variable zu verwenden, die durch den Variablen-Replacer ersetzt wird (z.B. `{process.Resolution}`. Zugehörig ist hierbei ebenso, welche Fehlermeldung im Falle einer fehlerhaften Validierung ausgegeben werden soll. In der Fehlermeldung können folgende Variablen genutzt werden: `${wanted}` für den exakten Inhalt aus dem Feld `<wanted>`, `${expected}` für den aufgelösten erwarteten Wert, `${found}` für den gefundenen Wert und `${image}` für den Dateinamen. Das Feld `<wanted>` kann wiederholt und mit dem Unterlement `<condition>` versehen werden. Dann wird der Check nur ausgeführt, wenn die konfigurierte Bedingung zutrifft.
`check` | Innerhalb eines jeden Elements check wird festgelegt, was JHove genau validieren soll. Hier wird beispielsweise festgelegt, welches Dateiformat erwartet wird. Für den erwarteten Wert kann innerhalb des Elements `<wanted>` eine direkte Eingabe auch als Bereich erfasst werden. Ebenso ist es hier auch möglich, eine Variable zu verwenden, die durch den Variablen-Replacer ersetzt wird (z.B. `{process.Resolution}`. Zugehörig ist hierbei ebenso, welche Fehlermeldung im Falle einer fehlerhaften Validierung ausgegeben werden soll. In der Fehlermeldung können folgende Variablen genutzt werden: `${wanted}` für den exakten Inhalt aus dem Feld `<wanted>`, `${expected}` für den aufgelösten erwarteten Wert, `${found}` für den gefundenen Wert und `${image}` für den Dateinamen. Das Feld `<wanted>` kann wiederholt und mit dem Unterlement `<condition>` versehen werden. Dann wird der Check nur ausgeführt, wenn die konfigurierte Bedingung zutrifft. Im Feld `<checkType>` kann angegeben werden, wie genau die Prüfung ausgeführt wird. Der Defaultwert ist dabei `equals`, der gefundene Wert muss exakt mit dem konfigurierten Wert übereinstimmen. Die Option `multiple` prüft, ob der gefundene Wert ein vielfaches der konfigurierten Zahl ist. Bei `lesser` oder `greater` muss der gefundene Wert größer bzw. kleiner als der konfiguriert Wert sein, `exists` und `not exists` prüft auf die Existenz eines beliebigen Wertes und `same` prüft, ob der Wert mit einem anderen Wert übereinstimmt. Hierzu muss der andere Wert in `otherXpath` angegeben werden.


3 changes: 2 additions & 1 deletion docs/index_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ Parameter | Explanation
`openStepOnError` | This parameter determines which step of the workflow should be reopened if an error occurs within the validation. If this parameter is not used, the plugin simply activates the previous step of the validation step instead.
`lockAllStepsBetween` | This parameter is used to determine whether the work steps of the workflow between the validation step and the one specified within the parameter openStepOnError are to be set back to the status locked so that these work steps have to be run through again (`true`). If, on the other hand, the value is set to `false`, the status of the steps in between is not changed, so that these steps are not run through again.
`jhoveConfiguration` | This parameter specifies where the configuration file for JHove is located.
`check` | Within each element check is defined what exactly JHove should validate. For example, here you define which file format is expected. For the expected value, a direct input can also be entered as a range within the `<wanted>` element. It is also possible to use a variable here, which is replaced by the variable replacer (e.g. `{process.Resolution}`. Also included is which error message should be issued in case of an incorrect validation. The following variables can be used in the error message: `${wanted}` for the exact content from the `<wanted>` field, `${expected}` for the resolved expected value, `${found}` for the found value and `${image}` for the file name. The field `<wanted>` can be repeated and can contain the sub-element `<condition>`. The check is then only executed if the configured condition applies.
`check` | Within each element check is defined what exactly JHove should validate. For example, here you define which file format is expected. For the expected value, a direct input can also be entered as a range within the `<wanted>` element. It is also possible to use a variable here, which is replaced by the variable replacer (e.g. `{process.Resolution}`. Also included is which error message should be issued in case of an incorrect validation. The following variables can be used in the error message: `${wanted}` for the exact content from the `<wanted>` field, `${expected}` for the resolved expected value, `${found}` for the found value and `${image}` for the file name. The field `<wanted>` can be repeated and can contain the sub-element `<condition>`. The check is then only executed if the configured condition applies. The `<checkType>` field can be used to specify how exactly the check is to be carried out. The default value is `equals`, the value found must match the configured value exactly. The `multiple` option checks whether the value found is a multiple of the configured number. With `lesser` or `greater`, the value found must be greater or smaller than the configured value, `exists` and `not exists` checks for the existence of any value and `same` checks whether the value matches another value. To do this, the other value must be specified in `otherXpath`.


141 changes: 123 additions & 18 deletions install/plugin_intranda_step_tif_validation.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,124 @@
<lockAllStepsBetween>true</lockAllStepsBetween>
<jhoveConfiguration>/opt/digiverso/goobi/config/jhove/jhove.conf</jhoveConfiguration>
<namespace uri="http://www.loc.gov/mix/v20" name="mix" />
<namespace uri="http://hul.harvard.edu/ois/xml/ns/jhove" name="jhove" />
<!-- Counter check -->
<check>
<xpath>count(//jhove:repInfo/jhove:format)</xpath>
<wanted>1.0</wanted>
<error_message>Check format count for "${image}": Expected value "${expected}", but found value "${found}".</error_message>
</check>
<namespace uri="http://schema.openpreservation.org/ois/xml/ns/jhove" name="jhove" />

<!-- format is 'TIFF' -->
<check>
<xpath>string(//jhove:repInfo/jhove:format)</xpath>
<wanted>TIFF</wanted>
<error_message> Check format for "${image}": Expected value "${expected}", but found value "${found}".</error_message>
</check>
<!--Check if the image is well-formed and valid -->

<!-- image is well-formed and valid-->
<check>
<xpath>//jhove:repInfo/jhove:status</xpath>
<wanted>Well-Formed and valid</wanted>
<wanted value="Well-Formed and valid"></wanted>
<error_message> Check status for "${image}": Expected value "${expected}", but found value "${found}".</error_message>
</check>

<!-- compression type is 'Uncompressed' -->
<check>
<xpath>//mix:Compression/mix:compressionScheme</xpath>
<wanted>Uncompressed</wanted>
<error_message>Check compression scheme for "${image}": Expected value "${expected}", but found value "${found}".</error_message>
</check>
<!--Check the color profile -->

<!-- planar configuration -->
<check>
<xpath>string(//mix:iccProfileName)</xpath>
<wanted>Adobe RGB (1998)</wanted>
<error_message> Check color profile for "${image}": Expected value "${expected}", but found value "${found}".</error_message>
<xpath>//jhove:property[jhove:name='PlanarConfiguration']/jhove:values/jhove:value</xpath>
<wanted>1</wanted>
<error_message>Check planar configuration for "${image}": Expected value "${expected}", but found value "${found}".</error_message>
</check>
<!--Check color depth -->

<!-- byte order -->
<check>
<xpath>string(//mix:bitsPerSampleValue[1])</xpath>
<wanted>16</wanted>
<xpath>//jhove:property[jhove:name='ByteOrder']/jhove:values/jhove:value</xpath>
<wanted>little-endian</wanted>
<error_message>Check compression scheme for "${image}": Expected value "${expected}", but found value "${found}".</error_message>
</check>

<!-- bit order is MSB-to-LSB -->
<check>
<xpath>//jhove:property[jhove:name='FillOrder']/jhove:values/jhove:value</xpath>
<wanted>1</wanted>
<error_message>Check compression scheme for "${image}": Expected value "${expected}", but found value "${found}".</error_message>
</check>

<!-- color space -->
<check>
<xpath>//mix:PhotometricInterpretation/mix:colorSpace</xpath>
<wanted>RGB</wanted>
<error_message>Check compression scheme for "${image}": Expected value "${expected}", but found value "${found}".</error_message>
</check>

<!--Check color depth, allowed is 8,8,8 or 16,16,16-->
<check>
<xpath>string(//mix:samplesPerPixel[1])</xpath>
<wanted>3</wanted>
<error_message> Check color depth for "${image}": Expected value "${expected}", but found value "${found}".</error_message>
</check>
<!--Check for resolution (number or range) -->
<check>
<xpath>string(//mix:bitsPerSampleValue[1])</xpath>
<wanted>8|16</wanted>
<error_message> Check color depth for "${image}": Expected value is 8 or 16 but found value "${found}".</error_message>
</check>
<check>
<xpath>string(//mix:bitsPerSampleValue[2])</xpath>
<wanted>8|16</wanted>
<error_message> Check color depth for "${image}": Expected value is 8 or 16 but found value "${found}".</error_message>
</check>
<check>
<xpath>string(//mix:bitsPerSampleValue[2])</xpath>
<wanted>8|16</wanted>
<error_message> Check color depth for "${image}": Expected value is 8 or 16 but found value "${found}".</error_message>
</check>

<!-- Resolution checks -->

<!-- values exist -->
<check>
<xpath>//mix:ImageAssessmentMetadata//mix:SpatialMetrics/mix:xSamplingFrequency/mix:numerator</xpath>
<wanted>exists</wanted>
<error_message>Check x-axis resolution": value not found".</error_message>
<checkType>exists</checkType>
</check>

<check>
<xpath>//mix:ImageAssessmentMetadata//mix:SpatialMetrics/mix:ySamplingFrequency/mix:numerator</xpath>
<wanted>exists</wanted>
<error_message>Check y-axis resolution": value not found".</error_message>
<checkType>exists</checkType>
</check>
<check>
<xpath>//mix:ImageAssessmentMetadata//mix:SpatialMetrics/mix:samplingFrequencyUnit</xpath>
<wanted>exists</wanted>
<error_message>Check resolution unit": value not found".</error_message>
<checkType>exists</checkType>
</check>
<!-- values are identical -->
<check>
<xpath>//mix:ImageAssessmentMetadata//mix:SpatialMetrics/mix:xSamplingFrequency/mix:numerator</xpath>
<wanted></wanted>
<error_message> Check resolution for "${image}": X- and Y-resolution differ.</error_message>
<checkType>same</checkType>
<otherXpath>//mix:ImageAssessmentMetadata//mix:SpatialMetrics/mix:ySamplingFrequency/mix:numerator</otherXpath>
</check>
<!-- at least 300 dpi -->
<check>
<xpath>//mix:ImageAssessmentMetadata//mix:SpatialMetrics/mix:xSamplingFrequency/mix:numerator</xpath>
<wanted>300</wanted>
<error_message>Check x-axis resolution": Expected value at least "${expected}", but found value "${found}".</error_message>
<checkType>greater</checkType>
</check>
<check>
<xpath>//mix:ImageAssessmentMetadata//mix:SpatialMetrics/mix:ySamplingFrequency/mix:numerator</xpath>
<wanted>300</wanted>
<error_message>Check y-axis resolution": Expected value at least "${expected}", but found value "${found}"".</error_message>
<checkType>greater</checkType>
</check>

<!-- get expected resolution from process property -->
<integrated_check name="resolution_check">
<mix_uri>http://www.loc.gov/mix/v20</mix_uri>
<!-- get the value from the property 'Resolution' -->
Expand All @@ -51,9 +138,27 @@
<condition value="{process.Resolution}" matches="other" />
</wanted>
<!-- default configuration that is used if none of the above conditions apply.
If no default configuration exists and no condition applies, the check is not executed -->
If no default configuration exists and no condition applies, the check is not executed.
Can be a fixed value or a range. -->
<wanted>100.0-899.23</wanted>
<error_message> Check resolution for "${image}": Expected value "${expected}", but found value "${found}".</error_message>
</integrated_check>

<!-- resolution values for x-axis and y-axis are the same-->
<integrated_check name="resolution_check">
<mix_uri>http://www.loc.gov/mix/v20</mix_uri>
<wanted>1</wanted>
<error_message> Check resolution for "${image}": x-axis and y-axis differ.</error_message>
<checkType>same</checkType>
</integrated_check>

<!-- resolution is at least 300 dpi-->
<integrated_check name="resolution_check">
<mix_uri>http://www.loc.gov/mix/v20</mix_uri>
<wanted>300</wanted>
<error_message> Check resolution for "${image}": must be at least "${expected}" dpi, but found value "${found}".</error_message>
<checkType>greater</checkType>
</integrated_check>

</config>
</config_plugin>
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,10 @@ private void readChecks() {
}
}
if (match) {
this.checks.add(new TifValidationResolutionCheck(wantedValue, errorMessage, mixUri));

TifValidationResolutionCheck check = new TifValidationResolutionCheck(wantedValue, errorMessage, mixUri);
check.setCheckType(hc.getString("/checkType", "equals"));
this.checks.add(check);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public TifValidationResolutionCheck(String expectedValue, String errorMessage, S
private void createReplaceMap() {
this.replaceMap = new HashMap<>();
this.replaceMap.put("wanted", this.expectedValue);
this.replaceMap.put("expected", this.expectedValue);
}

@Override
Expand All @@ -83,13 +84,21 @@ public boolean check(Document doc) {
compressionValueX = resolutionXnum.intValue();
compressionValueY = resolutionYnum.intValue();
}
ValueRange range = ValueRangeFactory.create(expectedValue);

if (range.contains(compressionValueX) && range.contains(compressionValueY)) {
return true;
} else {
this.replaceMap.put("found", compressionValueX + "," + compressionValueY);
return false;
this.replaceMap.put("found", compressionValueX + "," + compressionValueY);
int expected = Integer.parseInt(expectedValue);
switch (checkType) {
case "equals": {
ValueRange range = ValueRangeFactory.create(expectedValue);
return range.contains(compressionValueX) && range.contains(compressionValueY);
}
case "same":
return compressionValueX.equals(compressionValueY);
case "greater":
return expected <= compressionValueX.intValue() && expected <= compressionValueY.intValue();
case "lesser":
return expected >= compressionValueX.intValue() && expected >= compressionValueY.intValue();
default:
throw new IllegalArgumentException("Unexpected value: " + checkType);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,12 @@ public boolean check(Document doc) {
} else if (!(value instanceof String)) {
value = value.toString();
}
this.replaceMap.put("found", (String) value);
String val = (String) value;
this.replaceMap.put("found", val);
switch (checkType) {
case "exists":
return true;
case "greater":

if (NumberUtils.isCreatable(val)) {
if (val.contains(".")) {
double expected = Double.parseDouble(expectedValue);
Expand Down

0 comments on commit 9144bb3

Please sign in to comment.