EN · DE · RU · FR · ES

#752: Status.java

projectforge-business/src/main/java/org/projectforge/framework/xmlstream/Status.java Java enum — single-value sentinel for XML deserialization control. 32 lines. Source: projectforge-business/src/main/java/org/projectforge/framework/xmlstream/Status.java 32 lines · 5 code · 25 comments · 2 blank
Purpose: An enum with a single value: IGNORE. 32 lines, of which 21 are the GPLv3 license header. One of the shortest and most unusual files in the project. The Javadoc on IGNORE explains: "Used by XmlObjectReader.newInstance(Class, org.dom4j.Element, String)" — it is used by the newInstance() method of XmlObjectReader during XML reading.

Why a Single-Value Enum?

This is the Sentinel Pattern — a special value that signals the need to skip an element during reading. When XmlObjectReader.newInstance() encounters an XML element for which there is no registered class (e.g., a tag from an old format version that was removed in a newer version), it returns Status.IGNORE rather than crashing with an error.

Why not just return null? Because null is ambiguous: it could mean "skip" OR "an error occurred" OR "the element is empty". Status.IGNORE is an explicit, named signal: "I recognize this element as ignorable, consciously skipping it, continue processing."

Three-State Resolution

The enum enables clean three-state return value semantics:

Object result = newInstance(clazz, element, version);
if (result == Status.IGNORE) {
    // Unknown element, skip it
} else if (result == null) {
    // Recognized but has null value (field is empty)
} else {
    // Normal deserialized object
}

This is significantly cleaner than returning null with ambiguous semantics. The pattern is common in parsers and deserializers — e.g., Rust uses Option<T>, Haskell uses Maybe, and here — a single-element enum.

Where Used

Method XmlObjectReader.newInstance(Class<?> clazz, Element rootElement, String version) — a protected factory method that subclasses can override. At each level, it checks AliasMap: if the tag is registered, creates an object; if not registered — returns Status.IGNORE, and the calling code skips that element. This allows XML files to contain "extra" tags (e.g., from a newer format version when read by an older version) without errors — a backward compatibility mechanism.

Why Enum, Not a Constant?

An enum with one value is simultaneously both a type and a value. If newInstance() returned just Object (where null = skip), the calling code would need if (result == null). But null could also be a legitimate result (a genuinely empty field). Using a separate type Status allows the calling code to precisely distinguish between "skip this" (IGNORE) and "value is absent" (null).

Contrast: Status.IGNORE vs. @XmlOmitField vs. Default Skipping

MechanismScopeWhen activated
Status.IGNORERuntime — per-element, during readXML tag has no corresponding Java class registered
@XmlOmitField (#757)Compile-time — on field declarationAlways — field never serialized/deserialized
Default-value skippingCompile-time — in @XmlFieldField equals declared default value

Git History

868d6abb7 2025 → 2026 (copyright year update)
63081666f Source file headers: 2024→2025
b6092df09 Copyright 2023 → 2024
ab45d51fa Copyright 2001-2022 → 2001-2023
5f7ef41b8 Copyright 2021 → 2022
cd27dd997 package xstream → xmlstream
ceb63e8a1 Source code header: (C) 2001-2021
7c79f1922 Copyright of source header → 2020
dd5ca38ac CopyRight of all java file-header updated or created
9ebb88522 Initial commit
The enum has one value (IGNORE) and has never changed since the initial commit beyond copyright headers and the package rename. A single-value enum with a clear sentinel purpose is a "done" design — there's nothing to add or modify. This is one of the most stable files in the entire ProjectForge codebase.