You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2010/04/30 18:37:54 UTC
svn commit: r939734 - in /jackrabbit/sandbox/jackrabbit-j3/src:
main/java/org/apache/jackrabbit/j3/ main/java/org/apache/jackrabbit/j3/api/
main/java/org/apache/jackrabbit/j3/api/management/
main/java/org/apache/jackrabbit/j3/data/ main/java/org/apache...
Author: thomasm
Date: Fri Apr 30 16:37:54 2010
New Revision: 939734
URL: http://svn.apache.org/viewvc?rev=939734&view=rev
Log:
Data store.
Added:
jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/RandomInputStream.java
jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestLargeObject.java
Modified:
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/RepositoryImpl.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/SessionImpl.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/ValueFactoryImpl.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/api/JackrabbitRepository.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/api/management/DataStoreGarbageCollector.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/data/GarbageCollector.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Bundle.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/StorageSession.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Val.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/jdbc/JdbcStorage.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/jdbc/JdbcStorageSession.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/mem/MemStorageSession.java
jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/util/LobStore.java
jackrabbit/sandbox/jackrabbit-j3/src/site/resources/images/drawing.png
jackrabbit/sandbox/jackrabbit-j3/src/site/resources/images/drawing.svg
jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestAll.java
jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestBundle.java
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/RepositoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/RepositoryImpl.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/RepositoryImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/RepositoryImpl.java Fri Apr 30 16:37:54 2010
@@ -58,11 +58,12 @@ public class RepositoryImpl implements J
private final WeakHashMap<SessionImpl, RepositoryImpl> sessions = new WeakHashMap<SessionImpl, RepositoryImpl>();
private final Cache<Val, NodeData> readOnlyCache = new Cache<Val, NodeData>(Constants.MEM_CACHE_PER_REPOSITORY);
private final HashMap<String, ValueImpl> descriptors = new HashMap<String, ValueImpl>();
- private final LobStore lobStore = new LobStore(this);
+ private final LobStore lobStore = new LobStore();
private final NodeTypeRegistry ntReg = new NodeTypeRegistry();
private final ValueFactoryImpl valueFactory;
private final QueryObjectModelFactoryImpl qomFactory;
+ private boolean init;
private boolean closed;
private LockSystem lockSystem;
@@ -112,15 +113,25 @@ public class RepositoryImpl implements J
if (credentials == null) {
credentials = ANONYMOUS_CREDENTIALS;
}
- if (credentials instanceof SimpleCredentials) {
- SimpleCredentials sc = (SimpleCredentials) credentials;
- String userId = sc.getUserID();
- StorageSession storageSession = storage.openSession(userId, sc.getPassword());
- SessionImpl session = new SessionImpl(this, sc, storageSession, workspaceName, log);
- sessions.put(session, this);
- return session;
+ if (!(credentials instanceof SimpleCredentials)) {
+ throw ExceptionFactory.login();
}
- throw ExceptionFactory.login();
+ SimpleCredentials sc = (SimpleCredentials) credentials;
+ String userId = sc.getUserID();
+ StorageSession storageSession = storage.openSession(userId, sc.getPassword());
+ SessionImpl session = new SessionImpl(this, sc, storageSession, workspaceName, log);
+ initRepository(storageSession);
+ sessions.put(session, this);
+ return session;
+ }
+
+ private synchronized void initRepository(StorageSession session) {
+ if (init) {
+ return;
+ }
+ lobStore.setDataStore(session.getDataStore());
+ init = true;
+
}
public synchronized void close(SessionImpl session) {
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/SessionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/SessionImpl.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/SessionImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/SessionImpl.java Fri Apr 30 16:37:54 2010
@@ -50,6 +50,7 @@ import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import org.apache.jackrabbit.j3.api.JackrabbitSession;
+import org.apache.jackrabbit.j3.data.DataStore;
import org.apache.jackrabbit.j3.lock.LockManagerImpl;
import org.apache.jackrabbit.j3.mc.McException;
import org.apache.jackrabbit.j3.mc.NodeData;
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/ValueFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/ValueFactoryImpl.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/ValueFactoryImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/ValueFactoryImpl.java Fri Apr 30 16:37:54 2010
@@ -169,7 +169,7 @@ public class ValueFactoryImpl implements
return new ValueImpl(val, this);
}
- static InputStream getInputStream(Val value, ValueFactoryImpl factory) throws ValueFormatException {
+ static InputStream getInputStream(Val value, ValueFactoryImpl factory) throws RepositoryException {
switch (value.getType()) {
case PropertyType.BINARY:
return new ByteArrayInputStream(value.getBytes());
@@ -177,7 +177,7 @@ public class ValueFactoryImpl implements
if (factory == null) {
throw ExceptionFactory.illegalArgument("Need a lob store for binary reference: {0}", value.getString());
}
- return factory.lobStore.getInputStream(value.getString());
+ return factory.lobStore.getInputStream(value);
case Val.TYPE_MULTI_VALUE:
throw ExceptionFactory.valueFormat("The property is multi-valued");
}
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/api/JackrabbitRepository.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/api/JackrabbitRepository.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/api/JackrabbitRepository.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/api/JackrabbitRepository.java Fri Apr 30 16:37:54 2010
@@ -17,10 +17,8 @@
package org.apache.jackrabbit.j3.api;
import javax.jcr.Credentials;
-import javax.jcr.LoginException;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
-import org.apache.jackrabbit.j3.SessionImpl;
/**
* A Jackrabbit repository.
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/api/management/DataStoreGarbageCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/api/management/DataStoreGarbageCollector.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/api/management/DataStoreGarbageCollector.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/api/management/DataStoreGarbageCollector.java Fri Apr 30 16:37:54 2010
@@ -37,22 +37,6 @@ import javax.jcr.RepositoryException;
public interface DataStoreGarbageCollector {
/**
- * Set the delay between scanning items.
- * The main scan loop sleeps this many milliseconds after
- * scanning a node. The default is 0, meaning the scan should run at full speed.
- *
- * @param millis the number of milliseconds to sleep
- */
- void setSleepBetweenNodes(long millis);
-
- /**
- * Get the delay between scanning items.
- *
- * @return the number of milliseconds to sleep
- */
- long getSleepBetweenNodes();
-
- /**
* Set the event listener. If set, the event listener will be called
* for each item that is scanned. This mechanism can be used
* to display the progress.
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/data/GarbageCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/data/GarbageCollector.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/data/GarbageCollector.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/data/GarbageCollector.java Fri Apr 30 16:37:54 2010
@@ -55,7 +55,6 @@ import javax.jcr.observation.Observation
* <p>
* Example code to run the data store garbage collection:
* <pre>
- * JackrabbitRepositoryFactory jf = (JackrabbitRepositoryFactory) factory;
* RepositoryManager m = factory.getRepositoryManager((JackrabbitRepository) rep);
* GarbageCollector gc = m.createDataStoreGarbageCollector();
* try {
@@ -73,10 +72,6 @@ public class GarbageCollector implements
private MarkEventListener callback;
- private long sleepBetweenNodes;
-
- private int testDelay;
-
private final DataStore store;
private long startScanTimestamp;
@@ -115,23 +110,6 @@ public class GarbageCollector implements
}
}
- public void setSleepBetweenNodes(long millis) {
- this.sleepBetweenNodes = millis;
- }
-
- public long getSleepBetweenNodes() {
- return sleepBetweenNodes;
- }
-
- /**
- * When testing the garbage collection, a delay is used instead of simulating concurrent access.
- *
- * @param testDelay the delay in milliseconds
- */
- public void setTestDelay(int testDelay) {
- this.testDelay = testDelay;
- }
-
public void setMarkEventListener(MarkEventListener callback) {
this.callback = callback;
}
@@ -159,7 +137,7 @@ public class GarbageCollector implements
// adding a link to a BLOB updates the modified date
// reading usually doesn't, but when scanning, it does
- recurse(session.getRootNode(), sleepBetweenNodes);
+ recurse(session.getRootNode());
}
/**
@@ -195,14 +173,7 @@ public class GarbageCollector implements
return store;
}
- private void recurse(final Node n, long sleep) throws RepositoryException {
- if (sleep > 0) {
- try {
- Thread.sleep(sleep);
- } catch (InterruptedException e) {
- // ignore
- }
- }
+ private void recurse(final Node n) throws RepositoryException {
if (callback != null) {
callback.beforeScanning(n);
}
@@ -231,7 +202,7 @@ public class GarbageCollector implements
}
try {
for (NodeIterator it = n.getNodes(); it.hasNext();) {
- recurse(it.nextNode(), sleep);
+ recurse(it.nextNode());
}
} catch (InvalidItemStateException e) {
LOG.debug("Node removed concurrently - ignoring", e);
@@ -325,13 +296,6 @@ public class GarbageCollector implements
}
public void onEvent(EventIterator events) {
- if (testDelay > 0) {
- try {
- Thread.sleep(testDelay);
- } catch (InterruptedException e) {
- // ignore
- }
- }
while (events.hasNext()) {
Event event = events.nextEvent();
try {
@@ -340,7 +304,7 @@ public class GarbageCollector implements
Item item = session.getItem(path);
if (item.isNode()) {
Node n = (Node) item;
- recurse(n, testDelay);
+ recurse(n);
}
} catch (PathNotFoundException e) {
// ignore
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Bundle.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Bundle.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Bundle.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Bundle.java Fri Apr 30 16:37:54 2010
@@ -434,7 +434,7 @@ public class Bundle {
return Val.get(array);
}
case BINARY_REFERENCE:
- return Val.get(PropertyType.BINARY, readString());
+ return Val.get(Val.TYPE_BINARY_REFERENCE, readString());
case BOOLEAN_TRUE:
return Val.TRUE;
case BOOLEAN_FALSE:
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/StorageSession.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/StorageSession.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/StorageSession.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/StorageSession.java Fri Apr 30 16:37:54 2010
@@ -16,45 +16,150 @@
*/
package org.apache.jackrabbit.j3.mc;
+import org.apache.jackrabbit.j3.data.DataStore;
+
/**
* A session bound to a storage.
*/
public interface StorageSession {
+ /**
+ * The id of the main (default) workspace.
+ */
int MAIN_WORKSPACE_ID = 0;
+ /**
+ * Get the id of the root node.
+ *
+ * @return the root node id
+ */
Val getRootNodeId();
+ /**
+ * Read the node.
+ *
+ * @param nodeId the node id
+ * @return the node
+ */
NodeData getNode(Val nodeId);
+ /**
+ * Create a new node id.
+ *
+ * @param parentNodeId the parent node (may not be used)
+ * @param workspaceId the workspace id
+ * @param relPath the path relative to the parent (may not be used)
+ * @return the node id
+ */
Val newNodeId(Val parentNodeId, int workspaceId, Val relPath);
+ /**
+ * Calculate the workspace id from the node id.
+ *
+ * @param nodeId the node id
+ * @return the workspace id
+ */
int getWorkspaceId(Val nodeId);
+ /**
+ *
+ * @param nodeId
+ * @param newWorkspaceId
+ * @return
+ */
Val convertNodeId(Val nodeId, int newWorkspaceId);
+ /**
+ * Store the transaction.
+ *
+ * @param date the date
+ * @param nodes the changed nodes
+ * @param events the events
+ */
void store(long date, NodeData[] nodes, Bundle[] events);
+ /**
+ * Read events from the event journal.
+ *
+ * @param date the date of the first event (-1 to read the next page)
+ * @param size the size the number of elements to read at most
+ * @return the bundles the event bundles
+ */
Bundle[] getEvents(long date, int size);
+ /**
+ * Convert a node identifier to a node id.
+ *
+ * @param id the identifier
+ * @return the node id
+ */
Val convertIdentifierToNodeId(String id);
+ /**
+ * Convert a node id to a node identifier.
+ *
+ * @param nodeId the node id
+ * @return the identifier
+ */
String convertNodeIdToIdentifier(Val nodeId);
+ /**
+ * Close the session.
+ */
void close();
+ /**
+ * Check whether this session supports the event journal.
+ *
+ * @return true if it does
+ */
boolean supportsEventJournal();
+ /**
+ * Check whether this session support temporary storage.
+ *
+ * @return true if it does
+ */
boolean supportsTemp();
- boolean supportsNodeIdsWithoutPath();
-
+ /**
+ * Store into the temporary area.
+ *
+ * @param block the block id
+ * @param nodes the nodes
+ * @param events the events (may be null)
+ */
void storeTemp(int block, NodeData[] nodes, Bundle[] events);
+ /**
+ * Read a temporary block.
+ *
+ * @param block the block
+ * @return the nodes
+ */
NodeData[] getTempNodes(int block);
+ /**
+ * Read a temporary block.
+ *
+ * @param block the block
+ * @return the events
+ */
Bundle[] getTempEvents(int block);
+ /**
+ * Clear the temporary area.
+ *
+ * @param nodes clear nodes
+ * @param events clear events
+ */
void clearTemp(boolean nodes, boolean events);
+ /**
+ * Get the data store.
+ *
+ * @return the data store
+ */
+ DataStore getDataStore();
+
}
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Val.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Val.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Val.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/Val.java Fri Apr 30 16:37:54 2010
@@ -250,7 +250,7 @@ public class Val implements Comparable<V
case PropertyType.URI:
case PropertyType.WEAKREFERENCE:
return cache(type, x);
- case PropertyType.BINARY:
+ case TYPE_BINARY_REFERENCE:
return cache(TYPE_BINARY_REFERENCE, x);
}
throw ExceptionFactory.illegalArgument("type: {0}, value: {0}", type, x);
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/jdbc/JdbcStorage.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/jdbc/JdbcStorage.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/jdbc/JdbcStorage.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/jdbc/JdbcStorage.java Fri Apr 30 16:37:54 2010
@@ -21,6 +21,9 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import javax.jcr.RepositoryException;
+import org.apache.jackrabbit.j3.data.DataStore;
+import org.apache.jackrabbit.j3.data.FileDataStore;
import org.apache.jackrabbit.j3.mc.NodeData;
import org.apache.jackrabbit.j3.mc.Storage;
import org.apache.jackrabbit.j3.mc.StorageSession;
@@ -51,6 +54,8 @@ public class JdbcStorage implements Stor
private Connection connLock;
private PreparedStatement prepUpdateSetting;
+ private DataStore dataStore;
+
public JdbcStorage(String url) {
this.url = url;
}
@@ -128,7 +133,17 @@ public class JdbcStorage implements Stor
session.store(0, new NodeData[] { root }, null);
nextBaseNodeId++;
}
-
+ ResultSet rs = stat.executeQuery("call database_path()");
+ rs.next();
+ String homeDir = rs.getString(1);
+ if (homeDir != null) {
+ dataStore = new FileDataStore();
+ try {
+ dataStore.init(homeDir);
+ } catch (RepositoryException e) {
+ throw ExceptionFactory.mcException(e);
+ }
+ }
} catch (SQLException e) {
throw ExceptionFactory.mcException(e);
}
@@ -181,4 +196,8 @@ public class JdbcStorage implements Stor
return rootNodeId;
}
+ DataStore getDataStore() {
+ return dataStore;
+ }
+
}
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/jdbc/JdbcStorageSession.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/jdbc/JdbcStorageSession.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/jdbc/JdbcStorageSession.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/jdbc/JdbcStorageSession.java Fri Apr 30 16:37:54 2010
@@ -22,6 +22,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
+import org.apache.jackrabbit.j3.data.DataStore;
import org.apache.jackrabbit.j3.mc.Bundle;
import org.apache.jackrabbit.j3.mc.NodeData;
import org.apache.jackrabbit.j3.mc.StorageSession;
@@ -264,10 +265,6 @@ public class JdbcStorageSession implemen
return true;
}
- public boolean supportsNodeIdsWithoutPath() {
- return true;
- }
-
public NodeData[] getTempNodes(int block) {
ArrayList<NodeData> list = new ArrayList<NodeData>();
try {
@@ -304,4 +301,8 @@ public class JdbcStorageSession implemen
}
}
+ public DataStore getDataStore() {
+ return storage.getDataStore();
+ }
+
}
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/mem/MemStorageSession.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/mem/MemStorageSession.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/mem/MemStorageSession.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/mc/mem/MemStorageSession.java Fri Apr 30 16:37:54 2010
@@ -17,6 +17,7 @@
package org.apache.jackrabbit.j3.mc.mem;
import java.util.HashMap;
+import org.apache.jackrabbit.j3.data.DataStore;
import org.apache.jackrabbit.j3.mc.Bundle;
import org.apache.jackrabbit.j3.mc.NodeData;
import org.apache.jackrabbit.j3.mc.StorageSession;
@@ -86,10 +87,6 @@ public class MemStorageSession implement
return false;
}
- public boolean supportsNodeIdsWithoutPath() {
- return true;
- }
-
public Bundle[] getEvents(long date, int size) {
throw ExceptionFactory.unsupportedOperation();
}
@@ -110,4 +107,8 @@ public class MemStorageSession implement
throw ExceptionFactory.unsupportedOperation();
}
+ public DataStore getDataStore() {
+ return null;
+ }
+
}
Modified: jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/util/LobStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/util/LobStore.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/util/LobStore.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/main/java/org/apache/jackrabbit/j3/util/LobStore.java Fri Apr 30 16:37:54 2010
@@ -17,12 +17,14 @@
package org.apache.jackrabbit.j3.util;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
-import org.apache.jackrabbit.j3.RepositoryImpl;
+import org.apache.jackrabbit.j3.data.DataIdentifier;
+import org.apache.jackrabbit.j3.data.DataRecord;
import org.apache.jackrabbit.j3.data.DataStore;
import org.apache.jackrabbit.j3.mc.Val;
@@ -31,24 +33,53 @@ import org.apache.jackrabbit.j3.mc.Val;
*/
public class LobStore {
- private final RepositoryImpl rep;
+ private DataStore dataStore;
- public LobStore(RepositoryImpl rep) {
- this.rep = rep;
+ public void setDataStore(DataStore store) {
+ this.dataStore = store;
}
- public InputStream getInputStream(String ref) {
- // TODO Auto-generated method stub
- return null;
+ public DataStore getDataStore() {
+ return dataStore;
}
- public DataStore getDataStore() {
- return null;
+ public InputStream getInputStream(Val ref) throws RepositoryException {
+ String s = ref.getString();
+ s = s.substring(0, s.lastIndexOf(':'));
+ DataIdentifier id = new DataIdentifier(s);
+ DataRecord rec = dataStore.getRecordIfStored(id);
+ return rec.getStream();
+ }
+
+ private String create(InputStream stream) throws RepositoryException {
+ DataRecord rec = dataStore.addRecord(stream);
+ String ref = rec.getIdentifier().toString();
+ return ref + ":" + rec.getLength();
}
public Val createValue(InputStream in) throws RepositoryException {
try {
+ if (dataStore == null) {
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ byte[] buff = new byte[1024];
+ while (true) {
+ int len = in.read(buff);
+ if (len < 0) {
+ break;
+ }
+ out.write(buff, 0, len);
+ }
+ return Val.get(out.toByteArray());
+ } catch (IOException e) {
+ throw ExceptionFactory.repository(e, "Could not read from stream");
+ }
+ }
int min = getMinRecordLength();
+ if (min == Integer.MAX_VALUE) {
+ String ref = create(in);
+ return Val.get(Val.TYPE_BINARY_REFERENCE, ref);
+ }
int maxMemorySize = min - 1;
byte[] buffer = new byte[maxMemorySize];
int pos = 0, len = maxMemorySize;
@@ -85,12 +116,7 @@ public class LobStore {
}
private int getMinRecordLength() {
- return Integer.MAX_VALUE;
- }
-
- private String create(InputStream stream) {
- // TODO Auto-generated method stub
- return null;
+ return dataStore == null ? Integer.MAX_VALUE : dataStore.getMinRecordLength();
}
public boolean isStored(Val value) {
@@ -103,8 +129,8 @@ public class LobStore {
return false;
}
- public long getLength(Val value) {
- String s = value.getString();
+ public long getLength(Val ref) {
+ String s = ref.getString();
try {
return Long.parseLong(s.substring(s.lastIndexOf(':')));
} catch (Exception e) {
Modified: jackrabbit/sandbox/jackrabbit-j3/src/site/resources/images/drawing.png
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/site/resources/images/drawing.png?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
Binary files - no diff available.
Modified: jackrabbit/sandbox/jackrabbit-j3/src/site/resources/images/drawing.svg
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/site/resources/images/drawing.svg?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/site/resources/images/drawing.svg (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/site/resources/images/drawing.svg Fri Apr 30 16:37:54 2010
@@ -16,7 +16,7 @@
version="1.1"
inkscape:version="0.47 r22583"
sodipodi:docname="drawing.svg"
- inkscape:export-filename="/Users/tmueller/drawing.png"
+ inkscape:export-filename="/Users/tmueller/jackrabbit/sandbox/jackrabbit-j3/src/site/resources/images/drawing.png"
inkscape:export-xdpi="48.380001"
inkscape:export-ydpi="48.380001">
<defs
@@ -226,9 +226,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="0.66873709"
- inkscape:cx="256.23266"
- inkscape:cy="646.80961"
+ inkscape:zoom="0.47286853"
+ inkscape:cx="36.408726"
+ inkscape:cy="665.93735"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
@@ -238,7 +238,7 @@
inkscape:window-height="852"
inkscape:window-x="0"
inkscape:window-y="0"
- inkscape:window-maximized="1" />
+ inkscape:window-maximized="0" />
<metadata
id="metadata7">
<rdf:RDF>
@@ -288,7 +288,7 @@
id="rect3884"
style="fill:#3b0000;fill-opacity:1;stroke:#000000;stroke-width:1.0269829;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter3910)" />
<rect
- style="fill:#ffb200;fill-opacity:1;stroke:#000000;stroke-width:1.28393507;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ style="fill:#ddff55;fill-opacity:1;stroke:#000000;stroke-width:1.28393507000000007;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3757"
width="625.69257"
height="257.26605"
@@ -302,17 +302,18 @@
height="114.40515"
width="467.24728"
id="rect3876"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter3878)" />
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter3878)"
+ transform="matrix(1.2842992,0,0,0.99915362,-201.41663,0.07175458)" />
<rect
y="822.29254"
x="439.7944"
height="70.267014"
width="224.79643"
id="rect3788"
- style="fill:#ffff00;fill-opacity:1;stroke:#000000;stroke-width:1.27992463;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ style="fill:#eeffaa;fill-opacity:1;stroke:#000000;stroke-width:1.27992463000000001;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
rx="21.82123" />
<rect
- style="fill:#ff0000;fill-opacity:1;stroke:#000000;stroke-width:1.0269829;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ style="fill:#ccff00;fill-opacity:1;stroke:#000000;stroke-width:1.02698289999999992;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3759"
width="627.96228"
height="251.57126"
@@ -320,7 +321,7 @@
y="318.27814"
rx="23.700001" />
<rect
- style="fill:#ffff00;fill-opacity:1;stroke:#000000;stroke-width:1.23394859;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ style="fill:#eeffaa;fill-opacity:1;stroke:#000000;stroke-width:1.23394859000000001;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3674"
width="209.09579"
height="70.213562"
@@ -328,33 +329,34 @@
y="823.32568"
rx="23.700001" />
<rect
- style="fill:#0048ff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ style="fill:#aad400;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.16024995000000009;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect2859"
- width="467.24728"
+ width="628.9989"
height="114.40515"
- x="215.58446"
+ x="53.832813"
y="22.030411"
- rx="23.700001" />
+ rx="31.904467" />
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- x="245.14754"
+ x="77.758507"
y="90.5858"
id="text2861"><tspan
sodipodi:role="line"
id="tspan2863"
- x="245.14754"
- y="90.5858">App</tspan></text>
+ x="77.758507"
+ y="90.5858"
+ style="font-size:32">App</tspan></text>
<text
xml:space="preserve"
style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- x="62.45303"
- y="286.31436"
+ x="82.246674"
+ y="282.08487"
id="text2949"><tspan
sodipodi:role="line"
id="tspan2951"
- x="62.45303"
- y="286.31436">Jackrabbit 3</tspan></text>
+ x="82.246674"
+ y="282.08487">Jackrabbit 3</tspan></text>
<text
xml:space="preserve"
style="font-size:32px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
@@ -395,24 +397,24 @@
<text
xml:space="preserve"
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
- x="246.70222"
+ x="81.418549"
y="179.09171"
id="text3024"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3026"
- x="246.70222"
- y="179.09171">JCR API</tspan></text>
+ x="81.418549"
+ y="179.09171">JCR API (+ Jackrabbit API)</tspan></text>
<text
xml:space="preserve"
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
- x="243.10457"
+ x="77.820892"
y="619.8031"
id="text3028"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3030"
- x="243.10457"
+ x="77.820892"
y="619.8031">Micro Kernel API</tspan></text>
<text
xml:space="preserve"
@@ -556,7 +558,7 @@
sodipodi:role="line"
id="tspan3164"
x="466.52975"
- y="368.64398">Change</tspan></text>
+ y="368.64398">ChangeSet</tspan></text>
<text
xml:space="preserve"
style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
@@ -567,6 +569,6 @@
sodipodi:role="line"
id="tspan3168"
x="466.52975"
- y="418.74646">Cache</tspan></text>
+ y="418.74646">LobStore</tspan></text>
</g>
</svg>
Added: jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/RandomInputStream.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/RandomInputStream.java?rev=939734&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/RandomInputStream.java (added)
+++ jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/RandomInputStream.java Fri Apr 30 16:37:54 2010
@@ -0,0 +1,150 @@
+/*
+ * 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.j3;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * An input stream that returns pseudo-random bytes.
+ */
+public class RandomInputStream extends InputStream {
+
+ private static final long MUL = 0x5DEECE66DL;
+ private static final long ADD = 0xBL;
+ private static final long MASK = (1L << 48) - 1;
+ private static final int DEFAULT_MAX_READ_BLOCK_SIZE = 15;
+
+ private final long initialSeed;
+ private final long len;
+ private long markedState;
+ private long pos;
+ private long markedPos;
+ private long state;
+ private int maxReadBlockSize;
+
+ public String toString() {
+ return "new RandomInputStream(" + initialSeed + ", " + len + ")";
+ }
+
+ public RandomInputStream(long seed, long len) {
+ this(seed, len, DEFAULT_MAX_READ_BLOCK_SIZE);
+ }
+
+ public static void compareStreams(InputStream a, InputStream b) throws IOException {
+ a = new BufferedInputStream(a);
+ b = new BufferedInputStream(b);
+ long pos = 0;
+ while (true) {
+ int x = a.read();
+ int y = b.read();
+ if (x == -1 || y == -1) {
+ if (x == y) {
+ break;
+ }
+ }
+ if (x != y) {
+ throw new IOException("Incorrect byte at position " + pos + ": x=" + x + " y=" + y);
+ }
+ }
+ }
+
+ public RandomInputStream(long seed, long len, int maxReadBlockSize) {
+ this.initialSeed = seed;
+ this.len = len;
+ this.maxReadBlockSize = maxReadBlockSize;
+ setSeed(seed);
+ reset();
+ }
+
+ public long skip(long n) {
+ n = getReadBlock(n);
+ if (n == 0) {
+ return -1;
+ }
+ pos += n;
+ return n;
+ }
+
+ private int getReadBlock(long n) {
+ if (n > (len - pos)) {
+ n = (len - pos);
+ }
+ if (n > maxReadBlockSize) {
+ n = maxReadBlockSize;
+ } else if (n < 0) {
+ n = 0;
+ }
+ return (int) n;
+ }
+
+ public int read(byte[] b, int off, int len) {
+ if (pos >= this.len) {
+ return -1;
+ }
+ len = getReadBlock(len);
+ if (len == 0) {
+ return -1;
+ }
+ for (int i = 0; i < len; i++) {
+ b[off + i] = (byte) (next() & 255);
+ }
+ pos += len;
+ return len;
+ }
+
+ public int read(byte[] b) {
+ return read(b, 0, b.length);
+ }
+
+ public void close() {
+ pos = len;
+ }
+
+ private void setSeed(long seed) {
+ markedState = (seed ^ MUL) & MASK;
+ }
+
+ private int next() {
+ state = (state * MUL + ADD) & MASK;
+ return (int) (state >>> (48 - 32));
+ }
+
+ public void reset() {
+ pos = markedPos;
+ state = markedState;
+ }
+
+ public int read() {
+ if (pos >= len) {
+ return -1;
+ }
+ pos++;
+ return next() & 255;
+ }
+
+ public boolean markSupported() {
+ return true;
+ }
+
+ public void mark(int readlimit) {
+ markedPos = pos;
+ markedState = state;
+ }
+
+}
Modified: jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestAll.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestAll.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestAll.java Fri Apr 30 16:37:54 2010
@@ -35,11 +35,19 @@ public class TestAll {
TestSuite suite = new TestSuite("org.apache.jackrabbit.j3");
int todo;
+
+ // integrated lob storage
+ // database data store: should use the session to access the binary
+ // (like this we can also restrict on temporary storage per session)
+
// ability to disable the even journal (for each session?)
+
// XA API
- // integrated lob storage
+
// virtual repository
+
// session attribute to request cache size (only smaller except if in admin group)
+
// Repository.OPTION_JOURNALED_OBSERVATION_SUPPORTED
// external events
// ability to auto-delete old event journal entries
@@ -60,6 +68,7 @@ public class TestAll {
suite.addTestSuite(TestCache.class);
suite.addTestSuite(TestCreateNodesTraverse.class);
suite.addTestSuite(TestEventJournal.class);
+ suite.addTestSuite(TestLargeObject.class);
for (int i = 0; i < TestBase.URL.length; i++) {
suite.addTestSuite(TestConcurrentWrite.class);
Modified: jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestBundle.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestBundle.java?rev=939734&r1=939733&r2=939734&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestBundle.java (original)
+++ jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestBundle.java Fri Apr 30 16:37:54 2010
@@ -113,7 +113,7 @@ public class TestBundle extends TestCase
testLength(Val.get(PropertyType.PATH, "/xyz/abc"));
testLength(Val.get(PropertyType.REFERENCE, "abc:def"));
testLength(Val.get(PropertyType.WEAKREFERENCE, "abc:def"));
- testLength(Val.get(PropertyType.BINARY, "0x1234"));
+ testLength(Val.get(Val.TYPE_BINARY_REFERENCE, "0x1234"));
testLength(Val.get("long string with strange characters äöü \u1234"));
testLength(Val.get(new byte[1024]));
testLength(Val.get(new byte[1024 * 1024]));
Added: jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestLargeObject.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestLargeObject.java?rev=939734&view=auto
==============================================================================
--- jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestLargeObject.java (added)
+++ jackrabbit/sandbox/jackrabbit-j3/src/test/java/org/apache/jackrabbit/j3/TestLargeObject.java Fri Apr 30 16:37:54 2010
@@ -0,0 +1,52 @@
+/*
+ * 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.j3;
+
+import java.io.InputStream;
+import javax.jcr.Binary;
+import javax.jcr.Node;
+import javax.jcr.Session;
+import javax.jcr.ValueFactory;
+
+/**
+ * Tests large objects.
+ */
+public class TestLargeObject extends TestBase {
+
+ public void test() throws Exception {
+ Node n = session.getRootNode().addNode("testLargeObject");
+ session.save();
+ ValueFactory vf = session.getValueFactory();
+ Binary b = vf.createBinary(createRandomStream());
+ n.setProperty("data", b);
+ session.save();
+
+ Session session2 = openSession();
+ Node n2 = session2.getNode("/testLargeObject");
+ InputStream in = n2.getProperty("data").getBinary().getStream();
+ RandomInputStream.compareStreams(createRandomStream(), in);
+ session2.logout();
+
+ n.remove();
+ session.save();
+ }
+
+ private InputStream createRandomStream() {
+ return new RandomInputStream(1, 1000000);
+ }
+
+}