In Section 4.3, “Objects” the interface CapStruct was introduced as a superinterface of CapObject for providing readable properties of an entity. While CapObjects are mutable and thus not suitable as values, the interface Struct also inherits from CapStruct and represents an unmodifiable structured object.
Structs can be stored in markup properties of the content repository, if the markup property
uses the predefined grammar coremedia-struct-2008
. The Unified API will
transparently convert instances of
Struct
to and from XML. The storage format is compatible with the struct abstraction that used to
be provided with CoreMedia Starter Kit.
Structs
support only a limited range of primitive property types, namely strings, integers, Boolean,
links to
Content
and lists thereof. However, structs may also contain arbitrarily nested structs and lists of
structs as complex property values. While structs themselves are immutable, they provide the
builder()
method that returns a builder object that can be used to create other
similar structs.
Caution | |
---|---|
StructBuilders are not structs. They cannot be used as property values. |
A
StructBuilder
provides methods to set property values and to declare new properties. The method
set(String, Object)
sets a single property, whereas the method
setAll(Map)
sets multiple properties at once. The methods
declare...
take varying arguments depending on the type of property they
define. For list properties, the methods set(String, int, Object)
,
add(String, Object)
and add(String, int, Object)
provide ways to
replace a list element or to add a new list element. Likewise, remove(String,
int)
removes a single element from a list.
When building nested structs, a struct builder always considers either the top-level struct
or one of the substructs as the current struct. Set and declare operations are always
performed on the current struct. Using the methods enter(String)
a substruct of
the current struct can be selected as the new current struct. In the case of struct lists,
use enter(String, int)
. When calling up()
, the current struct can
be set back one level towards the top-level struct. Calling at(...)
, you can
navigate directly to a deeply nested substruct ignoring the previous current struct. The
method currentPath()
returns the current path, allowing you to return to a given
substruct later on.
The method mode(...)
requests one of three different behaviors that are
represented by the enumeration class
StructBuilderMode.
The mode determines how the struct builder reacts when a declare or set operation conflicts
with the existing declaration of a property. By default, a new property can be directly set
without declaring it, as long as the value is not null
or a list containing
values of mixed types, because a suitable property descriptor can be inferred. But that is
not allowed in all modes.
STRICT
: Declare operations fail if the property already exists. Set operations fail if no property descriptor exists and they fail if the existing property descriptor does not allow the value. Property descriptors are never inferred.DEFAULT
: Declare operations fail if the property already exists. Set operations fail if the existing property descriptor does not allow the value or if a new property descriptor cannot be inferred.LOOSE
: Declare operations never fail. Set operations fail only if the desired property descriptor cannot be inferred. If a new value does not match an existing property descriptor, the existing descriptor is replaced by another descriptor that allows the value.
You can use the method remove(String)
to remove a property declaration from the
current struct. In strict and default mode, this is necessary before a property can be
redeclared. Using removeAll()
the current struct be reset to an empty struct.
The method defaultTo(Struct)
can be used to extend the current struct with
those property declarations of the argument struct that were not previously present in the
current struct. This is useful to set default values when initializing a struct or when
merging multiple levels of struct-based configurations. When an existing struct property is
defaulted to another struct property, the default is applied recursively. When an existing
struct list property is defaulted to a struct property (not a struct list property), each
list element is augmented with default values individually.
Finally, when the struct is completely built, you can retrieve it from the builder by means
of the build()
method. The builder remains usable to build additional similar
structs. At any time, you can also retrieve the current struct using
currentStruct()
.
Caution | |
---|---|
StructBuilder instances are not thread-safe. Builders must not be accessed concurrently by multiple threads. |