public interface Property extends Cloneable, Serializable, Iterable<Property>
You can say that a Field
object is like a Java class and a Property object like a class instance. Thus,
schemas defines fields (or elements) which have a name and a type, and each field of a document can be instantiated
(if the schema permits) as a Property object.
Properties are always bound to a schema field that provides the type and constraints on the property values. An
exception is the root property the DocumentPart
object which is not bound to a field but to a schema.
So properties are holding the actual values for each defined field.
The usual way of using properties is to get a document from the storage server then modify document properties and send them back to the storage server to that modifications are be stored.
Note that the storage server can be on a remote machine so when modifying properties remotely they are serialized and sent through the network between the two machines. This means properties must hold serializable values and also they must store some state flags so that the storage can decide which property was modified and how in order to correctly update the stored versions.
As we have seen each property may hold a serializable value which we will refer to as the normalized
property value. For each schema field type there is only one java serializable object representation that will be
used as the normalized value. The property API is giving you the possibility to use different compatible objects when
setting or getting property values. Each property implementation will automatically convert the given value into a
normalized one; so internally only the normalized value is stored.
For example, for date properties you may use either Date
or Calendar
when setting or
retrieving a property value, but the normalized value will be the Calendar
one.
As we have seen, properties keep some state flags. Property flags can be divided in two groups:
Property Types:
Before going deeper in property flags, we will talk first about property types. There are several types of properties that are very closed on the type of fields they are bound onto.
DocumentPart
) - this is a special property that is bound to a schema instead of a
field And it is the root of the property tree.
Map
objects. These properties contains a set of schema defined properties. You cannot add new child
properties. You can only modify existing child properties. Complex property values are expressed as java
Map
objects.
Map
or a Collection
. These objects are
usually as scalar values - it doesn't make sense for example to set only some parts of that objects without creating
the object completely. An example of usage are Blob properties that use Blob
values.
As we've seen there are 2 categories of properties: container properties and scalar properties Complex and list properties are container properties while structured and scalar properties are scalar.
Dirty Flags:
Dirty flags are used to keep track of the dirty state of a property. The following flags are supported:
IS_PHANTOM
- whether the property is existing in the storage (was explicitly set by the user) or it
was dynamically generated using the default value by the implementation to fulfill schema definition. This applies to
all property types
IS_MODIFIED
- whether the property value was modified. This applies to all property types.
IS_NEW
- whether the property is a new property that was added to a parent list property This
applies only to properties that are children of a list property.
IS_REMOVED
- whether a property was removed. A removed property will be removed from the storage and
the next time you access the property it will be a phantom
one. This applies only to properties that are
children of a complex property.
IS_MOVED
- whether the property was moved on another position inside the container list. This
applies only to properties that are children of a list property.
There are several constraints on how property flags may change. This is a list of all changes that may occur over dirty flags:
The combinations not listed above are not permitted.
In case of list items, the REMOVED flag is not used since the property will be physically removed from the property tree.
Also when the dirty flag of a children property changes, its parent is informed to update its MODIFIED flag if needed. This way a modification on a children property is propagated to parents in the form of a MODIFIED flag.
Internal Flags:
Internal flags are used by the implementation to keep some internal state. For these flags you should look into the implementation
Apart flags properties can also hold some random user data using Property#setData(Object)
and
Property#getData()
methods. This can be used for example to keep a context attached to a property. But be
aware when using this you should provide serializable objects as the data you are attaching otherwise if properties
are serialized / unserialized this will generate errors. The API is not forcing you to use serializable values since
you can also use this feature to store temporary context data that will not be sent over the network.
TestPropertyModel
for usage of property APIModifier and Type | Field and Description |
---|---|
static int |
DIRTY_MASK
A mask for public flags.
|
static int |
IS_DIRTY
A mask for the first 4 flags: NEW, REMOVED, MODIFIED, MOVED.
|
static int |
IS_MODIFIED
Flag used to mark a property as dirty.
|
static int |
IS_MOVED
Flag used to mark a property as dirty.
|
static int |
IS_NEW
Flag used to mark a property as new.
|
static int |
IS_PHANTOM
Flag used to mark a property as phantom.
|
static int |
IS_REMOVED
Flag used to mark a property as dirty.
|
static int |
NONE
No dirty flags set.
|
Modifier and Type | Method and Description |
---|---|
void |
accept(PropertyVisitor visitor,
Object arg)
Method that implement the visitor pattern.
|
Property |
addEmpty()
Creates an empty child property and adds it as a property to the list container.
|
Property |
addValue(int index,
Object value)
Inserts at the given position a new value to the list.
|
Property |
addValue(Object value)
Appends a new value to the list.
|
void |
clearDirtyFlags()
Notify the property that its changes was stored so it can safely remove dirty flags.
|
<T> T |
convertTo(Serializable value,
Class<T> toType)
Converts the given normalized value to the given type.
|
Property |
get(int index)
Get the child property given it's index.
|
Property |
get(String name)
Gets the child property having the given name.
|
Collection<Property> |
getChildren()
Get a collection over the children properties.
|
Iterator<Property> |
getDirtyChildren()
Gets an iterator over the dirty children properties.
|
int |
getDirtyFlags()
Get the dirty flags that are set on this property.
|
Field |
getField()
Gets the field corresponding to this property.
|
String |
getName()
Gets the property name.
|
PropertyObjectResolver |
getObjectResolver() |
Property |
getParent()
Gets the property parent.
|
String |
getPath()
Gets the path of this property relative to the owner document.
|
DocumentPart |
getRoot()
Gets the root property.
|
Schema |
getSchema()
Gets the document schema defining the property tree from which the property belongs.
|
Type |
getType()
Get the type of the field corresponding to this property.
|
Serializable |
getValue()
Gets the property normalized value.
|
<T> T |
getValue(Class<T> type)
Gets the property value as the given type.
|
<T> T |
getValue(Class<T> type,
String path)
Gets the value of the property resolved using the given path.
|
Serializable |
getValue(String path)
Gets the value of the property resolved using the given path.
|
Serializable |
getValueForWrite()
Gets the property normalized value for write.
|
void |
init(Serializable value)
Initializes the property with the given normalized value.
|
boolean |
isComplex()
Tests whether this property is of a map (complex) type.
|
boolean |
isContainer()
Whether this property is a container - this means the property value is a map or a list.
|
boolean |
isDirty()
Tests whether a property is dirty.
|
boolean |
isForceDirty()
only for SimpleDocumentModel
|
boolean |
isList()
Tests whether this property is of a list type.
|
boolean |
isModified()
Tests if a property value was modified.
|
boolean |
isMoved()
Tests if a property value was moved to another index in the parent list if any.
|
boolean |
isNew()
Tests if this property is new (just created but not yet stored).
|
boolean |
isNormalized(Object value)
Checks if the given value is a normalized one.
|
boolean |
isPhantom()
Tests if the property is a phantom.
|
boolean |
isReadOnly()
Whether the property is read only.
|
boolean |
isRemoved()
Tests if a property is flagged as removed.
|
boolean |
isSameAs(Property property)
Compare the two properties by content.
|
boolean |
isScalar()
Tests whether this property is of a scalar type.
|
void |
moveTo(int index)
Moves a property position into the parent container list.
|
Object |
newInstance()
Creates a new and empty instance of a normalized value.
|
Serializable |
normalize(Object value)
Normalizes the given value as dictated by the property type.
|
Serializable |
remove()
Removes this property from the tree.
|
Property |
resolvePath(Path path)
Resolves the given path relative to the current property and return the property if any is found otherwise throws
an exception.
|
Property |
resolvePath(String path)
Same as
resolvePath(Path) but with a string path as argument. |
void |
setForceDirty(boolean forceDirty)
only for SimpleDocumentModel
|
void |
setReadOnly(boolean value)
Sets the read only flag.
|
void |
setValue(int index,
Object value)
Sets a child property value given its index.
|
void |
setValue(Object value)
Sets this property value.
|
void |
setValue(String path,
Object value)
Sets the value of the property resolved using the given path.
|
int |
size()
Get the count of the children properties.
|
boolean |
validateType(Class<?> type)
Validates the given value type.
|
forEach, iterator, spliterator
static final int NONE
static final int IS_NEW
static final int IS_MODIFIED
static final int IS_REMOVED
static final int IS_MOVED
static final int IS_PHANTOM
static final int IS_DIRTY
static final int DIRTY_MASK
boolean isNew()
A property is new when added to a collection. This is the typical state for a new property added to a list
boolean isRemoved()
boolean isModified()
boolean isMoved()
boolean isPhantom()
boolean isDirty()
This tests whether or not a dirty flag is set on the property.
boolean isForceDirty()
void setForceDirty(boolean forceDirty)
int getDirtyFlags()
void clearDirtyFlags()
Dirty flags are removed according to the type of the modifications. This way if the property was REMOVED it becomes a PHANTOM otherwise all dirty flags are cleared.
This method should be used by storage implementors to notify the property it should reset its dirty flags. Note that clearing dirty flags is not propagated to the parent property or to children. You need to clear dirty flags explicitly for each property.
boolean isReadOnly()
void setReadOnly(boolean value)
value
- true to set this property read only false otherwiseboolean isComplex()
boolean isList()
boolean isScalar()
boolean isContainer()
Container properties don't have a scalar values. Container values are computed each time they are requested - by
calling on of the getValue
methods - by collecting the values of the child properties.
String getPath()
The path for top level properties is the same to the property name.
Type getType()
Field getField()
The field is the object defining the property. You can see the field as a java class and the property as a class instance
Property getParent()
Schema getSchema()
DocumentPart getRoot()
void init(Serializable value) throws PropertyException
The given value must be normalized - note that no check is done on that.
The phantom flag is unset by this operation.
This method should be used to initialize properties.
value
- the normalized value to setPropertyException
void setValue(Object value) throws PropertyException
For complex or list properties the value will be set recursively (as a map or list value).
value
- the value to set{@link
- InvalidPropertyValueException} if the given value type is not compatible with the expected value
typePropertyException
Serializable getValue() throws PropertyException
Normalized values are of the java type that correspond to the field type.
PropertyException
Serializable getValueForWrite() throws PropertyException
Can be different fropm getValue()
in cases where the property adapts the value it is given to store.
PropertyException
<T> T getValue(Class<T> type) throws PropertyException
The value is converted using the registered converter to the given type.
If conversion is not supported a runtime exception will be triggered.
PropertyException
Serializable remove() throws PropertyException
This method marks the property as dirty and sets its value to null.
PropertyException
Property get(String name) throws PropertyNotFoundException
If the property is a scalar, this will return always null.
The given name should be the full name (i.e. prefixed name if any prefix exists).
If a non prefixed name is given, the first child property having the given local name will be returned.
Relative paths are not resolved. THis method is intended to lookup direct children. For path lookups use
resolvePath(String)
instead.
name
- the child property name (the full name including the prefix if any){@link
- UnsupportedOperationException} if the property is a scalar property (doesn't have children){@link
- PropertyNotFoundException} if the child property is not found in the type definitionPropertyNotFoundException
Property get(int index) throws PropertyNotFoundException
If this method is not supported an UnsupportedOperationException
must be thrown
Relative paths are not resolved. THis method is intended to lookup direct chilren. For path lookups, use
resolvePath(String)
instead.
index
- {@link
- UnsupportedOperationException} if the property is a scalar property (doesn't have children){@link
- PropertyNotFoundException} if the child property is not found in the type definitionPropertyNotFoundException
void setValue(int index, Object value) throws PropertyException
If this method is not supported, an UnsupportedOperationException
must be thrown.
This method will mark the child value as dirty for existing values and in the case of map properties it will mark phantom properties as new properties.
index
- value
- the new value{@link
- UnsupportedOperationException} if the property is a scalar property (doesn't have children){@link
- PropertyNotFoundException} if the child property is not found in the type definitionPropertyException
Collection<Property> getChildren()
The returned collection is ordered for list properties, and unordered for complex properties
Be aware that this method is creating phantom child properties for all schema fields that are not yet set.
int size()
ComplexType.getFieldsCount()
.Property addValue(Object value) throws PropertyException
The created property will be marked as isNew()
.
value
- PropertyException
Property addValue(int index, Object value) throws PropertyException
The created property will be marked as isNew()
.
value
- index
- the position to insert the valuePropertyException
Property addEmpty() throws PropertyException
This method is useful to construct lists.
PropertyException
PropertyException
void moveTo(int index)
This method applies only for list item properties. The given index includes removed properties.
index
- the position in the parent container to move this propertyUnsupportedOperationException
- if the operation is not supported by the target propertyProperty resolvePath(String path) throws PropertyNotFoundException
resolvePath(Path)
but with a string path as argument. This is the same as calling
resolvePath(new Path(path))
.path
- the string path to resolve.PropertyNotFoundException
- if the path cannot be resolvedProperty resolvePath(Path path) throws PropertyNotFoundException
The path format is a subset of XPath. Thus, / is used as path element separator, [n] for list element indexes. Attribute separator '@' are not supported since all properties are assumed to be elements. Also you .. and . can be used as element names.
Example of paths:
dc:title
attachments/item[2]/mimeType
../dc:title
path
- the path to resolve.PropertyNotFoundException
- if the path cannot be resolvedSerializable getValue(String path) throws PropertyException
This method is a shortcut for: resolvePath(path).getValue()
.
path
- the path to the propertyPropertyException
<T> T getValue(Class<T> type, String path) throws PropertyException
The value will be converted to the given type if possible, otherwise an exception will be thrown.
This method is a shortcut for: resolvePath(path).getValue(type)
.
T
- The type of the value to returntype
- the class of the valuepath
- the java path of the property valuePropertyException
PropertyException
void setValue(String path, Object value) throws PropertyException
This method is a shortcut for: resolvePath(path).setValue(value)
.
path
- the property pathvalue
- the valuePropertyException
PropertyException
Serializable normalize(Object value) throws PropertyConversionException
Normalized values are the ones that are used for transportation over the net and that are given to the storage implementation to be stored in the repository
Normalized values must be Serializable
If the given value is already normalized it will be returned back.
value
- the value to normalize according to the property typePropertyConversionException
boolean isNormalized(Object value)
Null values are considered as normalized.
value
- the value to check<T> T convertTo(Serializable value, Class<T> toType) throws PropertyConversionException
If the value has already the given type it will be returned back.
value
- the normalized value to converttoType
- the conversion typePropertyConversionException
- if the conversion cannot be made because of type incompatibilitiesboolean validateType(Class<?> type)
Tests if the given value type can be converted to a normalized type and thus a value of this type can be set to that property.
type
- the type to validateObject newInstance()
Empty is used in the sense of a value that has not been initialized or can be considered as an empty value. For
example for the String
type the empty value will be the empty string ""
void accept(PropertyVisitor visitor, Object arg) throws PropertyException
The visitor must return null to stop visiting children otherwise a context object that will be passed as the arg argument to children
visitor
- the visitor to acceptarg
- an argument passed to the visitor. This should be used by the visitor to carry on the visiting
context.PropertyException
boolean isSameAs(Property property) throws PropertyException
property
- PropertyException
PropertyException
Iterator<Property> getDirtyChildren()
PropertyObjectResolver getObjectResolver()
PropertyObjectResolver
to manage this property reference to external entities, null if this
property's type has no resolver.Copyright © 2015 Nuxeo SA. All rights reserved.