public interface MicroKernel
The MicroKernel Data Model:
The Retention Policy for Revisions:
TODO specify retention policy for old revisions, i.e. minimal guaranteed retention period (OAK-114)
The Retention Policy for Binaries:
The MicroKernel implementation is free to remove binaries if both of the following conditions are met:
write(InputStream in)
. This includes simple property values such as
{"bin": ":blobId:1234"} as well as array property values such as
{"array": [":blobId:1234", ":blobId:5678"]}.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.
|
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.
|
static final String CONFLICT
String getHeadRevision() throws MicroKernelException
MicroKernelException
- if an error occursString checkpoint(long lifetime) throws MicroKernelException
lifetime
- time (in milliseconds) that the checkpoint should
remain availableMicroKernelException
- if the checkpoint could not be createdString getRevisionHistory(long since, int maxEntries, String path) throws MicroKernelException
[ { "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).since
- timestamp (ms) 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 occursString waitForCommit(String oldHeadRevisionId, long timeout) throws MicroKernelException, InterruptedException
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.oldHeadRevisionId
- id of earlier head revisiontimeout
- the maximum time to wait in millisecondsMicroKernelException
- if an error occursInterruptedException
- if the thread was interruptedString getJournal(String fromRevisionId, String toRevisionId, String path) throws MicroKernelException
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.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 occursString diff(String fromRevisionId, String toRevisionId, String path, int depth) throws MicroKernelException
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 |
... | ... |
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 occursboolean nodeExists(String path, String revisionId) throws MicroKernelException
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 occurslong getChildNodeCount(String path, String revisionId) throws MicroKernelException
getNodes(path, revisionId, 0, 0, 0, null)
and evaluating the :childNodeCount
property.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 occursString getNodes(String path, String revisionId, int depth, long offset, int maxChildNodes, String filter) throws MicroKernelException
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...] |
{ "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.
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 occursIllegalArgumentException
- if both an offset > 0
and a filter
on node names have been specifiedString commit(String path, String jsonDiff, String revisionId, String message) throws MicroKernelException
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.
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 occursString branch(String trunkRevisionId) throws MicroKernelException
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.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 occursmerge(String, String)
String merge(String branchRevisionId, String message) throws MicroKernelException
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.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.branch(String)
String rebase(String branchRevisionId, String newBaseRevisionId) throws MicroKernelException
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 CONFLICT
and is added
to the node whose properties or child nodes are in conflict.
type of conflicts:
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.String reset(String branchRevisionId, String ancestorRevisionId) throws MicroKernelException
branchRevisionId
to an ancestor
branch commit identified by ancestorRevisionId
.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.long getLength(String blobId) throws MicroKernelException
blobId
- blob identifierMicroKernelException
- if the specified blob does not exist or if another error occursint read(String blobId, long pos, byte[] buff, int off, int length) throws MicroKernelException
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.
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 occursString write(InputStream in) throws MicroKernelException
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.
in
- InputStream providing the blob contentMicroKernelException
- if an error occurs"Copyright © 2006 - 2015 Adobe Systems Incorporated. All Rights Reserved"