public class NodeStoreKernel extends Object implements MicroKernel
NodeStore
-based MicroKernel
implementation.CONFLICT
Constructor and Description |
---|
NodeStoreKernel(NodeStore store) |
Modifier and Type | Method and Description |
---|---|
String |
branch(String trunkRevisionId)
Creates a private branch revision off the specified public
trunk revision.
|
String |
checkpoint(long lifetime)
Creates a new checkpoint of the latest head revision.
|
String |
commit(String path,
String jsonDiff,
String revisionId,
String message)
Applies the specified changes on the specified target node.
|
String |
diff(String fromRevisionId,
String toRevisionId,
String path,
int depth)
Returns the JSON diff representation of the changes between the specified
revisions.
|
long |
getChildNodeCount(String path,
String revisionId)
Returns the number of child nodes of the specified node.
|
String |
getHeadRevision()
Return the id of the current head revision, i.e.
|
String |
getJournal(String fromRevisionId,
String toRevisionId,
String path)
Returns a revision journal, starting with
fromRevisionId
and ending with toRevisionId in chronological order. |
long |
getLength(String blobId)
Returns the length of the specified blob.
|
String |
getNodes(String path,
String revisionId,
int depth,
long offset,
int maxChildNodes,
String filter)
Returns the node tree rooted at the specified parent node with the
specified depth, maximum child node maxChildNodes and offset.
|
String |
getRevisionHistory(long since,
int maxEntries,
String path)
Returns a list of all currently available (historical) head revisions in
chronological order since a specific point in time.
|
String |
merge(String branchRevisionId,
String message)
Merges the specified private branch revision with the current
head revision.
|
boolean |
nodeExists(String path,
String revisionId)
Determines whether the specified node exists.
|
int |
read(String blobId,
long pos,
byte[] buff,
int off,
int length)
Reads up to
length bytes of data from the specified blob into
the given array of bytes where the actual number of bytes read is
min(length, max(0, blobLength - pos)) . |
String |
rebase(String branchRevisionId,
String newBaseRevisionId)
Rebases the specified private branch revision on top of specified new base
revision.
|
String |
reset(String branchRevisionId,
String ancestorRevisionId)
Resets the branch identified by
branchRevisionId to an ancestor
branch commit identified by ancestorRevisionId . |
String |
waitForCommit(String oldHeadRevisionId,
long timeout)
Waits for a commit to occur that is more recent than
oldHeadRevisionId . |
String |
write(InputStream in)
Stores the content of the given stream and returns an associated
identifier for later retrieval.
|
public NodeStoreKernel(NodeStore store)
public String getHeadRevision()
MicroKernel
getHeadRevision
in interface MicroKernel
public String checkpoint(long lifetime)
MicroKernel
checkpoint
in interface MicroKernel
lifetime
- time (in milliseconds) that the checkpoint should
remain availablepublic String getRevisionHistory(long since, int maxEntries, String path) throws MicroKernelException
MicroKernel
Format:
[ { "id" : "<revisionId>", "ts" : <revisionTimestamp>, "msg" : "<commitMessage>" }, ... ]The
path
parameter allows to filter the revisions by path, i.e.
only those revisions that affected the subtree rooted at path
will be included.
The maxEntries
parameter allows to limit the number of revisions
returned. if maxEntries < 0
no limit will be applied. otherwise,
if the number of revisions satisfying the specified since
and
path
criteria exceeds maxEntries
, only maxEntries
entries will be returned (in chronological order, starting with the oldest).
getRevisionHistory
in interface MicroKernel
since
- timestamp (number of milliseconds since midnight, January 1, 1970 UTC) of earliest revision to be returnedmaxEntries
- maximum #entries to be returned;
if < 0, no limit will be applied.path
- optional path filter; if null
or ""
the
default ("/"
) will be assumed, i.e. no filter
will be appliedMicroKernelException
- if an error occurspublic String waitForCommit(String oldHeadRevisionId, long timeout) throws MicroKernelException, InterruptedException
MicroKernel
oldHeadRevisionId
.
This method allows for efficient polling for new revisions. The method
will return the id of the current head revision if it is more recent than
oldHeadRevisionId
, or waits if either the specified amount of time
has elapsed or a new head revision has become available.
if a zero or negative timeout
value has been specified the method
will return immediately, i.e. calling waitForCommit(oldHeadRevisionId, 0)
is
equivalent to calling getHeadRevision()
.
Note that commits on a private branch will be ignored.
waitForCommit
in interface MicroKernel
oldHeadRevisionId
- id of earlier head revisiontimeout
- the maximum time to wait in millisecondsMicroKernelException
- if an error occursInterruptedException
- if the thread was interruptedpublic String getJournal(String fromRevisionId, String toRevisionId, String path) throws MicroKernelException
MicroKernel
fromRevisionId
and ending with toRevisionId
in chronological order.
Format:
[ { "id" : "<revisionId>", "ts" : <revisionTimestamp>, "msg" : "<commitMessage>", "changes" : "<JSON diff>" }, ... ]If
fromRevisionId
and toRevisionId
are not in chronological
order the returned journal will be empty (i.e. []
)
The path
parameter allows to filter the revisions by path, i.e.
only those revisions that affected the subtree rooted at path
will be included. The filter will also be applied to the JSON diff, i.e.
the diff will include only those changes that affected the subtree rooted
at path
.
A MicroKernelException
is thrown if either fromRevisionId
or toRevisionId
doesn't exist, if fromRevisionId
denotes
a private branch revision and toRevisionId
denotes
either a head revision or a revision on a different private branch,
or if another error occurs.
If the journal includes private branch revisions, those entries
will include a "branchRootId"
denoting the head revision the
private branch is based on.
getJournal
in interface MicroKernel
fromRevisionId
- id of first revision to be returned in journaltoRevisionId
- id of last revision to be returned in journal,
if null
the current head revision is assumedpath
- optional path filter; if null
or ""
the default ("/"
) will be assumed, i.e. no
filter will be appliedMicroKernelException
- if any of the specified revisions doesn't exist or if another error occurspublic String diff(String fromRevisionId, String toRevisionId, String path, int depth) throws MicroKernelException
MicroKernel
fromRevisionId
and toRevisionId
don't need not be in a specific chronological order.
The path
parameter allows to filter the changes included in the
JSON diff, i.e. only those changes that affected the subtree rooted at
path
will be included.
The depth
limit applies to the subtree rooted at path
.
It allows to limit the depth of the diff, i.e. only changes up to the
specified depth will be included in full detail. changes at paths exceeding
the specified depth limit will be reported as ^"/some/path" : {}
,
indicating that there are unspecified changes below that path.
depth value | scope of detailed diff |
---|---|
-1 | no limit will be applied |
0 | changes affecting the properties and child node names of the node at path |
1 | changes affecting the properties and child node names of the node at path and its direct descendants |
... | ... |
diff
in interface MicroKernel
fromRevisionId
- a revision id, if null
the current head revision is assumedtoRevisionId
- another revision id, if null
the current head revision is assumedpath
- optional path filter; if null
or ""
the default ("/"
) will be assumed, i.e. no
filter will be applieddepth
- depth limit; if -1
no limit will be appliedMicroKernelException
- if any of the specified revisions doesn't exist or if another error occurspublic boolean nodeExists(String path, String revisionId) throws MicroKernelException
MicroKernel
nodeExists
in interface MicroKernel
path
- path denoting noderevisionId
- revision id, if null
the current head revision is assumedtrue
if the specified node exists, otherwise false
MicroKernelException
- if the specified revision does not exist or if another error occurspublic long getChildNodeCount(String path, String revisionId) throws MicroKernelException
MicroKernel
This is a convenience method since the number of child nodes can be also
determined by calling getNodes(path, revisionId, 0, 0, 0, null)
and evaluating the :childNodeCount
property.
getChildNodeCount
in interface MicroKernel
path
- path denoting noderevisionId
- revision id, if null
the current head revision is assumedMicroKernelException
- if the specified node or revision does not exist or if another error occurspublic String getNodes(String path, String revisionId, int depth, long offset, int maxChildNodes, String filter) throws MicroKernelException
MicroKernel
depth
parameter:
depth = 0 | properties, including :childNodeCount and
child node names (i.e. empty child node objects) |
depth = 1 | properties, child nodes and their properties (including
:childNodeCount ) and their child node names
(i.e. empty child node objects) |
depth = 2 | [and so on...] |
Example (depth=0):
{ "someprop" : "someval", ":childNodeCount" : 2, "child1" : {}, "child2" : {} }Example (depth=1):
{ "someprop" : "someval", ":childNodeCount" : 2, "child1" : { "prop1" : 123, ":childNodeCount" : 2, "grandchild1" : {}, "grandchild2" : {} }, "child2" : { "prop1" : "bar", ":childNodeCount" : 0 } }Remarks:
:childNodeCount
equals 0, then the
node does not have any child nodes.
:childNodeCount
is larger than the number
of returned child nodes, then the node has more child nodes than those
included in the returned tree.offset
parameter is only applied to the direct child nodes
of the root of the returned node tree. maxChildNodes
however
is applied on all hierarchy levels.
An IllegalArgumentException
is thrown if both an offset
greater than zero and a filter
on node names (see below) have been
specified.
The order of the child nodes is stable for any given revisionId
,
i.e. calling getNodes
repeatedly with the same revisionId
is guaranteed to return the child nodes in the same order, but the
specific order used is implementation-dependent and may change across
different revisions of the same node.
The optional filter
parameter allows to specify glob patterns for names of
nodes and/or properties to be included or excluded.
Example:
{ "nodes": [ "foo*", "-foo1" ], "properties": [ "*", "-:childNodeCount" ] }In the above example all child nodes with names starting with "foo" will be included, except for nodes named "foo1"; similarly, all properties will be included except for the ":childNodeCount" metadata property (see below).
Glob Syntax:
nodes
or properties
filter consists of one or more globs.-
(dash) is treated as an exclusion pattern;
all others are considered inclusion patterns.-
(dash) must be escaped by prepending \
(backslash)
if it should be interpreted as a literal.*
(asterisk) serves as a wildcard, i.e. it matches any
substring in the target name.*
(asterisk) occurrences within the glob to be interpreted as
literals must be escaped by prepending \
(backslash).{"nodes":["*"],"properties":["*"]}
System-provided metadata properties:
:childNodeCount
provides the actual number of direct child nodes; this property
is included by the implicit default filter. it can be excluded by specifying a filter such
as {properties:["*", "-:childNodeCount"]}
:hash
provides a content-based identifier for the subtree
rooted at the :hash
property's parent node. :hash
values
are similar to fingerprints. they can be compared to quickly determine
if two subtrees are identical. if the :hash
values are different
the respective subtrees are different with regard to structure and/or properties.
if on the other hand the :hash
values are identical the respective
subtrees are identical with regard to structure and properties.
:hash
is not included by the implicit default filter.
it can be included by specifying a filter such as {properties:["*", ":hash"]}
.
Returning the :hash
property is optional. Some implementations
might only return it on specific nodes or might not support it at all.
If however a :hash
property is returned it has to obey the contract
described above.
Implementations that keep track of the child hash along with
the child node name can return the :hash
value also as
a property of the child node objects, even if they'd otherwise
be empty, for example due to a depth limit. If such child hashes
are returned, the client can use them as an alternative to child
paths when accessing those nodes.
:id
provides an implementation-specific identifier
of a node. Identifiers are like content hashes as described above,
except for the fact that two different identifiers may refer to
identical subtrees. Also :id
values may be returned for
child nodes, in which case the client can use them for accessing
those nodes.
getNodes
in interface MicroKernel
path
- path denoting root of node tree to be retrieved,
or alternatively a previously returned
:hash
or :id
value; in the latter case
the revisionId
parameter is ignored.revisionId
- revision id, if null
the current head revision is assumed;
the revisionId
parameter is ignored if path
is an identifier (i.e. a :hash
or :id
value).depth
- maximum depth of returned treeoffset
- start position in the iteration order of child nodes (0 to start at the
beginning)maxChildNodes
- maximum number of sibling child nodes to retrieve (-1 for all)filter
- optional filter on property and/or node names; if null
or
""
the default filter will be assumednull
if the specified node does not existMicroKernelException
- if the specified revision does not exist or if another error occurspublic String commit(String path, String jsonDiff, String revisionId, String message) throws MicroKernelException
MicroKernel
If path.length() == 0
the paths specified in the
jsonDiff
are expected to be absolute.
The implementation tries to merge changes if the revision id of the commit is set accordingly. As an example, deleting a node is allowed if the node existed in the given revision, even if it was deleted in the meantime.
commit
in interface MicroKernel
path
- path denoting target nodejsonDiff
- changes to be applied in JSON diff format.revisionId
- id of revision the changes are based on,
if null
the current head revision is assumedmessage
- commit messageMicroKernelException
- if the specified revision doesn't exist or if another error occurspublic String branch(String trunkRevisionId) throws MicroKernelException
MicroKernel
A MicroKernelException
is thrown if trunkRevisionId
doesn't
exist, if it's not a trunk revision (i.e. it's not reachable
by traversing the revision history in reverse chronological order starting
from the current head revision) or if another error occurs.
branch
in interface MicroKernel
trunkRevisionId
- id of public trunk revision to base branch on,
if null
the current head revision is assumedMicroKernelException
- if trunkRevisionId
doesn't exist,
if it's not a trunk revision
or if another error occursMicroKernel.merge(String, String)
public String merge(String branchRevisionId, String message) throws MicroKernelException
MicroKernel
A MicroKernelException
is thrown if branchRevisionId
doesn't
exist, if it's not a branch revision, if the merge fails because of
conflicting changes or if another error occurs.
merge
in interface MicroKernel
branchRevisionId
- id of private branch revisionmessage
- commit messageMicroKernelException
- if branchRevisionId
doesn't exist,
if it's not a branch revision, if the merge
fails because of conflicting changes or if
another error occurs.MicroKernel.branch(String)
public String rebase(String branchRevisionId, String newBaseRevisionId) throws MicroKernelException
MicroKernel
A MicroKernelException
is thrown if branchRevisionId
doesn't
exist, if it's not a branch revision, if newBaseRevisionId
doesn't exist,
if it's a branch revision or if another error occurs.
If rebasing results in a conflict, conflicting nodes are annotated with a conflict
marker denoting the type of the conflict and the value(s) before the rebase operation.
The conflict marker is an internal node with the name MicroKernel.CONFLICT
and is added
to the node whose properties or child nodes are in conflict.
type of conflicts:
On conflict the conflict marker node carries the conflicting value of the branch while the rebased value in the branch itself will be set to the conflicting value of the trunk. In the case of conflicting properties, the conflicting value is the property value from the branch. In the case of conflicting node, the conflicting value is the node from the branch.
rebase
in interface MicroKernel
branchRevisionId
- id of private branch revisionnewBaseRevisionId
- id of new base revisionMicroKernelException
- if branchRevisionId
doesn't exist,
if it's not a branch revision, if newBaseRevisionId
doesn't exist, if it's a branch revision, or if another error occurs.public String reset(String branchRevisionId, String ancestorRevisionId) throws MicroKernelException
MicroKernel
branchRevisionId
to an ancestor
branch commit identified by ancestorRevisionId
.reset
in interface MicroKernel
branchRevisionId
- id of the private branch revisionancestorRevisionId
- id of the ancestor commit to reset the branch to.ancestorRevisionId
. An implementation is
free to create a new id for the reset branch.MicroKernelException
- if branchRevisionId
doesn't exist,
if it's not a branch revision, if ancestorRevisionId
is not a revision on that branch or if another error occurs.public long getLength(String blobId) throws MicroKernelException
MicroKernel
getLength
in interface MicroKernel
blobId
- blob identifierMicroKernelException
- if the specified blob does not exist or if another error occurspublic int read(String blobId, long pos, byte[] buff, int off, int length) throws MicroKernelException
MicroKernel
length
bytes of data from the specified blob into
the given array of bytes where the actual number of bytes read is
min(length, max(0, blobLength - pos))
.
If the returned value is smaller than length
, no more data is available.
This method never returns negative values.
read
in interface MicroKernel
blobId
- blob identifierpos
- the offset within the blobbuff
- the buffer into which the data is read.off
- the start offset in array buff
at which the data is written.length
- the maximum number of bytes to readMicroKernelException
- if the specified blob does not exist or if another error occurspublic String write(InputStream in) throws MicroKernelException
MicroKernel
If identical stream content has been stored previously, then the existing identifier will be returned instead of storing a redundant copy.
The stream is closed by this method.
write
in interface MicroKernel
in
- InputStream providing the blob contentMicroKernelException
- if an error occurs"Copyright © 2006 - 2015 Adobe Systems Incorporated. All Rights Reserved"