Class MemoryNodeBuilder
- java.lang.Object
-
- org.apache.jackrabbit.oak.plugins.memory.MemoryNodeBuilder
-
- All Implemented Interfaces:
NodeBuilder
- Direct Known Subclasses:
SegmentNodeBuilder
public class MemoryNodeBuilder extends Object implements NodeBuilder
In-memory node state builder.A
MemoryNodeBuilder
instance tracks uncommitted changes without relying on weak references or requiring hard references on the entire accessed subtree. It does this by relying onMutableNodeState
instances for tracking uncommitted changes and onHead
instances for tracking the connectedness of the builder. A builder keeps a reference to the parent builder and knows its own name, which is used to check for relevant changes in its parent builder and update its state accordingly.A builder is in one of three possible states, which is tracked within its
Head
instance:- unconnected
- A child builder with no content changes starts in this state. Before each access the unconnected builder checks its parent for relevant changes.
- connected
-
Once a builder is first modified, it switches to the connected state
and records all modification in a shared
MutableNodeState
instance. Before each access the connected builder checks whether its parents base state has been reset and if so, resets its own base state accordingly. - root
- Same as the connected state but only the root of the builder hierarchy can have this state.
-
-
Constructor Summary
Constructors Modifier Constructor Description MemoryNodeBuilder(@NotNull NodeState base)
Creates a new in-memory node state builder rooted at and based on the passedbase
state.protected
MemoryNodeBuilder(MemoryNodeBuilder parent, String name)
Creates a new in-memory child builder.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected void
annotateSourcePath()
Annotate this builder with its source path if this builder has not been transiently added.@NotNull NodeBuilder
child(@NotNull String name)
Returns a builder for constructing changes to the named child node.Blob
createBlob(InputStream stream)
protected MemoryNodeBuilder
createChildBuilder(String name)
Factory method for creating new child state builders.boolean
exists()
Checks whether this builder represents a node that exists.@NotNull NodeState
getBaseState()
Returns the original base state that this builder is modifying.boolean
getBoolean(@NotNull String name)
Returns the boolean value of the named property.@NotNull NodeBuilder
getChildNode(@NotNull String name)
Returns a builder for constructing changes to the named child node.long
getChildNodeCount(long max)
Returns the current number of child nodes.@NotNull Iterable<String>
getChildNodeNames()
Returns the names of current child nodes.protected String
getName()
Accessor for name@Nullable String
getName(@NotNull String name)
Returns the name value of the named property.@NotNull Iterable<String>
getNames(@NotNull String name)
Returns the name values of the named property.@NotNull NodeState
getNodeState()
Returns an immutable node state that matches the current state of the builder.protected MemoryNodeBuilder
getParent()
Accessor for parent builderString
getPath()
@NotNull Iterable<? extends PropertyState>
getProperties()
Returns the current properties.PropertyState
getProperty(String name)
Returns the current state of the named property, ornull
if the property is not set.long
getPropertyCount()
Returns the current number of properties.@Nullable String
getString(@NotNull String name)
Returns the name value of the named property.boolean
hasChildNode(@NotNull String name)
Checks whether the named child node currently exists.boolean
hasProperty(String name)
Checks whether the named property exists.boolean
isModified()
Check whether this builder represents a modified node, which has either modified properties or removed or added child nodes.boolean
isNew()
Check whether this builder represents a new node, which is not present in the base state.boolean
isNew(String name)
Check whether the named property is new, i.e.boolean
isReplaced()
Check whether this builder represents a node that used to exist but was then replaced with other content, for example as a result of aNodeBuilder.setChildNode(String)
call.boolean
isReplaced(String name)
Check whether the named property exists in the base state but is replaced with other content, for example as a result of aNodeBuilder.setProperty(PropertyState)
call.boolean
isRoot()
boolean
moveTo(@NotNull NodeBuilder newParent, @NotNull String newName)
This implementation has the same semantics as adding this node with namenewName
as a new child ofnewParent
followed by removing this node.boolean
remove()
Remove this child node from its parent.@NotNull NodeBuilder
removeProperty(String name)
Remove the named property.void
reset(@NotNull NodeState newBase)
Throws away all changes in this builder and resets the base to the given node state.protected void
set(NodeState newState)
Replaces the current state of this builder with the given node state.@NotNull NodeBuilder
setChildNode(@NotNull String name)
Adds the named child node and returns a builder for modifying it.@NotNull NodeBuilder
setChildNode(@NotNull String name, @NotNull NodeState state)
Adds or replaces a subtree.@NotNull NodeBuilder
setProperty(@NotNull PropertyState property)
Set a property state<T> @NotNull NodeBuilder
setProperty(String name, T value)
Set a property state<T> @NotNull NodeBuilder
setProperty(String name, T value, Type<T> type)
Set a property stateString
toString()
protected void
updated()
Called whenever this node is modified, i.e.
-
-
-
Constructor Detail
-
MemoryNodeBuilder
protected MemoryNodeBuilder(MemoryNodeBuilder parent, String name)
Creates a new in-memory child builder.- Parameters:
parent
- parent buildername
- name of this node
-
MemoryNodeBuilder
public MemoryNodeBuilder(@NotNull @NotNull NodeState base)
Creates a new in-memory node state builder rooted at and based on the passedbase
state.- Parameters:
base
- base state of the new builder
-
-
Method Detail
-
isRoot
public final boolean isRoot()
- Returns:
true
iff this is the root builder
-
createChildBuilder
protected MemoryNodeBuilder createChildBuilder(String name)
Factory method for creating new child state builders. Subclasses may override this method to control the behavior of child state builders.- Returns:
- new builder
-
updated
protected void updated()
Called whenever this node is modified, i.e. a property is added, changed or removed, or a child node is added or removed. Changes inside child nodes or the subtrees below are not reported. The default implementation triggers anupdated()
call on the root builder (unless this is already the root builder), which subclasses can use to capture aggregate update information across the whole tree.
-
getParent
protected final MemoryNodeBuilder getParent()
Accessor for parent builder
-
getName
protected final String getName()
Accessor for name
-
reset
public void reset(@NotNull @NotNull NodeState newBase)
Throws away all changes in this builder and resets the base to the given node state.- Parameters:
newBase
- new base state
-
set
protected void set(NodeState newState)
Replaces the current state of this builder with the given node state. The base state remains unchanged.- Parameters:
newState
- new state
-
getNodeState
@NotNull public @NotNull NodeState getNodeState()
Description copied from interface:NodeBuilder
Returns an immutable node state that matches the current state of the builder.- Specified by:
getNodeState
in interfaceNodeBuilder
- Returns:
- immutable node state
-
getBaseState
@NotNull public @NotNull NodeState getBaseState()
Description copied from interface:NodeBuilder
Returns the original base state that this builder is modifying. The return value may be non-existent (i.e. itsexists
method returnsfalse
) if this builder represents a new node that didn't exist in the base content tree.- Specified by:
getBaseState
in interfaceNodeBuilder
- Returns:
- base node state, possibly non-existent
-
exists
public boolean exists()
Description copied from interface:NodeBuilder
Checks whether this builder represents a node that exists.- Specified by:
exists
in interfaceNodeBuilder
- Returns:
true
if the node exists,false
otherwise
-
isNew
public boolean isNew()
Description copied from interface:NodeBuilder
Check whether this builder represents a new node, which is not present in the base state.- Specified by:
isNew
in interfaceNodeBuilder
- Returns:
true
for a new node
-
isNew
public boolean isNew(String name)
Description copied from interface:NodeBuilder
Check whether the named property is new, i.e. not present in the base state.- Specified by:
isNew
in interfaceNodeBuilder
- Parameters:
name
- property name- Returns:
true
for a new property
-
isModified
public boolean isModified()
Description copied from interface:NodeBuilder
Check whether this builder represents a modified node, which has either modified properties or removed or added child nodes.- Specified by:
isModified
in interfaceNodeBuilder
- Returns:
true
for a modified node
-
isReplaced
public boolean isReplaced()
Description copied from interface:NodeBuilder
Check whether this builder represents a node that used to exist but was then replaced with other content, for example as a result of aNodeBuilder.setChildNode(String)
call.- Specified by:
isReplaced
in interfaceNodeBuilder
- Returns:
true
for a replaced node
-
isReplaced
public boolean isReplaced(String name)
Description copied from interface:NodeBuilder
Check whether the named property exists in the base state but is replaced with other content, for example as a result of aNodeBuilder.setProperty(PropertyState)
call.- Specified by:
isReplaced
in interfaceNodeBuilder
- Parameters:
name
- property name- Returns:
true
for a replaced property
-
getChildNodeCount
public long getChildNodeCount(long max)
Description copied from interface:NodeBuilder
Returns the current number of child nodes.If an implementation does know the exact value, it returns it (even if the value is higher than max). If the implementation does not know the exact value, and the child node count is higher than max, it may return Long.MAX_VALUE. The cost of the operation is at most O(max).
- Specified by:
getChildNodeCount
in interfaceNodeBuilder
- Parameters:
max
- the maximum value- Returns:
- number of child nodes
-
getChildNodeNames
@NotNull public @NotNull Iterable<String> getChildNodeNames()
Description copied from interface:NodeBuilder
Returns the names of current child nodes.- Specified by:
getChildNodeNames
in interfaceNodeBuilder
- Returns:
- child node names
-
hasChildNode
public boolean hasChildNode(@NotNull @NotNull String name)
Description copied from interface:NodeBuilder
Checks whether the named child node currently exists.- Specified by:
hasChildNode
in interfaceNodeBuilder
- Parameters:
name
- child node name- Returns:
true
if the named child node exists,false
otherwise
-
child
@NotNull public @NotNull NodeBuilder child(@NotNull @NotNull String name)
Description copied from interface:NodeBuilder
Returns a builder for constructing changes to the named child node. If the named child node does not already exist, a new empty child node is automatically created as the base state of the returned child builder. Otherwise the existing child node state is used as the base state of the returned builder.All updates to the returned child builder will implicitly affect also this builder, as if a
setNode(name, childBuilder.getNodeState())
method call had been made after each update. Repeated calls to this method with the same name will return the same child builder instance until an explicitNodeBuilder.setChildNode(String, NodeState)
orNodeBuilder.remove()
call is made, at which point the link between this builder and a previously returned child builder for that child node name will get broken.- Specified by:
child
in interfaceNodeBuilder
- Parameters:
name
- name of the child node- Returns:
- child builder
-
getChildNode
@NotNull public @NotNull NodeBuilder getChildNode(@NotNull @NotNull String name)
Description copied from interface:NodeBuilder
Returns a builder for constructing changes to the named child node. If the named child node does not already exist, the returned builder will refer to a non-existent node and trying to modify it will causeIllegalStateException
s to be thrown.- Specified by:
getChildNode
in interfaceNodeBuilder
- Parameters:
name
- name of the child node- Returns:
- child builder, possibly non-existent
-
setChildNode
@NotNull public @NotNull NodeBuilder setChildNode(@NotNull @NotNull String name)
Description copied from interface:NodeBuilder
Adds the named child node and returns a builder for modifying it. Possible previous content in the named subtree is removed.- Specified by:
setChildNode
in interfaceNodeBuilder
- Parameters:
name
- name of the child node- Returns:
- child builder
-
setChildNode
@NotNull public @NotNull NodeBuilder setChildNode(@NotNull @NotNull String name, @NotNull @NotNull NodeState state)
Description copied from interface:NodeBuilder
Adds or replaces a subtree.- Specified by:
setChildNode
in interfaceNodeBuilder
- Parameters:
name
- name of the child node containing the new subtreestate
- subtree- Returns:
- child builder
-
remove
public boolean remove()
Description copied from interface:NodeBuilder
Remove this child node from its parent.- Specified by:
remove
in interfaceNodeBuilder
- Returns:
true
for existing nodes,false
otherwise
-
moveTo
public boolean moveTo(@NotNull @NotNull NodeBuilder newParent, @NotNull @NotNull String newName) throws IllegalArgumentException
This implementation has the same semantics as adding this node with namenewName
as a new child ofnewParent
followed by removing this node. As a consequence this implementation allows moving this node into the subtree rooted here, the result of which is the same as removing this node.See also
the general contract
forMoveTo
.- Specified by:
moveTo
in interfaceNodeBuilder
- Parameters:
newParent
- builder for the new parent.newName
- name of this child at the new parent- Returns:
true
on success,false
otherwise- Throws:
IllegalArgumentException
- if the given name string is empty or contains the forward slash character
-
annotateSourcePath
protected final void annotateSourcePath()
Annotate this builder with its source path if this builder has not been transiently added. The source path is written to a property with the nameMoveDetector.SOURCE_PATH
.The source path of a builder is its current path if its current source path annotation is empty and none of its parents has a source path annotation set. Otherwise it is the source path of the first parent (or self) that has its source path annotation set appended with the relative path from that parent to this builder.
This builder has been transiently added when there exists no base node at its source path.
-
getPropertyCount
public long getPropertyCount()
Description copied from interface:NodeBuilder
Returns the current number of properties.- Specified by:
getPropertyCount
in interfaceNodeBuilder
- Returns:
- number of properties
-
getProperties
@NotNull public @NotNull Iterable<? extends PropertyState> getProperties()
Description copied from interface:NodeBuilder
Returns the current properties.- Specified by:
getProperties
in interfaceNodeBuilder
- Returns:
- current properties
-
hasProperty
public boolean hasProperty(String name)
Description copied from interface:NodeBuilder
Checks whether the named property exists. The implementation is equivalent togetProperty(name) != null
, but may be optimized to avoid having to load the property value.- Specified by:
hasProperty
in interfaceNodeBuilder
- Parameters:
name
- property name- Returns:
true
if the named property exists,false
otherwise
-
getProperty
public PropertyState getProperty(String name)
Description copied from interface:NodeBuilder
Returns the current state of the named property, ornull
if the property is not set.- Specified by:
getProperty
in interfaceNodeBuilder
- Parameters:
name
- property name- Returns:
- property state
-
getBoolean
public boolean getBoolean(@NotNull @NotNull String name)
Description copied from interface:NodeBuilder
Returns the boolean value of the named property. The implementation is equivalent to the following code, but may be optimized.PropertyState property = builder.getProperty(name); return property != null && property.getType() == Type.BOOLEAN && property.getValue(Type.BOOLEAN);
- Specified by:
getBoolean
in interfaceNodeBuilder
- Parameters:
name
- property name- Returns:
- boolean value of the named property, or
false
-
getString
@Nullable public @Nullable String getString(@NotNull @NotNull String name)
Description copied from interface:NodeBuilder
Returns the name value of the named property. The implementation is equivalent to the following code, but may be optimized.PropertyState property = builder.getProperty(name); if (property != null && property.getType() == Type.STRING) { return property.getValue(Type.STRING); } else { return null; }
- Specified by:
getString
in interfaceNodeBuilder
- Parameters:
name
- property name- Returns:
- string value of the named property, or
null
-
getName
@Nullable public @Nullable String getName(@NotNull @NotNull String name)
Description copied from interface:NodeBuilder
Returns the name value of the named property. The implementation is equivalent to the following code, but may be optimized.PropertyState property = builder.getProperty(name); if (property != null && property.getType() == Type.NAME) { return property.getValue(Type.NAME); } else { return null; }
- Specified by:
getName
in interfaceNodeBuilder
- Parameters:
name
- property name- Returns:
- name value of the named property, or
null
-
getNames
@NotNull public @NotNull Iterable<String> getNames(@NotNull @NotNull String name)
Description copied from interface:NodeBuilder
Returns the name values of the named property. The implementation is equivalent to the following code, but may be optimized.PropertyState property = builder.getProperty(name); if (property != null && property.getType() == Type.NAMES) { return property.getValue(Type.NAMES); } else { return Collections.emptyList(); }
- Specified by:
getNames
in interfaceNodeBuilder
- Parameters:
name
- property name- Returns:
- name values of the named property, or an empty collection
-
setProperty
@NotNull public @NotNull NodeBuilder setProperty(@NotNull @NotNull PropertyState property)
Description copied from interface:NodeBuilder
Set a property state- Specified by:
setProperty
in interfaceNodeBuilder
- Parameters:
property
- The property state to set- Returns:
- this builder
-
setProperty
@NotNull public <T> @NotNull NodeBuilder setProperty(String name, @NotNull T value)
Description copied from interface:NodeBuilder
Set a property state- Specified by:
setProperty
in interfaceNodeBuilder
- Type Parameters:
T
- The type of this property. Must be one ofString, Blob, byte[], Long, Integer, Double, Boolean, BigDecimal
- Parameters:
name
- The name of this propertyvalue
- The value of this property- Returns:
- this builder
-
setProperty
@NotNull public <T> @NotNull NodeBuilder setProperty(String name, @NotNull T value, Type<T> type)
Description copied from interface:NodeBuilder
Set a property state- Specified by:
setProperty
in interfaceNodeBuilder
- Type Parameters:
T
- The type of this property.- Parameters:
name
- The name of this propertyvalue
- The value of this property- Returns:
- this builder
-
removeProperty
@NotNull public @NotNull NodeBuilder removeProperty(String name)
Description copied from interface:NodeBuilder
Remove the named property. This method has no effect if a property of the givenname
does not exist.- Specified by:
removeProperty
in interfaceNodeBuilder
- Parameters:
name
- name of the property
-
createBlob
public Blob createBlob(InputStream stream) throws IOException
- Specified by:
createBlob
in interfaceNodeBuilder
- Throws:
IOException
-
getPath
public final String getPath()
- Returns:
- path of this builder.
-
-