diff --git a/source/java/hibernate.cfg.xml b/source/java/hibernate.cfg.xml
index 8cb0ff9e28..92e7cf09a5 100644
--- a/source/java/hibernate.cfg.xml
+++ b/source/java/hibernate.cfg.xml
@@ -9,12 +9,13 @@
com.mysql.jdbc.Driver
thread
org.hibernate.dialect.MySQLInnoDBDialect
- true
+ false
2
5
20
900
50
+
diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java
index c8b9159f64..3f6db2b579 100644
--- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java
+++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java
@@ -17,6 +17,8 @@
package org.alfresco.repo.avm;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
@@ -25,6 +27,7 @@ import java.util.Set;
import org.alfresco.repo.avm.hibernate.HibernateHelper;
import org.alfresco.repo.avm.impl.AVMServiceImpl;
import org.hibernate.cfg.Configuration;
+import org.hibernate.stat.Statistics;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import junit.framework.TestCase;
@@ -39,6 +42,11 @@ public class AVMServiceTest extends TestCase
* The AVMService we are testing.
*/
private AVMService fService;
+
+ /**
+ * The start time of actual work for a test.
+ */
+ private long fStartTime;
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
@@ -47,11 +55,13 @@ public class AVMServiceTest extends TestCase
protected void setUp() throws Exception
{
Configuration cfg = HibernateHelper.GetConfiguration();
+ HibernateHelper.GetSessionFactory().getStatistics().setStatisticsEnabled(true);
SchemaExport se = new SchemaExport(cfg);
se.drop(false, true);
AVMServiceImpl service = new AVMServiceImpl();
service.setStorage("storage");
service.init(true);
+ fStartTime = System.currentTimeMillis();
fService = service;
}
@@ -61,6 +71,11 @@ public class AVMServiceTest extends TestCase
@Override
protected void tearDown() throws Exception
{
+ long now = System.currentTimeMillis();
+ System.out.println("Timing: " + (now - fStartTime) + "ms");
+ Statistics stats = HibernateHelper.GetSessionFactory().getStatistics();
+ stats.logSummary();
+ stats.clear();
HibernateHelper.Reset();
}
@@ -98,13 +113,13 @@ public class AVMServiceTest extends TestCase
try
{
testCreateDirectory();
- fService.createFile("main:testdir", "testfile");
+ fService.createFile("main:/testdir", "testfile");
fService.createFile("main:/", "testfile2");
fService.createSnapshot("main");
- PrintStream out = new PrintStream(fService.getFileOutputStream("main:testdir/testfile"));
+ PrintStream out = new PrintStream(fService.getFileOutputStream("main:/testdir/testfile"));
out.println("This is testdir/testfile");
out.close();
- out = new PrintStream(fService.getFileOutputStream("main:testfile2"));
+ out = new PrintStream(fService.getFileOutputStream("main:/testfile2"));
out.println("This is testfile2");
out.close();
fService.createSnapshot("main");
@@ -114,6 +129,15 @@ public class AVMServiceTest extends TestCase
System.out.println("V:" + version);
System.out.println(recursiveList("main", version));
}
+ BufferedReader reader =
+ new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/testdir/testfile")));
+ String line = reader.readLine();
+ assertEquals("This is testdir/testfile", line);
+ reader.close();
+ reader =
+ new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/testfile2")));
+ line = reader.readLine();
+ assertEquals("This is testfile2", line);
}
catch (Exception e)
{
@@ -130,7 +154,7 @@ public class AVMServiceTest extends TestCase
try
{
setupBasicTree();
- fService.createBranch(-1, "main:a", "main:d/e", "abranch");
+ fService.createBranch(-1, "main:/a", "main:/d/e", "abranch");
fService.createSnapshot("main");
Set versions = fService.getRepositoryVersions("main");
for (Integer version : versions)
@@ -138,8 +162,10 @@ public class AVMServiceTest extends TestCase
System.out.println("V:" + version);
System.out.println(recursiveList("main", version));
}
- List original = fService.getDirectoryListing(-1, "main:a");
- List branch = fService.getDirectoryListing(-1, "main:d/e/abranch");
+ String original = recursiveList("main:/a", -1, 0);
+ original = original.substring(original.indexOf('\n'));
+ String branch = recursiveList("main:/d/e/abranch", -1, 0);
+ branch = branch.substring(branch.indexOf('\n'));
assertEquals(original, branch);
}
catch (Exception e)
@@ -157,12 +183,226 @@ public class AVMServiceTest extends TestCase
try
{
setupBasicTree();
- fService.createLayeredDirectory("main:a", "main:d/e", "alayer");
+ fService.createLayeredDirectory("main:/a", "main:/d/e", "alayer");
fService.createSnapshot("main");
System.out.println(recursiveList("main", -1));
- List original = fService.getDirectoryListing(-1, "main:a");
- List layer = fService.getDirectoryListing(-1, "main:d/e/alayer");
+ assertEquals("main:/a", fService.getIndirectionPath(-1, "main:/d/e/alayer"));
+ String original = recursiveList("main:/a", -1, 0);
+ original = original.substring(original.indexOf('\n'));
+ String layer = recursiveList("main:/d/e/alayer", -1, 0);
+ layer = original.substring(original.indexOf('\n'));
assertEquals(original, layer);
+ PrintStream out = new PrintStream(fService.getFileOutputStream("main:/d/e/alayer/b/c/foo"));
+ out.println("I am main:/d/e/alayer/b/c/foo");
+ out.close();
+ fService.createSnapshot("main");
+ BufferedReader reader =
+ new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/b/c/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/b/c/foo", line);
+ System.out.println(recursiveList("main", -1));
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ fail();
+ }
+ }
+
+ /**
+ * Test creating a layered file.
+ */
+ public void testCreateLayeredFile()
+ {
+ try
+ {
+ setupBasicTree();
+ fService.createLayeredFile("main:/a/b/c/foo", "main:/d", "lfoo");
+ fService.createSnapshot("main");
+ System.out.println(recursiveList("main", -1));
+ assertEquals("main:/a/b/c/foo", fService.getIndirectionPath(-1, "main:/d/lfoo"));
+ BufferedReader reader =
+ new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/d/lfoo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/b/c/foo", line);
+ PrintStream out = new PrintStream(fService.getFileOutputStream("main:/d/lfoo"));
+ out.println("I am main:/d/lfoo");
+ out.close();
+ fService.createSnapshot("main");
+ System.out.println(recursiveList("main", -1));
+ reader =
+ new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/b/c/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/b/c/foo", line);
+ reader =
+ new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/d/lfoo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/d/lfoo", line);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ fail();
+ }
+ }
+
+ /**
+ * Test rename.
+ */
+ public void testRename()
+ {
+ try
+ {
+ setupBasicTree();
+ fService.rename("main:/a", "b", "main:/d/e", "brenamed");
+ fService.createSnapshot("main");
+ System.out.println(recursiveList("main", -1));
+ String original = recursiveList("main:/a/b", 0, 0);
+ original = original.substring(original.indexOf('\n'));
+ String renamed = recursiveList("main:/d/e/brenamed", 1, 0);
+ renamed = renamed.substring(renamed.indexOf('\n'));
+ assertEquals(original, renamed);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ fail();
+ }
+ }
+
+ /**
+ * Test remove.
+ */
+ public void testRemove()
+ {
+ try
+ {
+ setupBasicTree();
+ System.out.println(recursiveList("main", -1));
+ fService.removeNode("main:/a/b/c", "foo");
+ fService.createSnapshot("main");
+ System.out.println(recursiveList("main", -1));
+ List l = fService.getDirectoryListing(-1, "main:/a/b/c");
+ assertEquals(1, l.size());
+ fService.removeNode("main:/d", "e");
+ fService.createSnapshot("main");
+ System.out.println(recursiveList("main", -1));
+ l = fService.getDirectoryListing(-1, "main:/d");
+ assertEquals(0, l.size());
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ fail();
+ }
+ }
+
+ /**
+ * Test branching from one repository to another.
+ */
+ public void testBranchAcross()
+ {
+ try
+ {
+ setupBasicTree();
+ fService.createRepository("second");
+ fService.createBranch(-1, "main:/", "second:/", "main");
+ fService.createSnapshot("second");
+ System.out.println(recursiveList("second", -1));
+ String original = recursiveList("main:/", -1, 0);
+ original = original.substring(original.indexOf('\n'));
+ String branch = recursiveList("second:/main", -1, 0);
+ branch = branch.substring(branch.indexOf('\n'));
+ assertEquals(original, branch);
+ // Now make sure nothing happens to the branched from place,
+ // if the branch is modified.
+ PrintStream out =
+ new PrintStream(fService.getFileOutputStream("second:/main/a/b/c/foo"));
+ out.println("I am second:/main/a/b/c/foo");
+ out.close();
+ fService.createSnapshot("second");
+ System.out.println(recursiveList("second", -1));
+ BufferedReader reader =
+ new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/b/c/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/b/c/foo", line);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ fail();
+ }
+ }
+
+ /**
+ * Test creating a layer across repositories.
+ */
+ public void testLayerAcross()
+ {
+ try
+ {
+ setupBasicTree();
+ fService.createRepository("second");
+ fService.createLayeredDirectory("main:/", "second:/", "main");
+ fService.createSnapshot("second");
+ System.out.println(recursiveList("second", -1));
+ String original = recursiveList("main:/", -1, 0);
+ original = original.substring(original.indexOf('\n'));
+ String layer = recursiveList("second:/main", -1, 0);
+ layer = layer.substring(layer.indexOf('\n'));
+ assertEquals(original, layer);
+ // Now make sure that a copy on write will occur and
+ // that the underlying stuff doesn't get changed.
+ PrintStream out = new PrintStream(fService.getFileOutputStream("second:/main/a/b/c/foo"));
+ out.println("I am second:/main/a/b/c/foo");
+ out.close();
+ fService.createSnapshot("second");
+ System.out.println(recursiveList("second", -1));
+ BufferedReader reader =
+ new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "second:/main/a/b/c/foo")));
+ String line = reader.readLine();
+ reader.close();
+ assertEquals("I am second:/main/a/b/c/foo", line);
+ reader =
+ new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/b/c/foo")));
+ line = reader.readLine();
+ reader.close();
+ assertEquals("I am main:/a/b/c/foo", line);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace(System.err);
+ fail();
+ }
+ }
+
+ /**
+ * Test rename across repositories.
+ */
+ public void testRenameAcross()
+ {
+ try
+ {
+ setupBasicTree();
+ fService.createRepository("second");
+ fService.rename("main:/a/b", "c", "second:/", "cmoved");
+ ArrayList toSnapshot = new ArrayList();
+ toSnapshot.add("main");
+ toSnapshot.add("second");
+ System.out.println(recursiveList("main", -1));
+ System.out.println(recursiveList("second", -1));
+ // Check that the moved thing has identical contents to the thing it
+ // was moved from.
+ String original = recursiveList("main:/a/b/c", 0, 0);
+ original = original.substring(original.indexOf('\n'));
+ String moved = recursiveList("second:/cmoved", -1, 0);
+ moved = moved.substring(moved.indexOf('\n'));
+ assertEquals(original, moved);
}
catch (Exception e)
{
@@ -194,7 +434,7 @@ public class AVMServiceTest extends TestCase
{
builder.append(' ');
}
- builder.append(path);
+ builder.append(path.substring(path.lastIndexOf('/') + 1));
builder.append(' ');
Lookup lookup = fService.lookup(version, path);
AVMNode node = lookup.getCurrentNode();
@@ -202,7 +442,7 @@ public class AVMServiceTest extends TestCase
builder.append('\n');
if (node instanceof DirectoryNode)
{
- String basename = path.endsWith("/") ? path.substring(0, path.length() - 1) : path + "/";
+ String basename = path.endsWith("/") ? path : path + "/";
List listing = fService.getDirectoryListing(version, path);
for (FolderEntry entry : listing)
{
@@ -218,18 +458,18 @@ public class AVMServiceTest extends TestCase
private void setupBasicTree()
{
fService.createDirectory("main:/", "a");
- fService.createDirectory("main:a", "b");
- fService.createDirectory("main:a/b", "c");
+ fService.createDirectory("main:/a", "b");
+ fService.createDirectory("main:/a/b", "c");
fService.createDirectory("main:/", "d");
- fService.createDirectory("main:d", "e");
- fService.createDirectory("main:d/e", "f");
- fService.createFile("main:a/b/c", "foo");
- PrintStream out = new PrintStream(fService.getFileOutputStream("main:a/b/c/foo"));
- out.println("I am main:a/b/c/foo");
+ fService.createDirectory("main:/d", "e");
+ fService.createDirectory("main:/d/e", "f");
+ fService.createFile("main:/a/b/c", "foo");
+ PrintStream out = new PrintStream(fService.getFileOutputStream("main:/a/b/c/foo"));
+ out.println("I am main:/a/b/c/foo");
out.close();
- fService.createFile("main:a/b/c", "bar");
- out = new PrintStream(fService.getFileOutputStream("main:a/b/c/bar"));
- out.println("I am main:a/b/c/bar");
+ fService.createFile("main:/a/b/c", "bar");
+ out = new PrintStream(fService.getFileOutputStream("main:/a/b/c/bar"));
+ out.println("I am main:/a/b/c/bar");
out.close();
ArrayList toSnapshot = new ArrayList();
toSnapshot.add("main");
diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java
index 9195849d96..c2e7513a1f 100644
--- a/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java
+++ b/source/java/org/alfresco/repo/avm/LayeredDirectoryNode.java
@@ -18,6 +18,7 @@
package org.alfresco.repo.avm;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.TreeMap;
@@ -71,7 +72,7 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
time);
fData = new LayeredDirectoryNodeBeanImpl(repos.getSuperRepository().issueID(),
-1,
- -1,
+ 0,
null,
null,
null,
@@ -102,7 +103,7 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
attrs.setLastModifier("britt");
fData = new LayeredDirectoryNodeBeanImpl(repos.getSuperRepository().issueID(),
-1,
- -1,
+ 0,
null,
null,
null,
@@ -112,8 +113,8 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
thatBean.getPrimaryIndirection(),
other.getUnderlying());
setDataBean(fData);
- fData.setAdded(thatBean.getAdded());
- fData.setDeleted(thatBean.getDeleted());
+ fData.setAdded(new HashMap(thatBean.getAdded()));
+ fData.setDeleted(new HashSet(thatBean.getDeleted()));
// fData.setPrimaryIndirection(thatBean.getPrimaryIndirection());
repos.getSuperRepository().getSession().save(fData);
}
@@ -135,7 +136,7 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
attrs.setLastModifier("britt");
fData = new LayeredDirectoryNodeBeanImpl(repos.getSuperRepository().issueID(),
-1,
- -1,
+ 0,
null,
null,
null,
@@ -174,7 +175,7 @@ public class LayeredDirectoryNode extends DirectoryNode implements Layered
attrs.setLastModifier("britt");
fData = new LayeredDirectoryNodeBeanImpl(repo.getSuperRepository().issueID(),
-1,
- -1,
+ 0,
null,
null,
null,
diff --git a/source/java/org/alfresco/repo/avm/LayeredFileNode.java b/source/java/org/alfresco/repo/avm/LayeredFileNode.java
index d3b6176bd3..c7f6c05461 100644
--- a/source/java/org/alfresco/repo/avm/LayeredFileNode.java
+++ b/source/java/org/alfresco/repo/avm/LayeredFileNode.java
@@ -62,7 +62,7 @@ public class LayeredFileNode extends FileNode implements Layered
fData =
new LayeredFileNodeBeanImpl(repo.getSuperRepository().issueID(),
-1,
- -1L,
+ 0L,
null,
null,
null,
@@ -99,7 +99,7 @@ public class LayeredFileNode extends FileNode implements Layered
fData =
new LayeredFileNodeBeanImpl(repos.getSuperRepository().issueID(),
-1,
- -1L,
+ 0L,
null,
null,
null,
@@ -126,7 +126,7 @@ public class LayeredFileNode extends FileNode implements Layered
time);
fData = new LayeredFileNodeBeanImpl(repo.getSuperRepository().issueID(),
-1,
- -1L,
+ 0L,
null,
null,
null,
@@ -151,10 +151,16 @@ public class LayeredFileNode extends FileNode implements Layered
*/
public AVMNode possiblyCopy(Lookup lPath)
{
- // LayeredFileNodes are always copied.
- // TODO This is busted. Need to set the PlainFileNode contents
- // to share with underlying file node.
- PlainFileNode newMe = new PlainFileNode(lPath.getRepository());
+ Lookup lookup = lPath.getRepository().getSuperRepository().lookup(-1, fData.getIndirection());
+ AVMNode indirect = lookup.getCurrentNode();
+ if (!(indirect instanceof FileNode))
+ {
+ throw new AlfrescoRuntimeException("Unbacked layered file node.");
+ }
+ // This is a mildly dirty trick. We use getContentForRead so as not to startle
+ // the ultimate destination content into copying itself prematurely.
+ FileContent content = ((FileNode)indirect).getContentForRead(-1, lPath.getRepository());
+ PlainFileNode newMe = new PlainFileNode(content, lPath.getRepository(), fData.getBasicAttributes());
newMe.setAncestor(this);
return newMe;
}
diff --git a/source/java/org/alfresco/repo/avm/Lookup.java b/source/java/org/alfresco/repo/avm/Lookup.java
index 398db0a259..23319d9cc6 100644
--- a/source/java/org/alfresco/repo/avm/Lookup.java
+++ b/source/java/org/alfresco/repo/avm/Lookup.java
@@ -120,7 +120,15 @@ public class Lookup
}
else
{
- comp.setIndirection(fComponents.get(fPosition).getIndirection() + "/" + name);
+ String parentIndirection = fComponents.get(fPosition).getIndirection();
+ if (parentIndirection.endsWith("/"))
+ {
+ comp.setIndirection(parentIndirection + name);
+ }
+ else
+ {
+ comp.setIndirection(parentIndirection + "/" + name);
+ }
}
fLayeredYet = true;
// Record the first layer seen.
@@ -278,7 +286,6 @@ public class Lookup
public String getCurrentIndirection()
{
String value = fComponents.get(fPosition).getIndirection();
- System.err.println(value);
return value;
}
diff --git a/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java b/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java
index e216bee1a4..7dfe5cc7ad 100644
--- a/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java
+++ b/source/java/org/alfresco/repo/avm/PlainDirectoryNode.java
@@ -96,7 +96,7 @@ public class PlainDirectoryNode extends DirectoryNode
attrs.setLastModifier("britt");
fData = new PlainDirectoryNodeBeanImpl(repos.getSuperRepository().issueID(),
-1,
- -1,
+ 0,
null,
null,
null,
diff --git a/source/java/org/alfresco/repo/avm/PlainFileNode.java b/source/java/org/alfresco/repo/avm/PlainFileNode.java
index a5fdeb06c2..41f6872ca1 100644
--- a/source/java/org/alfresco/repo/avm/PlainFileNode.java
+++ b/source/java/org/alfresco/repo/avm/PlainFileNode.java
@@ -60,7 +60,7 @@ public class PlainFileNode extends FileNode
time);
fData = new PlainFileNodeBeanImpl(repos.getSuperRepository().issueID(),
-1,
- -1,
+ 0,
null,
null,
null,
@@ -92,7 +92,7 @@ public class PlainFileNode extends FileNode
attrs.setLastModifier("britt");
fData = new PlainFileNodeBeanImpl(repos.getSuperRepository().issueID(),
-1,
- -1,
+ 0,
null,
null,
null,
@@ -103,7 +103,40 @@ public class PlainFileNode extends FileNode
fData.getContent().setRefCount(fData.getContent().getRefCount() + 1);
setDataBean(fData);
}
-
+
+ /**
+ * Constructor that takes a FileContent to share.
+ * @param content The FileContent to share.
+ * @param repos The Repository.
+ */
+ public PlainFileNode(FileContent content,
+ Repository repos,
+ BasicAttributesBean oAttrs)
+ {
+ // Setup sensible BasicAttributes.
+ long time = System.currentTimeMillis();
+ // TODO Figure out how to get user from context.
+
+ BasicAttributesBean attrs = new BasicAttributesBeanImpl(oAttrs);
+ attrs.setCreateDate(time);
+ attrs.setModDate(time);
+ attrs.setAccessDate(time);
+ attrs.setCreator("britt");
+ attrs.setLastModifier("britt");
+ fData = new PlainFileNodeBeanImpl(repos.getSuperRepository().issueID(),
+ -1,
+ 0,
+ null,
+ null,
+ null,
+ repos.getDataBean(),
+ attrs,
+ content.getDataBean());
+ repos.getSuperRepository().getSession().save(fData);
+ fData.getContent().setRefCount(fData.getContent().getRefCount() + 1);
+ setDataBean(fData);
+ }
+
/**
* Copy on write logic.
* @param lPath The lookup path.
diff --git a/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml b/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml
index 7f21e19cb9..c3f2ecafc7 100644
--- a/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml
+++ b/source/java/org/alfresco/repo/avm/hibernate/AVM.hbm.xml
@@ -75,6 +75,7 @@
column="primary_indirection" type="boolean" />