This includes the following information:
NodeState
represents the state of a Node
.
NodeState
represents the state of a Node
.
Depending on context, a NodeState instance can be interpreted as representing the state of just that node, of the subtree starting at that node, or of an entire tree in case it's a root node.
The crucial difference between this interface and the similarly named class in Jackrabbit 2.x is that this interface represents a specific, immutable state of a node, whereas the Jackrabbit 2.x class represented the current state of a node.
As mentioned above, all node and property states are always immutable. Thus repeating a method call is always guaranteed to produce the same result as before unless some internal error occurs (see below). This immutability only applies to a specific state instance. Different states of a node can obviously be different, and in some cases even different instances of the same state may behave slightly differently. For example due to performance optimization or other similar changes the iteration order of properties or child nodes may be different for two instances of the same state.
In addition to being immutable, a specific state instance guaranteed to be fully thread-safe. Possible caching or other internal changes need to be properly synchronized so that any number of concurrent clients can safely access a state instance.
A node state can be (and often is) backed by local files or network resources. All IO operations or related concerns like caching should be handled transparently below this interface. Potential IO problems and recovery attempts like retrying a timed-out network access need to be handled below this interface, and only hard errors should be thrown up as {@link RuntimeException unchecked exceptions} that higher level codeis not expected to be able to recover from.
Since this interface exposes no higher level constructs like access controls, locking, node types or even path parsing, there's no way for content access to fail because of such concerns. Such functionality and related checked exceptions or other control flow constructs should be implemented on a higher level above this interface.
Not all content exposed by this interface needs to be backed by actual persisted data. An implementation may want to provide derived data, like for example the aggregate size of the entire subtree as an extra virtual property. A virtualization, sharding or caching layer could provide a composite view over multiple underlying content trees. Or a basic access control layer could decide to hide certain content based on specific rules. All such features need to be implemented according to the API contract of this interface. A separate higher level interface needs to be used if an implementation can't for example guarantee immutability of exposed content as discussed above.
Two node states are considered equal if and only if their properties and child nodes match, regardless of ordering. The {@link Object#equals(Object)} method needs to be implemented so that itcomplies with this definition. And while node states are not meant for use as hash keys, the {@link Object#hashCode()} method should still beimplemented according to this equality contract.
Depending on context, a NodeState instance can be interpreted as representing the state of just that node, of the subtree starting at that node, or of an entire tree in case it's a root node.
The crucial difference between this interface and the similarly named class in Jackrabbit 2.x is that this interface represents a specific, immutable state of a node, whereas the Jackrabbit 2.x class represented the current state of a node.
As mentioned above, all node and property states are always immutable. Thus repeating a method call is always guaranteed to produce the same result as before unless some internal error occurs (see below). This immutability only applies to a specific state instance. Different states of a node can obviously be different, and in some cases even different instances of the same state may behave slightly differently. For example due to performance optimization or other similar changes the iteration order of properties or child nodes may be different for two instances of the same state.
In addition to being immutable, a specific state instance guaranteed to be fully thread-safe. Possible caching or other internal changes need to be properly synchronized so that any number of concurrent clients can safely access a state instance.
A node state can be (and often is) backed by local files or network resources. All IO operations or related concerns like caching should be handled transparently below this interface. Potential IO problems and recovery attempts like retrying a timed-out network access need to be handled below this interface, and only hard errors should be thrown up as {@link RuntimeException unchecked exceptions} that higher level codeis not expected to be able to recover from.
Since this interface exposes no higher level constructs like access controls, locking, node types or even path parsing, there's no way for content access to fail because of such concerns. Such functionality and related checked exceptions or other control flow constructs should be implemented on a higher level above this interface.
Not all content exposed by this interface needs to be backed by actual persisted data. An implementation may want to provide derived data, like for example the aggregate size of the entire subtree as an extra virtual property. A virtualization, sharding or caching layer could provide a composite view over multiple underlying content trees. Or a basic access control layer could decide to hide certain content based on specific rules. All such features need to be implemented according to the API contract of this interface. A separate higher level interface needs to be used if an implementation can't for example guarantee immutability of exposed content as discussed above.
Two node states are considered equal if and only if their properties and child nodes match, regardless of ordering. The {@link Object#equals(Object)} method needs to be implemented so that itcomplies with this definition. And while node states are not meant for use as hash keys, the {@link Object#hashCode()} method should still beimplemented according to this equality contract.
Depending on context, a NodeState instance can be interpreted as representing the state of just that node, of the subtree starting at that node, or of an entire tree in case it's a root node.
The crucial difference between this interface and the similarly named class in Jackrabbit 2.x is that this interface represents a specific, immutable state of a node, whereas the Jackrabbit 2.x class represented the current state of a node.
As mentioned above, all node and property states are always immutable. Thus repeating a method call is always guaranteed to produce the same result as before unless some internal error occurs (see below). This immutability only applies to a specific state instance. Different states of a node can obviously be different, and in some cases even different instances of the same state may behave slightly differently. For example due to performance optimization or other similar changes the iteration order of properties or child nodes may be different for two instances of the same state.
In addition to being immutable, a specific state instance guaranteed to be fully thread-safe. Possible caching or other internal changes need to be properly synchronized so that any number of concurrent clients can safely access a state instance.
A node state can be (and often is) backed by local files or network resources. All IO operations or related concerns like caching should be handled transparently below this interface. Potential IO problems and recovery attempts like retrying a timed-out network access need to be handled below this interface, and only hard errors should be thrown up as {@link RuntimeException unchecked exceptions} that higher level codeis not expected to be able to recover from.
Since this interface exposes no higher level constructs like locking, node types or even path parsing, there's no way for content access to fail because of such concerns. Such functionality and related checked exceptions or other control flow constructs should be implemented on a higher level above this interface. On the other hand read access controls can be implemented below this interface, in which case some content that would otherwise be accessible might not show up through such an implementation.
The {@link #getChildNode(String)} method is special in that itnever returns a {@code null} value, even if the named childnode does not exist. Instead a client should use the {@link #exists()}method on the returned child state to check whether that node exists. The purpose of this separation of concerns is to allow an implementation to lazily load content only when it's actually read instead of just traversed. It also simplifies client code by avoiding the need for many {@code null} checks when traversing paths.
The iterability of a node is a related concept to the above-mentioned existence. A node state is iterable if it is included in the return values of the {@link #getChildNodeCount(long)}, {@link #getChildNodeNames()} and {@link #getChildNodeEntries()} methods.An iterable node is guaranteed to exist, though not all existing nodes are necessarily iterable.
Furthermore, a non-existing node is guaranteed to contain no properties or iterable child nodes. It can, however contain non-iterable children. Such scenarios are typically the result of access control restrictions.
Not all content exposed by this interface needs to be backed by actual persisted data. An implementation may want to provide derived data, like for example the aggregate size of the entire subtree as an extra virtual property. A virtualization, sharding or caching layer could provide a composite view over multiple underlying trees. Or a an access control layer could decide to hide certain content based on specific rules. All such features need to be implemented according to the API contract of this interface. A separate higher level interface needs to be used if an implementation can't for example guarantee immutability of exposed content as discussed above.
Two node states are considered equal if and only if their existence, properties and iterable child nodes match, regardless of ordering. The {@link Object#equals(Object)} method needs to be implemented so that itcomplies with this definition. And while node states are not meant for use as hash keys, the {@link Object#hashCode()} method should still beimplemented according to this equality contract.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|