package com.c2kernel.persistency;
import com.c2kernel.entity.C2KLocalObject;
import com.c2kernel.persistency.outcome.Outcome;
import com.c2kernel.persistency.outcome.Viewpoint;
import com.c2kernel.process.auth.Authenticator;
import com.c2kernel.utils.Logger;
/** 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. There are old generic
* query methods, but these are deprecated. The kernel does no analytical querying of the ClusterStorages, only simple gets and puts.
*
* 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(Integer, String)} and {@link #getClusterContents(Integer, String)} for clusters they return
* {@link #READ} and {@link #READWRITE} from queryClusterSupport
* and {@link #put(Integer, C2KLocalObject)} and {@link #delete(Integer, String)} for clusters they return {@link #WRITE} and {@link #READWRITE}
* from {@link #getClusterContents(Integer, String)}.
* Operations that have notbeen declared as not supported should throw a ClusterStorageException.
* 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 com.c2kernel.lifecycle.instance.Workflow
*/
public static final String LIFECYCLE = "LifeCycle";
/**
* This cluster holds all outcomes of this Item. The path to each outcome is "Outcome/Schema Name/Schema Version/Event ID"
*/
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/Event ID"
*/
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/Schema Name/Viewpoint Name"
*/
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 };
// connection maintenance
public abstract void open(Authenticator auth)
throws ClusterStorageException;
public abstract void close()
throws ClusterStorageException;
// introspection
public abstract short queryClusterSupport(String clusterType);
public abstract String getName();
// for addressing queries
public abstract String getId();
/** Quickly gets the first string of the slashed path */
public 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;
}
}
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
return root+"/"+obj.getName();
}
/* object manipulation */
// retrieve object by path
public abstract C2KLocalObject get(Integer sysKey, String path)
throws ClusterStorageException;
// store object by path
public abstract void put(Integer sysKey, C2KLocalObject obj)
throws ClusterStorageException;
// delete cluster
public abstract void delete(Integer sysKey, String path)
throws ClusterStorageException;
// db specific queries
@Deprecated
public Object query(Object query)
throws ClusterStorageException {
throw new ClusterStorageException("Query not supported on this storage");
}
@Deprecated
public String queryToXML(String query, boolean genericFormat)
throws ClusterStorageException {
throw new ClusterStorageException("Query not supported on this storage");
}
// directory listing
public abstract String[] getClusterContents(Integer sysKey, String path)
throws ClusterStorageException;
}