Interface Property

All Superinterfaces:
Cloneable, Iterable<Property>, Serializable
All Known Subinterfaces:
DocumentPart
All Known Implementing Classes:
AbstractProperty, ArrayProperty, BinaryProperty, BlobProperty, BlobProperty.ScalarMemberProperty, BooleanProperty, ComplexProperty, DateProperty, DocumentPartImpl, DoubleProperty, ExternalBlobProperty, ListProperty, LongProperty, MapProperty, RemovedProperty, ScalarProperty, StringProperty

public interface Property extends Cloneable, Serializable, Iterable<Property>
Document properties are instances of document schema fields.

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:

  • Dirty Flags - that reflect the public status of the document
  • Internal Flags - that reflect some internal state

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.

  • Root Property (or 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.
  • Complex Properties - container properties that are bound to complex field types that can be represented as java 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.
    • Structured Properties - this is a special case of complex properties. The difference is that structured property values are expressed as scalar java objects instead of java maps. By scalar java objects we mean any well structured object which is not a container like a 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.
  • List Properties - container properties that are bound to list field types.
  • Scalar Properties - atomic properties that are bound to scalar field types and that are using as values scalar or primitive java objects like arrays, primitives, String, Date etc.

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:

  • NONE + MODIFIED => MODFIED
  • NONE + REMOVED => REMOVED
  • NONE + MOVED => MOVED
  • PHANTOM + MODIFIED => MODIFIED
  • NEW + MODIFIED => NEW | MODIFIED
  • NEW + MOVED => NEW | MOVED
  • MODIFIED + REMOVED => REMOVED
  • MODIFIED + MOVED => MODIFIED | MOVED
  • MODIFIED + MODIFIED => MODIFIED

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

Author:
Bogdan Stefanescu
See Also:
  • "<code>TestPropertyModel</code> for usage of property API"
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    A mask for public flags.
    static final int
    A mask for the first 4 flags: NEW, REMOVED, MODIFIED, MOVED.
    static final int
    Flag used to mark a property as dirty.
    static final int
    Flag used to mark a property as dirty.
    static final int
    Flag used to mark a property as new.
    static final int
    Flag used to mark a property as phantom.
    static final int
    Flag used to mark a property as dirty.
    static final int
    No dirty flags set.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    accept(PropertyVisitor visitor, Object arg)
    Method that implement the visitor pattern.
    Creates an empty child property and adds it as a property to the list container.
    addValue(int index, Object value)
    Inserts at the given position a new value to the list.
    Appends a new value to the list.
    void
    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.
    get(int index)
    Get the child property given it's index.
    get(String name)
    Gets the child property having the given name.
    Get a collection over the children properties.
    Gets an iterator over the dirty children properties.
    int
    Get the dirty flags that are set on this property.
    Gets the field corresponding to this property.
    Gets the property name.
     
    Gets the property parent.
    Gets the root property.
    Gets the document schema defining the property tree from which the property belongs.
    Get the type of the field corresponding to this property.
    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.
    Gets the value of the property resolved using the given path.
    Gets the property normalized value for write.
    Gets the xpath of this property.
    boolean
    Whether or not this property has a default value.
    void
    Initializes the property with the given normalized value.
    boolean
    Tests whether this property is of a map (complex) type.
    boolean
    Whether this property is a container - this means the property value is a map or a list.
    boolean
    Tests whether a property is dirty.
    boolean
    only for SimpleDocumentModel
    boolean
    Tests whether this property is of a list type.
    boolean
    Tests if a property value was modified.
    boolean
    Tests if a property value was moved to another index in the parent list if any.
    boolean
    Tests if this property is new (just created but not yet stored).
    boolean
    Checks if the given value is a normalized one.
    boolean
    Tests if the property is a phantom.
    boolean
    Whether the property is read only.
    boolean
    Tests if a property is flagged as removed.
    boolean
    isSameAs(Property property)
    Compare the two properties by content.
    boolean
    Tests whether this property is of a scalar type.
    boolean
    Returns true if this property is flagged as secured in system.
    void
    moveTo(int index)
    Moves a property position into the parent container list.
    Creates a new and empty instance of a normalized value.
    Normalizes the given value as dictated by the property type.
    Removes this property from the tree.
    Same as resolvePath(Path) but with a string path as argument.
    Resolves the given path relative to the current property and return the property if any is found otherwise throws an exception.
    void
    set(String name, Property property)
    Sets the child property having the given name.
    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
    Sets this property value.
    void
    setValue(String path, Object value)
    Sets the value of the property resolved using the given path.
    int
    Get the count of the children properties.
    boolean
    Validates the given value type.

    Methods inherited from interface java.lang.Iterable

    forEach, iterator, spliterator
  • Field Details

    • NONE

      static final int NONE
      No dirty flags set.
      See Also:
    • IS_NEW

      static final int IS_NEW
      Flag used to mark a property as new. Property was added to a list.
      See Also:
    • IS_MODIFIED

      static final int IS_MODIFIED
      Flag used to mark a property as dirty. Property value was modified.
      See Also:
    • IS_REMOVED

      static final int IS_REMOVED
      Flag used to mark a property as dirty. Property was removed.
      See Also:
    • IS_MOVED

      static final int IS_MOVED
      Flag used to mark a property as dirty. Property was moved to another index.
      See Also:
    • IS_PHANTOM

      static final int IS_PHANTOM
      Flag used to mark a property as phantom.
      See Also:
    • IS_DIRTY

      static final int IS_DIRTY
      A mask for the first 4 flags: NEW, REMOVED, MODIFIED, MOVED.
      See Also:
    • DIRTY_MASK

      static final int DIRTY_MASK
      A mask for public flags.
      See Also:
  • Method Details

    • isNew

      boolean isNew()
      Tests if this property is new (just created but not yet stored).

      A property is new when added to a collection. This is the typical state for a new property added to a list

      Returns:
      true if this property is new, false otherwise
    • isRemoved

      boolean isRemoved()
      Tests if a property is flagged as removed. Removed properties are child property that were removed from their container.
      Returns:
      if the property was removed, false otherwise
    • isModified

      boolean isModified()
      Tests if a property value was modified.
      Returns:
      if the property was removed, false otherwise
    • isMoved

      boolean isMoved()
      Tests if a property value was moved to another index in the parent list if any.
      Returns:
      if the property was removed, false otherwise
    • isPhantom

      boolean isPhantom()
      Tests if the property is a phantom. This means it doesn't exists yet in the storage and it is not a new property. This is a placeholder for a property that is defined by the schema but was not yet set.
      Returns:
      true if a phantom false otherwise
    • isDirty

      boolean isDirty()
      Tests whether a property is dirty.

      This tests whether or not a dirty flag is set on the property.

      Returns:
      true if the property changed or is new
    • isForceDirty

      boolean isForceDirty()
      only for SimpleDocumentModel
    • setForceDirty

      void setForceDirty(boolean forceDirty)
      only for SimpleDocumentModel
    • getDirtyFlags

      int getDirtyFlags()
      Get the dirty flags that are set on this property.
      Returns:
      the dirty flags mask
    • clearDirtyFlags

      void clearDirtyFlags()
      Notify the property that its changes was stored so it can safely remove dirty flags.

      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.

    • isReadOnly

      boolean isReadOnly()
      Whether the property is read only.
      Returns:
      true if read only false otherwise
    • setReadOnly

      void setReadOnly(boolean value)
      Sets the read only flag.
      Parameters:
      value - true to set this property read only false otherwise
    • isSecured

      boolean isSecured()
      Returns true if this property is flagged as secured in system.
      Since:
      11.1
    • isComplex

      boolean isComplex()
      Tests whether this property is of a map (complex) type.
      Returns:
      true if the property is of map type, false otherwise
    • isList

      boolean isList()
      Tests whether this property is of a list type.
      Returns:
      true if the property is of list type, false otherwise
    • isScalar

      boolean isScalar()
      Tests whether this property is of a scalar type.
      Returns:
      true if the property is of a scalar type, false otherwise
    • isContainer

      boolean isContainer()
      Whether this property is a container - this means the property value is a map or a list.

      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.

      Returns:
      true if scalar false otherwise
    • hasDefaultValue

      boolean hasDefaultValue()
      Whether or not this property has a default value. For complex property, this method will lookup in its children.
      Returns:
      true if property has a default value
      Since:
      11.1
    • getName

      String getName()
      Gets the property name.
      Returns:
      the property name
    • getXPath

      String getXPath()
      Gets the xpath of this property.

      The xpath is of the form pref:foo/mylist/123/elem, of note:

      • there is no initial /
      • the schema prefix is only present if a prefix is configured for the base property's schema
      • list elements indexes start at 0
      • list elements aren't using the old syntax foo/bar[123]/baz but the new syntax foo/123/baz
      Returns:
      the xpath
      Since:
      9.1
    • getType

      Type getType()
      Get the type of the field corresponding to this property.
      Returns:
      the property type
    • getField

      Field getField()
      Gets the field corresponding to this property.

      The field is the object defining the property. You can see the field as a java class and the property as a class instance

    • getParent

      Property getParent()
      Gets the property parent.
      Returns:
      the property parent for sub properties or null for top level properties
    • getSchema

      Schema getSchema()
      Gets the document schema defining the property tree from which the property belongs.
      Returns:
      the document schema owning the field corresponding to the property
    • getRoot

      DocumentPart getRoot()
      Gets the root property.
      Returns:
      the root property
    • init

      void init(Serializable value) throws PropertyException
      Initializes the property with the given normalized value.

      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.

      Parameters:
      value - the normalized value to set
      Throws:
      PropertyException
    • setValue

      void setValue(Object value) throws PropertyException
      Sets this property value. The value will be first normalized and then set.

      For complex or list properties the value will be set recursively (as a map or list value).

      Parameters:
      value - the value to set
      Throws:
      InvalidPropertyValueException - if the given value type is not compatible with the expected value type
      PropertyException
    • getValue

      Serializable getValue() throws PropertyException
      Gets the property normalized value.

      Normalized values are of the java type that correspond to the field type.

      Returns:
      the property value, which may be null
      Throws:
      PropertyException
    • getValueForWrite

      Serializable getValueForWrite() throws PropertyException
      Gets the property normalized value for write.

      Can be different fropm getValue() in cases where the property adapts the value it is given to store.

      Returns:
      the property value to use for write, which may be null
      Throws:
      PropertyException
      Since:
      5.2.1
    • getValue

      <T> T getValue(Class<T> type) throws PropertyException
      Gets the property value as the given type.

      The value is converted using the registered converter to the given type.

      If conversion is not supported a runtime exception will be triggered.

      Returns:
      the property value, which may be null
      Throws:
      PropertyException
    • remove

      Removes this property from the tree.

      This method marks the property as dirty and sets its value to null.

      Returns:
      the old property value
      Throws:
      PropertyException
    • get

      Gets the child property having the given name.

      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.

      Parameters:
      name - the child property name (the full name including the prefix if any)
      Returns:
      the child property if any null if no child property with that name is found or if the property is a scalar
      Throws:
      UnsupportedOperationException - if the property is a scalar property (doesn't have children)
      PropertyNotFoundException - if the child property is not found in the type definition
    • get

      Property get(int index) throws PropertyNotFoundException
      Get the child property given it's index. This operation is mandatory for List properties.

      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.

      Returns:
      the child property if any null if no child property with that name is found or if the property is a scalar
      Throws:
      UnsupportedOperationException - if the property is a scalar property (doesn't have children)
      PropertyNotFoundException - if the child property is not found in the type definition
    • set

      void set(String name, Property property) throws PropertyException
      Sets the child property having the given name.

      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.

      Parameters:
      name - the child property name (the full name including the prefix if any)
      property - the child property to set
      Throws:
      UnsupportedOperationException - if the current property is a scalar property (doesn't have children)
      PropertyNotFoundException - if the child property is not found in the type definition
      PropertyException
      Since:
      11.1
    • setValue

      void setValue(int index, Object value) throws PropertyException
      Sets a child property value given its index. This method is required only for List properties.

      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.

      Parameters:
      value - the new value
      Throws:
      UnsupportedOperationException - if the property is a scalar property (doesn't have children)
      PropertyNotFoundException - if the child property is not found in the type definition
      PropertyException
    • getChildren

      Collection<Property> getChildren()
      Get a collection over the children properties. This includes all children including phantom ones (those who are not yet set by the user).

      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.

      Returns:
      the children properties
    • size

      int size()
      Get the count of the children properties. This includes phantom properties. So the returned size will be equal to the one returned by the property ComplexType.getFieldsCount().
      Returns:
      the children properties count
    • addValue

      Property addValue(Object value) throws PropertyException
      Appends a new value to the list. A new property will be created to store the given value and appended to the children list.

      The created property will be marked as isNew().

      Returns:
      the added property
      Throws:
      PropertyException
    • addValue

      Property addValue(int index, Object value) throws PropertyException
      Inserts at the given position a new value to the list. A new property will be created to store the given value and appended to the children list.

      The created property will be marked as isNew().

      Parameters:
      index - the position to insert the value
      Returns:
      the added property
      Throws:
      PropertyException
    • addEmpty

      Property addEmpty() throws PropertyException
      Creates an empty child property and adds it as a property to the list container.

      This method is useful to construct lists.

      Returns:
      the created property
      Throws:
      PropertyException
    • moveTo

      void moveTo(int index)
      Moves a property position into the parent container list.

      This method applies only for list item properties. The given index includes removed properties.

      Parameters:
      index - the position in the parent container to move this property
      Throws:
      UnsupportedOperationException - if the operation is not supported by the target property
    • resolvePath

      Property resolvePath(String path) throws PropertyNotFoundException
      Same as resolvePath(Path) but with a string path as argument. This is the same as calling resolvePath(new Path(path)).
      Parameters:
      path - the string path to resolve.
      Returns:
      the resolved property
      Throws:
      PropertyNotFoundException - if the path cannot be resolved
    • resolvePath

      Property resolvePath(Path path) throws PropertyNotFoundException
      Resolves the given path relative to the current property and return the property if any is found otherwise throws an exception.

      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
      Parameters:
      path - the path to resolve.
      Returns:
      the resolved property
      Throws:
      PropertyNotFoundException - if the path cannot be resolved
    • getValue

      Serializable getValue(String path) throws PropertyException
      Gets the value of the property resolved using the given path.

      This method is a shortcut for: resolvePath(path).getValue().

      Parameters:
      path - the path to the property
      Returns:
      the property value
      Throws:
      PropertyException
    • getValue

      <T> T getValue(Class<T> type, String path) throws PropertyException
      Gets the value of the property resolved using the given path.

      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).

      Type Parameters:
      T - The type of the value to return
      Parameters:
      type - the class of the value
      path - the java path of the property value
      Returns:
      the value
      Throws:
      PropertyException
    • setValue

      void setValue(String path, Object value) throws PropertyException
      Sets the value of the property resolved using the given path.

      This method is a shortcut for: resolvePath(path).setValue(value).

      Parameters:
      path - the property path
      value - the value
      Throws:
      PropertyException
    • normalize

      Normalizes the given value as dictated by the property type.

      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.

      Parameters:
      value - the value to normalize according to the property type
      Returns:
      the normalized value
      Throws:
      PropertyConversionException
    • isNormalized

      boolean isNormalized(Object value)
      Checks if the given value is a normalized one. This means the value has a type that is normalized.

      Null values are considered as normalized.

      Parameters:
      value - the value to check
      Returns:
      true if the value is normalized false otherwise
    • convertTo

      <T> T convertTo(Serializable value, Class<T> toType) throws PropertyConversionException
      Converts the given normalized value to the given type.

      If the value has already the given type it will be returned back.

      Parameters:
      value - the normalized value to convert
      toType - the conversion type
      Returns:
      the converted value, which may be null
      Throws:
      PropertyConversionException - if the conversion cannot be made because of type incompatibilities
    • validateType

      boolean validateType(Class<?> type)
      Validates the given value 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.

      Parameters:
      type - the type to validate
      Returns:
      true if the type is valid, false otherwise
    • newInstance

      Object newInstance()
      Creates a new and empty instance of a normalized value.

      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 ""

      Returns:
      the empty instance the empty instance, or null for some implementations
    • accept

      void accept(PropertyVisitor visitor, Object arg) throws PropertyException
      Method that implement the visitor pattern.

      The visitor must return null to stop visiting children otherwise a context object that will be passed as the arg argument to children

      Parameters:
      visitor - the visitor to accept
      arg - an argument passed to the visitor. This should be used by the visitor to carry on the visiting context.
      Throws:
      PropertyException
    • isSameAs

      boolean isSameAs(Property property) throws PropertyException
      Compare the two properties by content.
      Returns:
      true If the properties have a similar content, otherwise false
      Throws:
      PropertyException
    • getDirtyChildren

      Iterator<Property> getDirtyChildren()
      Gets an iterator over the dirty children properties.
      Returns:
      the iterator
    • getObjectResolver

      PropertyObjectResolver getObjectResolver()
      Returns:
      A PropertyObjectResolver to manage this property reference to external entities, null if this property's type has no resolver.
      Since:
      7.1