diff options
| author | Andrew Branson <andrew.branson@cern.ch> | 2013-01-15 14:24:30 +0100 |
|---|---|---|
| committer | Andrew Branson <andrew.branson@cern.ch> | 2013-01-15 14:24:30 +0100 |
| commit | d5c7f3380db4f6cb9f80462883d97a6edfd68a98 (patch) | |
| tree | 1c23b171b6a907b3b8553874ba496d98912e76cb | |
Initial commit
| -rw-r--r-- | pom.xml | 87 | ||||
| -rw-r--r-- | src/main/java/com/c2kernel/persistency/XMLDBClusterStorage.java | 261 | ||||
| -rw-r--r-- | src/main/java/com/c2kernel/persistency/XMLDBSyskeyTypeClusterStorage.java | 283 | ||||
| -rw-r--r-- | src/main/java/com/c2kernel/persistency/XMLDBTypeSyskeyCollClusterStorage.java | 279 | ||||
| -rw-r--r-- | src/main/resources/module.xml | 11 |
5 files changed, 921 insertions, 0 deletions
@@ -0,0 +1,87 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>cristal</groupId>
+ <artifactId>xmldb</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+ <name>cristal-xmldb</name>
+ <description>CRISTAL Module</description>
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <targetPath>META-INF/cristal</targetPath>
+ <filtering>true</filtering>
+ <includes>
+ <include>module.xml</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ <targetPath>com/c2kernel/persistency/xmldb/resources</targetPath>
+ <excludes>
+ <exclude>module.xml</exclude>
+ </excludes>
+ </resource>
+ </resources>
+ </build>
+ <distributionManagement>
+ <repository>
+ <id>releases</id>
+ <url>http://cristal.cccs.uwe.ac.uk:8081/nexus/content/repositories/releases</url>
+ </repository>
+ <snapshotRepository>
+ <id>snapshots</id>
+ <url>http://cristal.cccs.uwe.ac.uk:8081/nexus/content/repositories/snapshots</url>
+ </snapshotRepository>
+ </distributionManagement>
+
+ <repositories>
+ <repository>
+ <id>releases</id>
+ <name>CRISTAL Nexus Release Repository</name>
+ <url>http://cristal.cccs.uwe.ac.uk:8081/nexus/content/repositories/releases</url>
+ <releases>
+ <enabled>true</enabled>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>snapshots</id>
+ <name>CRISTAL Nexus Snapshot Repository</name>
+ <url>http://cristal.cccs.uwe.ac.uk:8081/nexus/content/repositories/snapshots</url>
+ <releases>
+ <enabled>false</enabled>
+ </releases>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>public</id>
+ <name>CRISTAL Nexus Public Repository</name>
+ <url>http://cristal.cccs.uwe.ac.uk:8081/nexus/content/repositories/public</url>
+ </repository>
+ </repositories>
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>cristal</groupId>
+ <artifactId>cristal-kernel</artifactId>
+ <version>2.3.3-SNAPSHOT</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>cristal</groupId>
+ <artifactId>cristal-kernel</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.exist-db</groupId>
+ <artifactId>exist</artifactId>
+ <version>1.4.3</version>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file diff --git a/src/main/java/com/c2kernel/persistency/XMLDBClusterStorage.java b/src/main/java/com/c2kernel/persistency/XMLDBClusterStorage.java new file mode 100644 index 0000000..157f7c6 --- /dev/null +++ b/src/main/java/com/c2kernel/persistency/XMLDBClusterStorage.java @@ -0,0 +1,261 @@ +/*
+ * XMLDbClusterStorage.java
+ *
+ * Copyright (c) 2012, The CRISTAL Consortium. All rights reserved.
+ *
+ * CRISTAL kernel 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; without 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, see:
+ * http://www.gnu.org/licenses/
+ */
+
+package com.c2kernel.persistency;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.exist.xmldb.DatabaseInstanceManager;
+import org.xmldb.api.DatabaseManager;
+import org.xmldb.api.base.Collection;
+import org.xmldb.api.base.Database;
+import org.xmldb.api.base.ErrorCodes;
+import org.xmldb.api.base.Resource;
+import org.xmldb.api.base.Service;
+import org.xmldb.api.base.XMLDBException;
+import org.xmldb.api.modules.CollectionManagementService;
+
+import com.c2kernel.entity.C2KLocalObject;
+import com.c2kernel.persistency.outcome.Outcome;
+import com.c2kernel.process.Gateway;
+import com.c2kernel.utils.Logger;
+
+public class XMLDBClusterStorage extends ClusterStorage {
+
+ Database database;
+ Collection db;
+
+ public XMLDBClusterStorage() throws Exception {
+
+ }
+
+ private Collection verifyCollection(Collection parent, String name, boolean create) throws ClusterStorageException {
+ Collection coll;
+ try {
+ coll = parent.getChildCollection(name);
+ if (coll == null)
+ throw new XMLDBException(ErrorCodes.NO_SUCH_COLLECTION);
+ } catch (XMLDBException ex) {
+ if (ex.errorCode == ErrorCodes.NO_SUCH_COLLECTION) {
+ if (create) {
+ try {
+ CollectionManagementService collManager = (CollectionManagementService)parent.getService("CollectionManagementService", "1.0");
+ coll = collManager.createCollection(name);
+ } catch (Exception ex2) {
+ throw new ClusterStorageException("Could not create XMLDB collection for item "+name);
+ }
+ }
+ else // not found
+ return null;
+ }
+ else {
+ Logger.error(ex);
+ throw new ClusterStorageException("Error loading XMLDB collection for item "+name);
+ }
+ }
+ return coll;
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#open()
+ */
+ @Override
+ public void open() throws ClusterStorageException {
+
+ final String driver = "org.exist.xmldb.DatabaseImpl";
+ // Uncomment the following for integrated existdb
+ //System.setProperty("exist.initdb", "true");
+ //System.setProperty("exist.home", Gateway.getProperty("XMLDB.home"));
+ try {
+ Class<?> cl = Class.forName(driver);
+ database = (Database) cl.newInstance();
+ database.setProperty("create-database", "true");
+ DatabaseManager.registerDatabase(database);
+ db = DatabaseManager.getCollection(Gateway.getProperty("XMLDB.URI"), Gateway.getProperty("XMLDB.user"), Gateway.getProperty("XMLDB.password"));
+ } catch (Exception ex) {
+ Logger.error(ex);
+ throw new ClusterStorageException("Error initializing XMLDB");
+ }
+
+ if (db == null)
+ throw new ClusterStorageException("Root collection is null. Problem connecting to XMLDB.");
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#close()
+ */
+ @Override
+ public void close() throws ClusterStorageException {
+ try {
+ db.close();
+ //DatabaseInstanceManager manager = (DatabaseInstanceManager)db.getService("DatabaseInstanceManager", "1.0");
+ //manager.shutdown();
+ } catch (XMLDBException e) {
+ Logger.error(e);
+ throw new ClusterStorageException("Error shutting down eXist XMLDB");
+ }
+
+
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#queryClusterSupport(java.lang.String)
+ */
+ @Override
+ public short queryClusterSupport(String clusterType) {
+ return READWRITE;
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#getName()
+ */
+ @Override
+ public String getName() {
+ // TODO Auto-generated method stub
+ return "XMLDB";
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#getId()
+ */
+ @Override
+ public String getId() {
+ // TODO Auto-generated method stub
+ return "XMLDB";
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#get(java.lang.Integer, java.lang.String)
+ */
+ @Override
+ public C2KLocalObject get(Integer sysKey, String path)
+ throws ClusterStorageException {
+ String type = ClusterStorage.getClusterType(path);
+ // Get item collection
+ String strSysKey = String.valueOf(sysKey);
+ Collection itemColl = verifyCollection(db, strSysKey, false);
+ if (itemColl == null) return null; // doesn't exist
+
+ try {
+ String resource = path.replace('/', '.');
+ String objString = (String)itemColl.getResource(resource).getContent();
+ itemColl.close();
+ if (type.equals("Outcome"))
+ return new Outcome(path, objString);
+ else {
+ C2KLocalObject obj = (C2KLocalObject)Gateway.getMarshaller().unmarshall(objString);
+ return obj;
+ }
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new ClusterStorageException("XMLDB error");
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#put(java.lang.Integer, com.c2kernel.entity.C2KLocalObject)
+ */
+ @Override
+ public void put(Integer sysKey, C2KLocalObject obj)
+ throws ClusterStorageException {
+
+ String resName = getPath(obj);
+ String type = obj.getClusterType();
+ String strSysKey = String.valueOf(sysKey);
+ Collection itemColl = verifyCollection(db, strSysKey, true);
+
+ try {
+ resName = resName.replace('/', '.');
+ String objString = Gateway.getMarshaller().marshall(obj);
+ Resource res = itemColl.getResource(resName);
+ if (res == null)
+ res = itemColl.createResource(resName, "XMLResource");
+ res.setContent(objString);
+ itemColl.storeResource(res);
+ itemColl.close();
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new ClusterStorageException("XMLDB error");
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#delete(java.lang.Integer, java.lang.String)
+ */
+ @Override
+ public void delete(Integer sysKey, String path)
+ throws ClusterStorageException {
+ String type = ClusterStorage.getClusterType(path);
+ String strSysKey = String.valueOf(sysKey);
+ Collection itemColl = verifyCollection(db, strSysKey, false);
+ if (itemColl == null) return;
+
+
+ try {
+ String resource = path.replace('/', '.');
+ Resource res = itemColl.getResource(resource);
+ if (res != null) itemColl.removeResource(res);
+ itemColl.close(); itemColl.close();
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new ClusterStorageException("XMLClusterStorage.delete() - Could not delete "+path+" to "+sysKey);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#getClusterContents(java.lang.Integer, java.lang.String)
+ */
+ @Override
+ public String[] getClusterContents(Integer sysKey, String path)
+ throws ClusterStorageException {
+ String type = ClusterStorage.getClusterType(path);
+ String strSysKey = String.valueOf(sysKey);
+ Collection coll = verifyCollection(db, strSysKey, false);
+ if (coll == null) return new String[0];
+
+ ArrayList<String> contents = new ArrayList<String>();
+
+ // Find prefix for our path level
+ StringBuffer resPrefix = new StringBuffer();
+ String[] pathComps = path.split("/");
+ if (pathComps.length > 1)
+ for (int i = 0; i < pathComps.length; i++) {
+ if (pathComps[i].length()>0) resPrefix.append(pathComps[i]).append(".");
+ }
+
+ // Look at each entry for matches. Trim off the ends.
+ try {
+ for (String res: coll.listResources()) {
+ if (res.startsWith(resPrefix.toString())) {
+ String resName = res.substring(resPrefix.length());
+ if (resName.indexOf('.')>-1)
+ resName = resName.substring(0, resName.indexOf('.'));
+ contents.add(resName);
+ }
+ }
+ } catch (XMLDBException e) {
+ Logger.error(e);
+ throw new ClusterStorageException("Error listing collection resources for item "+strSysKey);
+ }
+ return contents.toArray(new String[contents.size()]);
+ }
+
+}
diff --git a/src/main/java/com/c2kernel/persistency/XMLDBSyskeyTypeClusterStorage.java b/src/main/java/com/c2kernel/persistency/XMLDBSyskeyTypeClusterStorage.java new file mode 100644 index 0000000..8e02468 --- /dev/null +++ b/src/main/java/com/c2kernel/persistency/XMLDBSyskeyTypeClusterStorage.java @@ -0,0 +1,283 @@ +/*
+ * XMLDbClusterStorage.java
+ *
+ * Copyright (c) 2012, The CRISTAL Consortium. All rights reserved.
+ *
+ * CRISTAL kernel 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; without 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, see:
+ * http://www.gnu.org/licenses/
+ */
+
+package com.c2kernel.persistency;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.exist.xmldb.DatabaseInstanceManager;
+import org.xmldb.api.DatabaseManager;
+import org.xmldb.api.base.Collection;
+import org.xmldb.api.base.Database;
+import org.xmldb.api.base.ErrorCodes;
+import org.xmldb.api.base.Resource;
+import org.xmldb.api.base.Service;
+import org.xmldb.api.base.XMLDBException;
+import org.xmldb.api.modules.CollectionManagementService;
+
+import com.c2kernel.entity.C2KLocalObject;
+import com.c2kernel.persistency.outcome.Outcome;
+import com.c2kernel.process.Gateway;
+import com.c2kernel.utils.Logger;
+
+public class XMLDBSyskeyTypeClusterStorage extends ClusterStorage {
+
+ Database database;
+ Collection db;
+
+ public XMLDBSyskeyTypeClusterStorage() throws Exception {
+
+ }
+
+ private Collection verifyCollection(Collection parent, String name, boolean create) throws ClusterStorageException {
+ Collection coll;
+ try {
+ coll = parent.getChildCollection(name);
+ if (coll == null)
+ throw new XMLDBException(ErrorCodes.NO_SUCH_COLLECTION);
+ } catch (XMLDBException ex) {
+ if (ex.errorCode == ErrorCodes.NO_SUCH_COLLECTION) {
+ if (create) {
+ try {
+ CollectionManagementService collManager = (CollectionManagementService)parent.getService("CollectionManagementService", "1.0");
+ coll = collManager.createCollection(name);
+ } catch (Exception ex2) {
+ throw new ClusterStorageException("Could not create XMLDB collection for item "+name);
+ }
+ }
+ else // not found
+ return null;
+ }
+ else {
+ Logger.error(ex);
+ throw new ClusterStorageException("Error loading XMLDB collection for item "+name);
+ }
+ }
+ return coll;
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#open()
+ */
+ @Override
+ public void open() throws ClusterStorageException {
+
+ final String driver = "org.exist.xmldb.DatabaseImpl";
+ // Uncomment the following for integrated existdb
+ //System.setProperty("exist.initdb", "true");
+ //System.setProperty("exist.home", Gateway.getProperty("XMLDB.home"));
+ try {
+ Class<?> cl = Class.forName(driver);
+ database = (Database) cl.newInstance();
+ database.setProperty("create-database", "true");
+ DatabaseManager.registerDatabase(database);
+ db = DatabaseManager.getCollection(Gateway.getProperty("XMLDB.URI"), Gateway.getProperty("XMLDB.user"), Gateway.getProperty("XMLDB.password"));
+ } catch (Exception ex) {
+ Logger.error(ex);
+ throw new ClusterStorageException("Error initializing XMLDB");
+ }
+
+ if (db == null)
+ throw new ClusterStorageException("Root collection is null. Problem connecting to XMLDB.");
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#close()
+ */
+ @Override
+ public void close() throws ClusterStorageException {
+ try {
+ db.close();
+ //DatabaseInstanceManager manager = (DatabaseInstanceManager)db.getService("DatabaseInstanceManager", "1.0");
+ //manager.shutdown();
+ } catch (XMLDBException e) {
+ Logger.error(e);
+ throw new ClusterStorageException("Error shutting down eXist XMLDB");
+ }
+
+
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#queryClusterSupport(java.lang.String)
+ */
+ @Override
+ public short queryClusterSupport(String clusterType) {
+ return READWRITE;
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#getName()
+ */
+ @Override
+ public String getName() {
+ // TODO Auto-generated method stub
+ return "XMLDB";
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#getId()
+ */
+ @Override
+ public String getId() {
+ // TODO Auto-generated method stub
+ return "XMLDB";
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#get(java.lang.Integer, java.lang.String)
+ */
+ @Override
+ public C2KLocalObject get(Integer sysKey, String path)
+ throws ClusterStorageException {
+ String type = ClusterStorage.getClusterType(path);
+ // Get item collection
+ String strSysKey = String.valueOf(sysKey);
+ Collection itemColl = verifyCollection(db, strSysKey, false);
+ if (itemColl == null) return null; // doesn't exist
+ // Get type collection
+ Collection typeColl = verifyCollection(itemColl, type, false);
+ if (typeColl == null) return null; // doesn't exist
+
+ try {
+ String resource = path.substring(path.indexOf('/')+1).replace('/', '.');
+ String objString = (String)typeColl.getResource(resource).getContent();
+ typeColl.close(); itemColl.close();
+ if (type.equals("Outcome"))
+ return new Outcome(path, objString);
+ else {
+ C2KLocalObject obj = (C2KLocalObject)Gateway.getMarshaller().unmarshall(objString);
+ return obj;
+ }
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new ClusterStorageException("XMLDB error");
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#put(java.lang.Integer, com.c2kernel.entity.C2KLocalObject)
+ */
+ @Override
+ public void put(Integer sysKey, C2KLocalObject obj)
+ throws ClusterStorageException {
+
+ String resName = getPath(obj);
+ String type = obj.getClusterType();
+ String strSysKey = String.valueOf(sysKey);
+ Collection itemColl = verifyCollection(db, strSysKey, true);
+ Collection typeColl = verifyCollection(itemColl, type, true);
+
+ try {
+ resName = resName.substring(resName.indexOf('/')+1).replace('/', '.');
+ String objString = Gateway.getMarshaller().marshall(obj);
+ Resource res = typeColl.getResource(resName);
+ if (res == null)
+ res = typeColl.createResource(resName, "XMLResource");
+ res.setContent(objString);
+ typeColl.storeResource(res);
+ typeColl.close(); itemColl.close();
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new ClusterStorageException("XMLDB error");
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#delete(java.lang.Integer, java.lang.String)
+ */
+ @Override
+ public void delete(Integer sysKey, String path)
+ throws ClusterStorageException {
+ String type = ClusterStorage.getClusterType(path);
+ String strSysKey = String.valueOf(sysKey);
+ Collection itemColl = verifyCollection(db, strSysKey, false);
+ if (itemColl == null) return;
+ Collection typeColl = verifyCollection(itemColl, type, false);
+ if (typeColl == null) return;
+
+ try {
+ String resource = path.substring(path.indexOf('/')+1).replace('/', '.');
+ Resource res = typeColl.getResource(resource);
+ if (res != null) typeColl.removeResource(res);
+ typeColl.close(); itemColl.close();
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new ClusterStorageException("XMLClusterStorage.delete() - Could not delete "+path+" to "+sysKey);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#getClusterContents(java.lang.Integer, java.lang.String)
+ */
+ @Override
+ public String[] getClusterContents(Integer sysKey, String path)
+ throws ClusterStorageException {
+ String type = ClusterStorage.getClusterType(path);
+ String strSysKey = String.valueOf(sysKey);
+ Collection coll = verifyCollection(db, strSysKey, false);
+ if (coll == null) return new String[0];
+
+ ArrayList<String> contents = new ArrayList<String>();
+
+ // If it's the root, list the child collections
+ if (type.equals(ClusterStorage.ROOT)) {
+ try {
+ for (String childName : coll.listChildCollections()) {
+ contents.add(childName);
+ }
+ } catch (XMLDBException ex) {
+ Logger.error(ex);
+ throw new ClusterStorageException("Error finding collection contents for item "+strSysKey);
+ }
+
+ return contents.toArray(new String[contents.size()]);
+ }
+
+ coll = verifyCollection(coll, type, false);
+ if (coll == null) return new String[0];
+
+ // Find prefix for our path level
+ StringBuffer resPrefix = new StringBuffer();
+ String[] pathComps = path.split("/");
+ if (pathComps.length > 1)
+ for (int i = 1; i < pathComps.length; i++) {
+ if (pathComps[i].length()>0) resPrefix.append(pathComps[i]).append(".");
+ }
+
+ // Look at each entry for matches. Trim off the ends.
+ try {
+ for (String res: coll.listResources()) {
+ if (res.startsWith(resPrefix.toString())) {
+ String resName = res.substring(resPrefix.length());
+ if (resName.indexOf('.')>-1)
+ resName = resName.substring(0, resName.indexOf('.'));
+ contents.add(resName);
+ }
+ }
+ } catch (XMLDBException e) {
+ Logger.error(e);
+ throw new ClusterStorageException("Error listing collection resources for item "+strSysKey);
+ }
+ return contents.toArray(new String[contents.size()]);
+ }
+
+}
diff --git a/src/main/java/com/c2kernel/persistency/XMLDBTypeSyskeyCollClusterStorage.java b/src/main/java/com/c2kernel/persistency/XMLDBTypeSyskeyCollClusterStorage.java new file mode 100644 index 0000000..7d625f8 --- /dev/null +++ b/src/main/java/com/c2kernel/persistency/XMLDBTypeSyskeyCollClusterStorage.java @@ -0,0 +1,279 @@ +/*
+ * XMLDbClusterStorage.java
+ *
+ * Copyright (c) 2012, The CRISTAL Consortium. All rights reserved.
+ *
+ * CRISTAL kernel 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; without 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, see:
+ * http://www.gnu.org/licenses/
+ */
+
+package com.c2kernel.persistency;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.exist.xmldb.DatabaseInstanceManager;
+import org.xmldb.api.DatabaseManager;
+import org.xmldb.api.base.Collection;
+import org.xmldb.api.base.Database;
+import org.xmldb.api.base.ErrorCodes;
+import org.xmldb.api.base.Resource;
+import org.xmldb.api.base.Service;
+import org.xmldb.api.base.XMLDBException;
+import org.xmldb.api.modules.CollectionManagementService;
+
+import com.c2kernel.entity.C2KLocalObject;
+import com.c2kernel.persistency.outcome.Outcome;
+import com.c2kernel.process.Gateway;
+import com.c2kernel.utils.Logger;
+
+public class XMLDBTypeSyskeyCollClusterStorage extends ClusterStorage {
+
+ Database database;
+ Collection db;
+ HashMap<String, Collection> rootCollections = new HashMap<String, Collection>();
+
+ public XMLDBTypeSyskeyCollClusterStorage() throws Exception {
+
+ }
+
+ private Collection verifyCollection(Collection parent, String name, boolean create) throws ClusterStorageException {
+ Collection coll;
+ try {
+ coll = parent.getChildCollection(name);
+ if (coll == null)
+ throw new XMLDBException(ErrorCodes.NO_SUCH_COLLECTION);
+ } catch (XMLDBException ex) {
+ if (ex.errorCode == ErrorCodes.NO_SUCH_COLLECTION) {
+ if (create) {
+ try {
+ CollectionManagementService collManager = (CollectionManagementService)parent.getService("CollectionManagementService", "1.0");
+ coll = collManager.createCollection(name);
+ } catch (Exception ex2) {
+ throw new ClusterStorageException("Could not create XMLDB collection for item "+name);
+ }
+ }
+ else // not found
+ return null;
+ }
+ else {
+ Logger.error(ex);
+ throw new ClusterStorageException("Error loading XMLDB collection for item "+name);
+ }
+ }
+ return coll;
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#open()
+ */
+ @Override
+ public void open() throws ClusterStorageException {
+
+ final String driver = "org.exist.xmldb.DatabaseImpl";
+ // Uncomment the following for integrated existdb
+ //System.setProperty("exist.initdb", "true");
+ //System.setProperty("exist.home", Gateway.getProperty("XMLDB.home"));
+ try {
+ Class<?> cl = Class.forName(driver);
+ database = (Database) cl.newInstance();
+ database.setProperty("create-database", "true");
+ DatabaseManager.registerDatabase(database);
+ db = DatabaseManager.getCollection(Gateway.getProperty("XMLDB.URI"), Gateway.getProperty("XMLDB.user"), Gateway.getProperty("XMLDB.password"));
+ } catch (Exception ex) {
+ Logger.error(ex);
+ throw new ClusterStorageException("Error initializing XMLDB");
+ }
+
+ if (db == null)
+ throw new ClusterStorageException("Root collection is null. Problem connecting to XMLDB.");
+
+ // Get all cluster root collections
+ for (String cluster : allClusterTypes) {
+ rootCollections.put(cluster, verifyCollection(db, cluster, true));
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#close()
+ */
+ @Override
+ public void close() throws ClusterStorageException {
+ try {
+ db.close();
+ //DatabaseInstanceManager manager = (DatabaseInstanceManager)db.getService("DatabaseInstanceManager", "1.0");
+ //manager.shutdown();
+ } catch (XMLDBException e) {
+ Logger.error(e);
+ throw new ClusterStorageException("Error shutting down eXist XMLDB");
+ }
+
+
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#queryClusterSupport(java.lang.String)
+ */
+ @Override
+ public short queryClusterSupport(String clusterType) {
+ return READWRITE;
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#getName()
+ */
+ @Override
+ public String getName() {
+ // TODO Auto-generated method stub
+ return "XMLDB";
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#getId()
+ */
+ @Override
+ public String getId() {
+ // TODO Auto-generated method stub
+ return "XMLDB";
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#get(java.lang.Integer, java.lang.String)
+ */
+ @Override
+ public C2KLocalObject get(Integer sysKey, String path)
+ throws ClusterStorageException {
+ String type = ClusterStorage.getClusterType(path);
+ String strSysKey = String.valueOf(sysKey);
+ Collection coll = verifyCollection(rootCollections.get(type), strSysKey, false);
+ if (coll == null) return null; // doesn't exist
+
+ try {
+ String resource = path.substring(path.indexOf('/')+1).replace('/', '.');
+ String objString = (String)coll.getResource(resource).getContent();
+ coll.close();
+ if (type.equals("Outcome"))
+ return new Outcome(path, objString);
+ else {
+ C2KLocalObject obj = (C2KLocalObject)Gateway.getMarshaller().unmarshall(objString);
+ return obj;
+ }
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new ClusterStorageException("XMLDB error");
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#put(java.lang.Integer, com.c2kernel.entity.C2KLocalObject)
+ */
+ @Override
+ public void put(Integer sysKey, C2KLocalObject obj)
+ throws ClusterStorageException {
+
+ String resName = getPath(obj);
+ String type = obj.getClusterType();
+ String strSysKey = String.valueOf(sysKey);
+ Collection coll = verifyCollection(rootCollections.get(type), strSysKey, true);
+
+ try {
+ resName = resName.substring(resName.indexOf('/')+1).replace('/', '.');
+ String objString = Gateway.getMarshaller().marshall(obj);
+ Resource res = coll.getResource(resName);
+ if (res == null)
+ res = coll.createResource(resName, "XMLResource");
+ res.setContent(objString);
+ coll.storeResource(res);
+ coll.close();
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new ClusterStorageException("XMLDB error");
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#delete(java.lang.Integer, java.lang.String)
+ */
+ @Override
+ public void delete(Integer sysKey, String path)
+ throws ClusterStorageException {
+ String type = ClusterStorage.getClusterType(path);
+ String strSysKey = String.valueOf(sysKey);
+ Collection coll = verifyCollection(rootCollections.get(type), strSysKey, false);
+ if (coll == null) return;
+
+ try {
+ String resource = path.substring(path.indexOf('/')+1).replace('/', '.');
+ Resource res = coll.getResource(resource);
+ if (res != null) coll.removeResource(res);
+ coll.close();
+ } catch (Exception e) {
+ Logger.error(e);
+ throw new ClusterStorageException("XMLClusterStorage.delete() - Could not delete "+path+" to "+sysKey);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see com.c2kernel.persistency.ClusterStorage#getClusterContents(java.lang.Integer, java.lang.String)
+ */
+ @Override
+ public String[] getClusterContents(Integer sysKey, String path)
+ throws ClusterStorageException {
+ String type = ClusterStorage.getClusterType(path);
+ String strSysKey = String.valueOf(sysKey);
+ ArrayList<String> contents = new ArrayList<String>();
+
+ if (type.equals(ClusterStorage.ROOT)) { // list rootColls this item appears in
+ for (Collection rootColl : rootCollections.values()) {
+ try {
+ for (String childName : rootColl.listChildCollections()) {
+ if (childName.equals(strSysKey))
+ contents.add(rootColl.getName());
+ }
+ } catch (XMLDBException ex) {
+ Logger.error(ex);
+ throw new ClusterStorageException("Error finding root collections for item "+strSysKey);
+ }
+
+ }
+ return contents.toArray(new String[contents.size()]);
+ }
+
+
+ Collection itemColl = verifyCollection(rootCollections.get(type), strSysKey, false);
+ if (itemColl == null) return new String[0];
+ StringBuffer resPrefix = new StringBuffer();
+ String[] pathComps = path.split("/");
+ if (pathComps.length > 1)
+ for (int i = 1; i < pathComps.length; i++) {
+ if (pathComps[i].length()>0) resPrefix.append(pathComps[i]).append(".");
+ }
+
+ try {
+ for (String res: itemColl.listResources()) {
+ if (res.startsWith(resPrefix.toString())) {
+ String resName = res.substring(resPrefix.length());
+ if (resName.indexOf('.')>-1)
+ resName = resName.substring(0, resName.indexOf('.'));
+ contents.add(resName);
+ }
+ }
+ } catch (XMLDBException e) {
+ Logger.error(e);
+ throw new ClusterStorageException("Error listing collection resources for item "+strSysKey);
+ }
+ return contents.toArray(new String[contents.size()]);
+ }
+
+}
diff --git a/src/main/resources/module.xml b/src/main/resources/module.xml new file mode 100644 index 0000000..33219c7 --- /dev/null +++ b/src/main/resources/module.xml @@ -0,0 +1,11 @@ +<CristalModule ns="xmldb" name="xmldb">
+ <Info>
+ <Description>CRISTAL XMLDB Module using eXistDB</Description>
+ <Version>0.0.1-SNAPSHOT</Version>
+ </Info>
+ <Config name="Module.debug">true</Config>
+ <Config name="XMLDB.URI">xmldb:exist:///db</Config>
+ <Config name="XMLDB.user">admin</Config>
+ <Config name="XMLDB.password">admin</Config>
+ <Imports/>
+</CristalModule>
\ No newline at end of file |
