You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by st...@apache.org on 2012/03/01 13:41:22 UTC
svn commit: r1295539 - in
/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store:
./ pm/
Author: stefan
Date: Thu Mar 1 12:41:21 2012
New Revision: 1295539
URL: http://svn.apache.org/viewvc?rev=1295539&view=rev
Log:
some minor refactoring
Added:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/BDbPersistenceManager.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/FSPersistenceManager.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/H2PersistenceManager.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/InMemPersistenceManager.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/MongoPersistenceManager.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/PersistenceManager.java
Removed:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/BDbPersistenceManager.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/FSPersistenceManager.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/H2PersistenceManager.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/InMemPersistenceManager.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/MongoPersistenceManager.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/PersistenceManager.java
Modified:
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java
jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/IdFactory.java
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java?rev=1295539&r1=1295538&r2=1295539&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/DefaultRevisionStore.java Thu Mar 1 12:41:21 2012
@@ -25,6 +25,8 @@ import org.apache.jackrabbit.mk.model.No
import org.apache.jackrabbit.mk.model.MutableNode;
import org.apache.jackrabbit.mk.model.StoredCommit;
import org.apache.jackrabbit.mk.model.StoredNode;
+import org.apache.jackrabbit.mk.store.pm.H2PersistenceManager;
+import org.apache.jackrabbit.mk.store.pm.PersistenceManager;
import org.apache.jackrabbit.mk.util.SimpleLRUCache;
import java.io.File;
Modified: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/IdFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/IdFactory.java?rev=1295539&r1=1295538&r2=1295539&view=diff
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/IdFactory.java (original)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/IdFactory.java Thu Mar 1 12:41:21 2012
@@ -23,7 +23,7 @@ import org.apache.jackrabbit.mk.util.Asc
/**
* Create new commit and internal content object ids based on serialized data.
*/
-abstract class IdFactory {
+public abstract class IdFactory {
/**
* Creates a new id based on the specified serialized data.
Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/BDbPersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/BDbPersistenceManager.java?rev=1295539&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/BDbPersistenceManager.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/BDbPersistenceManager.java Thu Mar 1 12:41:21 2012
@@ -0,0 +1,194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.jackrabbit.mk.store.pm;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+import org.apache.jackrabbit.mk.model.ChildNodeEntriesMap;
+import org.apache.jackrabbit.mk.model.Commit;
+import org.apache.jackrabbit.mk.model.Node;
+import org.apache.jackrabbit.mk.model.StoredCommit;
+import org.apache.jackrabbit.mk.store.BinaryBinding;
+import org.apache.jackrabbit.mk.store.Binding;
+import org.apache.jackrabbit.mk.store.IdFactory;
+import org.apache.jackrabbit.mk.store.NotFoundException;
+import org.apache.jackrabbit.mk.util.StringUtils;
+
+import com.sleepycat.je.Database;
+import com.sleepycat.je.DatabaseConfig;
+import com.sleepycat.je.DatabaseEntry;
+import com.sleepycat.je.Durability;
+import com.sleepycat.je.Environment;
+import com.sleepycat.je.EnvironmentConfig;
+import com.sleepycat.je.EnvironmentMutableConfig;
+import com.sleepycat.je.LockMode;
+import com.sleepycat.je.OperationStatus;
+
+/**
+ *
+ */
+public class BDbPersistenceManager implements PersistenceManager {
+
+ private final static byte[] HEAD_ID = new byte[]{0};
+ private Environment dbEnv;
+ private Database db;
+ private Database head;
+
+ // TODO: make this configurable
+ private IdFactory idFactory = IdFactory.getDigestFactory();
+
+ public void initialize(File homeDir) throws Exception {
+ File dbDir = new File(homeDir, "db");
+ if (!dbDir.exists()) {
+ dbDir.mkdir();
+ }
+
+ EnvironmentConfig envConfig = new EnvironmentConfig();
+ //envConfig.setTransactional(true);
+ envConfig.setAllowCreate(true);
+ dbEnv = new Environment(dbDir, envConfig);
+
+ EnvironmentMutableConfig envMutableConfig = new EnvironmentMutableConfig();
+ //envMutableConfig.setDurability(Durability.COMMIT_SYNC);
+ //envMutableConfig.setDurability(Durability.COMMIT_NO_SYNC);
+ envMutableConfig.setDurability(Durability.COMMIT_WRITE_NO_SYNC);
+ dbEnv.setMutableConfig(envMutableConfig);
+
+ DatabaseConfig dbConfig = new DatabaseConfig();
+ dbConfig.setAllowCreate(true);
+ //dbConfig.setDeferredWrite(true);
+ db = dbEnv.openDatabase(null, "revs", dbConfig);
+
+ head = dbEnv.openDatabase(null, "head", dbConfig);
+
+ // TODO FIXME workaround in case we're not closed properly
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ public void run() {
+ try { close(); } catch (Throwable ignore) {}
+ }
+ });
+ }
+
+ public void close() {
+ try {
+ if (db.getConfig().getDeferredWrite()) {
+ db.sync();
+ }
+ db.close();
+ head.close();
+ dbEnv.close();
+
+ db = null;
+ dbEnv = null;
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ public String readHead() throws Exception {
+ DatabaseEntry key = new DatabaseEntry(HEAD_ID);
+ DatabaseEntry data = new DatabaseEntry();
+
+ if (head.get(null, key, data, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
+ return StringUtils.convertBytesToHex(data.getData());
+ } else {
+ return null;
+ }
+ }
+
+ public void writeHead(String id) throws Exception {
+ DatabaseEntry key = new DatabaseEntry(HEAD_ID);
+ DatabaseEntry data = new DatabaseEntry(StringUtils.convertHexToBytes(id));
+
+ head.put(null, key, data);
+ }
+
+ public Binding readNodeBinding(String id) throws NotFoundException, Exception {
+ DatabaseEntry key = new DatabaseEntry(StringUtils.convertHexToBytes(id));
+ DatabaseEntry data = new DatabaseEntry();
+
+ if (db.get(null, key, data, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
+ ByteArrayInputStream in = new ByteArrayInputStream(data.getData());
+ return new BinaryBinding(in);
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String writeNode(Node node) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ node.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ byte[] rawId = idFactory.createContentId(bytes);
+ return persist(bytes, rawId);
+ }
+
+ public StoredCommit readCommit(String id) throws NotFoundException, Exception {
+ DatabaseEntry key = new DatabaseEntry(StringUtils.convertHexToBytes(id));
+ DatabaseEntry data = new DatabaseEntry();
+
+ if (db.get(null, key, data, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
+ ByteArrayInputStream in = new ByteArrayInputStream(data.getData());
+ return StoredCommit.deserialize(id, new BinaryBinding(in));
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String writeCommit(Commit commit) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ commit.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ byte[] rawId = idFactory.createCommitId(bytes);
+ return persist(bytes, rawId);
+ }
+
+ public ChildNodeEntriesMap readCNEMap(String id) throws NotFoundException, Exception {
+ DatabaseEntry key = new DatabaseEntry(StringUtils.convertHexToBytes(id));
+ DatabaseEntry data = new DatabaseEntry();
+
+ if (db.get(null, key, data, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
+ ByteArrayInputStream in = new ByteArrayInputStream(data.getData());
+ return ChildNodeEntriesMap.deserialize(new BinaryBinding(in));
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String writeCNEMap(ChildNodeEntriesMap map) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ map.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ byte[] rawId = idFactory.createContentId(bytes);
+ return persist(bytes, rawId);
+ }
+
+ //-------------------------------------------------------< implementation >
+
+ protected String persist(byte[] bytes, byte[] rawId) throws Exception {
+ String id = StringUtils.convertBytesToHex(rawId);
+
+ DatabaseEntry key = new DatabaseEntry(rawId);
+ DatabaseEntry data = new DatabaseEntry(bytes);
+
+ db.put(null, key, data);
+
+ return id;
+ }
+}
Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/FSPersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/FSPersistenceManager.java?rev=1295539&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/FSPersistenceManager.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/FSPersistenceManager.java Thu Mar 1 12:41:21 2012
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.jackrabbit.mk.store.pm;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+
+import org.apache.jackrabbit.mk.model.ChildNodeEntriesMap;
+import org.apache.jackrabbit.mk.model.Commit;
+import org.apache.jackrabbit.mk.model.Node;
+import org.apache.jackrabbit.mk.model.StoredCommit;
+import org.apache.jackrabbit.mk.store.BinaryBinding;
+import org.apache.jackrabbit.mk.store.Binding;
+import org.apache.jackrabbit.mk.store.IdFactory;
+import org.apache.jackrabbit.mk.store.NotFoundException;
+import org.apache.jackrabbit.mk.util.IOUtils;
+import org.apache.jackrabbit.mk.util.StringUtils;
+
+/**
+ *
+ */
+public class FSPersistenceManager implements PersistenceManager {
+
+ private File dataDir;
+ private File head;
+
+ // TODO: make this configurable
+ private IdFactory idFactory = IdFactory.getDigestFactory();
+
+ public void initialize(File homeDir) throws Exception {
+ dataDir = new File(homeDir, "data");
+ if (!dataDir.exists()) {
+ dataDir.mkdir();
+ }
+ head = new File(homeDir, "HEAD");
+ if (!head.exists()) {
+ writeHead("");
+ }
+ }
+
+ public void close() {
+ }
+
+ public String readHead() throws Exception {
+ FileInputStream in = new FileInputStream(head);
+ try {
+ return IOUtils.readString(in);
+ } finally {
+ in.close();
+ }
+ }
+
+ public void writeHead(String id) throws Exception {
+ FileOutputStream out = new FileOutputStream(head);
+ try {
+ IOUtils.writeString(out, id);
+ } finally {
+ out.close();
+ }
+ }
+
+ public Binding readNodeBinding(String id) throws NotFoundException, Exception {
+ File f = getFile(id);
+ if (f.exists()) {
+ BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
+ try {
+ return new BinaryBinding(in);
+ } finally {
+ in.close();
+ }
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String writeNode(Node node) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ node.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ byte[] rawId = idFactory.createContentId(bytes);
+ return writeFile(bytes, rawId);
+ }
+
+ public StoredCommit readCommit(String id) throws NotFoundException, Exception {
+ File f = getFile(id);
+ if (f.exists()) {
+ BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
+ try {
+ return StoredCommit.deserialize(id, new BinaryBinding(in));
+ } finally {
+ in.close();
+ }
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String writeCommit(Commit commit) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ commit.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ byte[] rawId = idFactory.createCommitId(bytes);
+ return writeFile(bytes, rawId);
+ }
+
+ public ChildNodeEntriesMap readCNEMap(String id) throws NotFoundException, Exception {
+ File f = getFile(id);
+ if (f.exists()) {
+ BufferedInputStream in = new BufferedInputStream(new FileInputStream(f));
+ try {
+ return ChildNodeEntriesMap.deserialize(new BinaryBinding(in));
+ } finally {
+ in.close();
+ }
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String writeCNEMap(ChildNodeEntriesMap map) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ map.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ byte[] rawId = idFactory.createContentId(bytes);
+ return writeFile(bytes, rawId);
+ }
+
+ //-------------------------------------------------------< implementation >
+
+ private File getFile(String id) {
+ StringBuilder buf = new StringBuilder(id.substring(0, 2));
+ buf.append('/');
+ buf.append(id.substring(2));
+ return new File(dataDir, buf.toString());
+ }
+
+ private String writeFile(byte[] data, byte[] rawId) throws Exception {
+ File tmp = File.createTempFile("tmp", null, dataDir);
+
+ try {
+ FileOutputStream fos = new FileOutputStream(tmp);
+
+ try {
+ fos.write(data);
+ } finally {
+ //fos.getChannel().force(true);
+ fos.close();
+ }
+
+ String id = StringUtils.convertBytesToHex(rawId);
+ File dst = getFile(id);
+ if (dst.exists()) {
+ // already exists
+ return id;
+ }
+ // move tmp file
+ tmp.setReadOnly();
+ if (tmp.renameTo(dst)) {
+ return id;
+ }
+ // make sure parent dir exists and try again
+ dst.getParentFile().mkdir();
+ if (tmp.renameTo(dst)) {
+ return id;
+ }
+ throw new Exception("failed to create " + dst);
+ } finally {
+ tmp.delete();
+ }
+ }
+}
Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/H2PersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/H2PersistenceManager.java?rev=1295539&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/H2PersistenceManager.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/H2PersistenceManager.java Thu Mar 1 12:41:21 2012
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.jackrabbit.mk.store.pm;
+
+import org.apache.jackrabbit.mk.model.ChildNodeEntriesMap;
+import org.apache.jackrabbit.mk.model.Commit;
+import org.apache.jackrabbit.mk.model.Node;
+import org.apache.jackrabbit.mk.model.StoredCommit;
+import org.apache.jackrabbit.mk.store.BinaryBinding;
+import org.apache.jackrabbit.mk.store.Binding;
+import org.apache.jackrabbit.mk.store.IdFactory;
+import org.apache.jackrabbit.mk.store.NotFoundException;
+import org.apache.jackrabbit.mk.util.StringUtils;
+import org.h2.jdbcx.JdbcConnectionPool;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+/**
+ *
+ */
+public class H2PersistenceManager implements PersistenceManager {
+
+ private static final boolean FAST = Boolean.getBoolean("mk.fastDb");
+
+ private JdbcConnectionPool cp;
+
+ // TODO: make this configurable
+ private IdFactory idFactory = IdFactory.getDigestFactory();
+
+ //---------------------------------------------------< PersistenceManager >
+
+ public void initialize(File homeDir) throws Exception {
+ File dbDir = new File(homeDir, "db");
+ if (!dbDir.exists()) {
+ dbDir.mkdir();
+ }
+
+ Class.forName("org.h2.Driver");
+ String url = "jdbc:h2:" + dbDir.getCanonicalPath() + "/revs";
+ if (FAST) {
+ url += ";log=0;undo_log=0";
+ }
+ cp = JdbcConnectionPool.create(url, "sa", "");
+ cp.setMaxConnections(40);
+ Connection con = cp.getConnection();
+ try {
+ Statement stmt = con.createStatement();
+ stmt.execute("create table if not exists REVS (ID binary primary key, DATA binary)");
+ stmt.execute("create table if not exists head(id varchar) as select ''");
+ stmt.execute("create sequence if not exists datastore_id");
+/*
+ DbBlobStore store = new DbBlobStore();
+ store.setConnectionPool(cp);
+ blobStore = store;
+*/
+ } finally {
+ con.close();
+ }
+ }
+
+ public void close() {
+ cp.dispose();
+ }
+
+ public String readHead() throws Exception {
+ Connection con = cp.getConnection();
+ try {
+ PreparedStatement stmt = con.prepareStatement("select * from head");
+ ResultSet rs = stmt.executeQuery();
+ String headId = null;
+ if (rs.next()) {
+ headId = rs.getString(1);
+ }
+ stmt.close();
+ return headId;
+ } finally {
+ con.close();
+ }
+ }
+
+ public void writeHead(String id) throws Exception {
+ Connection con = cp.getConnection();
+ try {
+ PreparedStatement stmt = con.prepareStatement("update head set id=?");
+ stmt.setString(1, id);
+ stmt.execute();
+ stmt.close();
+ } finally {
+ con.close();
+ }
+ }
+
+ public Binding readNodeBinding(String id) throws NotFoundException, Exception {
+ Connection con = cp.getConnection();
+ try {
+ PreparedStatement stmt = con.prepareStatement("select DATA from REVS where ID = ?");
+ try {
+ stmt.setBytes(1, StringUtils.convertHexToBytes(id));
+ ResultSet rs = stmt.executeQuery();
+ if (rs.next()) {
+ ByteArrayInputStream in = new ByteArrayInputStream(rs.getBytes(1));
+ return new BinaryBinding(in);
+ } else {
+ throw new NotFoundException(id);
+ }
+ } finally {
+ stmt.close();
+ }
+ } finally {
+ con.close();
+ }
+ }
+
+ public String writeNode(Node node) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ node.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ byte[] rawId = idFactory.createContentId(bytes);
+ String id = StringUtils.convertBytesToHex(rawId);
+
+ Connection con = cp.getConnection();
+ try {
+ PreparedStatement stmt = con
+ .prepareStatement(
+ "insert into REVS (ID, DATA) select ?, ? where not exists (select 1 from revs where ID = ?)");
+ try {
+ stmt.setBytes(1, rawId);
+ stmt.setBytes(2, bytes);
+ stmt.setBytes(3, rawId);
+ stmt.executeUpdate();
+ } finally {
+ stmt.close();
+ }
+ } finally {
+ con.close();
+ }
+ return id;
+ }
+
+ public StoredCommit readCommit(String id) throws NotFoundException, Exception {
+ Connection con = cp.getConnection();
+ try {
+ PreparedStatement stmt = con.prepareStatement("select DATA from REVS where ID = ?");
+ try {
+ stmt.setBytes(1, StringUtils.convertHexToBytes(id));
+ ResultSet rs = stmt.executeQuery();
+ if (rs.next()) {
+ ByteArrayInputStream in = new ByteArrayInputStream(rs.getBytes(1));
+ return StoredCommit.deserialize(id, new BinaryBinding(in));
+ } else {
+ throw new NotFoundException(id);
+ }
+ } finally {
+ stmt.close();
+ }
+ } finally {
+ con.close();
+ }
+ }
+
+ public String writeCommit(Commit commit) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ commit.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ byte[] rawId = idFactory.createCommitId(bytes);
+ String id = StringUtils.convertBytesToHex(rawId);
+
+ Connection con = cp.getConnection();
+ try {
+ PreparedStatement stmt = con
+ .prepareStatement(
+ "insert into REVS (ID, DATA) select ?, ? where not exists (select 1 from revs where ID = ?)");
+ try {
+ stmt.setBytes(1, rawId);
+ stmt.setBytes(2, bytes);
+ stmt.setBytes(3, rawId);
+ stmt.executeUpdate();
+ } finally {
+ stmt.close();
+ }
+ } finally {
+ con.close();
+ }
+ return id;
+ }
+
+ public ChildNodeEntriesMap readCNEMap(String id) throws NotFoundException, Exception {
+ Connection con = cp.getConnection();
+ try {
+ PreparedStatement stmt = con.prepareStatement("select DATA from REVS where ID = ?");
+ try {
+ stmt.setBytes(1, StringUtils.convertHexToBytes(id));
+ ResultSet rs = stmt.executeQuery();
+ if (rs.next()) {
+ ByteArrayInputStream in = new ByteArrayInputStream(rs.getBytes(1));
+ return ChildNodeEntriesMap.deserialize(new BinaryBinding(in));
+ } else {
+ throw new NotFoundException(id);
+ }
+ } finally {
+ stmt.close();
+ }
+ } finally {
+ con.close();
+ }
+ }
+
+ public String writeCNEMap(ChildNodeEntriesMap map) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ map.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ byte[] rawId = idFactory.createContentId(bytes);
+ String id = StringUtils.convertBytesToHex(rawId);
+
+ Connection con = cp.getConnection();
+ try {
+ PreparedStatement stmt = con
+ .prepareStatement(
+ "insert into REVS (ID, DATA) select ?, ? where not exists (select 1 from revs where ID = ?)");
+ try {
+ stmt.setBytes(1, rawId);
+ stmt.setBytes(2, bytes);
+ stmt.setBytes(3, rawId);
+ stmt.executeUpdate();
+ } finally {
+ stmt.close();
+ }
+ } finally {
+ con.close();
+ }
+ return id;
+ }
+}
\ No newline at end of file
Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/InMemPersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/InMemPersistenceManager.java?rev=1295539&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/InMemPersistenceManager.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/InMemPersistenceManager.java Thu Mar 1 12:41:21 2012
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.jackrabbit.mk.store.pm;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.jackrabbit.mk.blobs.BlobStore;
+import org.apache.jackrabbit.mk.blobs.MemoryBlobStore;
+import org.apache.jackrabbit.mk.model.ChildNodeEntriesMap;
+import org.apache.jackrabbit.mk.model.Commit;
+import org.apache.jackrabbit.mk.model.Node;
+import org.apache.jackrabbit.mk.model.StoredCommit;
+import org.apache.jackrabbit.mk.store.BinaryBinding;
+import org.apache.jackrabbit.mk.store.Binding;
+import org.apache.jackrabbit.mk.store.IdFactory;
+import org.apache.jackrabbit.mk.store.NotFoundException;
+import org.apache.jackrabbit.mk.util.StringUtils;
+
+/**
+ *
+ */
+public class InMemPersistenceManager implements PersistenceManager, BlobStore {
+
+ private final Map<String, byte[]> nodes = Collections.synchronizedMap(new HashMap<String, byte[]>());
+ private final Map<String, StoredCommit> commits = Collections.synchronizedMap(new HashMap<String, StoredCommit>());
+ private final Map<String, ChildNodeEntriesMap> cneMaps = Collections.synchronizedMap(new HashMap<String, ChildNodeEntriesMap>());
+ private final BlobStore blobs = new MemoryBlobStore();
+
+ private String head;
+
+ // TODO: make this configurable
+ private IdFactory idFactory = IdFactory.getDigestFactory();
+
+ public void initialize(File homeDir) throws Exception {
+ head = null;
+ }
+
+ public void close() {
+ }
+
+ public String readHead() throws Exception {
+ return head;
+ }
+
+ public void writeHead(String id) throws Exception {
+ head = id;
+ }
+
+ public Binding readNodeBinding(String id) throws NotFoundException, Exception {
+ byte[] bytes = nodes.get(id);
+ if (bytes != null) {
+ return new BinaryBinding(new ByteArrayInputStream(bytes));
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String writeNode(Node node) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ node.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ String id = StringUtils.convertBytesToHex(idFactory.createContentId(bytes));
+
+ if (!nodes.containsKey(id)) {
+ nodes.put(id, bytes);
+ }
+
+ return id;
+ }
+
+ public StoredCommit readCommit(String id) throws NotFoundException, Exception {
+ StoredCommit commit = commits.get(id);
+ if (commit != null) {
+ return commit;
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String writeCommit(Commit commit) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ commit.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ String id = StringUtils.convertBytesToHex(idFactory.createCommitId(bytes));
+
+ if (!commits.containsKey(id)) {
+ commits.put(id, StoredCommit.deserialize(id, new BinaryBinding(new ByteArrayInputStream(bytes))));
+ }
+
+ return id;
+ }
+
+ public ChildNodeEntriesMap readCNEMap(String id) throws NotFoundException, Exception {
+ ChildNodeEntriesMap map = cneMaps.get(id);
+ if (map != null) {
+ return map;
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String writeCNEMap(ChildNodeEntriesMap map) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ map.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ String id = StringUtils.convertBytesToHex(idFactory.createContentId(bytes));
+
+ if (!cneMaps.containsKey(id)) {
+ cneMaps.put(id, ChildNodeEntriesMap.deserialize(new BinaryBinding(new ByteArrayInputStream(bytes))));
+ }
+
+ return id;
+ }
+
+ //------------------------------------------------------------< BlobStore >
+
+ public String addBlob(String tempFilePath) throws Exception {
+ return blobs.addBlob(tempFilePath);
+ }
+
+ public String writeBlob(InputStream in) throws Exception {
+ return blobs.writeBlob(in);
+ }
+
+ public int readBlob(String blobId, long pos, byte[] buff, int off, int length) throws NotFoundException, Exception {
+ return blobs.readBlob(blobId, pos, buff, off, length);
+ }
+
+ public long getBlobLength(String blobId) throws Exception {
+ return blobs.getBlobLength(blobId);
+ }
+}
Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/MongoPersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/MongoPersistenceManager.java?rev=1295539&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/MongoPersistenceManager.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/MongoPersistenceManager.java Thu Mar 1 12:41:21 2012
@@ -0,0 +1,484 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.jackrabbit.mk.store.pm;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.util.Iterator;
+
+import org.apache.jackrabbit.mk.blobs.BlobStore;
+import org.apache.jackrabbit.mk.fs.FilePath;
+import org.apache.jackrabbit.mk.model.ChildNodeEntriesMap;
+import org.apache.jackrabbit.mk.model.Commit;
+import org.apache.jackrabbit.mk.model.Node;
+import org.apache.jackrabbit.mk.model.StoredCommit;
+import org.apache.jackrabbit.mk.store.BinaryBinding;
+import org.apache.jackrabbit.mk.store.Binding;
+import org.apache.jackrabbit.mk.store.IdFactory;
+import org.apache.jackrabbit.mk.store.NotFoundException;
+import org.apache.jackrabbit.mk.util.ExceptionFactory;
+import org.apache.jackrabbit.mk.util.IOUtils;
+import org.apache.jackrabbit.mk.util.StringUtils;
+import org.bson.types.ObjectId;
+
+import com.mongodb.BasicDBObject;
+import com.mongodb.DB;
+import com.mongodb.DBCollection;
+import com.mongodb.DBObject;
+import com.mongodb.Mongo;
+import com.mongodb.MongoException;
+import com.mongodb.WriteConcern;
+import com.mongodb.gridfs.GridFS;
+import com.mongodb.gridfs.GridFSDBFile;
+import com.mongodb.gridfs.GridFSInputFile;
+
+/**
+ *
+ */
+public class MongoPersistenceManager implements PersistenceManager, BlobStore {
+
+ private static final boolean BINARY_FORMAT = false;
+
+ private static final String HEAD_COLLECTION = "head";
+ private static final String NODES_COLLECTION = "nodes";
+ private static final String COMMITS_COLLECTION = "commits";
+ private static final String CNEMAPS_COLLECTION = "cneMaps";
+ private static final String ID_FIELD = ":id";
+ private static final String DATA_FIELD = ":data";
+
+ private Mongo con;
+ private DB db;
+ private DBCollection nodes;
+ private DBCollection commits;
+ private DBCollection cneMaps;
+ private GridFS fs;
+
+ // TODO: make this configurable
+ private IdFactory idFactory = IdFactory.getDigestFactory();
+
+ public void initialize(File homeDir) throws Exception {
+ con = new Mongo();
+ //con = new Mongo("localhost", 27017);
+
+ db = con.getDB("mk");
+ db.setWriteConcern(WriteConcern.SAFE);
+
+ if (!db.collectionExists(HEAD_COLLECTION)) {
+ // capped collection of size 1
+ db.createCollection(HEAD_COLLECTION, new BasicDBObject("capped", true).append("size", 256).append("max", 1));
+ }
+
+ nodes = db.getCollection(NODES_COLLECTION);
+ nodes.ensureIndex(
+ new BasicDBObject(ID_FIELD, 1),
+ new BasicDBObject("unique", true));
+
+ commits = db.getCollection(COMMITS_COLLECTION);
+ commits.ensureIndex(
+ new BasicDBObject(ID_FIELD, 1),
+ new BasicDBObject("unique", true));
+
+ cneMaps = db.getCollection(CNEMAPS_COLLECTION);
+ cneMaps.ensureIndex(
+ new BasicDBObject(ID_FIELD, 1),
+ new BasicDBObject("unique", true));
+
+ fs = new GridFS(db);
+ }
+
+ public void close() {
+ con.close();
+ con = null;
+ db = null;
+ }
+
+ public String readHead() throws Exception {
+ DBObject entry = db.getCollection(HEAD_COLLECTION).findOne();
+ if (entry == null) {
+ return null;
+ }
+ return (String) entry.get(ID_FIELD);
+ }
+
+ public void writeHead(String id) throws Exception {
+ // capped collection of size 1
+ db.getCollection(HEAD_COLLECTION).insert(new BasicDBObject(ID_FIELD, id));
+ }
+
+ public Binding readNodeBinding(String id) throws NotFoundException, Exception {
+ BasicDBObject key = new BasicDBObject();
+ if (BINARY_FORMAT) {
+ key.put(ID_FIELD, StringUtils.convertHexToBytes(id));
+ } else {
+ key.put(ID_FIELD, id);
+ }
+ final BasicDBObject nodeObject = (BasicDBObject) nodes.findOne(key);
+ if (nodeObject != null) {
+ // todo support partitioned child node lists
+ if (BINARY_FORMAT) {
+ byte[] bytes = (byte[]) nodeObject.get(DATA_FIELD);
+ return new BinaryBinding(new ByteArrayInputStream(bytes));
+ } else {
+ return new DBObjectBinding(nodeObject);
+ }
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String writeNode(Node node) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ node.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ byte[] key = idFactory.createContentId(bytes);
+ String id = StringUtils.convertBytesToHex(key);
+
+ // todo support partitioned child node lists
+ BasicDBObject nodeObject;
+ if (BINARY_FORMAT) {
+ nodeObject = new BasicDBObject(ID_FIELD, key).append(DATA_FIELD, bytes);
+ } else {
+ nodeObject = new BasicDBObject(ID_FIELD, id);
+ node.serialize(new DBObjectBinding(nodeObject));
+ }
+ try {
+ nodes.insert(nodeObject);
+ } catch (MongoException.DuplicateKey ignore) {
+ // fall through
+ }
+
+ return id;
+ }
+
+ public StoredCommit readCommit(String id) throws NotFoundException, Exception {
+ BasicDBObject key = new BasicDBObject();
+ if (BINARY_FORMAT) {
+ key.put(ID_FIELD, StringUtils.convertHexToBytes(id));
+ } else {
+ key.put(ID_FIELD, id);
+ }
+ BasicDBObject commitObject = (BasicDBObject) commits.findOne(key);
+ if (commitObject != null) {
+ if (BINARY_FORMAT) {
+ byte[] bytes = (byte[]) commitObject.get(DATA_FIELD);
+ return StoredCommit.deserialize(id, new BinaryBinding(new ByteArrayInputStream(bytes)));
+ } else {
+ return StoredCommit.deserialize(id, new DBObjectBinding(commitObject));
+ }
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String writeCommit(Commit commit) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ commit.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ byte[] key = idFactory.createCommitId(bytes);
+ String id = StringUtils.convertBytesToHex(key);
+
+ BasicDBObject commitObject;
+ if (BINARY_FORMAT) {
+ commitObject = new BasicDBObject(ID_FIELD, key).append(DATA_FIELD, bytes);
+ } else {
+ commitObject = new BasicDBObject(ID_FIELD, id);
+ commit.serialize(new DBObjectBinding(commitObject));
+ }
+ try {
+ commits.insert(commitObject);
+ } catch (MongoException.DuplicateKey ignore) {
+ // fall through
+ }
+
+ return id;
+ }
+
+ public ChildNodeEntriesMap readCNEMap(String id) throws NotFoundException, Exception {
+ BasicDBObject key = new BasicDBObject();
+ if (BINARY_FORMAT) {
+ key.put(ID_FIELD, StringUtils.convertHexToBytes(id));
+ } else {
+ key.put(ID_FIELD, id);
+ }
+ BasicDBObject mapObject = (BasicDBObject) cneMaps.findOne(key);
+ if (mapObject != null) {
+ if (BINARY_FORMAT) {
+ byte[] bytes = (byte[]) mapObject.get(DATA_FIELD);
+ return ChildNodeEntriesMap.deserialize(new BinaryBinding(new ByteArrayInputStream(bytes)));
+ } else {
+ return ChildNodeEntriesMap.deserialize(new DBObjectBinding(mapObject));
+ }
+ } else {
+ throw new NotFoundException(id);
+ }
+ }
+
+ public String writeCNEMap(ChildNodeEntriesMap map) throws Exception {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ map.serialize(new BinaryBinding(out));
+ byte[] bytes = out.toByteArray();
+ byte[] key = idFactory.createContentId(bytes);
+ String id = StringUtils.convertBytesToHex(key);
+
+ BasicDBObject mapObject;
+ if (BINARY_FORMAT) {
+ mapObject = new BasicDBObject(ID_FIELD, key).append(DATA_FIELD, bytes);
+ } else {
+ mapObject = new BasicDBObject(ID_FIELD, id);
+ map.serialize(new DBObjectBinding(mapObject));
+ }
+ try {
+ cneMaps.insert(mapObject);
+ } catch (MongoException.DuplicateKey ignore) {
+ // fall through
+ }
+
+ return id;
+ }
+
+ //------------------------------------------------------------< BlobStore >
+
+ public String addBlob(String tempFilePath) throws Exception {
+ try {
+ FilePath file = FilePath.get(tempFilePath);
+ try {
+ InputStream in = file.newInputStream();
+ return writeBlob(in);
+ } finally {
+ file.delete();
+ }
+ } catch (Exception e) {
+ throw ExceptionFactory.convert(e);
+ }
+ }
+
+ public String writeBlob(InputStream in) throws Exception {
+ GridFSInputFile f = fs.createFile(in, true);
+ //f.save(0x20000); // save in 128k chunks
+ f.save();
+
+ return f.getId().toString();
+ }
+
+ public int readBlob(String blobId, long pos, byte[] buff, int off,
+ int length) throws Exception {
+
+ GridFSDBFile f = fs.findOne(new ObjectId(blobId));
+ if (f == null) {
+ throw new NotFoundException(blobId);
+ }
+ // todo provide a more efficient implementation
+ InputStream in = f.getInputStream();
+ try {
+ in.skip(pos);
+ return in.read(buff, off, length);
+ } finally {
+ IOUtils.closeQuietly(in);
+ }
+ }
+
+ public long getBlobLength(String blobId) throws Exception {
+ GridFSDBFile f = fs.findOne(new ObjectId(blobId));
+ if (f == null) {
+ throw new NotFoundException(blobId);
+ }
+
+ return f.getLength();
+ }
+
+ //-------------------------------------------------------< implementation >
+
+ protected final static String ENCODED_DOT = "_x46_";
+ protected final static String ENCODED_DOLLAR_SIGN = "_x36_";
+
+ /**
+ * see http://www.mongodb.org/display/DOCS/Legal+Key+Names
+ *
+ * @param name
+ * @return
+ */
+ protected static String encodeName(String name) {
+ StringBuilder buf = null;
+ for (int i = 0; i < name.length(); i++) {
+ if (i == 0 && name.charAt(i) == '$') {
+ // mongodb field names must not start with '$'
+ buf = new StringBuilder();
+ buf.append(ENCODED_DOLLAR_SIGN);
+ } else if (name.charAt(i) == '.') {
+ // . is a reserved char for mongodb field names
+ if (buf == null) {
+ buf = new StringBuilder(name.substring(0, i));
+ }
+ buf.append(ENCODED_DOT);
+ } else {
+ if (buf != null) {
+ buf.append(name.charAt(i));
+ }
+ }
+ }
+
+ return buf == null ? name : buf.toString();
+ }
+
+ protected static String decodeName(String name) {
+ StringBuilder buf = null;
+
+ int lastPos = 0;
+ if (name.startsWith(ENCODED_DOLLAR_SIGN)) {
+ buf = new StringBuilder("$");
+ lastPos = ENCODED_DOLLAR_SIGN.length();
+ }
+
+ int pos;
+ while ((pos = name.indexOf(ENCODED_DOT, lastPos)) != -1) {
+ if (buf == null) {
+ buf = new StringBuilder();
+ }
+ buf.append(name.substring(lastPos, pos));
+ buf.append('.');
+ lastPos = pos + ENCODED_DOT.length();
+ }
+
+ if (buf != null) {
+ buf.append(name.substring(lastPos));
+ return buf.toString();
+ } else {
+ return name;
+ }
+ }
+
+ //--------------------------------------------------------< inner classes >
+
+ protected class DBObjectBinding implements Binding {
+
+ BasicDBObject obj;
+
+ protected DBObjectBinding(BasicDBObject obj) {
+ this.obj = obj;
+ }
+
+ @Override
+ public void write(String key, String value) throws Exception {
+ obj.append(encodeName(key), value);
+ }
+
+ @Override
+ public void write(String key, byte[] value) throws Exception {
+ obj.append(encodeName(key), StringUtils.convertBytesToHex(value));
+ }
+
+ @Override
+ public void write(String key, long value) throws Exception {
+ obj.append(encodeName(key), value);
+ }
+
+ @Override
+ public void write(String key, int value) throws Exception {
+ obj.append(encodeName(key), value);
+ }
+
+ @Override
+ public void writeMap(String key, int count, StringEntryIterator iterator) throws Exception {
+ BasicDBObject childObj = new BasicDBObject();
+ while (iterator.hasNext()) {
+ StringEntry entry = iterator.next();
+ childObj.append(encodeName(entry.getKey()), entry.getValue());
+ }
+ obj.append(encodeName(key), childObj);
+ }
+
+ @Override
+ public void writeMap(String key, int count, BytesEntryIterator iterator) throws Exception {
+ BasicDBObject childObj = new BasicDBObject();
+ while (iterator.hasNext()) {
+ BytesEntry entry = iterator.next();
+ childObj.append(encodeName(entry.getKey()), StringUtils.convertBytesToHex(entry.getValue()));
+ }
+ obj.append(encodeName(key), childObj);
+ }
+
+ @Override
+ public String readStringValue(String key) throws Exception {
+ return obj.getString(encodeName(key));
+ }
+
+ @Override
+ public byte[] readBytesValue(String key) throws Exception {
+ return StringUtils.convertHexToBytes(obj.getString(encodeName(key)));
+ }
+
+ @Override
+ public long readLongValue(String key) throws Exception {
+ return obj.getLong(encodeName(key));
+ }
+
+ @Override
+ public int readIntValue(String key) throws Exception {
+ return obj.getInt(encodeName(key));
+ }
+
+ @Override
+ public StringEntryIterator readStringMap(String key) throws Exception {
+ final BasicDBObject childObj = (BasicDBObject) obj.get(encodeName(key));
+ final Iterator<String> it = childObj.keySet().iterator();
+ return new StringEntryIterator() {
+ @Override
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ @Override
+ public StringEntry next() {
+ String key = it.next();
+ return new StringEntry(decodeName(key), childObj.getString(key));
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ @Override
+ public BytesEntryIterator readBytesMap(String key) throws Exception {
+ final BasicDBObject childObj = (BasicDBObject) obj.get(encodeName(key));
+ final Iterator<String> it = childObj.keySet().iterator();
+ return new BytesEntryIterator() {
+ @Override
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ @Override
+ public BytesEntry next() {
+ String key = it.next();
+ return new BytesEntry(
+ decodeName(key),
+ StringUtils.convertHexToBytes(childObj.getString(key)));
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ }
+}
Added: jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/PersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/PersistenceManager.java?rev=1295539&view=auto
==============================================================================
--- jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/PersistenceManager.java (added)
+++ jackrabbit/sandbox/microkernel/src/main/java/org/apache/jackrabbit/mk/store/pm/PersistenceManager.java Thu Mar 1 12:41:21 2012
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.apache.jackrabbit.mk.store.pm;
+
+import java.io.File;
+
+import org.apache.jackrabbit.mk.model.ChildNodeEntriesMap;
+import org.apache.jackrabbit.mk.model.Commit;
+import org.apache.jackrabbit.mk.model.Node;
+import org.apache.jackrabbit.mk.model.StoredCommit;
+import org.apache.jackrabbit.mk.store.Binding;
+import org.apache.jackrabbit.mk.store.NotFoundException;
+
+/**
+ * Defines the methods exposed by a persistence manager, that stores head
+ * revision id, nodes, child node entries and blobs.
+ *
+ * TODO: instead of deserializing objects on their own, return Binding
+ * instances, such as in #readNodeBinding.
+ */
+public interface PersistenceManager {
+
+ void initialize(File homeDir) throws Exception;
+
+ void close();
+
+ String readHead() throws Exception;
+
+ void writeHead(String id) throws Exception;
+
+ Binding readNodeBinding(String id) throws NotFoundException, Exception;
+
+ String writeNode(Node node) throws Exception;
+
+ ChildNodeEntriesMap readCNEMap(String id) throws NotFoundException, Exception;
+
+ String writeCNEMap(ChildNodeEntriesMap map) throws Exception;
+
+ StoredCommit readCommit(String id) throws NotFoundException, Exception;
+
+ String writeCommit(Commit commit) throws Exception;
+}