mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merged V2.2 to HEAD
8397: Fix for AR-2003, AR-2127, AR-2128 (Hibernate patch) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8506 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -33,6 +33,9 @@
|
||||
<property name="maximumStringLength">
|
||||
<value>${system.maximumStringLength}</value>
|
||||
</property>
|
||||
<property name="hibernateMaxExecutions">
|
||||
<value>${system.hibernateMaxExecutions}</value>
|
||||
</property>
|
||||
<property name="updateSchema">
|
||||
<value>${db.schema.update}</value>
|
||||
</property>
|
||||
|
@@ -23,16 +23,31 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="defaltOnLoadListsner" class="org.hibernate.event.def.DefaultLoadEventListener" />
|
||||
|
||||
<bean id="clearCGLibThreadLocal" class="org.alfresco.repo.domain.hibernate.HibernateLoadListener" />
|
||||
|
||||
<!-- Hibernate session factory -->
|
||||
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" parent="sessionFactoryBase">
|
||||
<property name="dataSource">
|
||||
<ref bean="dataSource" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="sessionFactoryBase" abstract="true">
|
||||
<property name="schemaUpdate">
|
||||
<value>false</value>
|
||||
</property>
|
||||
<property name="eventListeners" >
|
||||
<map>
|
||||
<entry key="load">
|
||||
<list>
|
||||
<ref bean="defaltOnLoadListsner" />
|
||||
<ref bean="clearCGLibThreadLocal" />
|
||||
</list>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
<property name="mappingResources">
|
||||
<list>
|
||||
<!-- -->
|
||||
@@ -289,6 +304,12 @@
|
||||
<property name="aclDaoComponent">
|
||||
<ref bean="aclDaoComponent"/>
|
||||
</property>
|
||||
<property name="avmSnapShotTriggeredIndexingMethodInterceptor">
|
||||
<ref bean="avmSnapShotTriggeredIndexingMethodInterceptor"/>
|
||||
</property>
|
||||
<property name="hibernateSessionHelper">
|
||||
<ref bean="hibernateSessionHelper"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="usageDeltaDao" class="org.alfresco.repo.usage.hibernate.HibernateUsageDeltaDAO">
|
||||
@@ -360,10 +381,17 @@
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="contentUrlDAOImpl" class="org.alfresco.repo.domain.hibernate.HibernateContentUrlDAOImpl">
|
||||
<property name="sessionFactory">
|
||||
<ref bean="sessionFactory"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
|
||||
<bean id="hibernateSessionHelper" class="org.alfresco.repo.domain.hibernate.HibernateSessionHelper">
|
||||
<property name="sessionFactory">
|
||||
<ref bean="sessionFactory"/>
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
@@ -2,6 +2,7 @@
|
||||
patch.service.not_relevant=Not relevant to schema {0}
|
||||
patch.executer.checking=Checking for patches to apply ...
|
||||
patch.service.applying_patch=\tApplying patch ''{0}'' ({1}).
|
||||
patch.progress=\t\tPatch {0}% complete, estimated complete at {1}.
|
||||
patch.executer.no_patches_required=No patches were required.
|
||||
patch.executer.system_readonly=Patches cannot be applied to a read-only system. Possible incompatibilities may exist between the application code and the existing data.
|
||||
patch.executer.not_executed =\n=== Recorded patch (not executed) === \nID: {0}\nRESULT: \n{1}\n=====================================
|
||||
|
@@ -1268,6 +1268,9 @@
|
||||
<!-- helper beans -->
|
||||
<property name="accessControlListDao">
|
||||
<ref bean="avmACLDAO" />
|
||||
</property>
|
||||
<property name="aclDaoComponent">
|
||||
<ref bean="aclDaoComponent" />
|
||||
</property>
|
||||
<property name="dependsOn" >
|
||||
<list>
|
||||
@@ -1380,6 +1383,9 @@
|
||||
<property name="permissionService">
|
||||
<ref bean="permissionService" />
|
||||
</property>
|
||||
<property name="aclDaoComponent">
|
||||
<ref bean="aclDaoComponent" />
|
||||
</property>
|
||||
<property name="avmSnapShotTriggeredIndexingMethodInterceptor">
|
||||
<ref bean="avmSnapShotTriggeredIndexingMethodInterceptor" />
|
||||
</property>
|
||||
|
@@ -74,6 +74,13 @@ system.acl.maxPermissionChecks=1000
|
||||
# org.alfresco.repo.domain.schema.SchemaBootstrap for V2.1.2
|
||||
system.maximumStringLength=-1
|
||||
|
||||
#
|
||||
# Limit hibernate session size by trying to amalgamate events for the L2 session invalidation
|
||||
# - hibernate works as is up to this size
|
||||
# - after the limit is hit events that can be grouped invalidate the L2 cache by type and not instance
|
||||
# events may not group if there are post action listener registered (this is not the case with the default distribution)
|
||||
system.hibernateMaxExecutions=20000
|
||||
|
||||
# #################### #
|
||||
# Lucene configuration #
|
||||
# #################### #
|
||||
|
@@ -27,9 +27,11 @@ package org.alfresco.repo.admin.patch;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.repo.node.integrity.IntegrityChecker;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
@@ -46,8 +48,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Base implementation of the patch. This class ensures that the patch is
|
||||
* thread- and transaction-safe.
|
||||
* Base implementation of the patch. This class ensures that the patch is thread- and transaction-safe.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
@@ -61,8 +62,14 @@ public abstract class AbstractPatch implements Patch
|
||||
* </ul>
|
||||
*/
|
||||
public static final String ERR_PROPERTY_NOT_SET = "patch.general.property_not_set";
|
||||
private static final String MSG_PROGRESS = "patch.progress";
|
||||
|
||||
private static final long RANGE_10 = 1000 * 60 * 90;
|
||||
private static final long RANGE_5 = 1000 * 60 * 60 * 4;
|
||||
private static final long RANGE_2 = 1000 * 60 * 90 * 10;
|
||||
|
||||
private static Log logger = LogFactory.getLog(AbstractPatch.class);
|
||||
private static Log progress_logger = LogFactory.getLog(PatchExecuter.class);
|
||||
|
||||
private String id;
|
||||
private int fixesFromSchema;
|
||||
@@ -73,7 +80,8 @@ public abstract class AbstractPatch implements Patch
|
||||
private List<Patch> dependsOn;
|
||||
/** flag indicating if the patch was successfully applied */
|
||||
private boolean applied;
|
||||
private boolean applyToTenants = true; // by default, apply to each tenant, if tenant service is enabled
|
||||
private boolean applyToTenants;
|
||||
|
||||
/** the service to register ourselves with */
|
||||
private PatchService patchService;
|
||||
/** used to ensure a unique transaction per execution */
|
||||
@@ -90,12 +98,19 @@ public abstract class AbstractPatch implements Patch
|
||||
protected TenantDeployerService tenantDeployerService;
|
||||
|
||||
|
||||
/** track completion * */
|
||||
int percentComplete = 0;
|
||||
|
||||
/** start time * */
|
||||
long startTime;
|
||||
|
||||
public AbstractPatch()
|
||||
{
|
||||
this.fixesFromSchema = -1;
|
||||
this.fixesToSchema = -1;
|
||||
this.targetSchema = -1;
|
||||
this.applied = false;
|
||||
this.applyToTenants = true; // by default, apply to each tenant, if tenant service is enabled
|
||||
this.dependsOn = Collections.emptyList();
|
||||
}
|
||||
|
||||
@@ -184,8 +199,8 @@ public abstract class AbstractPatch implements Patch
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param id the unique ID of the patch. This dictates the order in which patches are applied.
|
||||
* @param id
|
||||
* the unique ID of the patch. This dictates the order in which patches are applied.
|
||||
*/
|
||||
public void setId(String id)
|
||||
{
|
||||
@@ -200,7 +215,8 @@ public abstract class AbstractPatch implements Patch
|
||||
/**
|
||||
* Set the smallest schema number that this patch may be applied to.
|
||||
*
|
||||
* @param version a schema number not smaller than 0
|
||||
* @param version
|
||||
* a schema number not smaller than 0
|
||||
*/
|
||||
public void setFixesFromSchema(int version)
|
||||
{
|
||||
@@ -224,8 +240,8 @@ public abstract class AbstractPatch implements Patch
|
||||
/**
|
||||
* Set the largest schema version number that this patch may be applied to.
|
||||
*
|
||||
* @param version a schema version number not smaller than the
|
||||
* {@link #setFixesFromSchema(int) from version} number.
|
||||
* @param version
|
||||
* a schema version number not smaller than the {@link #setFixesFromSchema(int) from version} number.
|
||||
*/
|
||||
public void setFixesToSchema(int version)
|
||||
{
|
||||
@@ -242,12 +258,11 @@ public abstract class AbstractPatch implements Patch
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the schema version that this patch attempts to take the existing schema to.
|
||||
* This is for informational purposes only, acting as an indicator of intention rather
|
||||
* than having any specific effect.
|
||||
* Set the schema version that this patch attempts to take the existing schema to. This is for informational
|
||||
* purposes only, acting as an indicator of intention rather than having any specific effect.
|
||||
*
|
||||
* @param version a schema version number that must be greater than the
|
||||
* {@link #fixesToSchema max fix schema number}
|
||||
* @param version
|
||||
* a schema version number that must be greater than the {@link #fixesToSchema max fix schema number}
|
||||
*/
|
||||
public void setTargetSchema(int version)
|
||||
{
|
||||
@@ -264,7 +279,8 @@ public abstract class AbstractPatch implements Patch
|
||||
}
|
||||
|
||||
/**
|
||||
* @param description a thorough description of the patch
|
||||
* @param description
|
||||
* a thorough description of the patch
|
||||
*/
|
||||
public void setDescription(String description)
|
||||
{
|
||||
@@ -277,10 +293,10 @@ public abstract class AbstractPatch implements Patch
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all the dependencies for this patch. It should not be executed
|
||||
* before all the dependencies have been applied.
|
||||
* Set all the dependencies for this patch. It should not be executed before all the dependencies have been applied.
|
||||
*
|
||||
* @param dependsOn a list of dependencies
|
||||
* @param dependsOn
|
||||
* a list of dependencies
|
||||
*/
|
||||
public void setDependsOn(List<Patch> dependsOn)
|
||||
{
|
||||
@@ -295,8 +311,10 @@ public abstract class AbstractPatch implements Patch
|
||||
/**
|
||||
* Performs a null check on the supplied value.
|
||||
*
|
||||
* @param value value to check
|
||||
* @param name name of the property to report
|
||||
* @param value
|
||||
* value to check
|
||||
* @param name
|
||||
* name of the property to report
|
||||
*/
|
||||
protected final void checkPropertyNotNull(Object value, String name)
|
||||
{
|
||||
@@ -312,9 +330,8 @@ public abstract class AbstractPatch implements Patch
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the schema version properties have been set appropriately.
|
||||
* Derived classes can override this method to perform their own validation provided
|
||||
* that this method is called by the derived class.
|
||||
* Check that the schema version properties have been set appropriately. Derived classes can override this method to
|
||||
* perform their own validation provided that this method is called by the derived class.
|
||||
*/
|
||||
protected void checkProperties()
|
||||
{
|
||||
@@ -328,9 +345,8 @@ public abstract class AbstractPatch implements Patch
|
||||
checkPropertyNotNull(authenticationComponent, "authenticationComponent");
|
||||
if (fixesFromSchema == -1 || fixesToSchema == -1 || targetSchema == -1)
|
||||
{
|
||||
throw new AlfrescoRuntimeException(
|
||||
"Patch properties 'fixesFromSchema', 'fixesToSchema' and 'targetSchema' have not all been set on this patch: \n" +
|
||||
" patch: " + this);
|
||||
throw new AlfrescoRuntimeException("Patch properties 'fixesFromSchema', 'fixesToSchema' and 'targetSchema' have not all been set on this patch: \n"
|
||||
+ " patch: " + this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,8 +360,7 @@ public abstract class AbstractPatch implements Patch
|
||||
// ensure that this has not been executed already
|
||||
if (applied)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("The patch has already been executed: \n" +
|
||||
" patch: " + this);
|
||||
throw new AlfrescoRuntimeException("The patch has already been executed: \n" + " patch: " + this);
|
||||
}
|
||||
// check properties
|
||||
checkProperties();
|
||||
@@ -354,9 +369,7 @@ public abstract class AbstractPatch implements Patch
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\n" +
|
||||
"Patch will be applied: \n" +
|
||||
" patch: " + this);
|
||||
logger.debug("\n" + "Patch will be applied: \n" + " patch: " + this);
|
||||
}
|
||||
AuthenticationUtil.RunAsWork<String> authorisedPathWork = new AuthenticationUtil.RunAsWork<String>()
|
||||
{
|
||||
@@ -399,16 +412,14 @@ public abstract class AbstractPatch implements Patch
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(patchWork);
|
||||
}
|
||||
};
|
||||
startTime = System.currentTimeMillis();
|
||||
String report = AuthenticationUtil.runAs(authorisedPathWork, AuthenticationUtil.getSystemUserName());
|
||||
// the patch was successfully applied
|
||||
applied = true;
|
||||
// done
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("\n" +
|
||||
"Patch successfully applied: \n" +
|
||||
" patch: " + this + "\n" +
|
||||
" report: " + report);
|
||||
logger.debug("\n" + "Patch successfully applied: \n" + " patch: " + this + "\n" + " report: " + report);
|
||||
}
|
||||
return report;
|
||||
}
|
||||
@@ -435,7 +446,8 @@ public abstract class AbstractPatch implements Patch
|
||||
/**
|
||||
* Dumps the error's full message and trace to the String
|
||||
*
|
||||
* @param e the throwable
|
||||
* @param e
|
||||
* the throwable
|
||||
* @return Returns a String representative of the printStackTrace method
|
||||
*/
|
||||
private String makeReport(Throwable e)
|
||||
@@ -454,13 +466,91 @@ public abstract class AbstractPatch implements Patch
|
||||
}
|
||||
|
||||
/**
|
||||
* This method does the work. All transactions and thread-safety will be taken care of by this class.
|
||||
* Any exception will result in the transaction being rolled back. Integrity checks are downgraded
|
||||
* for the duration of the transaction.
|
||||
* This method does the work. All transactions and thread-safety will be taken care of by this class. Any exception
|
||||
* will result in the transaction being rolled back. Integrity checks are downgraded for the duration of the
|
||||
* transaction.
|
||||
*
|
||||
* @return Returns the report (only success messages).
|
||||
* @see #apply()
|
||||
* @throws Exception anything can be thrown. This must be used for all failures.
|
||||
* @throws Exception
|
||||
* anything can be thrown. This must be used for all failures.
|
||||
*/
|
||||
protected abstract String applyInternal() throws Exception;
|
||||
|
||||
/**
|
||||
* Support to report patch completion and estimated completion time.
|
||||
*
|
||||
* @param estimatedTotal
|
||||
* @param currentInteration
|
||||
*/
|
||||
protected void reportProgress(long estimatedTotal, long currentInteration)
|
||||
{
|
||||
if (progress_logger.isDebugEnabled())
|
||||
{
|
||||
progress_logger.debug(currentInteration + "/" + estimatedTotal);
|
||||
}
|
||||
if (currentInteration == 0)
|
||||
{
|
||||
// No point reporting the start - we have already done that elsewhere ....
|
||||
percentComplete = 0;
|
||||
}
|
||||
else if (currentInteration * 100l / estimatedTotal > percentComplete)
|
||||
{
|
||||
int previous = percentComplete;
|
||||
percentComplete = (int) (currentInteration * 100l / estimatedTotal);
|
||||
|
||||
if (percentComplete < 100)
|
||||
{
|
||||
// conditional report
|
||||
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long timeSoFar = currentTime - startTime;
|
||||
long timeRemaining = timeSoFar * (100 - percentComplete) / percentComplete;
|
||||
|
||||
int report = -1;
|
||||
|
||||
if (timeRemaining > 60000)
|
||||
{
|
||||
int reportInterval = getreportingInterval(timeSoFar, timeRemaining);
|
||||
|
||||
for (int i = previous + 1; i <= percentComplete; i++)
|
||||
{
|
||||
if (i % reportInterval == 0)
|
||||
{
|
||||
report = i;
|
||||
}
|
||||
}
|
||||
if (report > 0)
|
||||
{
|
||||
Date end = new Date(currentTime + timeRemaining);
|
||||
|
||||
String msg = I18NUtil.getMessage(MSG_PROGRESS, report, end);
|
||||
progress_logger.info(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getreportingInterval(long soFar, long toGo)
|
||||
{
|
||||
long total = soFar + toGo;
|
||||
if (total < RANGE_10)
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
else if (total < RANGE_5)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
else if (total < RANGE_2)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -29,7 +29,10 @@ import java.util.Map;
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||
import org.alfresco.repo.domain.AccessControlListDAO;
|
||||
import org.alfresco.repo.domain.hibernate.AclDaoComponentImpl;
|
||||
import org.alfresco.repo.security.permissions.ACLType;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
|
||||
/**
|
||||
* Migrate permissions from the OLD format to defining, shared and layered
|
||||
@@ -41,11 +44,22 @@ public class AVMPermissionsPatch extends AbstractPatch
|
||||
|
||||
private AccessControlListDAO accessControlListDao;
|
||||
|
||||
private AclDaoComponentImpl aclDaoComponent;
|
||||
|
||||
@Override
|
||||
protected String applyInternal() throws Exception
|
||||
{
|
||||
Long toDo = aclDaoComponent.getAVMHeadNodeCount();
|
||||
Long maxId = aclDaoComponent.getMaxAclId();
|
||||
|
||||
Thread progressThread = new Thread(new ProgressWatcher(toDo, maxId), "WCMPactchProgressWatcher");
|
||||
progressThread.start();
|
||||
|
||||
Map<ACLType, Integer> summary = accessControlListDao.patchAcls();
|
||||
|
||||
progressThread.interrupt();
|
||||
progressThread.join();
|
||||
|
||||
// build the result message
|
||||
String msg = I18NUtil.getMessage(MSG_SUCCESS, summary.get(ACLType.DEFINING), summary.get(ACLType.LAYERED));
|
||||
// done
|
||||
@@ -57,4 +71,57 @@ public class AVMPermissionsPatch extends AbstractPatch
|
||||
this.accessControlListDao = accessControlListDao;
|
||||
}
|
||||
|
||||
public void setAclDaoComponent(AclDaoComponentImpl aclDaoComponent)
|
||||
{
|
||||
this.aclDaoComponent = aclDaoComponent;
|
||||
}
|
||||
|
||||
|
||||
private class ProgressWatcher implements Runnable
|
||||
{
|
||||
private boolean running = true;
|
||||
|
||||
Long toDo;
|
||||
|
||||
Long max;
|
||||
|
||||
ProgressWatcher(Long toDo, Long max)
|
||||
{
|
||||
this.toDo = toDo;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
while (running)
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(60000);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
|
||||
if (running)
|
||||
{
|
||||
RetryingTransactionHelper txHelper = transactionService.getRetryingTransactionHelper();
|
||||
txHelper.setMaxRetries(1);
|
||||
Long done = txHelper.doInTransaction(new RetryingTransactionCallback<Long>()
|
||||
{
|
||||
|
||||
public Long execute() throws Throwable
|
||||
{
|
||||
return aclDaoComponent.getAVMNodeCountWithNewACLS(max);
|
||||
}
|
||||
}, true, true);
|
||||
|
||||
reportProgress(toDo, done);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -32,7 +32,10 @@ import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||
import org.alfresco.repo.avm.AVMNodeConverter;
|
||||
import org.alfresco.repo.avm.AVMRepository;
|
||||
import org.alfresco.repo.domain.PropertyValue;
|
||||
import org.alfresco.repo.domain.hibernate.AclDaoComponentImpl;
|
||||
import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
|
||||
import org.alfresco.service.cmr.avm.AVMService;
|
||||
import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
|
||||
@@ -43,6 +46,7 @@ import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
|
||||
/**
|
||||
* Remove ACLs on all but staging area stores On staging area stores, set ACls according to the users and roles as set
|
||||
@@ -60,6 +64,8 @@ public class WCMPermissionPatch extends AbstractPatch
|
||||
|
||||
PermissionService permissionService;
|
||||
|
||||
AclDaoComponentImpl aclDaoComponent;
|
||||
|
||||
public void setAvmService(AVMService avmService)
|
||||
{
|
||||
this.avmService = avmService;
|
||||
@@ -75,9 +81,20 @@ public class WCMPermissionPatch extends AbstractPatch
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
public void setAclDaoComponent(AclDaoComponentImpl aclDaoComponent)
|
||||
{
|
||||
this.aclDaoComponent = aclDaoComponent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String applyInternal() throws Exception
|
||||
{
|
||||
Long toDo = aclDaoComponent.getAVMHeadNodeCount();
|
||||
Long maxId = aclDaoComponent.getMaxAclId();
|
||||
|
||||
Thread progressThread = new Thread(new ProgressWatcher(toDo, maxId), "WCMPactchProgressWatcher");
|
||||
progressThread.start();
|
||||
|
||||
List<AVMStoreDescriptor> stores = avmService.getStores();
|
||||
for (AVMStoreDescriptor store : stores)
|
||||
{
|
||||
@@ -113,6 +130,9 @@ public class WCMPermissionPatch extends AbstractPatch
|
||||
}
|
||||
}
|
||||
|
||||
progressThread.interrupt();
|
||||
progressThread.join();
|
||||
|
||||
// build the result message
|
||||
String msg = I18NUtil.getMessage(MSG_SUCCESS);
|
||||
// done
|
||||
@@ -228,4 +248,50 @@ public class WCMPermissionPatch extends AbstractPatch
|
||||
return name.substring(0, index);
|
||||
}
|
||||
|
||||
private class ProgressWatcher implements Runnable
|
||||
{
|
||||
private boolean running = true;
|
||||
|
||||
Long toDo;
|
||||
|
||||
Long max;
|
||||
|
||||
ProgressWatcher(Long toDo, Long max)
|
||||
{
|
||||
this.toDo = toDo;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
while (running)
|
||||
{
|
||||
try
|
||||
{
|
||||
Thread.sleep(60000);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
running = false;
|
||||
}
|
||||
|
||||
if (running)
|
||||
{
|
||||
RetryingTransactionHelper txHelper = transactionService.getRetryingTransactionHelper();
|
||||
txHelper.setMaxRetries(1);
|
||||
Long done = txHelper.doInTransaction(new RetryingTransactionCallback<Long>()
|
||||
{
|
||||
|
||||
public Long execute() throws Throwable
|
||||
{
|
||||
return aclDaoComponent.getAVMNodeCountWithNewACLS(max);
|
||||
}
|
||||
}, true, true);
|
||||
|
||||
reportProgress(toDo, done);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -451,7 +451,6 @@ public class AVMServicePermissionsTest extends TestCase
|
||||
assertTrue(checkPermission("admin", storeName + ":/base", PermissionService.ALL_PERMISSIONS, true));
|
||||
assertTrue(checkHasPermission("admin", nodeRef, PermissionService.ALL_PERMISSIONS, true));
|
||||
|
||||
|
||||
permissionService.setPermission(nodeRef.getStoreRef(), "andy", PermissionService.ALL_PERMISSIONS, true);
|
||||
assertTrue(checkHasPermission("andy", nodeRef, PermissionService.ALL_PERMISSIONS, true));
|
||||
permissionService.setPermission(nodeRef.getStoreRef(), "andy", PermissionService.READ, true);
|
||||
@@ -495,11 +494,13 @@ public class AVMServicePermissionsTest extends TestCase
|
||||
avmService.purgeStore(storeName + "-layer-d");
|
||||
avmService.purgeStore(storeName + "-layer-layer-base");
|
||||
avmService.purgeStore(storeName + "-layer-layer-layer-base");
|
||||
|
||||
System.out.println(avmService.getStores());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void testSimpleUpdate() throws Exception
|
||||
public void testSimpleUpdate() throws Throwable
|
||||
{
|
||||
runAs("admin");
|
||||
String storeName = "PermissionsTest-" + getName() + "-" + (new Date().getTime());
|
||||
@@ -556,6 +557,11 @@ public class AVMServicePermissionsTest extends TestCase
|
||||
fileAcl = node.getAcl();
|
||||
assertNull(fileAcl);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
throw t;
|
||||
}
|
||||
finally
|
||||
{
|
||||
avmService.purgeStore(storeName);
|
||||
|
@@ -34,6 +34,8 @@ import org.alfresco.repo.avm.AVMNodeConverter;
|
||||
import org.alfresco.repo.avm.AVMRepository;
|
||||
import org.alfresco.repo.domain.AccessControlListDAO;
|
||||
import org.alfresco.repo.domain.DbAccessControlList;
|
||||
import org.alfresco.repo.domain.hibernate.AclDaoComponentImpl.Indirection;
|
||||
import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.security.permissions.ACLType;
|
||||
@@ -69,6 +71,10 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
|
||||
private AclDaoComponent aclDaoComponent;
|
||||
|
||||
private AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor;
|
||||
|
||||
private HibernateSessionHelper hibernateSessionHelper;
|
||||
|
||||
/**
|
||||
* Default constructory.
|
||||
*/
|
||||
@@ -91,6 +97,16 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
this.aclDaoComponent = aclDaoComponent;
|
||||
}
|
||||
|
||||
public void setAvmSnapShotTriggeredIndexingMethodInterceptor(AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor)
|
||||
{
|
||||
this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor;
|
||||
}
|
||||
|
||||
public void setHibernateSessionHelper(HibernateSessionHelper hibernateSessionHelper)
|
||||
{
|
||||
this.hibernateSessionHelper = hibernateSessionHelper;
|
||||
}
|
||||
|
||||
public Long getIndirectAcl(NodeRef nodeRef)
|
||||
{
|
||||
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef);
|
||||
@@ -233,10 +249,14 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
{
|
||||
inherited = aclDaoComponent.getInheritedAccessControlList(after);
|
||||
}
|
||||
updateChangedAclsImpl(startingPoint, changes, SetMode.ALL, inherited, after);
|
||||
Map<Long, Set<Long>> indirections = buildIndirections();
|
||||
updateChangedAclsImpl(startingPoint, changes, SetMode.ALL, inherited, after, indirections);
|
||||
}
|
||||
|
||||
private void updateChangedAclsImpl(NodeRef startingPoint, List<AclChange> changes, SetMode mode, Long inherited, Long setAcl)
|
||||
private void updateChangedAclsImpl(NodeRef startingPoint, List<AclChange> changes, SetMode mode, Long inherited, Long setAcl, Map<Long, Set<Long>> indirections)
|
||||
{
|
||||
hibernateSessionHelper.mark();
|
||||
try
|
||||
{
|
||||
HashMap<Long, Long> changeMap = new HashMap<Long, Long>();
|
||||
HashSet<Long> unchangedSet = new HashSet<Long>();
|
||||
@@ -260,10 +280,15 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
|
||||
if (inherited != null)
|
||||
{
|
||||
updateReferencingLayeredAcls(startingPoint, inherited);
|
||||
updateReferencingLayeredAcls(startingPoint, inherited, indirections);
|
||||
}
|
||||
updateInheritedChangedAcls(startingPoint, changeMap, unchangedSet, inherited, mode, indirections);
|
||||
updateLayeredAclsChangedByInheritance(changes, changeMap, unchangedSet, indirections);
|
||||
}
|
||||
finally
|
||||
{
|
||||
hibernateSessionHelper.resetAndRemoveMark();
|
||||
}
|
||||
updateInheritedChangedAcls(startingPoint, changeMap, unchangedSet, inherited, mode);
|
||||
updateLayeredAclsChangedByInheritance(changes, changeMap, unchangedSet);
|
||||
}
|
||||
|
||||
public void forceCopy(NodeRef nodeRef)
|
||||
@@ -283,10 +308,33 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
{
|
||||
throw new InvalidNodeRefException(nodeRef);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateReferencingLayeredAcls(NodeRef node, Long inherited)
|
||||
private Map<Long, Set<Long>> buildIndirections()
|
||||
{
|
||||
Map<Long, Set<Long>> answer = new HashMap<Long, Set<Long>>();
|
||||
|
||||
List<Indirection> indirections = aclDaoComponent.getAvmIndirections();
|
||||
for (Indirection indirection : indirections)
|
||||
{
|
||||
AVMNodeDescriptor toDesc = fAVMService.lookup(indirection.getToVersion(), indirection.getTo(), true);
|
||||
if (toDesc != null)
|
||||
{
|
||||
Long toId = Long.valueOf(toDesc.getId());
|
||||
Set<Long> referees = answer.get(toId);
|
||||
if (referees == null)
|
||||
{
|
||||
referees = new HashSet<Long>();
|
||||
answer.put(toId, referees);
|
||||
}
|
||||
referees.add(indirection.getFrom());
|
||||
}
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
private void updateReferencingLayeredAcls(NodeRef node, Long inherited, Map<Long, Set<Long>> indirections)
|
||||
{
|
||||
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(node);
|
||||
int version = avmVersionPath.getFirst();
|
||||
@@ -304,20 +352,18 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Pair<Integer, String>> paths = fAVMService.getHeadPaths(descriptor);
|
||||
for (Pair<Integer, String> current : paths)
|
||||
Set<Long> avmNodeIds = indirections.get(Long.valueOf(descriptor.getId()));
|
||||
if (avmNodeIds != null)
|
||||
{
|
||||
List<Long> avmNodeIds = aclDaoComponent.getAvmNodesByIndirection(current.getSecond());
|
||||
for (Long id : avmNodeIds)
|
||||
{
|
||||
// need to fix up inheritance as is has changed
|
||||
AVMNodeDescriptor layerDesc = new AVMNodeDescriptor(null, null, 0, null, null, null, 0, 0, 0, id, null, 0, null, 0, false, 0, false, 0, 0);
|
||||
|
||||
List<Pair<Integer, String>> layerPaths = fAVMRepository.getHeadPaths(layerDesc);
|
||||
// Update all locations with the updated ACL
|
||||
|
||||
for (Pair<Integer, String> layerPath : layerPaths)
|
||||
{
|
||||
AVMNodeDescriptor test = fAVMService.lookup(-1, layerPath.getSecond());
|
||||
if (test.isPrimary())
|
||||
{
|
||||
DbAccessControlList target = getAclAsSystem(-1, layerPath.getSecond());
|
||||
if (target != null)
|
||||
@@ -337,7 +383,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
{
|
||||
newInherited = aclDaoComponent.getInheritedAccessControlList(change.getAfter());
|
||||
}
|
||||
updateChangedAclsImpl(layeredNode, layeredChanges, SetMode.DIRECT_ONLY, newInherited, change.getAfter());
|
||||
updateChangedAclsImpl(layeredNode, layeredChanges, SetMode.DIRECT_ONLY, newInherited, change.getAfter(), indirections);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -348,14 +394,13 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (AVMException e)
|
||||
{
|
||||
throw new InvalidNodeRefException(node);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLayeredAclsChangedByInheritance(List<AclChange> changes, HashMap<Long, Long> changeMap, Set<Long> unchanged)
|
||||
private void updateLayeredAclsChangedByInheritance(List<AclChange> changes, HashMap<Long, Long> changeMap, Set<Long> unchanged, Map<Long, Set<Long>> indirections)
|
||||
{
|
||||
for (AclChange change : changes)
|
||||
{
|
||||
@@ -375,14 +420,16 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
// No need to force COW - any inherited ACL will have COWED if the top ACL required it
|
||||
setAclAsSystem(path.getSecond(), aclDaoComponent.getDbAccessControlList(change.getAfter()));
|
||||
NodeRef layeredNode = AVMNodeConverter.ToNodeRef(-1, path.getSecond());
|
||||
updateInheritedChangedAcls(layeredNode, changeMap, unchanged, aclDaoComponent.getInheritedAccessControlList(change.getAfter()), SetMode.DIRECT_ONLY);
|
||||
updateInheritedChangedAcls(layeredNode, changeMap, unchanged, aclDaoComponent.getInheritedAccessControlList(change.getAfter()), SetMode.DIRECT_ONLY,
|
||||
indirections);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateInheritedChangedAcls(NodeRef startingPoint, HashMap<Long, Long> changeMap, Set<Long> unchanged, Long unsetAcl, SetMode mode)
|
||||
private void updateInheritedChangedAcls(NodeRef startingPoint, HashMap<Long, Long> changeMap, Set<Long> unchanged, Long unsetAcl, SetMode mode,
|
||||
Map<Long, Set<Long>> indirections)
|
||||
{
|
||||
// Walk children and fix up any that reference the given list ..
|
||||
Pair<Integer, String> avmVersionPath = AVMNodeConverter.ToAVMVersionPath(startingPoint);
|
||||
@@ -404,9 +451,10 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
|
||||
if (descriptor.isLayeredDirectory())
|
||||
{
|
||||
setInheritanceForDirectChildren(descriptor, changeMap, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, descriptor.getPath()).getId()));
|
||||
setInheritanceForDirectChildren(descriptor, changeMap, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, descriptor.getPath()).getId()),
|
||||
indirections);
|
||||
}
|
||||
fixUpAcls(descriptor, changeMap, unchanged, unsetAcl, mode);
|
||||
fixUpAcls(descriptor, changeMap, unchanged, unsetAcl, mode, indirections);
|
||||
}
|
||||
}
|
||||
catch (AVMException e)
|
||||
@@ -415,7 +463,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
}
|
||||
}
|
||||
|
||||
private void fixUpAcls(AVMNodeDescriptor descriptor, Map<Long, Long> changes, Set<Long> unchanged, Long unsetAcl, SetMode mode)
|
||||
private void fixUpAcls(AVMNodeDescriptor descriptor, Map<Long, Long> changes, Set<Long> unchanged, Long unsetAcl, SetMode mode, Map<Long, Set<Long>> indirections)
|
||||
{
|
||||
DbAccessControlList acl = getAclAsSystem(-1, descriptor.getPath());
|
||||
Long id = null;
|
||||
@@ -429,7 +477,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
// No need to force COW - ACL should have COWed if required
|
||||
setAclAsSystem(descriptor.getPath(), aclDaoComponent.getDbAccessControlList(unsetAcl));
|
||||
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, descriptor.getPath());
|
||||
updateReferencingLayeredAcls(nodeRef, unsetAcl);
|
||||
updateReferencingLayeredAcls(nodeRef, unsetAcl, indirections);
|
||||
}
|
||||
else if (changes.containsKey(id))
|
||||
{
|
||||
@@ -466,16 +514,24 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
}
|
||||
for (AVMNodeDescriptor child : children.values())
|
||||
{
|
||||
fixUpAcls(child, changes, unchanged, unsetAcl, mode);
|
||||
hibernateSessionHelper.mark();
|
||||
try
|
||||
{
|
||||
fixUpAcls(child, changes, unchanged, unsetAcl, mode, indirections);
|
||||
}
|
||||
finally
|
||||
{
|
||||
hibernateSessionHelper.resetAndRemoveMark();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setInheritanceForDirectChildren(AVMNodeDescriptor descriptor, Map<Long, Long> changeMap, Long mergeFrom)
|
||||
private void setInheritanceForDirectChildren(AVMNodeDescriptor descriptor, Map<Long, Long> changeMap, Long mergeFrom, Map<Long, Set<Long>> indirections)
|
||||
{
|
||||
List<AclChange> changes = new ArrayList<AclChange>();
|
||||
setFixedAcls(descriptor, mergeFrom, changes, SetMode.DIRECT_ONLY, false);
|
||||
setFixedAcls(descriptor, mergeFrom, changes, SetMode.DIRECT_ONLY, false, indirections);
|
||||
for (AclChange change : changes)
|
||||
{
|
||||
if (!change.getBefore().equals(change.getAfter()))
|
||||
@@ -498,9 +554,10 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
String path = avmVersionPath.getSecond();
|
||||
try
|
||||
{
|
||||
Map<Long, Set<Long>> indirections = buildIndirections();
|
||||
List<AclChange> changes = new ArrayList<AclChange>();
|
||||
AVMNodeDescriptor descriptor = fAVMService.lookup(version, path);
|
||||
setFixedAcls(descriptor, mergeFrom, changes, SetMode.ALL, false);
|
||||
setFixedAcls(descriptor, mergeFrom, changes, SetMode.ALL, false, indirections);
|
||||
return changes;
|
||||
|
||||
}
|
||||
@@ -510,7 +567,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
}
|
||||
}
|
||||
|
||||
public void setFixedAcls(AVMNodeDescriptor descriptor, Long mergeFrom, List<AclChange> changes, SetMode mode, boolean set)
|
||||
public void setFixedAcls(AVMNodeDescriptor descriptor, Long mergeFrom, List<AclChange> changes, SetMode mode, boolean set, Map<Long, Set<Long>> indirections)
|
||||
{
|
||||
if (descriptor == null)
|
||||
{
|
||||
@@ -527,7 +584,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
if (previous == null)
|
||||
{
|
||||
NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, descriptor.getPath());
|
||||
updateReferencingLayeredAcls(nodeRef, mergeFrom);
|
||||
updateReferencingLayeredAcls(nodeRef, mergeFrom, indirections);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,8 +611,15 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
|
||||
if (acl == null)
|
||||
{
|
||||
setFixedAcls(child, mergeFrom, changes, mode, true);
|
||||
|
||||
hibernateSessionHelper.mark();
|
||||
try
|
||||
{
|
||||
setFixedAcls(child, mergeFrom, changes, mode, true, indirections);
|
||||
}
|
||||
finally
|
||||
{
|
||||
hibernateSessionHelper.resetAndRemoveMark();
|
||||
}
|
||||
}
|
||||
else if (acl.getAclType() == ACLType.LAYERED)
|
||||
{
|
||||
@@ -572,17 +636,33 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
for (AclChange change : newChanges)
|
||||
{
|
||||
if (change.getBefore().equals(acl.getId()))
|
||||
{
|
||||
hibernateSessionHelper.mark();
|
||||
try
|
||||
{
|
||||
setAclAsSystem(child.getPath(), aclDaoComponent.getDbAccessControlList(change.getAfter()));
|
||||
setFixedAcls(child, aclDaoComponent.getInheritedAccessControlList(change.getAfter()), newChanges, SetMode.DIRECT_ONLY, false);
|
||||
setFixedAcls(child, aclDaoComponent.getInheritedAccessControlList(change.getAfter()), newChanges, SetMode.DIRECT_ONLY, false, indirections);
|
||||
changes.addAll(newChanges);
|
||||
break;
|
||||
}
|
||||
finally
|
||||
{
|
||||
hibernateSessionHelper.resetAndRemoveMark();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setFixedAcls(child, mergeFrom, changes, mode, true);
|
||||
hibernateSessionHelper.mark();
|
||||
try
|
||||
{
|
||||
setFixedAcls(child, mergeFrom, changes, mode, true, indirections);
|
||||
}
|
||||
finally
|
||||
{
|
||||
hibernateSessionHelper.resetAndRemoveMark();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -599,11 +679,31 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
{
|
||||
CounterSet result = new CounterSet();
|
||||
List<AVMStoreDescriptor> stores = fAVMService.getStores();
|
||||
Map<Long, Set<Long>> indirections = buildIndirections();
|
||||
for (AVMStoreDescriptor store : stores)
|
||||
{
|
||||
AVMNodeDescriptor root = fAVMService.getStoreRoot(-1, store.getName());
|
||||
CounterSet update = fixOldAvmAcls(root);
|
||||
CounterSet update;
|
||||
switch (avmSnapShotTriggeredIndexingMethodInterceptor.getStoreType(store.getName()))
|
||||
{
|
||||
case AUTHOR:
|
||||
case AUTHOR_PREVIEW:
|
||||
case AUTHOR_WORKFLOW:
|
||||
case AUTHOR_WORKFLOW_PREVIEW:
|
||||
case STAGING:
|
||||
case STAGING_PREVIEW:
|
||||
case WORKFLOW:
|
||||
case WORKFLOW_PREVIEW:
|
||||
AVMNodeDescriptor www = fAVMService.lookup(-1, store.getName() + ":/www");
|
||||
update = fixOldAvmAcls(www, false, indirections);
|
||||
result.add(update);
|
||||
break;
|
||||
case UNKNOWN:
|
||||
default:
|
||||
update = fixOldAvmAcls(root, true, indirections);
|
||||
result.add(update);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
HashMap<ACLType, Integer> toReturn = new HashMap<ACLType, Integer>();
|
||||
@@ -614,20 +714,32 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
toReturn.put(ACLType.OLD, Integer.valueOf(result.get(ACLType.OLD).getCounter()));
|
||||
toReturn.put(ACLType.SHARED, Integer.valueOf(result.get(ACLType.SHARED).getCounter()));
|
||||
return toReturn;
|
||||
|
||||
}
|
||||
|
||||
private CounterSet fixOldAvmAcls(AVMNodeDescriptor node)
|
||||
private CounterSet fixOldAvmAcls(AVMNodeDescriptor node, boolean searchDirectories, Map<Long, Set<Long>> indirections)
|
||||
{
|
||||
hibernateSessionHelper.mark();
|
||||
try
|
||||
{
|
||||
return fixOldAvmAclsImpl(node, searchDirectories, indirections);
|
||||
}
|
||||
finally
|
||||
{
|
||||
hibernateSessionHelper.resetAndRemoveMark();
|
||||
}
|
||||
}
|
||||
|
||||
private CounterSet fixOldAvmAclsImpl(AVMNodeDescriptor node, boolean searchDirectories, Map<Long, Set<Long>> indirections)
|
||||
{
|
||||
CounterSet result = new CounterSet();
|
||||
// Do the children first
|
||||
|
||||
if (node.isDirectory())
|
||||
if (searchDirectories && node.isDirectory())
|
||||
{
|
||||
Map<String, AVMNodeDescriptor> children = fAVMRepository.getListingDirect(node, true);
|
||||
for (AVMNodeDescriptor child : children.values())
|
||||
{
|
||||
CounterSet update = fixOldAvmAcls(child);
|
||||
CounterSet update = fixOldAvmAcls(child, searchDirectories, indirections);
|
||||
result.add(update);
|
||||
}
|
||||
}
|
||||
@@ -660,7 +772,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
|
||||
List<AclChange> changes = new ArrayList<AclChange>();
|
||||
|
||||
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(id), changes, SetMode.DIRECT_ONLY, false);
|
||||
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(id), changes, SetMode.DIRECT_ONLY, false, indirections);
|
||||
|
||||
for (AclChange change : changes)
|
||||
{
|
||||
@@ -706,7 +818,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
}
|
||||
List<AclChange> changes = new ArrayList<AclChange>();
|
||||
|
||||
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, node.getPath()).getId()), changes, SetMode.DIRECT_ONLY, false);
|
||||
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, node.getPath()).getId()), changes, SetMode.DIRECT_ONLY, false, indirections);
|
||||
|
||||
for (AclChange change : changes)
|
||||
{
|
||||
@@ -746,7 +858,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
}
|
||||
List<AclChange> changes = new ArrayList<AclChange>();
|
||||
|
||||
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, node.getPath()).getId()), changes, SetMode.DIRECT_ONLY, false);
|
||||
setFixedAcls(node, aclDaoComponent.getInheritedAccessControlList(getAclAsSystem(-1, node.getPath()).getId()), changes, SetMode.DIRECT_ONLY, false, indirections);
|
||||
|
||||
for (AclChange change : changes)
|
||||
{
|
||||
@@ -818,44 +930,52 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
|
||||
private DbAccessControlList getStoreAclAsSystem(final String storeName)
|
||||
{
|
||||
return AuthenticationUtil.runAs(new RunAsWork<DbAccessControlList>(){
|
||||
return AuthenticationUtil.runAs(new RunAsWork<DbAccessControlList>()
|
||||
{
|
||||
|
||||
public DbAccessControlList doWork() throws Exception
|
||||
{
|
||||
return fAVMRepository.getStoreAcl(storeName);
|
||||
}}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
|
||||
private void setStoreAclAsSystem(final String storeName, final DbAccessControlList acl)
|
||||
{
|
||||
AuthenticationUtil.runAs(new RunAsWork<Object>(){
|
||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||
{
|
||||
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
fAVMRepository.setStoreAcl(storeName, acl);
|
||||
return null;
|
||||
}}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
|
||||
private DbAccessControlList getAclAsSystem(final int version, final String path)
|
||||
{
|
||||
return AuthenticationUtil.runAs(new RunAsWork<DbAccessControlList>(){
|
||||
return AuthenticationUtil.runAs(new RunAsWork<DbAccessControlList>()
|
||||
{
|
||||
|
||||
public DbAccessControlList doWork() throws Exception
|
||||
{
|
||||
return fAVMRepository.getACL(version, path);
|
||||
}}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
|
||||
private void setAclAsSystem(final String path, final DbAccessControlList acl)
|
||||
{
|
||||
AuthenticationUtil.runAs(new RunAsWork<Object>(){
|
||||
AuthenticationUtil.runAs(new RunAsWork<Object>()
|
||||
{
|
||||
|
||||
public Object doWork() throws Exception
|
||||
{
|
||||
fAVMRepository.setACL(path, acl);
|
||||
return null;
|
||||
}}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
}, AuthenticationUtil.getSystemUserName());
|
||||
}
|
||||
|
||||
public DbAccessControlList getAccessControlList(StoreRef storeRef)
|
||||
@@ -882,5 +1002,4 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@
|
||||
package org.alfresco.repo.domain.hibernate;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@@ -32,6 +33,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
import org.alfresco.repo.domain.DbAccessControlEntry;
|
||||
import org.alfresco.repo.domain.DbAccessControlList;
|
||||
@@ -60,8 +62,10 @@ import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Query;
|
||||
import org.hibernate.Session;
|
||||
import org.jgroups.tests.DeadlockTest.InRpc;
|
||||
import org.springframework.orm.hibernate3.HibernateCallback;
|
||||
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
|
||||
|
||||
@@ -92,12 +96,15 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
|
||||
|
||||
static String QUERY_GET_AVM_NODES_BY_ACL = "permission.FindAvmNodesByACL";
|
||||
|
||||
static String QUERY_GET_AVM_NODES_BY_INDIRECTION = "permission.FindAvmNodesIndirection";
|
||||
|
||||
static String QUERY_GET_LATEST_ACL_BY_ACLID = "permission.FindLatestAclByGuid";
|
||||
|
||||
static String QUERY_GET_LAYERED_DIRECTORIES = "permission.GetLayeredDirectories";
|
||||
|
||||
static String QUERY_GET_LAYERED_FILES = "permission.GetLayeredFiles";
|
||||
|
||||
/** Access to QName entities */
|
||||
private QNameDAO qnameDAO;
|
||||
|
||||
/** a transactionally-safe cache to be injected */
|
||||
private SimpleCache<Long, AccessControlList> aclCache;
|
||||
|
||||
@@ -1312,7 +1319,6 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
||||
private long getCrc(String str)
|
||||
{
|
||||
CRC32 crc = new CRC32();
|
||||
@@ -1538,22 +1544,6 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
|
||||
return avmNodeIds;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Long> getAvmNodesByIndirection(final String indirection)
|
||||
{
|
||||
HibernateCallback callback = new HibernateCallback()
|
||||
{
|
||||
public Object doInHibernate(Session session)
|
||||
{
|
||||
Query query = session.getNamedQuery(QUERY_GET_AVM_NODES_BY_INDIRECTION);
|
||||
query.setParameter("indirection", indirection);
|
||||
return query.list();
|
||||
}
|
||||
};
|
||||
List<Long> avmNodeIds = (List<Long>) getHibernateTemplate().execute(callback);
|
||||
return avmNodeIds;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<AclChange> disableInheritanceImpl(Long id, boolean setInheritedOnAcl, DbAccessControlList acl)
|
||||
{
|
||||
@@ -1748,14 +1738,6 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
|
||||
return ((Boolean) getHibernateTemplate().execute(callback)).booleanValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Just flushes the session
|
||||
*/
|
||||
public void flush()
|
||||
{
|
||||
getSession().flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* NO-OP
|
||||
*/
|
||||
@@ -1832,4 +1814,155 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total number of head nodes in the repository
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Long getAVMHeadNodeCount()
|
||||
{
|
||||
try
|
||||
{
|
||||
Session session = getSession();
|
||||
session.connection().setTransactionIsolation(1);
|
||||
Query query = getSession().getNamedQuery("permission.GetAVMHeadNodeCount");
|
||||
Long answer = (Long) query.uniqueResult();
|
||||
return answer;
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to set TX isolation level");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Long getMaxAclId()
|
||||
{
|
||||
try
|
||||
{
|
||||
Session session = getSession();
|
||||
session.connection().setTransactionIsolation(1);
|
||||
Query query = getSession().getNamedQuery("permission.GetMaxAclId");
|
||||
Long answer = (Long) query.uniqueResult();
|
||||
return answer;
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to set TX isolation level");
|
||||
}
|
||||
}
|
||||
|
||||
public Long getAVMNodeCountWithNewACLS(Long above)
|
||||
{
|
||||
try
|
||||
{
|
||||
Session session = getSession();
|
||||
session.connection().setTransactionIsolation(1);
|
||||
Query query = getSession().getNamedQuery("permission.GetAVMHeadNodeCountWherePermissionsHaveChanged");
|
||||
query.setParameter("above", above);
|
||||
Long answer = (Long) query.uniqueResult();
|
||||
return answer;
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Failed to set TX isolation level");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Indirection> getLayeredDirectories()
|
||||
{
|
||||
HibernateCallback callback = new HibernateCallback()
|
||||
{
|
||||
public Object doInHibernate(Session session)
|
||||
{
|
||||
Query query = session.getNamedQuery(QUERY_GET_LAYERED_DIRECTORIES);
|
||||
return query.list();
|
||||
}
|
||||
};
|
||||
List<Object[]> results = (List<Object[]>) getHibernateTemplate().execute(callback);
|
||||
ArrayList<Indirection> indirections = new ArrayList<Indirection>(results.size());
|
||||
for(Object[] row : results)
|
||||
{
|
||||
Long from = (Long)row[0];
|
||||
String to = (String) row[1];
|
||||
Integer version = (Integer) row[2];
|
||||
indirections.add(new Indirection(from, to, version));
|
||||
}
|
||||
return indirections;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Indirection> getLayeredFiles()
|
||||
{
|
||||
HibernateCallback callback = new HibernateCallback()
|
||||
{
|
||||
public Object doInHibernate(Session session)
|
||||
{
|
||||
Query query = session.getNamedQuery(QUERY_GET_LAYERED_FILES);
|
||||
return query.list();
|
||||
}
|
||||
};
|
||||
List<Object[]> results = (List<Object[]>) getHibernateTemplate().execute(callback);
|
||||
ArrayList<Indirection> indirections = new ArrayList<Indirection>(results.size());
|
||||
for(Object[] row : results)
|
||||
{
|
||||
Long from = (Long)row[0];
|
||||
String to = (String) row[1];
|
||||
Integer version = (Integer) row[2];
|
||||
indirections.add(new Indirection(from, to, version));
|
||||
}
|
||||
return indirections;
|
||||
}
|
||||
|
||||
public List<Indirection> getAvmIndirections()
|
||||
{
|
||||
List<Indirection> dirList = getLayeredDirectories();
|
||||
List<Indirection> fileList = getLayeredFiles();
|
||||
ArrayList<Indirection> answer = new ArrayList<Indirection>(dirList.size() + fileList.size());
|
||||
answer.addAll(dirList);
|
||||
answer.addAll(fileList);
|
||||
return answer;
|
||||
}
|
||||
|
||||
public void flush()
|
||||
{
|
||||
getSession().flush();
|
||||
}
|
||||
|
||||
public static class Indirection
|
||||
{
|
||||
Long from;
|
||||
|
||||
String to;
|
||||
|
||||
Integer toVersion;
|
||||
|
||||
Indirection(Long from, String to, Integer toVersion)
|
||||
{
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.toVersion = toVersion;
|
||||
}
|
||||
|
||||
public Long getFrom()
|
||||
{
|
||||
return from;
|
||||
}
|
||||
|
||||
public String getTo()
|
||||
{
|
||||
return to;
|
||||
}
|
||||
|
||||
public Integer getToVersion()
|
||||
{
|
||||
return toVersion;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,22 @@
|
||||
package org.alfresco.repo.domain.hibernate;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.event.LoadEvent;
|
||||
import org.hibernate.event.LoadEventListener;
|
||||
import org.hibernate.proxy.HibernateProxy;
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
|
||||
public class HibernateLoadListener implements LoadEventListener
|
||||
{
|
||||
|
||||
public void onLoad(LoadEvent event, LoadType loadType) throws HibernateException
|
||||
{
|
||||
Object obj = event.getResult();
|
||||
if (obj instanceof HibernateProxy) {
|
||||
Enhancer.registerCallbacks(obj.getClass(),null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.domain.hibernate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
|
||||
|
||||
/**
|
||||
* Utililty support against hibernate sessions. Supported by a super event listener which is registered on the even
|
||||
* listener of the hibernate session.
|
||||
*
|
||||
* @author andyh
|
||||
*/
|
||||
public class HibernateSessionHelper extends HibernateDaoSupport implements HibernateSessionSupport
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -2532286150392812816L;
|
||||
private static final String HIBERNATE_SESSION_EVENT_LISTENER = "HibernateSessionEventListener";
|
||||
|
||||
public void mark()
|
||||
{
|
||||
HibernateSessionHelperResourceProvider resource = getResource();
|
||||
resource.mark(getSession());
|
||||
}
|
||||
|
||||
public void mark(String label)
|
||||
{
|
||||
HibernateSessionHelperResourceProvider resource = getResource();
|
||||
resource.mark(getSession(), label);
|
||||
}
|
||||
|
||||
public void reset()
|
||||
{
|
||||
HibernateSessionHelperResourceProvider resource = getResource();
|
||||
resource.reset(getSession());
|
||||
}
|
||||
|
||||
public void reset(String label)
|
||||
{
|
||||
HibernateSessionHelperResourceProvider resource = getResource();
|
||||
resource.reset(getSession(), label);
|
||||
}
|
||||
|
||||
public void removeMark()
|
||||
{
|
||||
HibernateSessionHelperResourceProvider resource = getResource();
|
||||
resource.removeMark(getSession());
|
||||
}
|
||||
|
||||
public void removeMark(String label)
|
||||
{
|
||||
HibernateSessionHelperResourceProvider resource = getResource();
|
||||
resource.removeMark(getSession(), label);
|
||||
}
|
||||
|
||||
public void resetAndRemoveMark()
|
||||
{
|
||||
HibernateSessionHelperResourceProvider resource = getResource();
|
||||
resource.resetAndRemoveMark(getSession());
|
||||
}
|
||||
|
||||
public void resetAndRemoveMark(String label)
|
||||
{
|
||||
HibernateSessionHelperResourceProvider resource = getResource();
|
||||
resource.resetAndRemoveMark(getSession(), label);
|
||||
}
|
||||
|
||||
public List<String> getMarks()
|
||||
{
|
||||
HibernateSessionHelperResourceProvider resource = getResource();
|
||||
return resource.getMarks(getSession());
|
||||
}
|
||||
|
||||
public String getCurrentMark()
|
||||
{
|
||||
HibernateSessionHelperResourceProvider resource = getResource();
|
||||
return resource.getCurrentMark();
|
||||
}
|
||||
|
||||
public static HibernateSessionHelperResourceProvider getResource()
|
||||
{
|
||||
HibernateSessionHelperResourceProvider listener = (HibernateSessionHelperResourceProvider) AlfrescoTransactionSupport.getResource(HIBERNATE_SESSION_EVENT_LISTENER);
|
||||
if (listener == null)
|
||||
{
|
||||
listener = new HibernateSessionHelperResource();
|
||||
AlfrescoTransactionSupport.bindResource(HIBERNATE_SESSION_EVENT_LISTENER, listener);
|
||||
}
|
||||
return listener;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.domain.hibernate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.util.GUID;
|
||||
import org.hibernate.CacheMode;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.engine.EntityKey;
|
||||
|
||||
import com.sun.corba.se.spi.legacy.connection.GetEndPointInfoAgainException;
|
||||
|
||||
/**
|
||||
* Support to (optionally) listen to hibernate events generated by a hibernate session. The tracking is bound to a
|
||||
* transaction resource
|
||||
*
|
||||
* @author andyh
|
||||
*/
|
||||
public class HibernateSessionHelperResource implements HibernateSessionHelperResourceProvider
|
||||
{
|
||||
LinkedHashMap<String, Set<EntityKey>> marks = new LinkedHashMap<String, Set<EntityKey>>();
|
||||
|
||||
String currentMark = null;
|
||||
|
||||
HibernateSessionHelperResource()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public String getCurrentMark()
|
||||
{
|
||||
return currentMark;
|
||||
}
|
||||
|
||||
public List<String> getMarks(Session session)
|
||||
{
|
||||
ArrayList<String> answer = new ArrayList<String>(marks.size());
|
||||
for (String key : marks.keySet())
|
||||
{
|
||||
answer.add(key);
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
public void mark(Session session)
|
||||
{
|
||||
Thread thread = Thread.currentThread();
|
||||
|
||||
String guid = GUID.generate();
|
||||
mark(session, guid);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void mark(Session session, String label)
|
||||
{
|
||||
session.flush();
|
||||
if (label == null)
|
||||
{
|
||||
throw new HibernateSessionHelperResourceException("Null key is not supported");
|
||||
|
||||
}
|
||||
if (marks.containsKey(label))
|
||||
{
|
||||
throw new HibernateSessionHelperResourceException("Key already exists - " + label);
|
||||
}
|
||||
|
||||
if (marks.size() == 0)
|
||||
{
|
||||
SessionSizeResourceManager.setDisableInTransaction();
|
||||
}
|
||||
|
||||
HashSet<EntityKey> mark = new HashSet<EntityKey>((Set<EntityKey>) session.getStatistics().getEntityKeys());
|
||||
marks.put(label, mark);
|
||||
currentMark = label;
|
||||
|
||||
//System.out.println("Mark "+marks.size()+" "+currentMark);
|
||||
}
|
||||
|
||||
public void removeMark(Session session)
|
||||
{
|
||||
if (currentMark != null)
|
||||
{
|
||||
removeMark(session, currentMark);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new HibernateSessionHelperResourceException("No current mark");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void removeMark(Session session, String label)
|
||||
{
|
||||
if (label == null)
|
||||
{
|
||||
throw new HibernateSessionHelperResourceException("Null key is not supported");
|
||||
|
||||
}
|
||||
if (!marks.containsKey(label))
|
||||
{
|
||||
throw new HibernateSessionHelperResourceException("Key does not exist - " + label);
|
||||
}
|
||||
|
||||
if (marks.size() > 0)
|
||||
{
|
||||
marks.remove(label);
|
||||
|
||||
if (label.equals(currentMark))
|
||||
{
|
||||
currentMark = getLastMarkOrNull();
|
||||
}
|
||||
}
|
||||
|
||||
if (marks.size() == 0)
|
||||
{
|
||||
SessionSizeResourceManager.setEnableInTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
public void reset(Session session)
|
||||
{
|
||||
if (currentMark != null)
|
||||
{
|
||||
doResetAndRemove(session, currentMark, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new HibernateSessionHelperResourceException("No current mark");
|
||||
}
|
||||
}
|
||||
|
||||
public void reset(Session session, String label)
|
||||
{
|
||||
doResetAndRemove(session, label, false);
|
||||
}
|
||||
|
||||
public void resetAndRemoveMark(Session session)
|
||||
{
|
||||
if (currentMark != null)
|
||||
{
|
||||
doResetAndRemove(session, currentMark, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new HibernateSessionHelperResourceException("No current mark");
|
||||
}
|
||||
}
|
||||
|
||||
public void resetAndRemoveMark(Session session, String label)
|
||||
{
|
||||
doResetAndRemove(session, label, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void doResetAndRemove(Session session, String label, boolean remove)
|
||||
{
|
||||
if (label == null)
|
||||
{
|
||||
throw new HibernateSessionHelperResourceException("Null key is not supported");
|
||||
|
||||
}
|
||||
if (!marks.containsKey(label))
|
||||
{
|
||||
throw new HibernateSessionHelperResourceException("Key does not exist - " + label);
|
||||
}
|
||||
if (marks.size() > 0)
|
||||
{
|
||||
session.flush();
|
||||
|
||||
Set<EntityKey> check = marks.get(label);
|
||||
Set<EntityKey> current = new HashSet<EntityKey>((Set<EntityKey>) session.getStatistics().getEntityKeys());
|
||||
|
||||
Set<Object> toEvict = new HashSet<Object>(Math.max((int) (current.size() / .75f) + 1, 16));
|
||||
|
||||
for (EntityKey key : current)
|
||||
{
|
||||
if (!check.contains(key))
|
||||
{
|
||||
if (!key.getEntityName().startsWith("org.alfresco"))
|
||||
{
|
||||
System.out.println("Oops: " + key.getEntityName());
|
||||
}
|
||||
|
||||
if(key.getEntityName().equals(QNameEntityImpl.class.getName()))
|
||||
{
|
||||
//System.out.println("Skipping: " + key.getEntityName());
|
||||
continue;
|
||||
}
|
||||
Object val = session.get(key.getEntityName(), key.getIdentifier());
|
||||
if (val != null)
|
||||
{
|
||||
toEvict.add(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Object evitee : toEvict)
|
||||
{
|
||||
session.evict(evitee);
|
||||
}
|
||||
|
||||
String last;
|
||||
while ((last = getLastMarkOrNull()) != null)
|
||||
{
|
||||
if (!label.equals(last))
|
||||
{
|
||||
marks.remove(last);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (remove)
|
||||
{
|
||||
marks.remove(last);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
currentMark = getLastMarkOrNull();
|
||||
|
||||
if (marks.size() == 0)
|
||||
{
|
||||
SessionSizeResourceManager.setEnableInTransaction();
|
||||
}
|
||||
|
||||
//System.out.println("Removed "+marks.size()+" "+label);
|
||||
}
|
||||
}
|
||||
|
||||
private String getLastMarkOrNull()
|
||||
{
|
||||
String mark = null;
|
||||
for (String key : marks.keySet())
|
||||
{
|
||||
mark = key;
|
||||
}
|
||||
return mark;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
package org.alfresco.repo.domain.hibernate;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
|
||||
public class HibernateSessionHelperResourceException extends AlfrescoRuntimeException
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 2935681199033295625L;
|
||||
|
||||
public HibernateSessionHelperResourceException(String msgId, Object[] msgParams, Throwable cause)
|
||||
{
|
||||
super(msgId, msgParams, cause);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public HibernateSessionHelperResourceException(String msgId, Object[] msgParams)
|
||||
{
|
||||
super(msgId, msgParams);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public HibernateSessionHelperResourceException(String msgId, Throwable cause)
|
||||
{
|
||||
super(msgId, cause);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
public HibernateSessionHelperResourceException(String msgId)
|
||||
{
|
||||
super(msgId);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.domain.hibernate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Session;
|
||||
|
||||
public interface HibernateSessionHelperResourceProvider
|
||||
{
|
||||
public void mark(Session session);
|
||||
|
||||
public void mark(Session session, String label);
|
||||
|
||||
public void reset(Session session);
|
||||
|
||||
public void reset(Session session, String label);
|
||||
|
||||
public void removeMark(Session session);
|
||||
|
||||
public void removeMark(Session session, String label);
|
||||
|
||||
public void resetAndRemoveMark(Session session);
|
||||
|
||||
public void resetAndRemoveMark(Session session, String label);
|
||||
|
||||
public List<String> getMarks(Session session);
|
||||
|
||||
public String getCurrentMark();
|
||||
}
|
@@ -0,0 +1,570 @@
|
||||
package org.alfresco.repo.domain.hibernate;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.repo.domain.NodeKey;
|
||||
import org.alfresco.repo.domain.NodeStatus;
|
||||
import org.alfresco.repo.domain.Server;
|
||||
import org.alfresco.repo.domain.StoreKey;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.util.BaseSpringTest;
|
||||
import org.hibernate.engine.EntityKey;
|
||||
import org.springframework.orm.toplink.SessionReadCallback;
|
||||
|
||||
public class HibernateSessionHelperTest extends BaseSpringTest
|
||||
{
|
||||
|
||||
|
||||
protected void onTearDownInTransaction()
|
||||
{
|
||||
// force a flush to ensure that the database updates succeed
|
||||
getSession().flush();
|
||||
getSession().clear();
|
||||
}
|
||||
|
||||
public void testSimpleMark()
|
||||
{
|
||||
assertEquals(0, getSession().getStatistics().getEntityCount());
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
|
||||
StoreImpl store = new StoreImpl();
|
||||
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
|
||||
"TestWorkspace@" + getName() + " - " + System.currentTimeMillis());
|
||||
store.setKey(storeKey);
|
||||
// persist so that it is present in the hibernate cache
|
||||
getSession().save(store);
|
||||
|
||||
assertEquals(1, getSession().getStatistics().getEntityCount());
|
||||
|
||||
Server server = (Server) getSession().get(ServerImpl.class, new Long(1));
|
||||
if (server == null)
|
||||
{
|
||||
server = new ServerImpl();
|
||||
server.setIpAddress("" + "i_" + System.currentTimeMillis());
|
||||
getSession().save(server);
|
||||
}
|
||||
|
||||
assertEquals(2, getSession().getStatistics().getEntityCount());
|
||||
|
||||
HibernateSessionHelper helper = (HibernateSessionHelper)getApplicationContext().getBean("hibernateSessionHelper");
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
helper.mark();
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(1, helper.getMarks().size());
|
||||
|
||||
TransactionImpl transaction = new TransactionImpl();
|
||||
transaction.setServer(server);
|
||||
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
Serializable txID = getSession().save(transaction);
|
||||
|
||||
assertEquals(3, getSession().getStatistics().getEntityCount());
|
||||
|
||||
helper.reset();
|
||||
|
||||
assertEquals(2, getSession().getStatistics().getEntityCount());
|
||||
|
||||
getSession().get(TransactionImpl.class, txID);
|
||||
|
||||
assertEquals(3, getSession().getStatistics().getEntityCount());
|
||||
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
helper.resetAndRemoveMark();
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
|
||||
assertEquals(0, helper.getMarks().size());
|
||||
assertEquals(2, getSession().getStatistics().getEntityCount());
|
||||
|
||||
}
|
||||
|
||||
public void testNestedMarks()
|
||||
{
|
||||
assertEquals(0, getSession().getStatistics().getEntityCount());
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
|
||||
StoreImpl store = new StoreImpl();
|
||||
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
|
||||
"TestWorkspace@" + getName() + " - " + System.currentTimeMillis());
|
||||
store.setKey(storeKey);
|
||||
// persist so that it is present in the hibernate cache
|
||||
getSession().save(store);
|
||||
|
||||
assertEquals(1, getSession().getStatistics().getEntityCount());
|
||||
|
||||
Server server = (Server) getSession().get(ServerImpl.class, new Long(1));
|
||||
if (server == null)
|
||||
{
|
||||
server = new ServerImpl();
|
||||
server.setIpAddress("" + "i_" + System.currentTimeMillis());
|
||||
getSession().save(server);
|
||||
}
|
||||
|
||||
TransactionImpl transaction = new TransactionImpl();
|
||||
transaction.setServer(server);
|
||||
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
Serializable txID = getSession().save(transaction);
|
||||
|
||||
assertEquals(3, getSession().getStatistics().getEntityCount());
|
||||
|
||||
HibernateSessionHelper helper = (HibernateSessionHelper)getApplicationContext().getBean("hibernateSessionHelper");
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
helper.mark();
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(1, helper.getMarks().size());
|
||||
|
||||
NodeKey key1 = new NodeKey(store.getKey(), "1");
|
||||
createNodeStatus(transaction, key1);
|
||||
|
||||
assertEquals(4, getSession().getStatistics().getEntityCount());
|
||||
helper.mark();
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(2, helper.getMarks().size());
|
||||
|
||||
NodeKey key2 = new NodeKey(store.getKey(), "2");
|
||||
createNodeStatus(transaction, key2);
|
||||
|
||||
assertEquals(5, getSession().getStatistics().getEntityCount());
|
||||
helper.mark();
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(3, helper.getMarks().size());
|
||||
|
||||
NodeKey key3 = new NodeKey(store.getKey(), "3");
|
||||
createNodeStatus(transaction, key3);
|
||||
|
||||
assertEquals(6, getSession().getStatistics().getEntityCount());
|
||||
helper.mark();
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(4, helper.getMarks().size());
|
||||
|
||||
NodeKey key4 = new NodeKey(store.getKey(), "4");
|
||||
createNodeStatus(transaction, key4);
|
||||
|
||||
assertEquals(7, getSession().getStatistics().getEntityCount());
|
||||
helper.mark();
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(5, helper.getMarks().size());
|
||||
|
||||
NodeKey key5 = new NodeKey(store.getKey(), "5");
|
||||
createNodeStatus(transaction, key5);
|
||||
|
||||
assertEquals(8, getSession().getStatistics().getEntityCount());
|
||||
|
||||
helper.reset();
|
||||
assertEquals(7, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(5, helper.getMarks().size());
|
||||
assertFalse(sessionContainsNodeStatus(key5));
|
||||
assertTrue(sessionContainsNodeStatus(key4));
|
||||
assertTrue(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
getSession().get(NodeStatusImpl.class, key5);
|
||||
assertEquals(8, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(5, helper.getMarks().size());
|
||||
assertTrue(sessionContainsNodeStatus(key5));
|
||||
assertTrue(sessionContainsNodeStatus(key4));
|
||||
assertTrue(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
|
||||
helper.reset();
|
||||
assertEquals(7, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(5, helper.getMarks().size());
|
||||
assertFalse(sessionContainsNodeStatus(key5));
|
||||
assertTrue(sessionContainsNodeStatus(key4));
|
||||
assertTrue(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
getSession().get(NodeStatusImpl.class, key5);
|
||||
assertEquals(8, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(5, helper.getMarks().size());
|
||||
assertTrue(sessionContainsNodeStatus(key5));
|
||||
assertTrue(sessionContainsNodeStatus(key4));
|
||||
assertTrue(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
|
||||
helper.resetAndRemoveMark();
|
||||
|
||||
assertEquals(7, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(4, helper.getMarks().size());
|
||||
assertFalse(sessionContainsNodeStatus(key5));
|
||||
assertTrue(sessionContainsNodeStatus(key4));
|
||||
assertTrue(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
|
||||
helper.resetAndRemoveMark();
|
||||
|
||||
assertEquals(6, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(3, helper.getMarks().size());
|
||||
assertFalse(sessionContainsNodeStatus(key5));
|
||||
assertFalse(sessionContainsNodeStatus(key4));
|
||||
assertTrue(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
|
||||
|
||||
helper.resetAndRemoveMark();
|
||||
|
||||
assertEquals(5, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(2, helper.getMarks().size());
|
||||
assertFalse(sessionContainsNodeStatus(key5));
|
||||
assertFalse(sessionContainsNodeStatus(key4));
|
||||
assertFalse(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
|
||||
helper.resetAndRemoveMark();
|
||||
|
||||
assertEquals(4, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(1, helper.getMarks().size());
|
||||
assertFalse(sessionContainsNodeStatus(key5));
|
||||
assertFalse(sessionContainsNodeStatus(key4));
|
||||
assertFalse(sessionContainsNodeStatus(key3));
|
||||
assertFalse(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
|
||||
helper.resetAndRemoveMark();
|
||||
|
||||
assertEquals(3, getSession().getStatistics().getEntityCount());
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(0, helper.getMarks().size());
|
||||
assertFalse(sessionContainsNodeStatus(key5));
|
||||
assertFalse(sessionContainsNodeStatus(key4));
|
||||
assertFalse(sessionContainsNodeStatus(key3));
|
||||
assertFalse(sessionContainsNodeStatus(key2));
|
||||
assertFalse(sessionContainsNodeStatus(key1));
|
||||
|
||||
try
|
||||
{
|
||||
helper.reset();
|
||||
fail("can not reset");
|
||||
}
|
||||
catch(HibernateSessionHelperResourceException hshre)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void testNamedMarks()
|
||||
{
|
||||
assertEquals(0, getSession().getStatistics().getEntityCount());
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
|
||||
StoreImpl store = new StoreImpl();
|
||||
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
|
||||
"TestWorkspace@" + getName() + " - " + System.currentTimeMillis());
|
||||
store.setKey(storeKey);
|
||||
// persist so that it is present in the hibernate cache
|
||||
getSession().save(store);
|
||||
|
||||
assertEquals(1, getSession().getStatistics().getEntityCount());
|
||||
|
||||
Server server = (Server) getSession().get(ServerImpl.class, new Long(1));
|
||||
if (server == null)
|
||||
{
|
||||
server = new ServerImpl();
|
||||
server.setIpAddress("" + "i_" + System.currentTimeMillis());
|
||||
getSession().save(server);
|
||||
}
|
||||
|
||||
assertEquals(2, getSession().getStatistics().getEntityCount());
|
||||
|
||||
HibernateSessionHelper helper = (HibernateSessionHelper)getApplicationContext().getBean("hibernateSessionHelper");
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
helper.mark("One");
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(1, helper.getMarks().size());
|
||||
|
||||
TransactionImpl transaction = new TransactionImpl();
|
||||
transaction.setServer(server);
|
||||
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
Serializable txID = getSession().save(transaction);
|
||||
|
||||
assertEquals(3, getSession().getStatistics().getEntityCount());
|
||||
|
||||
helper.reset("One");
|
||||
|
||||
assertEquals(2, getSession().getStatistics().getEntityCount());
|
||||
|
||||
getSession().get(TransactionImpl.class, txID);
|
||||
|
||||
assertEquals(3, getSession().getStatistics().getEntityCount());
|
||||
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
helper.resetAndRemoveMark("One");
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
|
||||
assertEquals(0, helper.getMarks().size());
|
||||
assertEquals(2, getSession().getStatistics().getEntityCount());
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testNestedNamedMarks()
|
||||
{
|
||||
assertEquals(0, getSession().getStatistics().getEntityCount());
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
|
||||
StoreImpl store = new StoreImpl();
|
||||
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
|
||||
"TestWorkspace@" + getName() + " - " + System.currentTimeMillis());
|
||||
store.setKey(storeKey);
|
||||
// persist so that it is present in the hibernate cache
|
||||
getSession().save(store);
|
||||
|
||||
assertEquals(1, getSession().getStatistics().getEntityCount());
|
||||
|
||||
Server server = (Server) getSession().get(ServerImpl.class, new Long(1));
|
||||
if (server == null)
|
||||
{
|
||||
server = new ServerImpl();
|
||||
server.setIpAddress("" + "i_" + System.currentTimeMillis());
|
||||
getSession().save(server);
|
||||
}
|
||||
|
||||
TransactionImpl transaction = new TransactionImpl();
|
||||
transaction.setServer(server);
|
||||
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
Serializable txID = getSession().save(transaction);
|
||||
|
||||
assertEquals(3, getSession().getStatistics().getEntityCount());
|
||||
|
||||
HibernateSessionHelper helper = (HibernateSessionHelper)getApplicationContext().getBean("hibernateSessionHelper");
|
||||
assertNull(helper.getCurrentMark());
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
helper.mark("One");
|
||||
assertEquals("One", helper.getCurrentMark());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(1, helper.getMarks().size());
|
||||
|
||||
NodeKey key1 = new NodeKey(store.getKey(), "1");
|
||||
createNodeStatus(transaction, key1);
|
||||
|
||||
assertEquals(4, getSession().getStatistics().getEntityCount());
|
||||
helper.mark("Two");
|
||||
assertEquals("Two", helper.getCurrentMark());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(2, helper.getMarks().size());
|
||||
|
||||
NodeKey key2 = new NodeKey(store.getKey(), "2");
|
||||
createNodeStatus(transaction, key2);
|
||||
|
||||
assertEquals(5, getSession().getStatistics().getEntityCount());
|
||||
helper.mark("Three");
|
||||
assertEquals("Three", helper.getCurrentMark());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(3, helper.getMarks().size());
|
||||
|
||||
NodeKey key3 = new NodeKey(store.getKey(), "3");
|
||||
createNodeStatus(transaction, key3);
|
||||
|
||||
assertEquals(6, getSession().getStatistics().getEntityCount());
|
||||
helper.mark("Four");
|
||||
assertEquals("Four", helper.getCurrentMark());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(4, helper.getMarks().size());
|
||||
|
||||
NodeKey key4 = new NodeKey(store.getKey(), "4");
|
||||
createNodeStatus(transaction, key4);
|
||||
|
||||
assertEquals(7, getSession().getStatistics().getEntityCount());
|
||||
helper.mark("Five");
|
||||
assertEquals("Five", helper.getCurrentMark());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(5, helper.getMarks().size());
|
||||
|
||||
NodeKey key5 = new NodeKey(store.getKey(), "5");
|
||||
createNodeStatus(transaction, key5);
|
||||
|
||||
assertEquals(8, getSession().getStatistics().getEntityCount());
|
||||
|
||||
helper.reset("Five");
|
||||
assertEquals(7, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(5, helper.getMarks().size());
|
||||
assertFalse(sessionContainsNodeStatus(key5));
|
||||
assertTrue(sessionContainsNodeStatus(key4));
|
||||
assertTrue(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
getSession().get(NodeStatusImpl.class, key5);
|
||||
assertEquals(8, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(5, helper.getMarks().size());
|
||||
assertTrue(sessionContainsNodeStatus(key5));
|
||||
assertTrue(sessionContainsNodeStatus(key4));
|
||||
assertTrue(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
|
||||
helper.reset("Five");
|
||||
assertEquals(7, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(5, helper.getMarks().size());
|
||||
assertFalse(sessionContainsNodeStatus(key5));
|
||||
assertTrue(sessionContainsNodeStatus(key4));
|
||||
assertTrue(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
getSession().get(NodeStatusImpl.class, key5);
|
||||
assertEquals(8, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(5, helper.getMarks().size());
|
||||
assertTrue(sessionContainsNodeStatus(key5));
|
||||
assertTrue(sessionContainsNodeStatus(key4));
|
||||
assertTrue(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
|
||||
assertEquals("Five", helper.getCurrentMark());
|
||||
helper.resetAndRemoveMark("Five");
|
||||
assertEquals("Four", helper.getCurrentMark());
|
||||
|
||||
assertEquals(7, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(4, helper.getMarks().size());
|
||||
assertFalse(sessionContainsNodeStatus(key5));
|
||||
assertTrue(sessionContainsNodeStatus(key4));
|
||||
assertTrue(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
|
||||
helper.resetAndRemoveMark("Three");
|
||||
assertEquals("Two", helper.getCurrentMark());
|
||||
|
||||
assertEquals(5, getSession().getStatistics().getEntityCount());
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(2, helper.getMarks().size());
|
||||
assertFalse(sessionContainsNodeStatus(key5));
|
||||
assertFalse(sessionContainsNodeStatus(key4));
|
||||
assertFalse(sessionContainsNodeStatus(key3));
|
||||
assertTrue(sessionContainsNodeStatus(key2));
|
||||
assertTrue(sessionContainsNodeStatus(key1));
|
||||
|
||||
helper.resetAndRemoveMark("One");
|
||||
assertNull(helper.getCurrentMark());
|
||||
|
||||
assertEquals(3, getSession().getStatistics().getEntityCount());
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(0, helper.getMarks().size());
|
||||
assertFalse(sessionContainsNodeStatus(key5));
|
||||
assertFalse(sessionContainsNodeStatus(key4));
|
||||
assertFalse(sessionContainsNodeStatus(key3));
|
||||
assertFalse(sessionContainsNodeStatus(key2));
|
||||
assertFalse(sessionContainsNodeStatus(key1));
|
||||
|
||||
try
|
||||
{
|
||||
helper.reset("One");
|
||||
fail("can not reset");
|
||||
}
|
||||
catch(HibernateSessionHelperResourceException hshre)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void voidTestRemove()
|
||||
{
|
||||
assertEquals(0, getSession().getStatistics().getEntityCount());
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
|
||||
StoreImpl store = new StoreImpl();
|
||||
StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE,
|
||||
"TestWorkspace@" + getName() + " - " + System.currentTimeMillis());
|
||||
store.setKey(storeKey);
|
||||
// persist so that it is present in the hibernate cache
|
||||
getSession().save(store);
|
||||
|
||||
assertEquals(1, getSession().getStatistics().getEntityCount());
|
||||
|
||||
Server server = (Server) getSession().get(ServerImpl.class, new Long(1));
|
||||
if (server == null)
|
||||
{
|
||||
server = new ServerImpl();
|
||||
server.setIpAddress("" + "i_" + System.currentTimeMillis());
|
||||
getSession().save(server);
|
||||
}
|
||||
|
||||
TransactionImpl transaction = new TransactionImpl();
|
||||
transaction.setServer(server);
|
||||
transaction.setChangeTxnId(AlfrescoTransactionSupport.getTransactionId());
|
||||
Serializable txID = getSession().save(transaction);
|
||||
|
||||
assertEquals(3, getSession().getStatistics().getEntityCount());
|
||||
|
||||
HibernateSessionHelper helper = (HibernateSessionHelper)getApplicationContext().getBean("hibernateSessionHelper");
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
helper.mark("One");
|
||||
helper.mark("Two");
|
||||
helper.mark("Three");
|
||||
helper.mark("Four");
|
||||
helper.mark("Five");
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(5, helper.getMarks().size());
|
||||
assertEquals("Five", helper.getCurrentMark());
|
||||
|
||||
helper.removeMark();
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(4, helper.getMarks().size());
|
||||
assertEquals("Four", helper.getCurrentMark());
|
||||
|
||||
helper.removeMark("One");
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(3, helper.getMarks().size());
|
||||
assertEquals("Four", helper.getCurrentMark());
|
||||
|
||||
helper.removeMark();
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(2, helper.getMarks().size());
|
||||
assertEquals("Three", helper.getCurrentMark());
|
||||
|
||||
helper.removeMark("Two");
|
||||
assertTrue(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(1, helper.getMarks().size());
|
||||
assertEquals("Three", helper.getCurrentMark());
|
||||
|
||||
helper.removeMark("Three");
|
||||
assertFalse(SessionSizeResourceManager.isDisableInTransaction());
|
||||
assertEquals(0, helper.getMarks().size());
|
||||
assertNull(helper.getCurrentMark());
|
||||
}
|
||||
|
||||
private NodeStatus createNodeStatus(TransactionImpl transaction, NodeKey key)
|
||||
{
|
||||
NodeStatus nodeStatus = new NodeStatusImpl();
|
||||
nodeStatus.setKey(key);
|
||||
nodeStatus.setTransaction(transaction);
|
||||
getSession().save(nodeStatus);
|
||||
return nodeStatus;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean sessionContainsNodeStatus(NodeKey nodeKey)
|
||||
{
|
||||
Set<EntityKey> keys = (Set<EntityKey>)getSession().getStatistics().getEntityKeys();
|
||||
for(EntityKey key : keys)
|
||||
{
|
||||
if(key.getEntityName().equals(NodeStatusImpl.class.getName()))
|
||||
{
|
||||
if(key.getIdentifier().equals(nodeKey))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.domain.hibernate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface HibernateSessionSupport
|
||||
{
|
||||
public void mark();
|
||||
|
||||
public void mark(String label);
|
||||
|
||||
public void reset();
|
||||
|
||||
public void reset(String label);
|
||||
|
||||
public void removeMark();
|
||||
|
||||
public void removeMark(String label);
|
||||
|
||||
public void resetAndRemoveMark();
|
||||
|
||||
public void resetAndRemoveMark(String label);
|
||||
|
||||
public List<String> getMarks();
|
||||
|
||||
public String getCurrentMark();
|
||||
}
|
@@ -378,6 +378,53 @@
|
||||
where acl.aclId = :aclId and latest = true
|
||||
</query>
|
||||
|
||||
<!-- Note this query will not count correctly and is only an estimate -->
|
||||
<!-- It assumes there are no pending changes in layers -->
|
||||
<query name="permission.GetAVMHeadNodeCount">
|
||||
<![CDATA[
|
||||
select count(*)
|
||||
from HistoryLinkImpl hl
|
||||
right outer join hl.ancestor an
|
||||
where hl.ancestor is null
|
||||
]]>
|
||||
</query>
|
||||
|
||||
<query name="permission.GetAVMHeadNodeCountWherePermissionsHaveChanged">
|
||||
<![CDATA[
|
||||
select count(*)
|
||||
from org.alfresco.repo.avm.AVMNodeImpl node
|
||||
where node.acl.id > :above
|
||||
]]>
|
||||
</query>
|
||||
|
||||
|
||||
<query name="permission.GetMaxAclId">
|
||||
<![CDATA[
|
||||
select
|
||||
max(acl.id)
|
||||
from
|
||||
org.alfresco.repo.domain.hibernate.DbAccessControlListImpl as acl
|
||||
]]>
|
||||
</query>
|
||||
|
||||
<query name="permission.GetLayeredDirectories">
|
||||
<![CDATA[
|
||||
select
|
||||
node.id, node.indirection, node.indirectionVersion
|
||||
from org.alfresco.repo.avm.LayeredDirectoryNodeImpl node
|
||||
where node.primaryIndirection = true
|
||||
]]>
|
||||
</query>
|
||||
|
||||
<query name="permission.GetLayeredFiles">
|
||||
<![CDATA[
|
||||
select
|
||||
node.id, node.indirection, node.indirectionVersion
|
||||
from org.alfresco.repo.avm.LayeredFileNodeImpl node
|
||||
]]>
|
||||
</query>
|
||||
|
||||
|
||||
<!--
|
||||
|
||||
<query name="permission.GetAccessControlEntriesForAuthority">
|
||||
|
@@ -72,6 +72,15 @@ public class SessionSizeResourceManager extends HibernateDaoSupport implements M
|
||||
AlfrescoTransactionSupport.bindResource(KEY_DISABLE_IN_TRANSACTION, Boolean.TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable resource management for the duration of the current transaction. This is temporary
|
||||
* and relies on an active transaction.
|
||||
*/
|
||||
public static void setEnableInTransaction()
|
||||
{
|
||||
AlfrescoTransactionSupport.bindResource(KEY_DISABLE_IN_TRANSACTION, Boolean.FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns true if the resource management must be ignored in the current transaction.
|
||||
* If <code>false</code>, the global setting will take effect.
|
||||
|
@@ -71,6 +71,7 @@ import org.hibernate.dialect.MySQLDialect;
|
||||
import org.hibernate.dialect.MySQLInnoDBDialect;
|
||||
import org.hibernate.dialect.Oracle9Dialect;
|
||||
import org.hibernate.dialect.PostgreSQLDialect;
|
||||
import org.hibernate.engine.ActionQueue;
|
||||
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
|
||||
import org.hibernate.tool.hbm2ddl.SchemaExport;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -113,6 +114,10 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
||||
public static final int DEFAULT_MAX_STRING_LENGTH = 1024;
|
||||
private static volatile int maxStringLength = DEFAULT_MAX_STRING_LENGTH;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see PropertyValue#DEFAULT_MAX_STRING_LENGTH
|
||||
*/
|
||||
@@ -257,6 +262,25 @@ public class SchemaBootstrap extends AbstractLifecycleBean
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the limit for the hibernate executions queue
|
||||
* @return
|
||||
*/
|
||||
public int getHibernateMaxExecutions()
|
||||
{
|
||||
return ActionQueue.getMAX_EXECUTIONS_SIZE();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the limit for the hibernate executions queue
|
||||
* Less than zero always uses event amalgamation
|
||||
* @param hibernateMaxExecutions
|
||||
*/
|
||||
public void setHibernateMaxExecutions(int hibernateMaxExecutions)
|
||||
{
|
||||
ActionQueue.setMAX_EXECUTIONS_SIZE(hibernateMaxExecutions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to generate a schema creation SQL script from the given Hibernate
|
||||
* configuration.
|
||||
|
@@ -27,6 +27,7 @@ package org.alfresco.repo.security.permissions.impl;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.domain.DbAccessControlList;
|
||||
import org.alfresco.repo.domain.hibernate.AclDaoComponentImpl.Indirection;
|
||||
import org.alfresco.repo.security.permissions.ACLCopyMode;
|
||||
import org.alfresco.repo.security.permissions.AccessControlEntry;
|
||||
import org.alfresco.repo.security.permissions.AccessControlList;
|
||||
@@ -174,7 +175,7 @@ public interface AclDaoComponent extends TransactionalDao
|
||||
|
||||
public List<Long> getAvmNodesByACL(Long id);
|
||||
|
||||
public List<Long> getAvmNodesByIndirection(final String indirection);
|
||||
public List<Indirection> getAvmIndirections();
|
||||
|
||||
/**
|
||||
* hibernate lifecycle support
|
||||
|
Reference in New Issue
Block a user