Restricted Types and Validation¶
The schema constrains most of its values: identifiers follow a pattern, enumerations list their members, and physical quantities are bounded. The library enforces those constraints when the value is set.
Overview¶
A restricted simple type is a class with set() and get(). set() raises InscoperNBOValidationException when the value does not comply.
| Restriction | Example type | Rejected |
|---|---|---|
| Enumeration | LensConstruction_Type |
"Inscoper", "" |
| Regular expression | LSID_Type, AnnotationID_Type |
"Inscoper", with no namespace separator |
| Lower bound | NonNegativeFloat_Type, PositiveInt_Type |
-1, and 0 for the positive variants |
| Value range | PercentFraction_Type |
-1.0, 2.0 |
| Length | Hex40_Type |
Any string beyond 40 hexadecimal characters |
Two accessors expose the restriction itself, which is what a user interface needs to fill a combo box or to check an entry field before submitting.
| Accessor | Returns |
|---|---|
<Type>.getAllowedValues() |
The admissible members of an enumerated type |
instance.getPattern() |
The regular expression an identifier must match |
Restrictions compose through inheritance. AnnotationID_Type derives from LSID_Type and narrows the pattern to the Annotation namespace, so Annotation:23 is accepted where Image:1 is not.
Validation applies in four places: on set() of a restricted type, on a generated setter whose attribute is a restricted type, on import, and on export, where it also checks that every required attribute is present. Each accepts a trailing validate argument; passing False stores or writes the value as it is.
Disabling validation
Disable validation only to carry through data from a non-compliant source, and record that you did. The resulting document is not schema-valid, and downstream tools may reject it.
Validate, inspect, and bypass restrictions¶
import inscoper_nbo
# ── Step 1: Enumerations accept only the values declared in the schema
lens_construction = inscoper_nbo.LensConstruction_Type()
try:
lens_construction.set("Inscoper")
except inscoper_nbo.InscoperNBOValidationException as error:
print(f"Rejected value: {error}")
lens_construction.set("Simple")
# The admissible values are available from the class itself
print(list(inscoper_nbo.LensConstruction_Type.getAllowedValues()))
# ── Step 2: Identifiers are validated against their regular expression
lsid = inscoper_nbo.LSID_Type()
print(lsid.getPattern())
lsid.set("urn:lsid:openmicroscopy.org:Image:12345")
lsid.set("Image:1")
# Derived identifiers narrow the pattern further: AnnotationID_Type accepts only
# identifiers in the Annotation namespace.
annotation_id = inscoper_nbo.AnnotationID_Type()
print(annotation_id.getPattern())
try:
annotation_id.set("Image:1")
except inscoper_nbo.InscoperNBOValidationException as error:
print(f"Rejected identifier: {error}")
annotation_id.set("Annotation:23")
# ── Step 3: Numeric restrictions are enforced on the value range
percent = inscoper_nbo.PercentFraction_Type()
percent.set(0.5)
for out_of_range in (-1.0, 2.0):
try:
percent.set(out_of_range)
except inscoper_nbo.InscoperNBOValidationException as error:
print(f"Rejected fraction {out_of_range}: {error}")
positive = inscoper_nbo.PositiveFloat_Type()
try:
positive.set(0.0)
except inscoper_nbo.InscoperNBOValidationException as error:
print(f"Rejected zero: {error}")
# ── Step 4: Validation can be disabled for a single call
# Pass False as the second argument to store a value the schema does not allow.
# Use it only to carry through data produced by a non-compliant third-party
# source; the resulting document is no longer schema-valid.
lens_construction.set("Inscoper", False)
percent.set(2.0, False)
print(lens_construction.get(), percent.get())
# The same flag exists on generated setters and on XML import
external = inscoper_nbo.External()
external.setCompression("zlib")
external.setCompression("Inscoper", False)
ome = inscoper_nbo.OME()
non_compliant = """<?xml version="1.0"?>
<OME>
<Screen ID="Screen_1"/>
</OME>"""
try:
ome.fromXmlString(non_compliant)
except inscoper_nbo.InscoperNBOValidationException as error:
print(f"Rejected document: {error}")
ome.fromXmlString(non_compliant, False)
#include <NBO/NBO/AnnotationID_Type.h>
#include <NBO/NBO/External.h>
#include <NBO/NBO/LSID_Type.h>
#include <NBO/NBO/LensConstruction_Type.h>
#include <NBO/NBO/OME.h>
#include <NBO/NBO/PercentFraction_Type.h>
#include <NBO/NBO/PositiveFloat_Type.h>
#include <NBO/Shared/Exception/InscoperNBOException.h>
#include <iostream>
using namespace Inscoper;
int main() {
// Step 1: Enumerations accept only the values declared in the schema
NBO::LensConstruction_Type lensConstruction;
try {
lensConstruction.set("Inscoper");
} catch (const NBO::InscoperNBOValidationException &error) {
std::cout << "Rejected value: " << error.what() << std::endl;
}
lensConstruction.set("Simple");
// The admissible values are available from the class itself
for (const auto &value : NBO::LensConstruction_Type::getAllowedValues()) {
std::cout << value << " ";
}
std::cout << std::endl;
// Step 2: Identifiers are validated against their regular expression
NBO::LSID_Type lsid;
std::cout << lsid.getPattern() << std::endl;
lsid.set("urn:lsid:openmicroscopy.org:Image:12345");
lsid.set("Image:1");
// Derived identifiers narrow the pattern further: AnnotationID_Type accepts
// only identifiers in the Annotation namespace.
NBO::AnnotationID_Type annotationId;
std::cout << annotationId.getPattern() << std::endl;
try {
annotationId.set("Image:1");
} catch (const NBO::InscoperNBOValidationException &error) {
std::cout << "Rejected identifier: " << error.what() << std::endl;
}
annotationId.set("Annotation:23");
// Step 3: Numeric restrictions are enforced on the value range
NBO::PercentFraction_Type percent;
percent.set(0.5f);
for (float outOfRange : {-1.0f, 2.0f}) {
try {
percent.set(outOfRange);
} catch (const NBO::InscoperNBOValidationException &error) {
std::cout << "Rejected fraction " << outOfRange << ": " << error.what() << std::endl;
}
}
NBO::PositiveFloat_Type positive;
try {
positive.set(0.0f);
} catch (const NBO::InscoperNBOValidationException &error) {
std::cout << "Rejected zero: " << error.what() << std::endl;
}
// Step 4: Validation can be disabled for a single call
// Pass false as the second argument to store a value the schema does not allow.
// Use it only to carry through data produced by a non-compliant third-party
// source; the resulting document is no longer schema-valid.
lensConstruction.set("Inscoper", false);
percent.set(2.0f, false);
std::cout << lensConstruction.get() << " " << percent.get() << std::endl;
// The same flag exists on generated setters and on XML import
NBO::External external;
external.setCompression("zlib");
external.setCompression("Inscoper", false);
NBO::OME ome;
const std::string nonCompliant = R"(<?xml version="1.0"?>
<OME>
<Screen ID="Screen_1"/>
</OME>)";
try {
ome.fromXmlString(nonCompliant);
} catch (const NBO::InscoperNBOValidationException &error) {
std::cout << "Rejected document: " << error.what() << std::endl;
}
ome.fromXmlString(nonCompliant, false);
return 0;
}
import com.inscoper.nbo.AnnotationID_Type;
import com.inscoper.nbo.External;
import com.inscoper.nbo.LSID_Type;
import com.inscoper.nbo.LensConstruction_Type;
import com.inscoper.nbo.OME;
import com.inscoper.nbo.PercentFraction_Type;
import com.inscoper.nbo.PositiveFloat_Type;
public class RestrictedTypes {
public static void main(String[] args) {
// Step 1: Enumerations accept only the values declared in the schema
// The generated setters carry no throws clause, so the checked exception
// cannot be named in a catch block: catch Exception and read its message.
LensConstruction_Type lensConstruction = new LensConstruction_Type();
try {
lensConstruction.set("Inscoper");
} catch (Exception error) {
System.out.println("Rejected value: " + error.getMessage());
}
lensConstruction.set("Simple");
// The admissible values are available from the class itself
System.out.println(LensConstruction_Type.getAllowedValues());
// Step 2: Identifiers are validated against their regular expression
LSID_Type lsid = new LSID_Type();
System.out.println(lsid.getPattern());
lsid.set("urn:lsid:openmicroscopy.org:Image:12345");
lsid.set("Image:1");
// Derived identifiers narrow the pattern further: AnnotationID_Type accepts
// only identifiers in the Annotation namespace.
AnnotationID_Type annotationId = new AnnotationID_Type();
System.out.println(annotationId.getPattern());
try {
annotationId.set("Image:1");
} catch (Exception error) {
System.out.println("Rejected identifier: " + error.getMessage());
}
annotationId.set("Annotation:23");
// Step 3: Numeric restrictions are enforced on the value range
PercentFraction_Type percent = new PercentFraction_Type();
percent.set(0.5f);
for (float outOfRange : new float[] {-1.0f, 2.0f}) {
try {
percent.set(outOfRange);
} catch (Exception error) {
System.out.println("Rejected fraction " + outOfRange + ": " + error.getMessage());
}
}
PositiveFloat_Type positive = new PositiveFloat_Type();
try {
positive.set(0.0f);
} catch (Exception error) {
System.out.println("Rejected zero: " + error.getMessage());
}
// Step 4: Validation can be disabled for a single call
// Pass false as the second argument to store a value the schema does not allow.
// Use it only to carry through data produced by a non-compliant third-party
// source; the resulting document is no longer schema-valid.
lensConstruction.set("Inscoper", false);
percent.set(2.0f, false);
System.out.println(lensConstruction.get() + " " + percent.get());
// The same flag exists on generated setters and on XML import
External external = new External();
external.setCompression("zlib");
external.setCompression("Inscoper", false);
OME ome = new OME();
String nonCompliant = """
<?xml version="1.0"?>
<OME>
<Screen ID="Screen_1"/>
</OME>""";
try {
ome.fromXmlString(nonCompliant);
} catch (Exception error) {
System.out.println("Rejected document: " + error.getMessage());
}
ome.fromXmlString(nonCompliant, false);
}
}