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; }