EN · DE · RU · FR · ES

#754: XmlField.java

projectforge-business/src/main/java/org/projectforge/framework/xmlstream/XmlField.java Java annotation — central field-level annotation of the XmlStream framework. 92 lines. @Target(FIELD), @Retention(RUNTIME). Source: projectforge-business/src/main/java/org/projectforge/framework/xmlstream/XmlField.java 92 lines · 17 code · 63 comments · 12 blank
Purpose: The central annotation of the XmlStream framework — equivalent to JAXB's @XmlElement, @XmlAttribute, XStream's @XStreamAlias and @XStreamAsAttribute, all combined into one annotation. Marks a Java field as serializable to XML and controls exactly how it is written. Applied at the field level (@Target(FIELD)) and available at runtime via reflection (@Retention(RUNTIME)) — this is how XmlObjectWriter and XmlObjectReader discover serializable fields.

8 Annotation Attributes

alias() — XML element/attribute name

Overrides the field name during serialization. Without alias: private String firstName → tag <firstName>. With alias: @XmlField(alias="first-name") → tag <first-name>. Useful when the XML format must conform to an external schema or when a Java field name conflicts with an XML reserved word.

asAttribute() and asElement() — attribute vs. element

Controls whether the value is serialized as an XML attribute (compact) or an element (structured):

<!-- As attribute: -->
<user id="42" name="John"/>

<!-- As element: -->
<user><id>42</id><name>John</name></user>

Critical nuance from Javadoc: "asAttribute=false has no effect (please use asElement=true instead)" and vice versa. This means false is not a negation — it's "leave to default," which may be overridden by global settings in XmlObjectWriter.asAttributeAsDefault(). To guarantee attribute serialization, use asAttribute=true. To guarantee element, use asElement=true.

defaultDoubleValue / defaultIntValue / defaultStringValue / defaultBooleanValue — XML compression

If the field value equals the declared default, it is NOT serialized to XML. This is a compression mechanism: typical default values don't occupy space in the output. During deserialization, absent tags receive the default value. The magic numbers from XmlConstants (#751) serve as the "unset" sentinel for int and string defaults. For boolean, the default is false (the most common value). For double, the default is NaN ("not set").

asCDATA() — special character protection

If true, the string value is wrapped in an XML <![CDATA[...]]> block. Needed for fields that may contain <, >, & characters — e.g., HTML in description fields or SQL in logs. Without CDATA, these characters would need escaping as &lt;, &gt;, &amp;, making the XML unreadable.

Runtime Consumption

  1. XmlObjectWriter iterates all fields of an object via reflection during serialization
  2. For each field, checks for @XmlField (and absence of @XmlOmitField)
  3. If present, reads parameters: alias (tag name), asAttribute (format), default* (skip logic), asCDATA (format)
  4. Calls the appropriate Converter to transform the field value to a string
  5. XmlObjectReader does the reverse: reads tag/attribute from XML, finds the matching field by name or alias, calls Converter for reverse transformation

Comparison with XStream and JAXB

CapabilityXmlFieldXStreamJAXB
Field aliasalias="name"@XStreamAlias("name")@XmlElement(name="name")
Attribute vs elementasAttribute=true@XStreamAsAttribute@XmlAttribute
Field exclusion@XmlOmitField@XStreamOmitField@XmlTransient
Default valuedefaultIntValue=0❌ none❌ none
CDATAasCDATA=true❌ none❌ none
Format versioning✅ via XmlObject❌ none❌ none
XmlField + XmlStream provide more control over XML format than XStream, but require manual annotation. XStream "just works" without annotations but generates less controlled XML. The choice of XmlStream for data export was driven specifically by the need for format control and versioning.

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 (renamed to avoid XStream library confusion)
ceb63e8a1 Source code header: (C) 2001-2021
7c79f1922 Copyright of source header → 2020
32f634b88 Optimize imports
dd5ca38ac CopyRight of all java file-header updated or created
9ebb88522 Initial commit
The annotation attributes have been stable since initial commit. Only copyright headers, import optimization (32f634b88), and the package rename touched this file. The commented-out implementationClass() attribute suggests the author considered interface-to-implementation mapping at the field level but chose to handle it in XmlObjectReader.addImplementationMapping() instead.