/* * Copyright (C) 2006 Alfresco, Inc. * * Licensed under the Mozilla Public License version 1.1 * with a permitted attribution clause. You may obtain a * copy of the License at * * http://www.alfresco.org/legal/license.txt * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the * License. */ package org.alfresco.service.cmr.avm; import java.io.InputStream; import java.io.OutputStream; import java.util.Date; import java.util.List; import java.util.Map; import java.util.SortedMap; import org.alfresco.repo.domain.PropertyValue; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.namespace.QName; import org.alfresco.util.Pair; /** * This is the service interface for the * Alfresco Versioning Model (AVM). * * Because the AVM is a versioning repository, fully explicit * references to the nodes within it consist of an absolute AVM path, * and a version ID. Absolute AVM paths are of * the form: <store-name>:<store-relative-path>. *
* For example: mystore:/www/avm_webapps/ROOT/x/y/z.html
*
* Within AVMService, whenever an API takes a path * and a name, the path is the parent * directory in which the name appears. * Whenever just a path is needed by an API, it is an absolute * path to a file or directory. *
* The special version ID -1
(negative one)
* refers to the latest read/write version at the given absolute AVM path.
* Non-negative version ID values refer to read-only snapshots of a store.
* For this reason, the version ID -1
* is implicit for all write operations. Sometimes,
* -1
is referred to as the
* HEAD
version (a term that should be
* already be familiar to users of other versioning systems like
* CVS
* and SVN).
*
* Snapshots can be created explicitly via a call to
* {@link #createSnapshot(String store, String tag, String description) createSnapshot},
* or implicitly by various APIs in this interface and in
* {@link org.alfresco.service.cmr.avmsync.AVMSyncService AVMSyncService}.
* While a new snapshot of a store will have version a ID one higher
* than the previous snapshot in that store, the history of an AMV store
* does not necessarily contain a continuous range of version ID values,
* because {@link #purgeVersion(int version, String name) purgeVersion}
* may have been called. However, version ID values are never recycled
* within a store.
*
* @author britt
*/
public interface AVMService
{
/**
* Get an InputStream for reading the contents of a
* file identified by its version ID and AVM path.
* This method can be used for either plain or layered files.
*
* @param version The version ID to look in.
* @param path The absolute path to the file.
* @return An InputStream for the designated file.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public InputStream getFileInputStream(int version, String path);
/**
* Get an InputStream for reading the contents of a
* file node identified by its descriptor.
* This method can be used for either plain or layered files.
*
* @param desc The descriptor.
* @return An InputStream.
* @throws AVMNotFoundException
*/
public InputStream getFileInputStream(AVMNodeDescriptor desc);
/**
* Get an output stream to write to a file
* identified by an AVM path. This file must already exist.
* This method can be used for either plain or layered files.
*
* To create a plain file, see:
* {@link #createFile(String path, String name) createFile}.
* To create a layered file, see:
* {@link #createLayeredFile(String targetPath, String parent, String name) createLayeredFile}.
*
* @param path The absolute path to the file.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public OutputStream getFileOutputStream(String path);
/**
* Low-level internal function: Fetch a content reader for a file node.
*
* This function is similar to
* {@link getFileInputStream(int version, String path) getFileInputStream};
* however, it can be used to fetch either InputStream or a
* random-access nio channel.
*
* @param version The version ID of the file.
* @param path The absolute AVM path to the file.
* @return A ContentReader.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public ContentReader getContentReader(int version, String path);
/**
* Low-level internal function: Fetch a ContentWriter to a file node.
*
* @param path The path to the file.
* @return A ContentWriter.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public ContentWriter getContentWriter(String path);
/**
* Get a non-recursive listing of a directory
* identified by its version ID and path.
* If
* If instead, you wish to obtain a list of only
* the deleted nodes within a directory, see:
* {@link #getDeleted(int version, String path) getDeleted}.
*
* @param version The version ID to look in.
* @param path The absolute AVM path to the file.
* @param includeDeleted Whether to include deleted nodes
* @return A Map of names to descriptors.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public SortedMap
* If this function is called on a "plain" (non-layered) directory,
* it is equivalent to
* {@link #getDirectoryListing(int version, String path) getDirectoryListing}.
*
* @param version The version to look up.
* @param path The full path to get listing for.
* @return A Map of names to descriptors.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public SortedMap
* Note: the target of the indirection does not need to exist at
* the time the layered file node is created.
*
* @param targetPath The absolute path of the underlying file being pointed at
* @param parent The absolute path of the directory containing layered file to be created
* @param name The name of the layered file to be created
* @throws AVMNotFound
* @throws AVMExists
* @throws AVMWrongType
*/
public void createLayeredFile(String targetPath, String parent, String name);
/**
* Create a new layered directory. In whatever context this is created, this
* will be a layered directory that has a primary indirection.
*
* Note: a "primary" indirection is one in which the target is explicitly set;
* "non-primary" indirect nodes compute their effective target dynamically
* on the basis of their relative position to the closest "primary"
* indirect node that contains them. Therefore, changing the target of a
* "primary" layered directory node immediately alters the indirection
* targets computed by the "non-primary" layered nodes it contains.
*
* Note: the target of the indirection does not need to exist at
* the time the layered directory node is created.
*
* @param targetPath The absolute path to the underlying directory that
* the layered directory being created will point at.
* @param parent The absolute path to directory containing the layered directory being created.
* @param name The name of the layered directory being created
* @throws AVMNotFound
* @throws AVMExists
* @throws AVMWrongType
*/
public void createLayeredDirectory(String targetPath, String parent, String name);
/**
* Retarget a layered directory.
* Change the target pointed to by a layered directory node.
* This has the side effect of making the layered directory
* a primary indirection if the layered directory's indirection
* was "non-primary".
*
* @param path Path to the layered directory.
* @param target The new indirection target of the layered directory
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public void retargetLayeredDirectory(String path, String target);
/**
* Create a new AVMStore.
* All stores are top level objects within the AVM repository.
* The AVM is a forest of versioned trees; each versioned
* tree is contained within a AVM store with a unique
* name. If a store is removed via
* {@link purgeStore(String name) purgeStore}, the name of
* the deleted store can be reused in a later call to
* @{link createStore(String name) createStore}.
*
* The store name must be non-null, cannot be the empty string,
* and must not contain characters that are illegal in
* normal file names.
*
* @param name The name of the new AVMStore.
* @throws AVMExistsException
*/
public void createStore(String name);
/**
* Create a branch from a given version and path. As a side effect,
* an automatic snapshot is taken of the store that contains the
* node that is being branched from.
*
* @param version The version number from which to make the branch.
* @param srcPath The path to the node to branch from.
* @param dstPath The path to the directory to contain the new branch.
* @param name The name to give the new branch.
* @throws AVMNotFoundException
* @throws AVMExistsException
* @throws AVMWrongTypeException
*/
public void createBranch(int version, String srcPath, String dstPath, String name);
/**
* Remove a file or directory from its parent directory.
* In a layered context, the newly deleted node will hide
* a file of the same name in the corresponding layer below.
*
* If instead you want to make the file in the lower layer visible
* via transparency, see:
* {@link uncover(String dirPath, String name) uncover}.
* If you want to perform a removal and an uncover
* operation atomically, see:
* {@link #makeTransparent(String dirPath, String name) makeTransparent}.
*
*
*
* Caution: this removes directories even if they are not empty.
*
*
* Note: developers of records management systems must also
* be aware that the AVMNode corresponding to the
*
*
*
* Note: if instead you want to rename an AVM store, see
* {@link #renameStore(String sourceName, String destName) renameStore}.
*
* @param srcParent The absolute path to the parent directory.
* @param srcName The name of the node in the src directory.
* @param dstParent The absolute path to the destination directory.
* @param dstName The name that the node will have in the destination directory.
* @throws AVMNotFoundException
* @throws AVMExistsException
*/
public void rename(String srcParent, String srcName, String dstParent, String dstName);
/**
* If a layered directory
* Note: if you are looking for an atomic operation
* that first deletes an object, then performs
* an "uncover" operation to make it transparent, see
* {@link #makeTransparent(String dirPath, String name) makeTransparent}.
*
* @param dirPath The path to the layered directory.
* @param name The name to uncover.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public void uncover(String dirPath, String name);
/**
* Atomically delete
* Note: unless the operations that require this value
* to be valid are performed within a transaction,
* this value can become "stale".
*
* @param storeName The name of the AVMStore.
* @return The next version ID of the AVMStore.
* @throws AVMNotFoundException
*/
public int getNextVersionID(String storeName);
/**
* Get the latest snapshot ID of a store.
* @param storeName The store name.
* @return The ID of the latest extant version of the store.
* @throws AVMNotFoundException
*/
public int getLatestSnapshotID(String storeName);
/**
* Snapshot the given AVMStore.
* @param store The name of the AVMStore to snapshot.
* @param tag The short description.
* @param description The thick description.
* @throws AVMNotFoundException
*/
public int createSnapshot(String store, String tag, String description);
/**
* Get the set of versions in an AVMStore. The version ID values
* within this list will always be may appear out of order,
* and may contain missing values (due to the possibility that
* {@link #purgeStore(String name) purgeStore} operations have
* been performed).
*
* Because the number of versions that a store can contain
* may become large, this call can be a resource-intensive,
* and may even causing Out of Memory exceptions.
*
* @param name The name of the AVMStore.
* @return A Set of version descriptors.
* @throws AVMNotFoundException
*/
public List
*
*
* The order of the values returned is not guaranteed, nor are the version
* IDs necessarily free of "missing" values (due to the possibility that
* {@link #purgeStore(String name) purgeStore} operations have
* been performed).
*
*
* Note: for portability, all dates are stored as 64-bit longs, with a
* time resolution of one millisecond. Therefore, aliasing/wrapping
* are not a concern unless you need to plan 292.4 million years ahead.
* If so, please contact your system administrator.
*
* @param name The name of the AVMStore.
* @param from Earliest date of version to include.
* @param to Latest date of version to include.
* @return The Set of version descriptors that match.
* @throws AVMNotFoundException
*/
public List
* Note: paths that only access
* For those concerned with records management applications,
* it's worth noting that once every path to an asset has
* been deleted, the system will purge it entirely in an
* asynchronous manner.
*
* @param desc The node descriptor to get paths for.
* @return A List of version, path Pairs.
* @throws AVMNotFoundException
*/
public List
* For example, if "mysite--alice:/www" is a layered
* directory that targets "mysite:/www", and "mysite--alice"
* contains no content directly, then if the path
* path "mysite:/www/avm_webapps/ROOT/x/y/z" is valid,
* calling
* Note: while the store being purged disappears from view
* immediately, any nodes that become unreachable as a result
* are deleted asynchronously.
*
* @param name The name of the AVMStore.
* @throws AVMNotFoundException
*/
public void purgeStore(String name);
/**
* Purge a version from an AVMStore.
* Deletes everything that lives in the given version only.
*
* @param version The version to purge.
* @param name The name of the AVMStore from which to purge it.
* @throws AVMNotFoundException If path
does not refer to a directory
* node, AVMWrongTypeException
is thrown.
*
* @param version The version ID to look in.
* @param path The absolute AVM path to the file.
* @return A Map of names to descriptors.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public SortedMappath
* does not exist.
*
* @param path The path of the directory containing the created file.
* @param name The name of the new file
* @throws AVMNotFound
* @throws AVMExists
* @throws AVMWrongType
*/
public OutputStream createFile(String path, String name);
/**
* Create a new "plain" (non-layered) file.
* Guarantees that the entire contents of the
* input stream will be loaded atomically.
* The directory identified by path
must already exist.
*
* @param path The path of the directory containing the created file.
* @param name The name of the new file
* @param in An input stream with data for the file.
* @throws AVMNotFound
* @throws AVMExists
* @throws AVMWrongType
*/
public void createFile(String path, String name, InputStream in);
/**
* Create a new directory.
* If path
is within a layer, the new directory will be a layered directory;
* otherwise, the new directory will be a plain directory.
*
* @param path The simple absolute path to the parent.
* @param name The name to give the directory.
* @throws AVMNotFound
* @throws AVMExists
* @throws AVMWrongType
*/
public void createDirectory(String path, String name);
/**
* Create a new layered file.
* parent
directory and name
* provided might still be accessible via different
* path lookups after this function has completed;
* this because branching and versioning operations create
* manifestations of nodes in a manner that is similar
* to a UNIX hard link. If you need to discover every
* possible path that could retrieve the associated AVMNode, see:
* {@link #getPaths(AVMNodeDescriptor desc) getPaths},
* {@link #getHeadPaths(AVMNodeDescriptor desc) getHeadPaths}, and
* {@link #getPathsInStoreHead(AVMNodeDescriptor desc) getPathsInStoreHead}.
*
* @param parent The absolute path to the parent directory.
* @param name The name of the child to remove.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public void removeNode(String parent, String name);
/**
* A convenience method that removes a node specified by an AVM path.
* It merely parses an absolute path into a parent directory and a child
* name, then calls {@link #removeNode(parent, name) removeNode}.
*
* @param path The full path to the node to remove.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public void removeNode(String path);
/**
* Rename a file or directory.
* There are a number of things to note about the
* interaction of rename and layering:
*
*
* dirPath
* has a deleted entry of the given name
,
* remove that name from the deleted list,
* so that if a layer below it contains an entry
* of this name, it can be seen via transparency
* from dirPath
.
* name
within dirPath
* and {@link uncover(String dirPath, String name) uncover}
* it so whatever is underneath can be seen via transparency.
* If name
corresponds to a deletion already,
* then the deletion step is skipped, and the "uncover"
* operation is performed.
*
* @param dirPath The path to the layered directory.
* @param name The name of the item this method will
* {@link org.alfresco.service.cmr.avmsync.AVMSyncService#flatten(String layerPath, String underlyingPath) flatten}
*
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public void makeTransparent(String dirPath, String name);
/**
* Gets the ID that the next snapshotted version of a store
* will have.
*
*from
or to
can be null but not both.
*
*
* from
is null, all versions earlier than
* to
will be returned.
* to
is null, all versions later than
* from
will be returned.
* "mysite:/"
).
*
* @param version The version to look up.
* @param name The name of the AVMStore.
* @return A descriptor for the specified root.
* @throws AVMNotFoundException
*/
public AVMNodeDescriptor getStoreRoot(int version, String name);
/**
* Lookup a node identified by version ID and path.
*
* @param version The version ID to look under.
* @param path The simple absolute path to the parent directory.
* @return An AVMNodeDescriptor, or null if the node does not exist.
*/
public AVMNodeDescriptor lookup(int version, String path);
/**
* Lookup a node identified by version ID and path; optionally,
* if the node is deleted, its descriptor can still
* be retrieved.
*
* @param version The version ID to look under.
* @param path The simple absolute path to the parent directory.
* @param includeDeleted Whether to allow a deleted node to be retrieved
* @return An AVMNodeDescriptor, or null if the version does not exist.
*/
public AVMNodeDescriptor lookup(int version, String path, boolean includeDeleted);
/**
* Lookup a node identified by the directory node that contains it, and its name.
*
* @param dir The descriptor for the directory node.
* @param name The name to lookup.
* @return The descriptor for the child.
* @throws AVMWrongTypeException If dir
does not refer to a directory.
*/
public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name);
/**
* Lookup a node identified by the directory that contains it, and its name;
* optionally, the lookup can retrive the descriptor of a node even if
* it has been deleted from its containing directory.
*
* @param dir The descriptor for the directory node.
* @param name The name to lookup.
* @param includeDeleted Whether to allow a deleted node to be retrieved via the lookup
* @return The descriptor for the child, null if the child doesn't exist.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name, boolean includeDeleted);
/**
* Get a list of all paths that a given node has.
* This can be an extremely expensive operation due to the large number
* of paths to an AVMNodeDescriptor that can be generated
* via branching and versioning. For example, if an asset
* is present in the initial version of a store, and
* that store has been versioned 10,000 times,
* there are a minimum of 10,000 paths that lead to it.
* The effect of branching is multiplicative.
* desc
* via transparency are not returned by this function;
* only "direct" containment relationships are considered.
* HEAD
version ( -1
).
* This can be an expensive operation but less so than getPaths().
*
* @param desc The node descriptor to get paths for.
* @return A List of version, path Pairs.
* @throws AVMNotFoundException
*/
public ListHEAD
version ( -1
)
* of a store. This can be an expensive operation but less so than getHeadPaths().
*
* @param desc The node descriptor.
* @param store The store.
* @return A List of all paths meeting the criteria.
* @throws AVMNotFoundException
*/
public ListgetIndirectionPath
on
* "mysite--alice:/www/avm_webapps/ROOT/x/y/z" will yield
* "mysite:/www/avm_webapps/ROOT/x/y/z".
*
* @param version The version number to get.
* @param path The path to the node of interest.
* @return The indirection path, or null if the path is not in a layered context.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public String getIndirectionPath(int version, String path);
/**
* Purge an AVMStore.
* This completely removes an AVMStore.
* name
or version
* do not exist.
*/
public void purgeVersion(int version, String name);
/**
* Make a directory into a primary indirection node.
* @param path The full path.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public void makePrimary(String path);
/**
* Get a list of up to count nodes in the history chain of a node.
* The initial element of the list returned will be desc
* (as long as the count is non-zero).
*
* @param desc The descriptor for a node to find ancestors for.
* @param count maximum number of ancestors to return in the list
* (the value -1
means
* "no limit -- return them all")
* @return A List of ancestors starting with the most recent.
* @throws AVMNotFoundException
*/
public Listpath
.
*
*
* @param version The version to look under.
* @param path The absolute AVM path.
* @return A LayeringDescriptor.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public LayeringDescriptor getLayeringInfo(int version, String path);
/**
* Set a property on a node.
*
* @param path The path to the node to set the property on.
* @param name The QName of the property.
* @param value The property to set.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public void setNodeProperty(String path, QName name, PropertyValue value);
/**
* Set a collection of properties on a node.
*
* @param path The path to the node.
* @param properties The Map of properties to set.
* @throws AVMNotFoundException
* @throws AVMWrongTypeException
*/
public void setNodeProperties(String path, MapdstPath
.
* @throws AVMNotFoundException
*/
public void copy(int srcVersion, String srcPath, String dstPath, String name);
/**
* Rename a store.
*
* @param sourceName The original name.
* @param destName The new name.
* @throws AVMNotFoundException
* @throws AVMExistsException
*/
public void renameStore(String sourceName, String destName);
/**
* Revert a HEAD
path to a given version.
* This works by cloning the version to revert to, and then linking
* that new version into HEAD
.
* The reverted version will have the previous
* HEAD
version as ancestor.
*
* @param path The path to the node to revert.
* @param toRevertTo The descriptor of the version to revert to.
* @throws AVMNotFoundException
*/
public void revert(String path, AVMNodeDescriptor toRevertTo);
}