Skip to content

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);
    }
}