diff --git a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/avm-common-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/avm-common-SqlMap.xml
index 17477c71b0..be3ab964b8 100644
--- a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/avm-common-SqlMap.xml
+++ b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/avm-common-SqlMap.xml
@@ -784,6 +784,43 @@
order by version_id
+
+
+
+
+
+
+
+
update
diff --git a/config/alfresco/public-services-context.xml b/config/alfresco/public-services-context.xml
index 900d492fe5..21390c983b 100644
--- a/config/alfresco/public-services-context.xml
+++ b/config/alfresco/public-services-context.xml
@@ -912,6 +912,9 @@
hasAspect
getAPath
getGuid
+ getStoreVersionsFrom
+ getStoreVersionsTo
+ getStoreVersionsBetween
diff --git a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java
index c298fb30b8..bb50096024 100644
--- a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java
+++ b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java
@@ -949,4 +949,20 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa
grabLock(AVMUtil.extendAVMPath(path, name));
fService.createFile(path, name, in, aspects, properties);
}
+
+ public List getStoreVersionsTo(String name, int version)
+ {
+ return fService.getStoreVersionsTo(name, version);
+ }
+
+ public List getStoreVersionsFrom(String name, int version)
+ {
+ return fService.getStoreVersionsFrom(name, version);
+ }
+
+ public List getStoreVersionsBetween(String name, int from, int to)
+ {
+ return fService.getStoreVersionsBetween(name, from, to);
+ }
+
}
diff --git a/source/java/org/alfresco/repo/avm/AVMRepository.java b/source/java/org/alfresco/repo/avm/AVMRepository.java
index 790d94375d..08b63d58a1 100644
--- a/source/java/org/alfresco/repo/avm/AVMRepository.java
+++ b/source/java/org/alfresco/repo/avm/AVMRepository.java
@@ -3428,4 +3428,50 @@ public class AVMRepository
}
return store.getStoreAcl();
}
+
+ /**
+ * @param name
+ * @param version
+ * @return
+ */
+ public List getAVMStoreVersionsTo(String name, int version)
+ {
+ AVMStore store = getAVMStoreByName(name);
+ if (store == null)
+ {
+ throw new AVMNotFoundException("Store not found.");
+ }
+ return store.getVersionsTo(version);
+ }
+
+ /**
+ * @param name
+ * @param version
+ * @return
+ */
+ public List getAVMStoreVersionsFrom(String name, int version)
+ {
+ AVMStore store = getAVMStoreByName(name);
+ if (store == null)
+ {
+ throw new AVMNotFoundException("Store not found.");
+ }
+ return store.getVersionsFrom(version);
+ }
+
+ /**
+ * @param name
+ * @param startVersion
+ * @param endVersion
+ * @return
+ */
+ public List getAVMStoreVersionsBetween(String name, int startVersion, int endVersion)
+ {
+ AVMStore store = getAVMStoreByName(name);
+ if (store == null)
+ {
+ throw new AVMNotFoundException("Store not found.");
+ }
+ return store.getVersionsBetween(startVersion, endVersion);
+ }
}
diff --git a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java
index 699a8a0805..7dd0a3878c 100644
--- a/source/java/org/alfresco/repo/avm/AVMServiceImpl.java
+++ b/source/java/org/alfresco/repo/avm/AVMServiceImpl.java
@@ -1617,4 +1617,38 @@ public class AVMServiceImpl implements AVMService
}
fAVMRepository.setMimeType(path, mimeType);
}
+
+ public List getStoreVersionsTo(String name, int version)
+ {
+ if (name == null)
+ {
+ throw new AVMBadArgumentException("Illegal null argument.");
+ }
+ return fAVMRepository.getAVMStoreVersionsTo(name, version);
+ }
+
+ public List getStoreVersionsFrom(String name, int version)
+ {
+ if (name == null)
+ {
+ throw new AVMBadArgumentException("Illegal null argument.");
+ }
+ return fAVMRepository.getAVMStoreVersionsFrom(name, version);
+ }
+
+ /* (non-Javadoc)
+ * @see org.alfresco.service.cmr.avm.AVMService#getStoreVersionsBetween(java.lang.String, int, int)
+ */
+ public List getStoreVersionsBetween(String name, int startVersion, int endVersion)
+ {
+ if (name == null)
+ {
+ throw new AVMBadArgumentException("Illegal null argument.");
+ }
+ return fAVMRepository.getAVMStoreVersionsBetween(name, startVersion, endVersion);
+ }
+
+
+
+
}
diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java
index 77a8972690..5a49ecba5d 100644
--- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java
+++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java
@@ -29,11 +29,15 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.SortedMap;
import java.util.TreeMap;
+import javax.transaction.UserTransaction;
+
import org.alfresco.config.JNDIConstants;
import org.alfresco.model.ContentModel;
import org.alfresco.model.WCMModel;
@@ -47,6 +51,8 @@ import org.alfresco.repo.avm.actions.SimpleAVMSubmitAction;
import org.alfresco.repo.avm.util.BulkLoader;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.domain.PropertyValue;
+import org.alfresco.repo.domain.hibernate.SessionSizeResourceManager;
+import org.alfresco.repo.search.impl.lucene.ADMLuceneSearcherImpl;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
@@ -65,6 +71,7 @@ import org.alfresco.service.cmr.avmsync.AVMDifference;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.remote.RepoRemote;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.CrossRepositoryCopyService;
@@ -95,6 +102,430 @@ public class AVMServiceTest extends AVMServiceTestBase
super.testSetup();
}
+ public void test_ALF_786() throws Exception
+ {
+ int threads= 4;
+ int loops = 10;
+ int snapshotsPerLoop = 4;
+
+
+ int startVersion;
+ UserTransaction testTX = fTransactionService.getUserTransaction();
+ testTX.begin();
+ fService.createDirectory("main:/", "test");
+ startVersion = fService.createSnapshot("main", null, null).get("main");
+
+ testTX.commit();
+ testTX = fTransactionService.getUserTransaction();
+ testTX.begin();
+
+
+ StoreRef storeRef = AVMNodeConverter.ToStoreRef("main");
+ SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true);
+ ResultSet results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\"");
+ assertEquals(0, results.length());
+ results.close();
+ testTX.commit();
+
+ Thread runner = null;
+
+ for (int i = 0; i < threads; i++)
+ {
+ runner = new Nester("Concurrent-" + i, runner, false, snapshotsPerLoop, Nester.Mode.CREATE, loops);
+ }
+ if (runner != null)
+ {
+ runner.start();
+
+ try
+ {
+ runner.join();
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ testTX = fTransactionService.getUserTransaction();
+ testTX.begin();
+ // snap
+ testTX.commit();
+ testTX = fTransactionService.getUserTransaction();
+ testTX.begin();;
+ SortedMap listing = fService.getDirectoryListing(-1, "main:/test");
+ assertEquals(loops, listing.size());
+ for(AVMNodeDescriptor node : listing.values())
+ {
+ System.out.println("Listed: "+node.getPath()+" "+node.getVersionID());
+ }
+ List diffs = fSyncService.compare(startVersion, "main:/", -1, "main:/", null);
+ assertEquals(loops, diffs.size());
+ for(AVMDifference diff : diffs)
+ {
+ AVMNodeDescriptor desc = fService.lookup(diff.getDestinationVersion(), diff.getDestinationPath(), true);
+ assertFalse(desc.isDeleted());
+ }
+
+
+
+ searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true);
+ results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\"");
+ for(ResultSetRow row : results)
+ {
+ System.out.println("Found: "+row.getNodeRef());
+ }
+ assertEquals(loops, results.length());
+ results.close();
+ testTX.commit();
+
+ // update
+
+ runner = null;
+ for (int i = 0; i < threads; i++)
+ {
+ runner = new Nester("Concurrent-" + i, runner, false, snapshotsPerLoop, Nester.Mode.UPDATE, loops);
+ }
+ if (runner != null)
+ {
+ runner.start();
+
+ try
+ {
+ runner.join();
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ testTX = fTransactionService.getUserTransaction();
+ testTX.begin();
+ searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true);
+ results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\"");
+ for(ResultSetRow row : results)
+ {
+ System.out.println("Found: "+row.getNodeRef());
+ }
+ assertEquals(loops, results.length());
+ results.close();
+ testTX.commit();
+
+ // delete
+
+ runner = null;
+ for (int i = 0; i < threads; i++)
+ {
+ runner = new Nester("Concurrent-" + i, runner, false, snapshotsPerLoop, Nester.Mode.DELETE, loops);
+ }
+ if (runner != null)
+ {
+ runner.start();
+
+ try
+ {
+ runner.join();
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ testTX = fTransactionService.getUserTransaction();
+ testTX.begin();
+ searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true);
+ results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\"");
+ for(ResultSetRow row : results)
+ {
+ System.out.println("Found: "+row.getNodeRef());
+ }
+ assertEquals(0, results.length());
+ results.close();
+ testTX.commit();
+
+ // recreate
+
+ runner = null;
+ for (int i = 0; i < threads; i++)
+ {
+ runner = new Nester("Concurrent-" + i, runner, false, snapshotsPerLoop, Nester.Mode.CREATE, loops);
+ }
+ if (runner != null)
+ {
+ runner.start();
+
+ try
+ {
+ runner.join();
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ testTX = fTransactionService.getUserTransaction();
+ testTX.begin();
+ searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true);
+ results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\"");
+ for(ResultSetRow row : results)
+ {
+ System.out.println("Found: "+row.getNodeRef());
+ }
+ assertEquals(loops, results.length());
+ results.close();
+ testTX.commit();
+
+ //move
+
+ runner = null;
+ for (int i = 0; i < threads; i++)
+ {
+ runner = new Nester("Concurrent-" + i, runner, false, snapshotsPerLoop, Nester.Mode.MOVE, loops);
+ }
+ if (runner != null)
+ {
+ runner.start();
+
+ try
+ {
+ runner.join();
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ testTX = fTransactionService.getUserTransaction();
+ testTX.begin();
+ searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true);
+ results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\"");
+ for(ResultSetRow row : results)
+ {
+ System.out.println("Found: "+row.getNodeRef());
+ }
+ assertEquals(loops, results.length());
+ results.close();
+ testTX.commit();
+ }
+
+ public void xtest_ALF_786_PLUS() throws Exception
+ {
+ int startVersion;
+ UserTransaction testTX = fTransactionService.getUserTransaction();
+ testTX.begin();
+ fService.createDirectory("main:/", "test");
+ startVersion = fService.createSnapshot("main", null, null).get("main");
+
+ testTX.commit();
+ testTX = fTransactionService.getUserTransaction();
+ testTX.begin();
+
+
+ StoreRef storeRef = AVMNodeConverter.ToStoreRef("main");
+ SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true);
+ ResultSet results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\"");
+ assertEquals(0, results.length());
+ results.close();
+ testTX.commit();
+
+ Thread runner = null;
+
+ for (int i = 0; i < 10; i++)
+ {
+ runner = new Nester("Concurrent-" + i, runner, true, 10, Nester.Mode.CREATE, 10 );
+ }
+ if (runner != null)
+ {
+ runner.start();
+
+ try
+ {
+ runner.join();
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ testTX = fTransactionService.getUserTransaction();
+ testTX.begin();
+ // snap
+ testTX.commit();
+ testTX = fTransactionService.getUserTransaction();
+ testTX.begin();;
+ SortedMap listing = fService.getDirectoryListing(-1, "main:/test");
+ assertEquals(100, listing.size());
+ for(AVMNodeDescriptor node : listing.values())
+ {
+ System.out.println("Listed: "+node.getPath()+" "+node.getVersionID());
+ }
+ List diffs = fSyncService.compare(startVersion, "main:/", -1, "main:/", null);
+ assertEquals(100, diffs.size());
+ for(AVMDifference diff : diffs)
+ {
+ AVMNodeDescriptor desc = fService.lookup(diff.getDestinationVersion(), diff.getDestinationPath(), true);
+ assertFalse(desc.isDeleted());
+ }
+
+
+
+ searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef("main"), true);
+ results = searchService.query(storeRef, "lucene", "PATH:\"/test/*\"");
+ for(ResultSetRow row : results)
+ {
+ System.out.println("Found: "+row.getNodeRef());
+ }
+ assertEquals(100, results.length());
+ results.close();
+ testTX.commit();
+ }
+
+ static class Nester extends Thread
+ {
+ enum Mode {CREATE, UPDATE, DELETE, MOVE};
+
+ Thread waiter;
+
+ int i;
+
+ boolean multiThread;
+
+ int snapshotCount;
+
+ Mode mode;
+
+ int loopCount;
+
+ Nester(String name, Thread waiter, boolean multiThread, int snapshotCount, Mode mode, int loopCount)
+ {
+ super(name);
+ this.setDaemon(true);
+ this.waiter = waiter;
+ this.multiThread = multiThread;
+ this.snapshotCount = snapshotCount;
+ this.mode = mode;
+ this.loopCount = loopCount;
+ }
+
+ public void run()
+ {
+ fAuthenticationComponent.setSystemUserAsCurrentUser();
+ if (waiter != null)
+ {
+ waiter.start();
+ }
+ try
+ {
+ System.out.println("Start " + this.getName());
+ for(i = 0; i < loopCount; i++)
+ {
+ RetryingTransactionCallback create = new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ fService.createFile("main:/test", getName()+"-"+i);
+
+ return null;
+ }
+ };
+ RetryingTransactionCallback update = new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ fService.setMimeType("main:/test/"+getName()+"-"+i, "text/plain");
+
+ return null;
+ }
+ };
+ RetryingTransactionCallback delete = new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ fService.removeNode("main:/test/"+getName()+"-"+i);
+
+ return null;
+ }
+ };
+ RetryingTransactionCallback move = new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ fService.rename("main:/test/", getName()+"-"+i, "main:/test/", "MOVED-"+getName()+"-"+i);
+
+ return null;
+ }
+ };
+ if(multiThread || (waiter == null))
+ {
+ // only one thread creates for 786
+ switch(mode)
+ {
+ case CREATE:
+ fRetryingTransactionHelper.doInTransaction(create);
+ System.out.println(getName()+i);
+ break;
+ case UPDATE:
+ fRetryingTransactionHelper.doInTransaction(update);
+ break;
+ case DELETE:
+ fRetryingTransactionHelper.doInTransaction(delete);
+ break;
+ case MOVE:
+ fRetryingTransactionHelper.doInTransaction(move);
+ break;
+ default:
+ }
+
+ }
+
+ RetryingTransactionCallback snap = new RetryingTransactionCallback()
+ {
+ public Void execute() throws Throwable
+ {
+ fService.createSnapshot("main", null, null);
+
+
+ return null;
+ }
+ };
+ for(int s = 0; s < snapshotCount; s++)
+ {
+ fRetryingTransactionHelper.doInTransaction(snap);
+ }
+ }
+ System.out.println("End " + this.getName());
+ }
+ catch (Exception e)
+ {
+ System.out.println("End " + this.getName() + " with error " + e.getMessage());
+ e.printStackTrace();
+ }
+ finally
+ {
+ fAuthenticationComponent.clearCurrentSecurityContext();
+ }
+ if (waiter != null)
+ {
+ try
+ {
+ waiter.join();
+ System.out.println("Waited for " + waiter.getName()+" by "+this.getName());
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+ }
+
+ }
+
+
+
public void testDiffOrder()
{
try
@@ -348,6 +779,57 @@ public class AVMServiceTest extends AVMServiceTestBase
assertEquals(1, fService.getStoreVersions("main", null, new Date(times.get(0))).size());
assertEquals(3, fService.getStoreVersions("main", new Date(times.get(0)), null).size());
assertEquals(2, fService.getStoreVersions("main", new Date(times.get(1)), new Date(System.currentTimeMillis())).size());
+
+ // TO
+ assertEquals(1, fService.getStoreVersionsTo("main", 0).size());
+ assertEquals(0, fService.getStoreVersionsTo("main", 0).get(0).getVersionID());
+ assertEquals(2, fService.getStoreVersionsTo("main", 1).size());
+ assertEquals(0, fService.getStoreVersionsTo("main", 1).get(0).getVersionID());
+ assertEquals(1, fService.getStoreVersionsTo("main", 1).get(1).getVersionID());
+ assertEquals(3, fService.getStoreVersionsTo("main", 2).size());
+ assertEquals(0, fService.getStoreVersionsTo("main", 2).get(0).getVersionID());
+ assertEquals(1, fService.getStoreVersionsTo("main", 2).get(1).getVersionID());
+ assertEquals(2, fService.getStoreVersionsTo("main", 2).get(2).getVersionID());
+ assertEquals(4, fService.getStoreVersionsTo("main", 3).size());
+ assertEquals(0, fService.getStoreVersionsTo("main", 3).get(0).getVersionID());
+ assertEquals(1, fService.getStoreVersionsTo("main", 3).get(1).getVersionID());
+ assertEquals(2, fService.getStoreVersionsTo("main", 3).get(2).getVersionID());
+ assertEquals(3, fService.getStoreVersionsTo("main", 3).get(3).getVersionID());
+
+ // FROM
+
+ assertEquals(4, fService.getStoreVersionsFrom("main", 0).size());
+ assertEquals(0, fService.getStoreVersionsFrom("main", 0).get(0).getVersionID());
+ assertEquals(1, fService.getStoreVersionsFrom("main", 0).get(1).getVersionID());
+ assertEquals(2, fService.getStoreVersionsFrom("main", 0).get(2).getVersionID());
+ assertEquals(3, fService.getStoreVersionsFrom("main", 0).get(3).getVersionID());
+ assertEquals(3, fService.getStoreVersionsFrom("main", 1).size());
+ assertEquals(1, fService.getStoreVersionsFrom("main", 1).get(0).getVersionID());
+ assertEquals(2, fService.getStoreVersionsFrom("main", 1).get(1).getVersionID());
+ assertEquals(3, fService.getStoreVersionsFrom("main", 1).get(2).getVersionID());
+ assertEquals(2, fService.getStoreVersionsFrom("main", 2).size());
+ assertEquals(2, fService.getStoreVersionsFrom("main", 2).get(0).getVersionID());
+ assertEquals(3, fService.getStoreVersionsFrom("main", 2).get(1).getVersionID());
+ assertEquals(1, fService.getStoreVersionsFrom("main", 3).size());
+ assertEquals(3, fService.getStoreVersionsFrom("main", 3).get(0).getVersionID());
+ assertEquals(0, fService.getStoreVersionsFrom("main", 4).size());
+
+ // BETWEEN
+
+ assertEquals(1, fService.getStoreVersionsBetween("main", 0, 0).size());
+ assertEquals(0, fService.getStoreVersionsBetween("main", 0, 0).get(0).getVersionID());
+ assertEquals(1, fService.getStoreVersionsBetween("main", 1, 1).size());
+ assertEquals(1, fService.getStoreVersionsBetween("main", 1, 1).get(0).getVersionID());
+ assertEquals(1, fService.getStoreVersionsBetween("main", 2, 2).size());
+ assertEquals(2, fService.getStoreVersionsBetween("main", 2, 2).get(0).getVersionID());
+ assertEquals(1, fService.getStoreVersionsBetween("main", 3, 3).size());
+ assertEquals(3, fService.getStoreVersionsBetween("main", 3, 3).get(0).getVersionID());
+ assertEquals(0, fService.getStoreVersionsBetween("main", 4, 4).size());
+
+
+ assertEquals(2, fService.getStoreVersionsBetween("main", 1, 2).size());
+ assertEquals(1, fService.getStoreVersionsBetween("main", 1, 2).get(0).getVersionID());
+ assertEquals(2, fService.getStoreVersionsBetween("main", 1, 2).get(1).getVersionID());
}
catch (Exception e)
{
@@ -2182,7 +2664,7 @@ public class AVMServiceTest extends AVMServiceTestBase
{
setupBasicTree();
fService.removeNode("main:/a/b/c/foo/");
- fService.removeNode("main://d");
+ fService.removeNode("main:/d");
fService.createSnapshot("main", null, null);
StoreRef storeRef = AVMNodeConverter.ToStoreRef("main");
@@ -2208,7 +2690,7 @@ public class AVMServiceTest extends AVMServiceTestBase
// TODO: Fix auth in AVMDiskDriver and more??
results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin");
- if (results.length() == 6)
+ if (results.length() == 7)
{
for (ResultSetRow row : results)
{
diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTestBase.java b/source/java/org/alfresco/repo/avm/AVMServiceTestBase.java
index b5ff8c84da..6f54b26d95 100644
--- a/source/java/org/alfresco/repo/avm/AVMServiceTestBase.java
+++ b/source/java/org/alfresco/repo/avm/AVMServiceTestBase.java
@@ -29,7 +29,9 @@ import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor;
import org.alfresco.repo.search.IndexerAndSearcher;
import org.alfresco.repo.search.impl.lucene.LuceneQueryParser;
+import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
+import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
@@ -74,6 +76,10 @@ public class AVMServiceTestBase extends TestCase
*/
private long fStartTime;
+ protected static RetryingTransactionHelper fRetryingTransactionHelper;
+
+ protected static AuthenticationComponent fAuthenticationComponent;
+
protected static AVMSnapShotTriggeredIndexingMethodInterceptor fIndexingInterceptor;
protected static TransactionService fTransactionService;
@@ -108,6 +114,8 @@ public class AVMServiceTestBase extends TestCase
fLockingService = (AVMLockingService)fContext.getBean("AVMLockingService");
fIndexingInterceptor = (AVMSnapShotTriggeredIndexingMethodInterceptor)fContext.getBean("avmSnapShotTriggeredIndexingMethodInterceptor");
fAuthService = (AuthenticationService)fContext.getBean("AuthenticationService");
+ fAuthenticationComponent = (AuthenticationComponent) fContext.getBean("authenticationComponent");
+ fRetryingTransactionHelper = (RetryingTransactionHelper) fContext.getBean("retryingTransactionHelper");
CreateStoreTxnListener cstl = (CreateStoreTxnListener)fContext.getBean("createStoreTxnListener");
cstl.addCallback(
diff --git a/source/java/org/alfresco/repo/avm/AVMStore.java b/source/java/org/alfresco/repo/avm/AVMStore.java
index 2c67e00616..82e00c1095 100644
--- a/source/java/org/alfresco/repo/avm/AVMStore.java
+++ b/source/java/org/alfresco/repo/avm/AVMStore.java
@@ -211,6 +211,28 @@ public interface AVMStore
*/
public List getVersions();
+ /**
+ * Get all the versions starting from the last until the version specified
+ * @param version - the version which which to end
+ * @return - the versions in descending order
+ */
+ public List getVersionsFrom(int version);
+
+ /**
+ * Get all the versions after and including the one specified
+ * @param version - the version to start from
+ * @return - the versions in ascending order
+ */
+ public List getVersionsTo(int version);
+
+ /**
+ * Get all versions from an including startVersion up to but NOT including endVersion
+ * @param startVersion
+ * @param endVersion
+ * @return - the versions in ascending order
+ */
+ public List getVersionsBetween(int startVersion, int endVersion);
+
/**
* Get the versions from between the given dates. From or to
* may be null but not both.
diff --git a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java
index abd0b68e0e..1171e8c7fb 100644
--- a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java
+++ b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java
@@ -951,6 +951,65 @@ public class AVMStoreImpl implements AVMStore
return descs;
}
+
+
+ public List getVersionsTo(int version)
+ {
+ List versions = AVMDAOs.Instance().fVersionRootDAO.getByVersionsTo(this, version);
+ List descs = new ArrayList();
+ for (VersionRoot vr : versions)
+ {
+ VersionDescriptor desc =
+ new VersionDescriptor(getName(),
+ vr.getVersionID(),
+ vr.getCreator(),
+ vr.getCreateDate(),
+ vr.getTag(),
+ vr.getDescription());
+ descs.add(desc);
+ }
+ return descs;
+ }
+
+ public List getVersionsFrom(int version)
+ {
+ List versions = AVMDAOs.Instance().fVersionRootDAO.getByVersionsFrom(this, version);
+ List descs = new ArrayList();
+ for (VersionRoot vr : versions)
+ {
+ VersionDescriptor desc =
+ new VersionDescriptor(getName(),
+ vr.getVersionID(),
+ vr.getCreator(),
+ vr.getCreateDate(),
+ vr.getTag(),
+ vr.getDescription());
+ descs.add(desc);
+ }
+ return descs;
+ }
+
+
+
+
+ public List getVersionsBetween(int startVersion, int endVersion)
+ {
+ List versions = AVMDAOs.Instance().fVersionRootDAO.getByVersionsBetween(this, startVersion, endVersion);
+ List descs = new ArrayList();
+ for (VersionRoot vr : versions)
+ {
+ VersionDescriptor desc =
+ new VersionDescriptor(getName(),
+ vr.getVersionID(),
+ vr.getCreator(),
+ vr.getCreateDate(),
+ vr.getTag(),
+ vr.getDescription());
+ descs.add(desc);
+ }
+ return descs;
+ }
+
/**
* Get the AVMRepository.
* @return The AVMRepository
diff --git a/source/java/org/alfresco/repo/avm/MultiTAVMService.java b/source/java/org/alfresco/repo/avm/MultiTAVMService.java
index b8937b63fa..d5c69f501d 100644
--- a/source/java/org/alfresco/repo/avm/MultiTAVMService.java
+++ b/source/java/org/alfresco/repo/avm/MultiTAVMService.java
@@ -823,6 +823,24 @@ public class MultiTAVMService implements AVMService
}
+ public List getStoreVersionsTo(String name, int version)
+ {
+ // TODO - review
+ return fService.getStoreVersionsTo(name, version);
+ }
+
+ public List getStoreVersionsFrom(String name, int version)
+ {
+ // TODO - review
+ return fService.getStoreVersionsFrom(name, version);
+ }
+
+ public List getStoreVersionsBetween(String name, int from, int to)
+ {
+ // TODO - review
+ return fService.getStoreVersionsBetween(name, from, to);
+ }
+
private String getTenantStoreName(String avmStoreName)
{
if ((avmStoreName == null) || (! isTenantServiceEnabled()))
diff --git a/source/java/org/alfresco/repo/avm/VersionRootDAO.java b/source/java/org/alfresco/repo/avm/VersionRootDAO.java
index 47f9414a63..c30a036be4 100644
--- a/source/java/org/alfresco/repo/avm/VersionRootDAO.java
+++ b/source/java/org/alfresco/repo/avm/VersionRootDAO.java
@@ -85,4 +85,26 @@ public interface VersionRootDAO
* @return The highest numbered id.
*/
public Integer getMaxVersionID(AVMStore store);
+
+ /**
+ * @param store
+ * @param version
+ * @return
+ */
+ public List getByVersionsTo(AVMStore store, int version);
+
+ /**
+ * @param store
+ * @param version
+ * @return
+ */
+ public List getByVersionsFrom(AVMStore store, int version);
+
+ /**
+ * @param store
+ * @param startVersion
+ * @param endVersion
+ * @return
+ */
+ public List getByVersionsBetween(AVMStore store, int startVersion, int endVersion);
}
diff --git a/source/java/org/alfresco/repo/avm/ibatis/VersionRootDAOIbatis.java b/source/java/org/alfresco/repo/avm/ibatis/VersionRootDAOIbatis.java
index b5636e2abc..482ba3b6ba 100644
--- a/source/java/org/alfresco/repo/avm/ibatis/VersionRootDAOIbatis.java
+++ b/source/java/org/alfresco/repo/avm/ibatis/VersionRootDAOIbatis.java
@@ -25,6 +25,7 @@ import java.util.List;
import org.alfresco.repo.avm.AVMDAOs;
import org.alfresco.repo.avm.AVMNode;
import org.alfresco.repo.avm.AVMStore;
+import org.alfresco.repo.avm.AVMStoreImpl;
import org.alfresco.repo.avm.DirectoryNode;
import org.alfresco.repo.avm.VersionRoot;
import org.alfresco.repo.avm.VersionRootDAO;
@@ -140,6 +141,43 @@ class VersionRootDAOIbatis implements VersionRootDAO
return new Integer(maxVersionId.intValue());
}
+
+
+ public List getByVersionsTo(AVMStore store, int version)
+ {
+ List vrEntities = AVMDAOs.Instance().newAVMVersionRootDAO.getByVersionsTo(store.getId(), version);
+ List vrs = new ArrayList(vrEntities.size());
+ for (AVMVersionRootEntity vrEntity : vrEntities)
+ {
+ vrs.add(convertVersionRootEntityToVersionRoot(vrEntity));
+ }
+ return vrs;
+ }
+
+ public List getByVersionsFrom(AVMStore store, int version)
+ {
+ List vrEntities = AVMDAOs.Instance().newAVMVersionRootDAO.getByVersionsFrom(store.getId(), version);
+ List vrs = new ArrayList(vrEntities.size());
+ for (AVMVersionRootEntity vrEntity : vrEntities)
+ {
+ vrs.add(convertVersionRootEntityToVersionRoot(vrEntity));
+ }
+ return vrs;
+ }
+
+
+
+ public List getByVersionsBetween(AVMStore store, int startVersion, int endVersion)
+ {
+ List vrEntities = AVMDAOs.Instance().newAVMVersionRootDAO.getByVersionsBetween(store.getId(), startVersion, endVersion);
+ List vrs = new ArrayList(vrEntities.size());
+ for (AVMVersionRootEntity vrEntity : vrEntities)
+ {
+ vrs.add(convertVersionRootEntityToVersionRoot(vrEntity));
+ }
+ return vrs;
+ }
+
private AVMVersionRootEntity convertVersionRootToVersionRootEntity(VersionRoot vr)
{
if (vr == null)
diff --git a/source/java/org/alfresco/repo/domain/avm/AVMVersionRootDAO.java b/source/java/org/alfresco/repo/domain/avm/AVMVersionRootDAO.java
index 9eb8fb4dd4..9a103cde61 100644
--- a/source/java/org/alfresco/repo/domain/avm/AVMVersionRootDAO.java
+++ b/source/java/org/alfresco/repo/domain/avm/AVMVersionRootDAO.java
@@ -103,4 +103,26 @@ public interface AVMVersionRootDAO
public void deleteVersionLayeredNodeEntries(long versionRootId);
public List getVersionLayeredNodeEntries(long versionRootId);
+
+ /**
+ * @param id
+ * @param version
+ * @return
+ */
+ public List getByVersionsTo(long id, int version);
+
+ /**
+ * @param id
+ * @param version
+ * @return
+ */
+ public List getByVersionsFrom(long id, int version);
+
+ /**
+ * @param id
+ * @param startVersion
+ * @param endVersion
+ * @return
+ */
+ public List getByVersionsBetween(long id, int startVersion, int endVersion);
}
diff --git a/source/java/org/alfresco/repo/domain/avm/AbstractAVMVersionRootDAOImpl.java b/source/java/org/alfresco/repo/domain/avm/AbstractAVMVersionRootDAOImpl.java
index c949b93932..b39da86d2b 100644
--- a/source/java/org/alfresco/repo/domain/avm/AbstractAVMVersionRootDAOImpl.java
+++ b/source/java/org/alfresco/repo/domain/avm/AbstractAVMVersionRootDAOImpl.java
@@ -283,4 +283,27 @@ public abstract class AbstractAVMVersionRootDAOImpl implements AVMVersionRootDAO
protected abstract AVMVersionLayeredNodeEntryEntity createVersionLayeredNodeEntryEntity(long versionRootId, String md5sum, String path);
protected abstract int deleteVersionLayeredNodeEntryEntities(long versionRootId);
protected abstract List getVersionLayeredNodeEntryEntities(long storeId);
+
+
+ protected abstract List getVersionRootEntitiesByVersionsTo(long storeId, long to);
+ protected abstract List getVersionRootEntitiesByVersionsFrom(long storeId, long from);
+ protected abstract List getVersionRootEntitiesByVersionsBetween(long storeId, long from, long to);
+
+ public List getByVersionsTo(long id, int version)
+ {
+ return getVersionRootEntitiesByVersionsTo(id, version);
+ }
+
+ public List getByVersionsFrom(long id, int version)
+ {
+ return getVersionRootEntitiesByVersionsFrom(id, version);
+ }
+
+ public List getByVersionsBetween(long id, int startVersion, int endVersion)
+ {
+ return getVersionRootEntitiesByVersionsBetween(id, startVersion, endVersion);
+ }
+
+
+
}
diff --git a/source/java/org/alfresco/repo/domain/avm/ibatis/AVMVersionRootDAOImpl.java b/source/java/org/alfresco/repo/domain/avm/ibatis/AVMVersionRootDAOImpl.java
index c484d70e4e..1a0fab5ae7 100644
--- a/source/java/org/alfresco/repo/domain/avm/ibatis/AVMVersionRootDAOImpl.java
+++ b/source/java/org/alfresco/repo/domain/avm/ibatis/AVMVersionRootDAOImpl.java
@@ -46,9 +46,13 @@ public class AVMVersionRootDAOImpl extends AbstractAVMVersionRootDAOImpl
private static final String SELECT_AVM_VERSION_ROOT_BY_STORE_VERSION ="alfresco.avm.select_AVMVersionRootByStoreVersion";
private static final String SELECT_AVM_VERSION_ROOT_BY_ROOT_NODE_ID ="alfresco.avm.select_AVMVersionRootByRootNodeId";
private static final String SELECT_AVM_VERSION_ROOTS_BY_STORE_ID ="alfresco.avm.select_AVMVersionRootsByStoreId";
- private static final String SELECT_AVM_VERSION_ROOTS_BY_TO ="alfresco.avm.select_AVMVersionRootsByTo";
- private static final String SELECT_AVM_VERSION_ROOTS_BY_FROM ="alfresco.avm.select_AVMVersionRootsByFrom";
- private static final String SELECT_AVM_VERSION_ROOTS_BETWEEN ="alfresco.avm.select_AVMVersionRootsBetween";
+ private static final String SELECT_AVM_VERSION_ROOTS_BY_DATE_TO ="alfresco.avm.select_AVMVersionRootsByTo";
+ private static final String SELECT_AVM_VERSION_ROOTS_BY_DATE_FROM ="alfresco.avm.select_AVMVersionRootsByFrom";
+ private static final String SELECT_AVM_VERSION_ROOTS_BY_DATES_BETWEEN ="alfresco.avm.select_AVMVersionRootsBetween";
+
+ private static final String SELECT_AVM_VERSION_ROOTS_BY_VERSION_TO ="alfresco.avm.select_AVMVersionRootsByVersionTo";
+ private static final String SELECT_AVM_VERSION_ROOTS_BY_VERSION_FROM ="alfresco.avm.select_AVMVersionRootsByVersionFrom";
+ private static final String SELECT_AVM_VERSION_ROOTS_BY_VERSIONS_BETWEEN ="alfresco.avm.select_AVMVersionRootsByVersionsBetween";
private static final String INSERT_AVM_VERSION_LAYERED_NODE_ENTRY ="alfresco.avm.insert_AVMVersionLayeredNodeEntry";
private static final String DELETE_AVM_VERSION_LAYERED_NODE_ENTRIES ="alfresco.avm.delete_AVMVersionLayeredNodeEntries";
@@ -138,7 +142,7 @@ public class AVMVersionRootDAOImpl extends AbstractAVMVersionRootDAOImpl
Map params = new HashMap(2);
params.put("id", storeId);
params.put("to", to);
- return (List) template.queryForList(SELECT_AVM_VERSION_ROOTS_BY_TO, params);
+ return (List) template.queryForList(SELECT_AVM_VERSION_ROOTS_BY_DATE_TO, params);
}
@SuppressWarnings("unchecked")
@@ -147,7 +151,7 @@ public class AVMVersionRootDAOImpl extends AbstractAVMVersionRootDAOImpl
Map params = new HashMap(2);
params.put("id", storeId);
params.put("from", from);
- return (List) template.queryForList(SELECT_AVM_VERSION_ROOTS_BY_FROM, params);
+ return (List) template.queryForList(SELECT_AVM_VERSION_ROOTS_BY_DATE_FROM, params);
}
@SuppressWarnings("unchecked")
@@ -157,9 +161,37 @@ public class AVMVersionRootDAOImpl extends AbstractAVMVersionRootDAOImpl
params.put("id", storeId);
params.put("from", from);
params.put("to", to);
- return (List) template.queryForList(SELECT_AVM_VERSION_ROOTS_BETWEEN, params);
+ return (List) template.queryForList(SELECT_AVM_VERSION_ROOTS_BY_DATES_BETWEEN, params);
}
+ @Override
+ protected List getVersionRootEntitiesByVersionsBetween(long storeId, long from, long to)
+ {
+ Map params = new HashMap(3);
+ params.put("id", storeId);
+ params.put("from", from);
+ params.put("to", to);
+ return (List) template.queryForList(SELECT_AVM_VERSION_ROOTS_BY_VERSIONS_BETWEEN, params);
+ }
+
+ @Override
+ protected List getVersionRootEntitiesByVersionsFrom(long storeId, long from)
+ {
+ Map params = new HashMap(2);
+ params.put("id", storeId);
+ params.put("from", from);
+ return (List) template.queryForList(SELECT_AVM_VERSION_ROOTS_BY_VERSION_FROM, params);
+ }
+
+ @Override
+ protected List getVersionRootEntitiesByVersionsTo(long storeId, long to)
+ {
+ Map params = new HashMap(2);
+ params.put("id", storeId);
+ params.put("to", to);
+ return (List) template.queryForList(SELECT_AVM_VERSION_ROOTS_BY_VERSION_TO, params);
+ }
+
@Override
protected int deleteVersionRootEntity(long vrEntityId)
{
diff --git a/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptor.java b/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptor.java
index 8753bc85f1..6dedaa63c5 100644
--- a/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptor.java
+++ b/source/java/org/alfresco/repo/search/AVMSnapShotTriggeredIndexingMethodInterceptor.java
@@ -36,7 +36,7 @@ import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
- * Method interceptor for atomic indexing of AVM entries The properties can defined how stores are indexed based on type
+ * Method interceptor for atomic indexing of AVM entries The properties can defined how stores are indexed based on type
* (as set by Alfresco the Web site management UI) or based on the name of the store. Creates and deletes are indexed
* synchronously. Updates may be asynchronous, synchronous or ignored by the index.
*
@@ -100,14 +100,14 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
{
String store = (String) mi.getArguments()[0];
Object returnValue = mi.proceed();
-
- if (getIndexMode(store) != IndexMode.UNINDEXED)
+
+ if (getIndexMode(store) != IndexMode.UNINDEXED)
{
- AVMLuceneIndexer avmIndexer = getIndexer(store);
- if (avmIndexer != null)
- {
- avmIndexer.deleteIndex(store, IndexMode.SYNCHRONOUS);
- }
+ AVMLuceneIndexer avmIndexer = getIndexer(store);
+ if (avmIndexer != null)
+ {
+ avmIndexer.deleteIndex(store, IndexMode.SYNCHRONOUS);
+ }
}
return returnValue;
}
@@ -115,10 +115,10 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
{
String store = (String) mi.getArguments()[0];
Object returnValue = mi.proceed();
- if (getIndexMode(store) != IndexMode.UNINDEXED)
- {
- createIndex(store);
- }
+ if (getIndexMode(store) != IndexMode.UNINDEXED)
+ {
+ createIndex(store);
+ }
return returnValue;
}
else if (mi.getMethod().getName().equals("renameStore"))
@@ -127,24 +127,24 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
String to = (String) mi.getArguments()[1];
Object returnValue = mi.proceed();
int after = avmService.getLatestSnapshotID(to);
-
- if (getIndexMode(from) != IndexMode.UNINDEXED)
+
+ if (getIndexMode(from) != IndexMode.UNINDEXED)
{
- AVMLuceneIndexer avmIndexer = getIndexer(from);
- if (avmIndexer != null)
- {
- avmIndexer.deleteIndex(from, IndexMode.SYNCHRONOUS);
- }
+ AVMLuceneIndexer avmIndexer = getIndexer(from);
+ if (avmIndexer != null)
+ {
+ avmIndexer.deleteIndex(from, IndexMode.SYNCHRONOUS);
+ }
}
-
- if (getIndexMode(to) != IndexMode.UNINDEXED)
+
+ if (getIndexMode(to) != IndexMode.UNINDEXED)
{
- AVMLuceneIndexer avmIndexer = getIndexer(to);
- if (avmIndexer != null)
- {
- avmIndexer.createIndex(to, IndexMode.SYNCHRONOUS);
- avmIndexer.index(to, 0, after, getIndexMode(to));
- }
+ AVMLuceneIndexer avmIndexer = getIndexer(to);
+ if (avmIndexer != null)
+ {
+ avmIndexer.createIndex(to, IndexMode.SYNCHRONOUS);
+ avmIndexer.index(to, 0, after, getIndexMode(to));
+ }
}
return returnValue;
}
@@ -213,74 +213,76 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
{
this.defaultMode = defaultMode;
}
-
+
+ /**
+ * Is snapshot triggered indexing enabled
+ *
+ * @return true if indexing is enabled for AVM
+ */
+ public boolean isIndexingEnabled()
+ {
+ return enableIndexing;
+ }
+
/**
- * Is snapshot triggered indexing enabled
- *
- * @return true if indexing is enabled for AVM
- */
- public boolean isIndexingEnabled()
- {
- return enableIndexing;
- }
-
- /**
* @param store
* @param before
* @param after
*/
public void indexSnapshot(String store, int before, int after)
{
- indexSnapshotImpl(store, before, after);
+ indexSnapshotImpl(store, before, after);
}
-
- /**
- * @param store
- * @param after
- */
+
+ /**
+ * @param store
+ * @param after
+ */
public void indexSnapshot(String store, int after)
{
- indexSnapshotImpl(store, -1, after);
- }
-
- private void indexSnapshotImpl(String store, int before, int after)
- {
- if (getIndexMode(store) != IndexMode.UNINDEXED)
+ indexSnapshotImpl(store, -1, after);
+ }
+
+ private void indexSnapshotImpl(String store, int before, int after)
+ {
+ if (getIndexMode(store) != IndexMode.UNINDEXED)
{
- AVMLuceneIndexer avmIndexer = getIndexer(store);
- if (avmIndexer != null)
- {
- int last = getLastIndexedSnapshot(avmIndexer, store);
-
- if ((last == -1) && (! hasIndexBeenCreated(store)))
- {
- createIndex(store);
- }
-
- avmIndexer.index(store, (before != -1 ? before : last), after, getIndexMode(store));
- }
+ AVMLuceneIndexer avmIndexer = getIndexer(store);
+ if (avmIndexer != null)
+ {
+ int last = getLastIndexedSnapshot(avmIndexer, store);
+
+ if ((last == -1) && (! hasIndexBeenCreated(store)))
+ {
+ createIndex(store);
+ }
+
+ int from = before != -1 ? before : last;
+ avmIndexer.index(store, from, after, getIndexMode(store));
+ }
}
}
-
+
/**
* @param store
* @return - the last indexed snapshot
*/
public int getLastIndexedSnapshot(String store)
{
- AVMLuceneIndexer avmIndexer = getIndexer(store);
- if (avmIndexer != null)
+
+ AVMLuceneIndexer avmIndexer = getIndexer(store);
+ if (avmIndexer != null)
{
- return getLastIndexedSnapshot(avmIndexer, store);
+ return getLastIndexedSnapshot(avmIndexer, store);
}
return -1;
}
-
- private int getLastIndexedSnapshot(AVMLuceneIndexer avmIndexer, String store)
- {
- return avmIndexer.getLastIndexedSnapshot(store);
- }
-
+
+ private int getLastIndexedSnapshot(AVMLuceneIndexer avmIndexer, String store)
+ {
+ return avmIndexer.getLastIndexedSnapshot(store);
+ }
+
/**
* Is the snapshot applied to the index? Is there an entry for any node that was added OR have all the nodes in the
* transaction been deleted as expected?
@@ -291,8 +293,8 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
*/
public boolean isSnapshotIndexed(String store, int id)
{
- AVMLuceneIndexer avmIndexer = getIndexer(store);
- if (avmIndexer != null)
+ AVMLuceneIndexer avmIndexer = getIndexer(store);
+ if (avmIndexer != null)
{
return avmIndexer.isSnapshotIndexed(store, id);
}
@@ -315,8 +317,8 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
case SYNCHRONOUS:
case ASYNCHRONOUS:
int last = avmService.getLatestSnapshotID(store);
- AVMLuceneIndexer avmIndexer = getIndexer(store);
- if (avmIndexer != null)
+ AVMLuceneIndexer avmIndexer = getIndexer(store);
+ if (avmIndexer != null)
{
avmIndexer.flushPending();
return avmIndexer.isSnapshotSearchable(store, last);
@@ -343,11 +345,11 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
case SYNCHRONOUS:
case ASYNCHRONOUS:
int last = avmService.getLatestSnapshotID(store);
- AVMLuceneIndexer avmIndexer = getIndexer(store);
- if (avmIndexer != null)
+ AVMLuceneIndexer avmIndexer = getIndexer(store);
+ if (avmIndexer != null)
{
avmIndexer.flushPending();
- return getLastIndexedSnapshot(avmIndexer, store) == last;
+ return avmIndexer.isSnapshotIndexed(store, last);
}
return false;
default:
@@ -487,8 +489,8 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
public boolean hasIndexBeenCreated(String store)
{
- AVMLuceneIndexer avmIndexer = getIndexer(store);
- if (avmIndexer != null)
+ AVMLuceneIndexer avmIndexer = getIndexer(store);
+ if (avmIndexer != null)
{
avmIndexer.flushPending();
return avmIndexer.hasIndexBeenCreated(store);
@@ -498,8 +500,8 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
public void createIndex(String store)
{
- AVMLuceneIndexer avmIndexer = getIndexer(store);
- if (avmIndexer != null)
+ AVMLuceneIndexer avmIndexer = getIndexer(store);
+ if (avmIndexer != null)
{
avmIndexer.createIndex(store, IndexMode.SYNCHRONOUS);
}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexer.java b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexer.java
index 48f2806ec3..4d882050c6 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexer.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexer.java
@@ -18,8 +18,11 @@
*/
package org.alfresco.repo.search.impl.lucene;
+import java.util.List;
+
import org.alfresco.repo.search.BackgroundIndexerAware;
import org.alfresco.repo.search.IndexMode;
+import org.alfresco.service.cmr.avm.VersionDescriptor;
/**
* AVM specific indxer support
@@ -56,17 +59,6 @@ public interface AVMLuceneIndexer extends LuceneIndexer, BackgroundIndexerAware
*/
public void createIndex(String store, IndexMode mode);
- /**
- * Get the id of the last snapshot added to the index
- * @param store
- *
- * @param mode
- * - IndexMode.SYNCHRONOUS - the last searchable snapshop
- * - IndexMode.ASYNCHRONOUS - the last pending snapshot to be indexed. It may or may not be searchable.
- * @return - the snapshot id
- */
- public int getLastIndexedSnapshot(String store);
-
/**
* Is the snapshot applied to the index?
*
@@ -99,4 +91,12 @@ public interface AVMLuceneIndexer extends LuceneIndexer, BackgroundIndexerAware
* @return
*/
public long getIndexedDocCount();
+
+ /**
+ * Get the last snapshot in the index - this does not mean that all snapshots before it have been indexed.
+ *
+ * @param store
+ * @return
+ */
+ public int getLastIndexedSnapshot(String store);
}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java
index fcb51cf957..96f7bdd5a0 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java
@@ -59,6 +59,7 @@ import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.avm.AVMException;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMService;
+import org.alfresco.service.cmr.avm.VersionDescriptor;
import org.alfresco.service.cmr.avmsync.AVMDifference;
import org.alfresco.service.cmr.avmsync.AVMSyncException;
import org.alfresco.service.cmr.avmsync.AVMSyncService;
@@ -129,7 +130,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
private int startVersion = -1;
private int endVersion = -1;
-
+
private long indexedDocCount = 0;
/**
@@ -281,7 +282,12 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
}
else
{
- index(difference.getDestinationPath());
+ if (s_logger.isDebugEnabled())
+ {
+ s_logger.debug("new: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath());
+ }
+ // AR-786
+ reindex(difference.getDestinationPath(), dstDesc.isDirectory());
if (dstDesc.isDirectory())
{
indexDirectory(dstDesc);
@@ -289,13 +295,6 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
reindexAllAncestors(difference.getDestinationPath());
}
}
- // New Delete
- else if (!srcDesc.isDeleted() && ((dstDesc == null) || dstDesc.isDeleted()))
- {
- delete(difference.getSourcePath());
- delete(difference.getDestinationPath());
- reindexAllAncestors(difference.getDestinationPath());
- }
// Existing delete
else if (srcDesc.isDeleted())
{
@@ -311,7 +310,12 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
{
// We are back from the dead ...the node used to be deleted
// Treat as new
- index(difference.getDestinationPath());
+ // AR-786
+ if (s_logger.isDebugEnabled())
+ {
+ s_logger.debug("back: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath());
+ }
+ reindex(difference.getDestinationPath(), dstDesc.isDirectory());
if (dstDesc.isDirectory())
{
indexDirectory(dstDesc);
@@ -319,18 +323,49 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
reindexAllAncestors(difference.getDestinationPath());
}
}
- // Anything else then we reindex
+ // Anything else then we have a delete or reindex
else
{
- if (!difference.getSourcePath().equals(difference.getDestinationPath()))
+ // Unknown end state ...
+ if(dstDesc == null)
{
+ // we do not know what has happened - whatever it is does not apply to this snapshot
+ if (s_logger.isDebugEnabled())
+ {
+ s_logger.debug("unknown: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath());
+ }
+ }
+ // Delete
+ else if (dstDesc.isDeleted())
+ {
+ if (s_logger.isDebugEnabled())
+ {
+ s_logger.debug("delete: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath());
+ }
+ delete(difference.getSourcePath());
+ reindexAllAncestors(difference.getSourcePath());
+ delete(difference.getDestinationPath());
+ reindexAllAncestors(difference.getDestinationPath());
+ }
+ // move
+ else if (!difference.getSourcePath().equals(difference.getDestinationPath()))
+ {
+ if (s_logger.isDebugEnabled())
+ {
+ s_logger.debug("move: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath());
+ }
reindex(difference.getSourcePath(), srcDesc.isDirectory());
reindex(difference.getDestinationPath(), dstDesc.isDirectory());
reindexAllAncestors(difference.getSourcePath());
reindexAllAncestors(difference.getDestinationPath());
}
+ // update
else
{
+ if (s_logger.isDebugEnabled())
+ {
+ s_logger.debug("update: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath());
+ }
// If it is a directory, it is at the same path,
// so no cascade update is required for the bridge table data.
reindex(difference.getDestinationPath(), false);
@@ -382,10 +417,12 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
private void indexDirectory(AVMNodeDescriptor dir)
{
- Map children = avmService.getDirectoryListing(dir);
+ Map children = avmService.getDirectoryListing(dir, false);
for (AVMNodeDescriptor child : children.values())
{
- index(child.getPath());
+ // AR-786
+ reindex(child.getPath(), child.isDirectory());
+ reindexAllAncestors(child.getPath());
if (child.isDirectory())
{
indexDirectory(child);
@@ -542,7 +579,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
}
else
- // not a root node
+ // not a root node
{
xdoc.add(new Field("QNAME", qNameBuffer.toString(), Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO));
@@ -755,7 +792,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
if (isContent)
{
// Content is always tokenised
-
+
ContentData contentData = DefaultTypeConverter.INSTANCE.convert(ContentData.class, serializableValue);
if (!index || contentData.getMimetype() == null)
{
@@ -878,7 +915,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
}
}
else
- // URL not present (null reader) or no content at the URL (file missing)
+ // URL not present (null reader) or no content at the URL (file missing)
{
// log it
if (s_logger.isDebugEnabled())
@@ -898,20 +935,20 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
if (index)
{
- switch (tokenise) {
- case TRUE:
- case BOTH:
- default:
- fieldIndex = Field.Index.TOKENIZED;
- break;
- case FALSE:
- fieldIndex = Field.Index.UN_TOKENIZED;
- break;
+ switch (tokenise) {
+ case TRUE:
+ case BOTH:
+ default:
+ fieldIndex = Field.Index.TOKENIZED;
+ break;
+ case FALSE:
+ fieldIndex = Field.Index.UN_TOKENIZED;
+ break;
- }
- } else {
- fieldIndex = Field.Index.NO;
- }
+ }
+ } else {
+ fieldIndex = Field.Index.NO;
+ }
if ((fieldIndex != Field.Index.NO) || (fieldStore != Field.Store.NO))
{
@@ -956,7 +993,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
{
doc.add(new Field(attributeName, t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO));
}
-
+
doc.add(new Field(attributeName, t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO));
}
@@ -1027,7 +1064,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
{
locale = I18NUtil.getLocale();
}
-
+
StringBuilder builder;
MLAnalysisMode analysisMode;
VerbatimAnalyser vba;
@@ -1063,7 +1100,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
{
doc.add(new Field(attributeName, t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO));
}
-
+
doc.add(new Field(attributeName, t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO));
}
}
@@ -1132,7 +1169,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
break;
case BOTH:
doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO));
-
+
df = CachingDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", true);
try
{
@@ -1161,15 +1198,15 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
@Override
protected void doPrepare() throws IOException
{
- AuthenticationUtil.runAs(new RunAsWork()
- {
+ AuthenticationUtil.runAs(new RunAsWork()
+ {
public String doWork() throws Exception
{
- saveDelta();
- flushPending();
- return null;
+ saveDelta();
+ flushPending();
+ return null;
}
- }, AuthenticationUtil.getSystemUserName());
+ }, AuthenticationUtil.getSystemUserName());
}
@Override
@@ -1542,6 +1579,301 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
this.fullTextSearchIndexer = fullTextSearchIndexer;
}
+
+ public boolean isSnapshotIndexed(String store, int id)
+ {
+ if (id == 0)
+ {
+ return hasIndexBeenCreated(store);
+ }
+ else
+ {
+ return isSynchronousSnapshotPresent(store, id) || isSynchronousSnapshotPresent(store, id);
+ }
+ }
+
+ private boolean isSynchronousSnapshotPresent(String store, int id)
+ {
+ return isSynchronousSnapshotPresent(store, IndexChannel.MAIN, id) || isSynchronousSnapshotPresent(store, IndexChannel.DELTA, id) ;
+ }
+
+ private boolean isAsynchronousSnapshotPresent(String store, int id)
+ {
+ return isAsynchronousSnapshotPresent(store, IndexChannel.MAIN, id) || isAsynchronousSnapshotPresent(store, IndexChannel.DELTA, id) ;
+ }
+
+ public boolean isSnapshotSearchable(String store, int id)
+ {
+ if (id == 0)
+ {
+ return hasIndexBeenCreated(store);
+ }
+ else
+ {
+ return isSynchronousSnapshotPresent(store, id);
+ }
+ }
+
+
+ private boolean isSynchronousSnapshotPresent(String store, IndexChannel channel, int snapshot)
+ {
+ String prefix = SNAP_SHOT_ID + ":" + store + ":";
+ IndexReader reader = null;
+ try
+ {
+ if (channel == IndexChannel.DELTA)
+ {
+ flushPending();
+ reader = getDeltaReader();
+ }
+ else
+ {
+ reader = getReader();
+ }
+
+ TermEnum terms = null;
+ try
+ {
+ terms = reader.terms(new Term("ID", prefix));
+ if (terms.term() != null)
+ {
+ do
+ {
+ Term term = terms.term();
+ if (term.text().startsWith(prefix))
+ {
+ TermDocs docs = null;
+ try
+ {
+ docs = reader.termDocs(term);
+ if (docs.next())
+ {
+ String[] split = term.text().split(":");
+ int test = Integer.parseInt(split[3]);
+ if (test == snapshot)
+ {
+ return true;
+ }
+ }
+ }
+ finally
+ {
+ if (docs != null)
+ {
+ docs.close();
+ }
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ while (terms.next());
+ }
+ }
+ finally
+ {
+ if (terms != null)
+ {
+ terms.close();
+ }
+ }
+ return false;
+ }
+ catch (IOException e)
+ {
+ throw new AlfrescoRuntimeException("IO error", e);
+ }
+ finally
+ {
+ try
+ {
+ if (reader != null)
+ {
+ if (channel == IndexChannel.DELTA)
+ {
+ closeDeltaReader();
+ }
+ else
+ {
+ reader.close();
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ s_logger.warn("Failed to close main reader", e);
+ }
+ }
+ }
+
+ private boolean isAsynchronousSnapshotPresent(String store, IndexChannel channel, int snapshot)
+ {
+ String prefix = "\u0000BG:STORE:" + store + ":";
+ IndexReader reader = null;
+ try
+ {
+ if (channel == IndexChannel.DELTA)
+ {
+ flushPending();
+ reader = getDeltaReader();
+ }
+ else
+ {
+ reader = getReader();
+ }
+ TermEnum terms = null;
+ try
+ {
+ terms = reader.terms(new Term("ID", prefix));
+ if (terms.term() != null)
+ {
+ do
+ {
+ Term term = terms.term();
+ if (term.text().startsWith(prefix))
+ {
+ TermDocs docs = null;
+ try
+ {
+ docs = reader.termDocs(term);
+ if (docs.next())
+ {
+ String[] split = term.text().split(":");
+ int test = Integer.parseInt(split[4]);
+ if (test == snapshot)
+ {
+ return true;
+ }
+ }
+ }
+ finally
+ {
+ if (docs != null)
+ {
+ docs.close();
+ }
+ }
+
+ }
+ else
+ {
+ break;
+ }
+ }
+ while (terms.next());
+ }
+ }
+ finally
+ {
+ if (terms != null)
+ {
+ terms.close();
+ }
+ }
+ return false;
+ }
+ catch (IOException e)
+ {
+ throw new AlfrescoRuntimeException("IO error", e);
+ }
+ finally
+ {
+ try
+ {
+ if (reader != null)
+ {
+ if (channel == IndexChannel.DELTA)
+ {
+ closeDeltaReader();
+ }
+ else
+ {
+ reader.close();
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ s_logger.warn("Failed to close main reader", e);
+ }
+ }
+ }
+
+
+ public boolean hasIndexBeenCreated(String store)
+ {
+ return hasIndexBeenCreatedimpl(store, IndexChannel.MAIN) || hasIndexBeenCreatedimpl(store, IndexChannel.DELTA);
+ }
+
+ public boolean hasIndexBeenCreatedimpl(String store, IndexChannel channel)
+ {
+ IndexReader reader = null;
+ try
+ {
+ if (channel == IndexChannel.DELTA)
+ {
+ flushPending();
+ reader = getDeltaReader();
+ }
+ else
+ {
+ reader = getReader();
+ }
+ TermDocs termDocs = null;
+ try
+ {
+ termDocs = reader.termDocs(new Term("ISROOT", "T"));
+ return termDocs.next();
+ }
+ finally
+ {
+ if (termDocs != null)
+ {
+ termDocs.close();
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ throw new AlfrescoRuntimeException("IO error", e);
+ }
+ finally
+ {
+ try
+ {
+
+ if (reader != null)
+ {
+ if (channel == IndexChannel.DELTA)
+ {
+ closeDeltaReader();
+ }
+ else
+ {
+ reader.close();
+ }
+ }
+ }
+ catch (IOException e)
+ {
+ s_logger.warn("Failed to close main reader", e);
+ }
+ }
+
+ }
+
+ public synchronized long getIndexedDocCount()
+ {
+ return indexedDocCount;
+ }
+
+ private synchronized void incrementDocCount()
+ {
+ indexedDocCount++;
+ }
+
public int getLastIndexedSnapshot(String store)
{
int last = getLastAsynchronousSnapshot(store);
@@ -1556,31 +1888,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
}
return hasIndexBeenCreated(store) ? 0 : -1;
}
-
- public boolean isSnapshotIndexed(String store, int id)
- {
- if (id == 0)
- {
- return hasIndexBeenCreated(store);
- }
- else
- {
- return (id <= getLastAsynchronousSnapshot(store)) || (id <= getLastSynchronousSnapshot(store));
- }
- }
-
- public boolean isSnapshotSearchable(String store, int id)
- {
- if (id == 0)
- {
- return hasIndexBeenCreated(store);
- }
- else
- {
- return (id <= getLastSynchronousSnapshot(store));
- }
- }
-
+
private int getLastSynchronousSnapshot(String store)
{
int answer = getLastSynchronousSnapshot(store, IndexChannel.DELTA);
@@ -1798,76 +2106,4 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl
}
}
}
-
- public boolean hasIndexBeenCreated(String store)
- {
- return hasIndexBeenCreatedimpl(store, IndexChannel.MAIN) || hasIndexBeenCreatedimpl(store, IndexChannel.DELTA);
- }
-
- public boolean hasIndexBeenCreatedimpl(String store, IndexChannel channel)
- {
- IndexReader reader = null;
- try
- {
- if (channel == IndexChannel.DELTA)
- {
- flushPending();
- reader = getDeltaReader();
- }
- else
- {
- reader = getReader();
- }
- TermDocs termDocs = null;
- try
- {
- termDocs = reader.termDocs(new Term("ISROOT", "T"));
- return termDocs.next();
- }
- finally
- {
- if (termDocs != null)
- {
- termDocs.close();
- }
- }
- }
- catch (IOException e)
- {
- throw new AlfrescoRuntimeException("IO error", e);
- }
- finally
- {
- try
- {
-
- if (reader != null)
- {
- if (channel == IndexChannel.DELTA)
- {
- closeDeltaReader();
- }
- else
- {
- reader.close();
- }
- }
- }
- catch (IOException e)
- {
- s_logger.warn("Failed to close main reader", e);
- }
- }
-
- }
-
- public synchronized long getIndexedDocCount()
- {
- return indexedDocCount;
- }
-
- private synchronized void incrementDocCount()
- {
- indexedDocCount++;
- }
}
diff --git a/source/java/org/alfresco/service/cmr/avm/AVMService.java b/source/java/org/alfresco/service/cmr/avm/AVMService.java
index 42b1fc699c..572056c87f 100644
--- a/source/java/org/alfresco/service/cmr/avm/AVMService.java
+++ b/source/java/org/alfresco/service/cmr/avm/AVMService.java
@@ -1367,5 +1367,32 @@ public interface AVMService
* @throws AVMWrongTypeException
*/
public void setContentData(String path, ContentData data);
+
+ /**
+ * Get all versions from the last down to and including the one specified
+ * Returned in descending version id.
+ * @param name
+ * @param version
+ * @return list of version descriptors
+ */
+ public List getStoreVersionsFrom(String name, int version);
+
+ /**
+ * Get all versions from the first up to and including the one specified
+ * Returned in ascending version id order.
+ * @param name
+ * @param version
+ * @return list of version descriptors
+ */
+ public List getStoreVersionsTo(String name, int version);
+
+ /**
+ * Get all versions from an including startVersion up to but NOT including endVersion
+ * @param name
+ * @param startVersion
+ * @param endVersion
+ * @return list of version descriptors
+ */
+ public List getStoreVersionsBetween(String name, int startVersion, int endVersion);
}