mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merged V2.1 to HEAD
6486: Fix for AWC-1134 (Made minimum length for username and password configurable) 6487: Added "copy.verbose" property to build script to list all files being copied in the 'deploy-tomcat-exploded' and 'deploy-webclient-changes' targets 6488: Changed default CIFS server to remove underscore as it can cause problems with OpenOffice. 6489: Fix for WCM-498 (Expired items that are deleted are not represented as such in the change request dialog or submit dialog) 6490: Fix for WCM-446 and WCM-624. Multi-select and All operations in Modified Files list respect items in workflow and ignore them. 6491: Fixes profoundly brain dead behavior in AVMLockingService.init(). 6492: Refactoring of LookupCache to be clustering compatible 6493: Staging and locking changes 6494: WCM Revert action moved to end of all action lists to avoid accidently clicking it (as it has no confirmation screen!) 6496: Fixes for WCM-746 and WCM-747 - Edit File Properties and Edit Folder Properties working correctly again for AVM objects. 6497: Enable virtualization server to be (re)started at any point prior or during the startup of the alfresco webapp (fixes WCM-750). 6498: WCM-742 - moving locks from the preview sandbox to the main user sandbox. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6739 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -48,6 +48,7 @@ import org.alfresco.sandbox.SandboxConstants;
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.alfresco.service.cmr.avm.AVMService;
|
||||
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
|
||||
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
|
||||
import org.alfresco.service.cmr.avmsync.AVMSyncService;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
@@ -86,6 +87,7 @@ public class AVMExpiredContentProcessor
|
||||
protected Map<String, Map<String, List<String>>> expiredContent;
|
||||
protected AVMService avmService;
|
||||
protected AVMSyncService avmSyncService;
|
||||
protected AVMService avmLockingAwareService;
|
||||
protected NodeService nodeService;
|
||||
protected WorkflowService workflowService;
|
||||
protected PersonService personService;
|
||||
@@ -157,6 +159,11 @@ public class AVMExpiredContentProcessor
|
||||
{
|
||||
this.searchService = searchService;
|
||||
}
|
||||
|
||||
public void setAvmLockingAwareService(AVMService avmLockingAwareService)
|
||||
{
|
||||
this.avmLockingAwareService = avmLockingAwareService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the expired content processor.
|
||||
@@ -305,7 +312,7 @@ public class AVMExpiredContentProcessor
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Examining expiration date for '" + nodePath + "': " +
|
||||
expirationDateProp.getStringValue());
|
||||
expirationDateProp);
|
||||
|
||||
if (expirationDateProp != null)
|
||||
{
|
||||
@@ -465,10 +472,10 @@ public class AVMExpiredContentProcessor
|
||||
String path = workflowStoreName + ":/" + JNDIConstants.DIR_DEFAULT_WWW +
|
||||
"/" + JNDIConstants.DIR_DEFAULT_APPBASE;
|
||||
// DNS name mangle the property name - can only contain value DNS characters!
|
||||
String dnsProp = SandboxConstants.PROP_DNS + DNSNameMangler.MakeDNSName(userStore, packageName);
|
||||
String dnsProp = SandboxConstants.PROP_DNS + DNSNameMangler.MakeDNSName(stagingStore, packageName);
|
||||
this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, dnsProp),
|
||||
new PropertyValue(DataTypeDefinition.TEXT, path));
|
||||
|
||||
|
||||
// the main workflow store depends on the main user store (dist=1)
|
||||
String prop_key = SandboxConstants.PROP_BACKGROUND_LAYER + userStore;
|
||||
this.avmService.setStoreProperty(workflowStoreName, QName.createQName(null, prop_key),
|
||||
@@ -560,11 +567,10 @@ public class AVMExpiredContentProcessor
|
||||
String pathInWorkflowStore = workflowStoreName + ":" + relPath;
|
||||
|
||||
// call forceCopy to make sure the path appears modified in the workflow
|
||||
// sandbox, if the item is already modified or deleted this call has no
|
||||
// effect.
|
||||
this.avmService.forceCopy(pathInWorkflowStore);
|
||||
// sandbox, if the item is already modified or deleted this call has no effect.
|
||||
this.avmLockingAwareService.forceCopy(pathInWorkflowStore);
|
||||
}
|
||||
|
||||
|
||||
// convert package to workflow package
|
||||
AVMNodeDescriptor packageDesc = avmService.lookup(-1, packagesPath);
|
||||
NodeRef packageNodeRef = workflowService.createPackage(
|
||||
|
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.alfresco.repo.avm;
|
||||
|
||||
import org.alfresco.repo.transaction.TransactionListenerAdapter;
|
||||
|
||||
/**
|
||||
* This is the listener that cleans up the lookup cache on transaction
|
||||
* rollback.
|
||||
* @author britt
|
||||
*/
|
||||
public class AVMLookupCacheListener extends TransactionListenerAdapter
|
||||
{
|
||||
/**
|
||||
* The lookup cache.
|
||||
*/
|
||||
private LookupCache fLookupCache;
|
||||
|
||||
/**
|
||||
* A default constructor.
|
||||
*/
|
||||
public AVMLookupCacheListener()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Lookup Cache.
|
||||
* @param lookupCache
|
||||
*/
|
||||
public void setLookupCache(LookupCache lookupCache)
|
||||
{
|
||||
fLookupCache = lookupCache;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterRollback()
|
||||
*/
|
||||
@Override
|
||||
public void afterRollback()
|
||||
{
|
||||
fLookupCache.onRollback();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.transaction.TransactionListenerAdapter#afterCommit()
|
||||
*/
|
||||
@Override
|
||||
public void afterCommit()
|
||||
{
|
||||
fLookupCache.onCommit();
|
||||
}
|
||||
}
|
@@ -633,7 +633,6 @@ public class AVMRepository
|
||||
{
|
||||
throw new AVMNotFoundException("Store not found.");
|
||||
}
|
||||
fLookupCache.onDelete(pathParts[0]);
|
||||
sPath = srcRepo.lookupDirectory(-1, pathParts[1], true);
|
||||
if (sPath == null)
|
||||
{
|
||||
@@ -645,6 +644,7 @@ public class AVMRepository
|
||||
{
|
||||
throw new AVMNotFoundException("Not found: " + srcName);
|
||||
}
|
||||
fLookupCache.onDelete(pathParts[0]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -659,7 +659,6 @@ public class AVMRepository
|
||||
{
|
||||
throw new AVMNotFoundException("Store not found.");
|
||||
}
|
||||
fLookupCache.onWrite(pathParts[0]);
|
||||
Lookup dPath = dstRepo.lookupDirectory(-1, pathParts[1], true);
|
||||
if (dPath == null)
|
||||
{
|
||||
@@ -761,6 +760,7 @@ public class AVMRepository
|
||||
{
|
||||
dstNode.setAncestor(srcNode);
|
||||
}
|
||||
fLookupCache.onWrite(pathParts[0]);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -808,10 +808,10 @@ public class AVMRepository
|
||||
{
|
||||
throw new AVMNotFoundException("Store not found.");
|
||||
}
|
||||
fLookupCache.onSnapshot(storeName);
|
||||
Map<String, Integer> result = store.createSnapshot(tag, description, new HashMap<String, Integer>());
|
||||
for (Map.Entry<String, Integer> entry : result.entrySet())
|
||||
{
|
||||
fLookupCache.onSnapshot(entry.getKey());
|
||||
fCreateVersionTxnListener.versionCreated(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return result;
|
||||
@@ -1639,18 +1639,33 @@ public class AVMRepository
|
||||
*/
|
||||
public Lookup lookupDirectory(int version, String path)
|
||||
{
|
||||
fLookupCount.set(fLookupCount.get() + 1);
|
||||
if (fLookupCount.get() > 50)
|
||||
Integer count = fLookupCount.get();
|
||||
try
|
||||
{
|
||||
throw new AVMCycleException("Cycle in lookup.");
|
||||
if (count == null)
|
||||
{
|
||||
fLookupCount.set(1);
|
||||
}
|
||||
fLookupCount.set(fLookupCount.get() + 1);
|
||||
if (fLookupCount.get() > 50)
|
||||
{
|
||||
throw new AVMCycleException("Cycle in lookup.");
|
||||
}
|
||||
String [] pathParts = SplitPath(path);
|
||||
AVMStore store = getAVMStoreByName(pathParts[0]);
|
||||
if (store == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return store.lookupDirectory(version, pathParts[1], false);
|
||||
}
|
||||
String [] pathParts = SplitPath(path);
|
||||
AVMStore store = getAVMStoreByName(pathParts[0]);
|
||||
if (store == null)
|
||||
finally
|
||||
{
|
||||
return null;
|
||||
if (count == null)
|
||||
{
|
||||
fLookupCount.set(null);
|
||||
}
|
||||
}
|
||||
return store.lookupDirectory(version, pathParts[1], false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -36,12 +36,12 @@ public class AVMScaleTestP extends AVMServiceTestBase
|
||||
{
|
||||
public void testScaling()
|
||||
{
|
||||
int n = 4; // The number of BulkLoads to do.
|
||||
int n = 250; // The number of BulkLoads to do.
|
||||
int futzCount = 10; // The number of post snapshot modifications to make after each load.
|
||||
String load = "/Users/britt/hibernate-3.1"; // The tree of stuff to load.
|
||||
BulkLoader loader = new BulkLoader();
|
||||
loader.setAvmService(fService);
|
||||
loader.setPropertyCount(5);
|
||||
loader.setPropertyCount(50);
|
||||
BulkReader reader = new BulkReader();
|
||||
reader.setAvmService(fService);
|
||||
long lastTime = System.currentTimeMillis();
|
||||
|
@@ -36,8 +36,6 @@ import java.util.SortedMap;
|
||||
|
||||
import org.alfresco.repo.domain.DbAccessControlList;
|
||||
import org.alfresco.repo.domain.PropertyValue;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.repo.transaction.TransactionListener;
|
||||
import org.alfresco.service.cmr.avm.AVMBadArgumentException;
|
||||
import org.alfresco.service.cmr.avm.AVMException;
|
||||
import org.alfresco.service.cmr.avm.AVMExistsException;
|
||||
@@ -72,8 +70,6 @@ public class AVMServiceImpl implements AVMService
|
||||
*/
|
||||
private AVMRepository fAVMRepository;
|
||||
|
||||
private TransactionListener fTransactionListener;
|
||||
|
||||
/**
|
||||
* Basic constructor for the service.
|
||||
*/
|
||||
@@ -90,15 +86,6 @@ public class AVMServiceImpl implements AVMService
|
||||
fAVMRepository = avmRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the transaction listener.
|
||||
* @param transactionListener
|
||||
*/
|
||||
public void setTransactionListener(TransactionListener transactionListener)
|
||||
{
|
||||
fTransactionListener = transactionListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an InputStream from a file.
|
||||
* @param version The version to look under.
|
||||
@@ -139,7 +126,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Null path.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
return fAVMRepository.getOutputStream(path);
|
||||
}
|
||||
|
||||
@@ -169,7 +155,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Null path.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
return fAVMRepository.createContentWriter(path);
|
||||
}
|
||||
|
||||
@@ -361,7 +346,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
return fAVMRepository.createFile(path, name);
|
||||
}
|
||||
|
||||
@@ -378,7 +362,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
// Save the contents to temp space.
|
||||
File temp;
|
||||
try
|
||||
@@ -419,7 +402,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.createDirectory(path, name);
|
||||
}
|
||||
|
||||
@@ -436,7 +418,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.createLayeredFile(srcPath, parent, name);
|
||||
}
|
||||
|
||||
@@ -453,7 +434,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.createLayeredDirectory(srcPath, parent, name);
|
||||
}
|
||||
|
||||
@@ -485,7 +465,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.createBranch(version, srcPath, dstPath, name);
|
||||
}
|
||||
|
||||
@@ -501,7 +480,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal null argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.remove(parent, name);
|
||||
}
|
||||
|
||||
@@ -520,7 +498,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Cannot remove root node: " + path);
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.remove(basePath[0], basePath[1]);
|
||||
}
|
||||
|
||||
@@ -539,7 +516,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.rename(srcParent, srcName, dstParent, dstName);
|
||||
}
|
||||
|
||||
@@ -554,7 +530,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal null argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.uncover(dirPath, name);
|
||||
}
|
||||
|
||||
@@ -570,7 +545,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal null argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.flatten(dirPath, name);
|
||||
}
|
||||
|
||||
@@ -616,7 +590,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Store is null.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
return fAVMRepository.createSnapshot(store, tag, description);
|
||||
}
|
||||
|
||||
@@ -861,7 +834,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal null argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.retargetLayeredDirectory(path, target);
|
||||
}
|
||||
|
||||
@@ -875,7 +847,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Path is null.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.makePrimary(path);
|
||||
}
|
||||
|
||||
@@ -967,7 +938,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Null path.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.setOpacity(path, opacity);
|
||||
}
|
||||
|
||||
@@ -1018,7 +988,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal null argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.setNodeProperty(path, name, value);
|
||||
}
|
||||
|
||||
@@ -1033,7 +1002,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal null argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.setNodeProperties(path, properties);
|
||||
}
|
||||
|
||||
@@ -1091,7 +1059,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal null argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.deleteNodeProperty(path, name);
|
||||
}
|
||||
|
||||
@@ -1105,7 +1072,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Null path.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.deleteNodeProperties(path);
|
||||
}
|
||||
|
||||
@@ -1208,7 +1174,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Invalid null argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.deleteStoreProperty(store, name);
|
||||
}
|
||||
|
||||
@@ -1250,7 +1215,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Null Path.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
return fAVMRepository.getContentDataForWrite(path);
|
||||
}
|
||||
|
||||
@@ -1268,7 +1232,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Null Path.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.setContentData(path, data);
|
||||
}
|
||||
|
||||
@@ -1283,7 +1246,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal null argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.setMetaDataFrom(path, from);
|
||||
}
|
||||
|
||||
@@ -1300,7 +1262,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal Null Argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.addAspect(path, aspectName);
|
||||
}
|
||||
|
||||
@@ -1342,7 +1303,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Null path.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.removeAspect(path, aspectName);
|
||||
}
|
||||
|
||||
@@ -1374,7 +1334,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal Null Argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.link(parentPath, name, toLink);
|
||||
}
|
||||
|
||||
@@ -1388,7 +1347,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Null Path.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
return fAVMRepository.forceCopy(path);
|
||||
}
|
||||
|
||||
@@ -1427,7 +1385,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal name.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
AVMNodeDescriptor srcDesc = lookup(srcVersion, srcPath);
|
||||
recursiveCopy(srcVersion, srcDesc, dstPath, name);
|
||||
}
|
||||
@@ -1508,7 +1465,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Cannot revert store root: " + path);
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.revert(baseName[0], baseName[1], toRevertTo);
|
||||
}
|
||||
|
||||
@@ -1521,7 +1477,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal Null Argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.setGuid(path, guid);
|
||||
}
|
||||
|
||||
@@ -1534,7 +1489,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal Null Argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.setEncoding(path, encoding);
|
||||
}
|
||||
|
||||
@@ -1547,7 +1501,6 @@ public class AVMServiceImpl implements AVMService
|
||||
{
|
||||
throw new AVMBadArgumentException("Illegal Null Argument.");
|
||||
}
|
||||
AlfrescoTransactionSupport.bindListener(fTransactionListener);
|
||||
fAVMRepository.setMimeType(path, mimeType);
|
||||
}
|
||||
}
|
||||
|
@@ -347,136 +347,6 @@ public class AVMServiceTest extends AVMServiceTestBase
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test async indexing.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testAsyncIndex() throws Exception
|
||||
{
|
||||
// Make sure the slate is clean ...
|
||||
UserTransaction tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
if(fService.getStore("avmAsynchronousTest") != null)
|
||||
{
|
||||
assertTrue(fIndexingInterceptor.hasIndexBeenCreated("avmAsynchronousTest"));
|
||||
fService.purgeStore("avmAsynchronousTest");
|
||||
assertTrue(fIndexingInterceptor.hasIndexBeenCreated("avmAsynchronousTest"));
|
||||
assertFalse(fIndexingInterceptor.hasIndexBeenCreated("bananaStoreWoof"));
|
||||
}
|
||||
else
|
||||
{
|
||||
assertFalse(fIndexingInterceptor.hasIndexBeenCreated("avmAsynchronousTest"));
|
||||
}
|
||||
StoreRef storeRef = AVMNodeConverter.ToStoreRef("avmAsynchronousTest");
|
||||
Indexer indexer = fIndexerAndSearcher.getIndexer(storeRef);
|
||||
if(indexer instanceof AVMLuceneIndexer)
|
||||
{
|
||||
AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer)indexer;
|
||||
avmIndexer.deleteIndex("avmAsynchronousTest", IndexMode.SYNCHRONOUS);
|
||||
}
|
||||
tx.commit();
|
||||
|
||||
tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
assertEquals(-1, fIndexingInterceptor.getLastIndexedSnapshot("bananaStoreWoof"));
|
||||
assertEquals(-1, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
|
||||
tx.commit();
|
||||
|
||||
// TODO: Suspend and resume indexing in case we are really unlucky and hit an index before we expect it.
|
||||
|
||||
SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true);
|
||||
ResultSet results;
|
||||
|
||||
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
|
||||
assertEquals(0, results.length());
|
||||
results.close();
|
||||
|
||||
fService.createStore("avmAsynchronousTest");
|
||||
|
||||
tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
assertEquals(0, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
|
||||
tx.commit();
|
||||
|
||||
fService.createSnapshot("avmAsynchronousTest", null, null);
|
||||
|
||||
tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
assertEquals(0, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
|
||||
tx.commit();
|
||||
|
||||
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
|
||||
assertEquals(1, results.length());
|
||||
results.close();
|
||||
|
||||
fService.createDirectory("avmAsynchronousTest:/", "a");
|
||||
fService.createDirectory("avmAsynchronousTest:/a", "b");
|
||||
fService.createDirectory("avmAsynchronousTest:/a/b", "c");
|
||||
|
||||
tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
assertEquals(0, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
|
||||
assertTrue(fIndexingInterceptor.isIndexUpToDate("avmAsynchronousTest"));
|
||||
tx.commit();
|
||||
|
||||
fService.createSnapshot("avmAsynchronousTest", null, null);
|
||||
|
||||
tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
assertEquals(1, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
|
||||
assertTrue(fIndexingInterceptor.isIndexUpToDate("avmAsynchronousTest"));
|
||||
assertFalse(fIndexingInterceptor.isIndexUpToDateAndSearchable("avmAsynchronousTest"));
|
||||
assertEquals(IndexMode.ASYNCHRONOUS, fIndexingInterceptor.getIndexMode("avmAsynchronousTest"));
|
||||
assertEquals(IndexMode.SYNCHRONOUS, fIndexingInterceptor.getIndexMode("main"));
|
||||
assertTrue(fIndexingInterceptor.isSnapshotIndexed("avmAsynchronousTest", 0));
|
||||
assertTrue(fIndexingInterceptor.isSnapshotIndexed("avmAsynchronousTest", 1));
|
||||
assertFalse(fIndexingInterceptor.isSnapshotIndexed("avmAsynchronousTest", 2));
|
||||
tx.commit();
|
||||
|
||||
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
|
||||
assertEquals(1, results.length());
|
||||
results.close();
|
||||
|
||||
Thread.sleep(180000);
|
||||
|
||||
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
|
||||
assertEquals(4, results.length());
|
||||
results.close();
|
||||
|
||||
|
||||
tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
assertEquals(1, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
|
||||
assertTrue(fIndexingInterceptor.isIndexUpToDate("avmAsynchronousTest"));
|
||||
assertTrue(fIndexingInterceptor.isIndexUpToDateAndSearchable("avmAsynchronousTest"));
|
||||
tx.commit();
|
||||
|
||||
fService.purgeStore("avmAsynchronousTest");
|
||||
|
||||
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
|
||||
assertEquals(0, results.length());
|
||||
results.close();
|
||||
|
||||
fService.createStore("avmAsynchronousTest");
|
||||
fService.createSnapshot("avmAsynchronousTest", null, null);
|
||||
fService.createDirectory("avmAsynchronousTest:/", "a");
|
||||
fService.createDirectory("avmAsynchronousTest:/a", "b");
|
||||
fService.createDirectory("avmAsynchronousTest:/a/b", "c");
|
||||
fService.createSnapshot("avmAsynchronousTest", null, null);
|
||||
fService.purgeStore("avmAsynchronousTest");
|
||||
fService.createStore("avmAsynchronousTest");
|
||||
fService.createSnapshot("avmAsynchronousTest", null, null);
|
||||
fService.createDirectory("avmAsynchronousTest:/", "a");
|
||||
fService.createDirectory("avmAsynchronousTest:/a", "b");
|
||||
fService.createDirectory("avmAsynchronousTest:/a/b", "c");
|
||||
fService.createSnapshot("avmAsynchronousTest", null, null);
|
||||
|
||||
Thread.sleep(180000);
|
||||
|
||||
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
|
||||
assertEquals(4, results.length());
|
||||
results.close();
|
||||
}
|
||||
|
||||
public void testForceCopyDeleted()
|
||||
{
|
||||
@@ -537,8 +407,16 @@ public class AVMServiceTest extends AVMServiceTestBase
|
||||
fService.createBranch(1, "layer:/root", "branch:/", "branch");
|
||||
fService.createSnapshot("branch", null, null);
|
||||
fService.getFileOutputStream("main:/a/b/c/foo").close();
|
||||
System.out.println("main 1");
|
||||
System.out.println(recursiveList("main", 1, true));
|
||||
System.out.println("branch 1");
|
||||
System.out.println(recursiveList("branch", 1, true));
|
||||
assertEquals(fService.lookup(1, "main:/a/b/c/foo").getId(), fService.lookup(1,
|
||||
"branch:/branch/layer/b/c/foo").getId());
|
||||
System.out.println("main -1");
|
||||
System.out.println(recursiveList("main", -1, true));
|
||||
System.out.println("branch -1");
|
||||
System.out.println(recursiveList("branch", -1, true));
|
||||
assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getId(), fService.lookup(-1,
|
||||
"branch:/branch/layer/b/c/foo").getId());
|
||||
}
|
||||
@@ -5641,4 +5519,135 @@ public class AVMServiceTest extends AVMServiceTestBase
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test async indexing.
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testAsyncIndex() throws Exception
|
||||
{
|
||||
// Make sure the slate is clean ...
|
||||
UserTransaction tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
if(fService.getStore("avmAsynchronousTest") != null)
|
||||
{
|
||||
assertTrue(fIndexingInterceptor.hasIndexBeenCreated("avmAsynchronousTest"));
|
||||
fService.purgeStore("avmAsynchronousTest");
|
||||
assertTrue(fIndexingInterceptor.hasIndexBeenCreated("avmAsynchronousTest"));
|
||||
assertFalse(fIndexingInterceptor.hasIndexBeenCreated("bananaStoreWoof"));
|
||||
}
|
||||
else
|
||||
{
|
||||
assertFalse(fIndexingInterceptor.hasIndexBeenCreated("avmAsynchronousTest"));
|
||||
}
|
||||
StoreRef storeRef = AVMNodeConverter.ToStoreRef("avmAsynchronousTest");
|
||||
Indexer indexer = fIndexerAndSearcher.getIndexer(storeRef);
|
||||
if(indexer instanceof AVMLuceneIndexer)
|
||||
{
|
||||
AVMLuceneIndexer avmIndexer = (AVMLuceneIndexer)indexer;
|
||||
avmIndexer.deleteIndex("avmAsynchronousTest", IndexMode.SYNCHRONOUS);
|
||||
}
|
||||
tx.commit();
|
||||
|
||||
tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
assertEquals(-1, fIndexingInterceptor.getLastIndexedSnapshot("bananaStoreWoof"));
|
||||
assertEquals(-1, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
|
||||
tx.commit();
|
||||
|
||||
// TODO: Suspend and resume indexing in case we are really unlucky and hit an index before we expect it.
|
||||
|
||||
SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true);
|
||||
ResultSet results;
|
||||
|
||||
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
|
||||
assertEquals(0, results.length());
|
||||
results.close();
|
||||
|
||||
fService.createStore("avmAsynchronousTest");
|
||||
|
||||
tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
assertEquals(0, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
|
||||
tx.commit();
|
||||
|
||||
fService.createSnapshot("avmAsynchronousTest", null, null);
|
||||
|
||||
tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
assertEquals(0, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
|
||||
tx.commit();
|
||||
|
||||
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
|
||||
assertEquals(1, results.length());
|
||||
results.close();
|
||||
|
||||
fService.createDirectory("avmAsynchronousTest:/", "a");
|
||||
fService.createDirectory("avmAsynchronousTest:/a", "b");
|
||||
fService.createDirectory("avmAsynchronousTest:/a/b", "c");
|
||||
|
||||
tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
assertEquals(0, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
|
||||
assertTrue(fIndexingInterceptor.isIndexUpToDate("avmAsynchronousTest"));
|
||||
tx.commit();
|
||||
|
||||
fService.createSnapshot("avmAsynchronousTest", null, null);
|
||||
|
||||
tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
assertEquals(1, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
|
||||
assertTrue(fIndexingInterceptor.isIndexUpToDate("avmAsynchronousTest"));
|
||||
assertFalse(fIndexingInterceptor.isIndexUpToDateAndSearchable("avmAsynchronousTest"));
|
||||
assertEquals(IndexMode.ASYNCHRONOUS, fIndexingInterceptor.getIndexMode("avmAsynchronousTest"));
|
||||
assertEquals(IndexMode.SYNCHRONOUS, fIndexingInterceptor.getIndexMode("main"));
|
||||
assertTrue(fIndexingInterceptor.isSnapshotIndexed("avmAsynchronousTest", 0));
|
||||
assertTrue(fIndexingInterceptor.isSnapshotIndexed("avmAsynchronousTest", 1));
|
||||
assertFalse(fIndexingInterceptor.isSnapshotIndexed("avmAsynchronousTest", 2));
|
||||
tx.commit();
|
||||
|
||||
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
|
||||
assertEquals(1, results.length());
|
||||
results.close();
|
||||
|
||||
Thread.sleep(180000);
|
||||
|
||||
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
|
||||
assertEquals(4, results.length());
|
||||
results.close();
|
||||
|
||||
|
||||
tx = fTransactionService.getUserTransaction();
|
||||
tx.begin();
|
||||
assertEquals(1, fIndexingInterceptor.getLastIndexedSnapshot("avmAsynchronousTest"));
|
||||
assertTrue(fIndexingInterceptor.isIndexUpToDate("avmAsynchronousTest"));
|
||||
assertTrue(fIndexingInterceptor.isIndexUpToDateAndSearchable("avmAsynchronousTest"));
|
||||
tx.commit();
|
||||
|
||||
fService.purgeStore("avmAsynchronousTest");
|
||||
|
||||
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
|
||||
assertEquals(0, results.length());
|
||||
results.close();
|
||||
|
||||
fService.createStore("avmAsynchronousTest");
|
||||
fService.createSnapshot("avmAsynchronousTest", null, null);
|
||||
fService.createDirectory("avmAsynchronousTest:/", "a");
|
||||
fService.createDirectory("avmAsynchronousTest:/a", "b");
|
||||
fService.createDirectory("avmAsynchronousTest:/a/b", "c");
|
||||
fService.createSnapshot("avmAsynchronousTest", null, null);
|
||||
fService.purgeStore("avmAsynchronousTest");
|
||||
fService.createStore("avmAsynchronousTest");
|
||||
fService.createSnapshot("avmAsynchronousTest", null, null);
|
||||
fService.createDirectory("avmAsynchronousTest:/", "a");
|
||||
fService.createDirectory("avmAsynchronousTest:/a", "b");
|
||||
fService.createDirectory("avmAsynchronousTest:/a/b", "c");
|
||||
fService.createSnapshot("avmAsynchronousTest", null, null);
|
||||
|
||||
Thread.sleep(180000);
|
||||
|
||||
results = searchService.query(storeRef, "lucene", "PATH:\"//.\"");
|
||||
assertEquals(4, results.length());
|
||||
results.close();
|
||||
}
|
||||
}
|
||||
|
@@ -24,7 +24,6 @@
|
||||
package org.alfresco.repo.avm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
@@ -39,9 +38,7 @@ import org.alfresco.service.cmr.avm.AVMService;
|
||||
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
|
||||
import org.alfresco.service.cmr.avm.locking.AVMLockingService;
|
||||
import org.alfresco.service.cmr.avmsync.AVMSyncService;
|
||||
import org.alfresco.service.cmr.repository.ContentData;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||
@@ -225,6 +222,7 @@ public class AVMServiceTestBase extends TestCase
|
||||
Map<String, AVMNodeDescriptor> listing = fService.getDirectoryListing(version, path, true);
|
||||
for (String name : listing.keySet())
|
||||
{
|
||||
System.err.println(name);
|
||||
builder.append(recursiveList(basename + name, version, indent + 2, followLinks));
|
||||
}
|
||||
}
|
||||
|
@@ -214,11 +214,20 @@ public class AVMStoreImpl implements AVMStore, Serializable
|
||||
{
|
||||
continue;
|
||||
}
|
||||
fAVMRepository.forceCopy(entry.getPath());
|
||||
// TODO This leaves the behavior of LayeredFiles not quite
|
||||
// right.
|
||||
/*
|
||||
String parentName[] = AVMNodeConverter.SplitBase(entry.getPath());
|
||||
parentName[0] = parentName[0].substring(parentName[0].indexOf(':') + 1);
|
||||
lookup = lookupDirectory(-1, parentName[0], true);
|
||||
DirectoryNode parent = (DirectoryNode)lookup.getCurrentNode();
|
||||
AVMNode child = parent.lookupChild(lookup, parentName[1], false);
|
||||
// TODO For debugging.
|
||||
if (child == null)
|
||||
{
|
||||
System.err.println("Yoiks!");
|
||||
}
|
||||
// TODO This is funky. Need to look carefully to see that this call
|
||||
// does exactly what's needed.
|
||||
lookup.add(child, parentName[1], false);
|
||||
@@ -232,6 +241,7 @@ public class AVMStoreImpl implements AVMStore, Serializable
|
||||
newChild = ((LayeredFileNode)child).copyLiterally(lookup);
|
||||
}
|
||||
parent.putChild(parentName[1], newChild);
|
||||
*/
|
||||
}
|
||||
// Clear out the new nodes.
|
||||
List<AVMNode> newInRep = AVMDAOs.Instance().fAVMNodeDAO.getNewInStore(this);
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
package org.alfresco.repo.avm;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -34,8 +35,10 @@ import org.alfresco.util.Pair;
|
||||
* from the root directory of a repository.
|
||||
* @author britt
|
||||
*/
|
||||
class Lookup
|
||||
class Lookup implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -2844833688622561L;
|
||||
|
||||
/**
|
||||
* Is this lookup valid?
|
||||
*/
|
||||
|
@@ -3,14 +3,11 @@
|
||||
*/
|
||||
package org.alfresco.repo.avm;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.avm.util.SimplePath;
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
@@ -21,42 +18,10 @@ public class LookupCache
|
||||
{
|
||||
private static Logger fgLogger = Logger.getLogger(LookupCache.class);
|
||||
|
||||
|
||||
/**
|
||||
* Per transaction lookup results to be added to the cache on successful
|
||||
* commit.
|
||||
*/
|
||||
private ThreadLocal<Map<LookupKey, Lookup>> fToBeAdded;
|
||||
|
||||
/**
|
||||
* Per transaction set of invalidated lookup keys.
|
||||
*/
|
||||
private ThreadLocal<Set<LookupKey>> fToBePurged;
|
||||
|
||||
/**
|
||||
* The Map of of keys to lookups.
|
||||
*/
|
||||
private Map<LookupKey, Lookup> fCache;
|
||||
|
||||
/**
|
||||
* The Map of time stamps to keys.
|
||||
*/
|
||||
private SortedMap<Long, LookupKey> fTimeStamps;
|
||||
|
||||
/**
|
||||
* The inverse map of keys to timestamps.
|
||||
*/
|
||||
private Map<LookupKey, Long> fInverseTimeStamps;
|
||||
|
||||
/**
|
||||
* The timestamp to next issue.
|
||||
*/
|
||||
private long fTimeStamp;
|
||||
|
||||
/**
|
||||
* The maximum number of lines to have in the cache.
|
||||
*/
|
||||
private int fMaxSize;
|
||||
private SimpleCache<LookupKey, Lookup> fCache;
|
||||
|
||||
/**
|
||||
* Reference to the Node DAO.
|
||||
@@ -73,13 +38,6 @@ public class LookupCache
|
||||
*/
|
||||
public LookupCache()
|
||||
{
|
||||
fCache = new HashMap<LookupKey, Lookup>();
|
||||
fTimeStamps = new TreeMap<Long, LookupKey>();
|
||||
fInverseTimeStamps = new HashMap<LookupKey, Long>();
|
||||
fToBeAdded = new ThreadLocal<Map<LookupKey, Lookup>>();
|
||||
fToBePurged = new ThreadLocal<Set<LookupKey>>();
|
||||
fTimeStamp = 0L;
|
||||
fMaxSize = 100;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,13 +58,9 @@ public class LookupCache
|
||||
fAVMStoreDAO = dao;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum cache size.
|
||||
* @param maxSize
|
||||
*/
|
||||
public void setMaxSize(int maxSize)
|
||||
public void setTransactionalCache(SimpleCache<LookupKey, Lookup> cache)
|
||||
{
|
||||
fMaxSize = maxSize;
|
||||
fCache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,8 +79,14 @@ public class LookupCache
|
||||
LookupKey key = new LookupKey(version, path, store.getName(), write, includeDeleted);
|
||||
// Is it in the cache?
|
||||
Lookup found = findInCache(key);
|
||||
// TODO Testing.
|
||||
// found = null;
|
||||
if (found != null)
|
||||
{
|
||||
if (fgLogger.isDebugEnabled())
|
||||
{
|
||||
fgLogger.debug("Cache Hit: " + key + ", " + found.getCurrentNode().getId());
|
||||
}
|
||||
return found;
|
||||
}
|
||||
// Make up a Lookup to hold the results.
|
||||
@@ -155,7 +115,7 @@ public class LookupCache
|
||||
dir = (DirectoryNode)result.getCurrentNode();
|
||||
if (path.size() == 1 && path.get(0).equals(""))
|
||||
{
|
||||
updateCache(key, result);
|
||||
fCache.put(key, result);
|
||||
return result;
|
||||
}
|
||||
// Now look up each path element in sequence up to one
|
||||
@@ -184,7 +144,7 @@ public class LookupCache
|
||||
return null;
|
||||
}
|
||||
result.add(child, path.get(path.size() - 1), write);
|
||||
updateCache(key, result);
|
||||
fCache.put(key, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -195,24 +155,7 @@ public class LookupCache
|
||||
*/
|
||||
private synchronized Lookup findInCache(LookupKey key)
|
||||
{
|
||||
// Get the current transaction's purged set.
|
||||
Set<LookupKey> purged = fToBePurged.get();
|
||||
// Get the current transaction's added map.
|
||||
Map<LookupKey, Lookup> added = fToBeAdded.get();
|
||||
// See if it's cached in the transaction.
|
||||
Lookup found = (added != null) ? added.get(key) : null;
|
||||
// It's not.
|
||||
if (found == null)
|
||||
{
|
||||
// If it's been purged in the transaction it is
|
||||
// a miss.
|
||||
if (purged != null && purged.contains(key))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
found = fCache.get(key);
|
||||
}
|
||||
// Despite the odds, we found a hit.
|
||||
Lookup found = fCache.get(key);
|
||||
if (found != null)
|
||||
{
|
||||
// Get a freshened Lookup.
|
||||
@@ -224,8 +167,6 @@ public class LookupCache
|
||||
fgLogger.error("Invalid entry in cache: " + key);
|
||||
return null;
|
||||
}
|
||||
// Prepare the cache for a timestamp update on commit.
|
||||
updateCache(key, found);
|
||||
return result;
|
||||
}
|
||||
// Alternatively for a read lookup a write can match.
|
||||
@@ -234,18 +175,7 @@ public class LookupCache
|
||||
// Make a copy of the key and set it to 'write'
|
||||
LookupKey newKey = new LookupKey(key);
|
||||
newKey.setWrite(true);
|
||||
// Is it in the transaction's cache?
|
||||
found = (added != null) ? added.get(newKey) : null;
|
||||
// If not.
|
||||
if (found == null)
|
||||
{
|
||||
// If it's been purged it's a miss.
|
||||
if (purged != null && purged.contains(newKey))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
found = fCache.get(newKey);
|
||||
}
|
||||
found = fCache.get(newKey);
|
||||
if (found != null)
|
||||
{
|
||||
// We found it. Make a freshened copy of the Lookup.
|
||||
@@ -257,103 +187,12 @@ public class LookupCache
|
||||
fgLogger.error("Invalid entry in cache: " + newKey);
|
||||
return null;
|
||||
}
|
||||
// Prepare the cache to update time stamp.
|
||||
updateCache(newKey, found);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or update an entry in the cache.
|
||||
* @param key
|
||||
* @param lookup
|
||||
*/
|
||||
private void updateCache(LookupKey key, Lookup lookup)
|
||||
{
|
||||
// First, put it in the transaction scoped cache.
|
||||
Map<LookupKey, Lookup> map = fToBeAdded.get();
|
||||
if (map == null)
|
||||
{
|
||||
map = new HashMap<LookupKey, Lookup>();
|
||||
}
|
||||
map.put(key, lookup);
|
||||
// Remove any corresponding entry from the purge list.
|
||||
Set<LookupKey> purged = fToBePurged.get();
|
||||
if (purged == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
purged.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a transaction has successfully committed,
|
||||
* to make lookups from the transaction available to other transactions.
|
||||
*/
|
||||
public synchronized void onCommit()
|
||||
{
|
||||
// First get rid of all entries purged by the transaction.
|
||||
Set<LookupKey> purged = fToBePurged.get();
|
||||
if (purged != null)
|
||||
{
|
||||
purgeEntries(purged);
|
||||
}
|
||||
// Null out the thread local.
|
||||
fToBePurged.set(null);
|
||||
// Get and go through the transaction's added list.
|
||||
Map<LookupKey, Lookup> added = fToBeAdded.get();
|
||||
if (added == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (Map.Entry<LookupKey, Lookup> entry : added.entrySet())
|
||||
{
|
||||
LookupKey key = entry.getKey();
|
||||
Lookup lookup = entry.getValue();
|
||||
// If the cache already has the key, remove it.
|
||||
if (fCache.containsKey(key))
|
||||
{
|
||||
fCache.remove(key);
|
||||
Long oldTime = fInverseTimeStamps.get(key);
|
||||
fInverseTimeStamps.remove(key);
|
||||
fTimeStamps.remove(oldTime);
|
||||
}
|
||||
// Add the entry.
|
||||
long timeStamp = fTimeStamp++;
|
||||
fTimeStamps.put(timeStamp, key);
|
||||
fInverseTimeStamps.put(key, timeStamp);
|
||||
fCache.put(key, lookup);
|
||||
// Check if we're over the limit and purge the
|
||||
// LRU entry if we are.
|
||||
if (fCache.size() > fMaxSize)
|
||||
{
|
||||
// Get rid of the oldest entry.
|
||||
Long oldTime = fTimeStamps.firstKey();
|
||||
LookupKey old = fTimeStamps.remove(oldTime);
|
||||
fInverseTimeStamps.remove(old);
|
||||
fCache.remove(old);
|
||||
}
|
||||
}
|
||||
// Null out the ThreadLocal.
|
||||
fToBeAdded.set(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a Set of entries.
|
||||
* @param keys The Set of entries.
|
||||
*/
|
||||
private void purgeEntries(Set<LookupKey> keys)
|
||||
{
|
||||
for (LookupKey key : keys)
|
||||
{
|
||||
fCache.remove(key);
|
||||
Long time = fInverseTimeStamps.remove(key);
|
||||
fTimeStamps.remove(time);
|
||||
}
|
||||
}
|
||||
|
||||
// Following are the cache invalidation calls.
|
||||
|
||||
/**
|
||||
@@ -362,37 +201,25 @@ public class LookupCache
|
||||
*/
|
||||
public synchronized void onWrite(String storeName)
|
||||
{
|
||||
// Get or make up the purged Set for this transaction.
|
||||
Set<LookupKey> purged = fToBePurged.get();
|
||||
if (purged == null)
|
||||
{
|
||||
purged = new HashSet<LookupKey>();
|
||||
fToBePurged.set(purged);
|
||||
}
|
||||
// Invalidate if it's a read lookup in the store, or
|
||||
// any read lookup is it's layered.
|
||||
for (Map.Entry<LookupKey, Lookup> entry : fCache.entrySet())
|
||||
List<LookupKey> keys = new ArrayList<LookupKey>();
|
||||
for (LookupKey key : fCache.getKeys())
|
||||
{
|
||||
if ((entry.getKey().getStoreName().equals(storeName) &&
|
||||
!entry.getKey().isWrite()) ||
|
||||
(!entry.getKey().isWrite() && entry.getValue().isLayered()))
|
||||
{
|
||||
purged.add(entry.getKey());
|
||||
}
|
||||
keys.add(key);
|
||||
}
|
||||
// Remove entries from the added set using the same criteria.
|
||||
Map<LookupKey, Lookup> added = fToBeAdded.get();
|
||||
if (added == null)
|
||||
for (LookupKey key : keys)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (Map.Entry<LookupKey, Lookup> entry : added.entrySet())
|
||||
{
|
||||
if ((entry.getKey().getStoreName().equals(storeName) &&
|
||||
!entry.getKey().isWrite()) ||
|
||||
(!entry.getKey().isWrite() && entry.getValue().isLayered()))
|
||||
Lookup value = fCache.get(key);
|
||||
if ((key.getStoreName().equals(storeName) &&
|
||||
!key.isWrite()) || value == null ||
|
||||
(!key.isWrite() && value.isLayered()))
|
||||
{
|
||||
added.remove(entry.getKey());
|
||||
if (fgLogger.isDebugEnabled())
|
||||
{
|
||||
fgLogger.debug("Invalidating: " + key + ", " + (value != null ? value.getCurrentNode().getId() : -2));
|
||||
}
|
||||
fCache.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -403,34 +230,23 @@ public class LookupCache
|
||||
*/
|
||||
public synchronized void onDelete(String storeName)
|
||||
{
|
||||
// Get or make up a fresh purged Set.
|
||||
Set<LookupKey> purged = fToBePurged.get();
|
||||
if (purged == null)
|
||||
{
|
||||
purged = new HashSet<LookupKey>();
|
||||
fToBePurged.set(purged);
|
||||
}
|
||||
// Invalidate any entries that are in the store or are layered lookups.
|
||||
for (Map.Entry<LookupKey, Lookup> entry : fCache.entrySet())
|
||||
List<LookupKey> keys = new ArrayList<LookupKey>();
|
||||
for (LookupKey key : fCache.getKeys())
|
||||
{
|
||||
if (entry.getKey().getStoreName().equals(storeName) ||
|
||||
entry.getValue().isLayered())
|
||||
{
|
||||
purged.add(entry.getKey());
|
||||
}
|
||||
keys.add(key);
|
||||
}
|
||||
// Get rid of any similarly matching elements in the added list.
|
||||
Map<LookupKey, Lookup> added = fToBeAdded.get();
|
||||
if (added == null)
|
||||
for (LookupKey key : keys)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (Map.Entry<LookupKey, Lookup> entry : added.entrySet())
|
||||
{
|
||||
if (entry.getKey().getStoreName().equals(storeName) ||
|
||||
entry.getValue().isLayered())
|
||||
Lookup value = fCache.get(key);
|
||||
if (key.getStoreName().equals(storeName) ||
|
||||
value == null || value.isLayered())
|
||||
{
|
||||
added.remove(entry.getKey());
|
||||
if (fgLogger.isDebugEnabled())
|
||||
{
|
||||
fgLogger.debug("Invalidating: " + key + ", " + (value != null ? value.getCurrentNode().getId() : -2));
|
||||
}
|
||||
fCache.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,48 +257,31 @@ public class LookupCache
|
||||
*/
|
||||
public synchronized void onSnapshot(String storeName)
|
||||
{
|
||||
// Get or make up a purged set.
|
||||
Set<LookupKey> purged = fToBePurged.get();
|
||||
if (purged == null)
|
||||
{
|
||||
purged = new HashSet<LookupKey>();
|
||||
fToBePurged.set(purged);
|
||||
}
|
||||
// Invalidate any entries that in the store and writes or
|
||||
// any layered lookups.
|
||||
for (Map.Entry<LookupKey, Lookup> entry : fCache.entrySet())
|
||||
List<LookupKey> keys = new ArrayList<LookupKey>();
|
||||
for (LookupKey key : fCache.getKeys())
|
||||
{
|
||||
if ((entry.getKey().getStoreName().equals(storeName) &&
|
||||
entry.getKey().isWrite()) ||
|
||||
entry.getValue().isLayered())
|
||||
{
|
||||
purged.add(entry.getKey());
|
||||
}
|
||||
keys.add(key);
|
||||
}
|
||||
// Remove from the added list by the same criteria.
|
||||
Map<LookupKey, Lookup> added = fToBeAdded.get();
|
||||
if (added == null)
|
||||
for (LookupKey key : keys)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (Map.Entry<LookupKey, Lookup> entry : added.entrySet())
|
||||
{
|
||||
if ((entry.getKey().getStoreName().equals(storeName) &&
|
||||
entry.getKey().isWrite()) ||
|
||||
entry.getValue().isLayered())
|
||||
Lookup value = fCache.get(key);
|
||||
if ((key.getStoreName().equals(storeName) &&
|
||||
key.isWrite()) ||
|
||||
value == null || value.isLayered())
|
||||
{
|
||||
added.remove(entry.getKey());
|
||||
if (fgLogger.isDebugEnabled())
|
||||
{
|
||||
fgLogger.debug("Invalidating: " + key + ", " + (value != null ? value.getCurrentNode().getId() : -2));
|
||||
}
|
||||
fCache.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a rollback has occurred.
|
||||
*/
|
||||
public synchronized void onRollback()
|
||||
public synchronized void reset()
|
||||
{
|
||||
// Just toss the transaction level changes.
|
||||
fToBeAdded.set(null);
|
||||
fToBePurged.set(null);
|
||||
fCache.clear();
|
||||
}
|
||||
}
|
||||
|
@@ -3,14 +3,18 @@
|
||||
*/
|
||||
package org.alfresco.repo.avm;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.repo.avm.util.SimplePath;
|
||||
|
||||
/**
|
||||
* This is the key by which Lookup's are retrieved from the cache.
|
||||
* @author britt
|
||||
*/
|
||||
public class LookupKey
|
||||
public class LookupKey implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 8471482833953423406L;
|
||||
|
||||
/**
|
||||
* The name of the store.
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -3,12 +3,16 @@
|
||||
*/
|
||||
package org.alfresco.repo.avm.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Holds a simple path.
|
||||
* @author britt
|
||||
*/
|
||||
public class SimplePath
|
||||
public class SimplePath implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 2696828491008988470L;
|
||||
|
||||
/**
|
||||
* The names of the path's components.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user