summaryrefslogtreecommitdiff
path: root/src/main/java/org/cristalise/kernel/persistency/ClusterStorage.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/cristalise/kernel/persistency/ClusterStorage.java')
-rw-r--r--src/main/java/org/cristalise/kernel/persistency/ClusterStorage.java296
1 files changed, 296 insertions, 0 deletions
diff --git a/src/main/java/org/cristalise/kernel/persistency/ClusterStorage.java b/src/main/java/org/cristalise/kernel/persistency/ClusterStorage.java
new file mode 100644
index 0000000..ca43e67
--- /dev/null
+++ b/src/main/java/org/cristalise/kernel/persistency/ClusterStorage.java
@@ -0,0 +1,296 @@
+/**
+ * This file is part of the CRISTAL-iSE kernel.
+ * Copyright (c) 2001-2014 The CRISTAL Consortium. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * http://www.fsf.org/licensing/licenses/lgpl.html
+ */
+package org.cristalise.kernel.persistency;
+
+import org.cristalise.kernel.collection.Collection;
+import org.cristalise.kernel.common.PersistencyException;
+import org.cristalise.kernel.common.SystemKey;
+import org.cristalise.kernel.entity.C2KLocalObject;
+import org.cristalise.kernel.lookup.ItemPath;
+import org.cristalise.kernel.persistency.outcome.Outcome;
+import org.cristalise.kernel.persistency.outcome.Viewpoint;
+import org.cristalise.kernel.process.auth.Authenticator;
+import org.cristalise.kernel.utils.Logger;
+
+
+/**
+ * <p>Interface for persistency managers of entities. It allows different kernel
+ * objects to be stored in different backend. For instance, Properties may be
+ * stored in LDAP, while Events, Outcomes and Viewpoints could be stored in a
+ * relational database. The kernel does and needs no analytical querying of the
+ * ClusterStorages, only simple gets and puts. This may be implemented on top
+ * of the storage implementation separately.
+ *
+ * <p>Each item is indexed by its {@link ItemPath}, which is may be constructed from its
+ * UUID, equivalent {@link SystemKey} object, or
+ *
+ * <p>Each first-level path under the Item is defined as a Cluster. Different
+ * Clusters may be stored in different places. Each ClusterStorage must support
+ * {@link #get(ItemPath, String)} and
+ * {@link #getClusterContents(ItemPath, String)} for clusters they return
+ * {@link #READ} and {@link #READWRITE} from queryClusterSupport and
+ * {@link #put(ItemPath, C2KLocalObject)} and {@link #delete(ItemPath, String)}
+ * for clusters they return {@link #WRITE} and {@link #READWRITE} from
+ * {@link #getClusterContents(ItemPath, String)}. Operations that have not been
+ * declared as not supported should throw a PersistencyException. If a
+ * cluster does not exist, get should return null, and delete should return with
+ * no action.
+ */
+public abstract class ClusterStorage {
+
+ /**
+ * Constant to return from {@link #queryClusterSupport(String)} for Cluster
+ * types this storage does not support.
+ */
+ public static final short NONE = 0;
+ /**
+ * Constant to return from {@link #queryClusterSupport(String)} for Cluster
+ * types this storage can read from a database but not write. An example
+ * would be pre-existing data in a database that is mapped to Items in some
+ * way.
+ */
+ public static final short READ = 1;
+ /**
+ * Constant to return from {@link #queryClusterSupport(String)} for Cluster
+ * types this storage can write to a database but not read. An example would
+ * be a realtime database export of data, which is transformed in an
+ * unrecoverable way for use in other systems.
+ */
+ public static final short WRITE = 2;
+ /**
+ * Constant to return from {@link #queryClusterSupport(String)} for data
+ * stores that CRISTAL may use for both reading and writing for the given
+ * Cluster type.
+ */
+ public static final short READWRITE = 3;
+
+ // Cluster types
+ /**
+ * The defined path of the root of the CRISTAL Kernel object cluster tree. A
+ * zero-length string.
+ */
+ public static final String ROOT = "";
+ /**
+ * The root of the Property object cluster. All Property paths start with
+ * this. Defined as "Property". Properties are stored underneath according
+ * to their name e.g. "Property/Name"
+ */
+ public static final String PROPERTY = "Property";
+ /**
+ * The root of the Collection object cluster. All Collection paths start
+ * with this. Defined as "Collection". Collections are stored underneath by
+ * name e.g. "Collection/Composition"
+ */
+ public static final String COLLECTION = "Collection";
+ /**
+ * The cluster which holds the Item workflow. Defined as "LifeCycle". Holds
+ * the workflow inside, which is named "workflow", hence
+ * "LifeCycle/workflow".
+ *
+ * @see org.cristalise.kernel.lifecycle.instance.Workflow
+ */
+ public static final String LIFECYCLE = "LifeCycle";
+ /**
+ * This cluster holds all outcomes of this Item. The path to each outcome is
+ * "Outcome/<i>Schema Name</i>/<i>Schema Version</i>/<i>Event ID</i>"
+ */
+ public static final String OUTCOME = "Outcome";
+ /**
+ * This is the cluster that contains all event for this Item. This cluster
+ * may be instantiated in a client as a History, which is a RemoteMap.
+ * Events are stored with their ID: "/AuditTrail/<i>Event ID</i>"
+ */
+ public static final String HISTORY = "AuditTrail";
+ /**
+ * This cluster contains all viewpoints. Its name is defined as "ViewPoint".
+ * The paths of viewpoint objects stored here follow this pattern:
+ * "ViewPoint/<i>Schema Name</i>/<i>Viewpoint Name</i>"
+ */
+ public static final String VIEWPOINT = "ViewPoint";
+ /**
+ * Agents store their persistent jobs in this cluster that have been pushed
+ * to them by activities configured to do so. The name is defined as "Job"
+ * and each new job received is assigned an integer ID one more than the
+ * highest already present.
+ */
+ public static final String JOB = "Job";
+
+ /**
+ * An array of all currently supported cluster types, for iterative
+ * purposes.
+ */
+ public static final String[] allClusterTypes = { PROPERTY, COLLECTION,
+ LIFECYCLE, OUTCOME, HISTORY, VIEWPOINT, JOB };
+
+ /**
+ * Connects to the storage. It must be possible to retrieve CRISTAL local
+ * objects after this method returns.
+ *
+ * @param auth
+ * The Authenticator instance that the user or server logged in
+ * with.
+ * @throws PersistencyException
+ * If storage initialization failed
+ */
+ public abstract void open(Authenticator auth)
+ throws PersistencyException;
+
+ /**
+ * Shuts down the storage. Data must be completely written to disk before
+ * this method returns, so the process can exit. No further gets or puts
+ * should follow.
+ *
+ * @throws PersistencyException
+ * If closing failed
+ */
+ public abstract void close() throws PersistencyException;
+
+ /**
+ * Declares whether or not this ClusterStorage can read or write a
+ * particular CRISTAL local object type.
+ *
+ * @param clusterType
+ * The Cluster type requested. Must be one of the Cluster type
+ * constants from this class.
+ * @return A ClusterStorage constant: NONE, READ, WRITE, or READWRITE
+ */
+ public abstract short queryClusterSupport(String clusterType);
+
+ /**
+ * @return A full name of this storage for logging
+ */
+ public abstract String getName();
+
+ /**
+ * @return A short code for this storage for reference
+ */
+ public abstract String getId();
+
+ /**
+ * Utility method to find the cluster for a particular Local Object (the
+ * first part of its path)
+ *
+ * @param Local
+ * object path
+ * @return The cluster to which it belongs
+ */
+ protected static String getClusterType(String path) {
+ try {
+ if (path == null || path.length() == 0)
+ return ClusterStorage.ROOT;
+ int start = path.charAt(0) == '/' ? 1 : 0;
+ int end = path.indexOf('/', start + 1);
+ if (end == -1)
+ end = path.length();
+ return path.substring(start, end);
+ } catch (Exception ex) {
+ Logger.error(ex);
+ return ClusterStorage.ROOT;
+ }
+ }
+
+ /**
+ * Gives the path for a local object. Varies by Cluster.
+ *
+ * @param C2KLocalObject
+ * @return Its path
+ */
+ public static String getPath(C2KLocalObject obj) {
+ String root = obj.getClusterType();
+ if (root == null)
+ return null; // no storage allowed
+ if (obj instanceof Outcome) {
+ Outcome oc = (Outcome) obj;
+ return root + "/" + oc.getSchemaType() + "/"
+ + oc.getSchemaVersion() + "/" + oc.getName();
+ } else if (obj instanceof Viewpoint) {
+ Viewpoint vp = (Viewpoint) obj;
+ return root + "/" + vp.getSchemaName() + "/" + vp.getName();
+ } else if (obj instanceof Collection) {
+ Collection<?> coll = (Collection<?>) obj;
+ return root + "/" + coll.getName() + "/" +coll.getVersionName();
+ }
+ return root + "/" + obj.getName();
+ }
+
+ /* object manipulation */
+
+ // retrieve object by path
+ /**
+ * Fetches a CRISTAL local object from storage
+ *
+ * @param itemPath
+ * The ItemPath of the containing Item
+ * @param path
+ * The path of the local object
+ * @return The C2KLocalObject, or null if the object was not found
+ * @throws PersistencyException
+ * when retrieval failed
+ */
+ public abstract C2KLocalObject get(ItemPath itemPath, String path)
+ throws PersistencyException;
+
+ /**
+ * Stores a CRISTAL local object. The path is automatically generated.
+ *
+ * @param itemPath
+ * The Item that the object will be stored under
+ * @param obj
+ * The C2KLocalObject to store
+ * @throws PersistencyException
+ * When storage fails
+ */
+ public abstract void put(ItemPath itemPath, C2KLocalObject obj)
+ throws PersistencyException;
+
+ /**
+ * Remove a CRISTAL local object from storage. This should be used sparingly
+ * and responsibly, as it violated traceability. Objects removed in this way
+ * are not expected to be recoverable.
+ *
+ * @param itemPath
+ * The containing Item
+ * @param path
+ * The path of the object to be removed
+ * @throws PersistencyException
+ * When deletion fails or is not allowed
+ */
+ public abstract void delete(ItemPath itemPath, String path)
+ throws PersistencyException;
+
+ // directory listing
+ /**
+ * Queries the local path below the given root and returns the possible next
+ * elements.
+ *
+ * @param itemPath
+ * The Item to query
+ * @param path
+ * The path within that Item to query. May be ClusterStorage.ROOT
+ * (empty String)
+ * @return A String array of the possible next path elements
+ * @throws PersistencyException
+ * When an error occurred during the query
+ */
+ public abstract String[] getClusterContents(ItemPath itemPath, String path)
+ throws PersistencyException;
+
+}