diff --git a/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.MySQLInnoDBDialect/upgrade-2-move-qnames.sql b/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.MySQLInnoDBDialect/upgrade-2-move-qnames.sql
index 26942d6bbd..358e93570c 100644
--- a/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.MySQLInnoDBDialect/upgrade-2-move-qnames.sql
+++ b/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.MySQLInnoDBDialect/upgrade-2-move-qnames.sql
@@ -354,7 +354,7 @@ ALTER TABLE alf_qname DROP INDEX t_fk_alf_qn_ns;
ALTER TABLE alf_qname DROP FOREIGN KEY t_fk_alf_qn_ns;
-- Remove the FILLER- values from the namespace uri
-UPDATE alf_namespace SET uri = 'empty' WHERE uri = 'FILLER-';
+UPDATE alf_namespace SET uri = '.empty' WHERE uri = 'FILLER-';
UPDATE alf_namespace SET uri = SUBSTR(uri, 8) WHERE uri LIKE 'FILLER-%';
--
diff --git a/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.Oracle9Dialect/upgrade-2-move-qnames.sql b/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.Oracle9Dialect/upgrade-2-move-qnames.sql
index 9fb0d86124..2e0e33db3f 100644
--- a/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.Oracle9Dialect/upgrade-2-move-qnames.sql
+++ b/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.Oracle9Dialect/upgrade-2-move-qnames.sql
@@ -355,7 +355,7 @@ DROP INDEX t_fk_alf_qn_ns;
ALTER TABLE alf_qname DROP CONSTRAINT t_fk_alf_qn_ns;
-- Remove the FILLER- values from the namespace uri
-UPDATE alf_namespace SET uri = 'empty' WHERE uri = 'FILLER-';
+UPDATE alf_namespace SET uri = '.empty' WHERE uri = 'FILLER-';
UPDATE alf_namespace SET uri = SUBSTR(uri, 8) WHERE uri LIKE 'FILLER-%';
--
diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties
index 4030e94773..f528faddb0 100644
--- a/config/alfresco/messages/patch-service.properties
+++ b/config/alfresco/messages/patch-service.properties
@@ -213,3 +213,10 @@ patch.wcmPermissionPatch.result=Updated ACLs: ACLS are moved to the staging area
patch.avmWebProjectInheritPermissions.description=Break inheritance of permissions on wca:webfolder object to hide access by default.
patch.avmWebProjectInheritPermissions.result=Removed inheritance of permissions on all wca:webfolder objects.
+
+
+patch.wcmPostPermissionSnapshotPatch.description=Snapshot stores (after fixing ACLs so they are only set on the staging area store).
+patch.wcmPostPermissionSnapshotPatch.result=Snapshot complete after WCM ACL changes.
+
+
+
diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml
index 2d5c559160..2d9a343a69 100644
--- a/config/alfresco/patch/patch-services-context.xml
+++ b/config/alfresco/patch/patch-services-context.xml
@@ -1390,6 +1390,30 @@
+
+
+
+ patch.wcmPostPermissionSnapshotPatch
+ patch.wcmPostPermissionSnapshotPatch.description
+ 0
+ 122
+ 123
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
patch.avmWebProjectInheritPermissions02
diff --git a/source/java/org/alfresco/repo/admin/patch/impl/AVMPermissionsPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/AVMPermissionsPatch.java
index c73607b694..d317444504 100644
--- a/source/java/org/alfresco/repo/admin/patch/impl/AVMPermissionsPatch.java
+++ b/source/java/org/alfresco/repo/admin/patch/impl/AVMPermissionsPatch.java
@@ -49,16 +49,23 @@ public class AVMPermissionsPatch extends AbstractPatch
@Override
protected String applyInternal() throws Exception
{
- Long toDo = aclDaoComponent.getAVMHeadNodeCount();
- Long maxId = aclDaoComponent.getMaxAclId();
+ Thread progressThread = null;
+ if (aclDaoComponent.supportsProgressTracking())
+ {
+ Long toDo = aclDaoComponent.getAVMHeadNodeCount();
+ Long maxId = aclDaoComponent.getMaxAclId();
- Thread progressThread = new Thread(new ProgressWatcher(toDo, maxId), "WCMPactchProgressWatcher");
- progressThread.start();
+ progressThread = new Thread(new ProgressWatcher(toDo, maxId), "WCMPactchProgressWatcher");
+ progressThread.start();
+ }
Map summary = accessControlListDao.patchAcls();
- progressThread.interrupt();
- progressThread.join();
+ if (progressThread != null)
+ {
+ progressThread.interrupt();
+ progressThread.join();
+ }
// build the result message
String msg = I18NUtil.getMessage(MSG_SUCCESS, summary.get(ACLType.DEFINING), summary.get(ACLType.LAYERED));
diff --git a/source/java/org/alfresco/repo/admin/patch/impl/WCMPermissionPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/WCMPermissionPatch.java
index 1867892d05..2ec49dd6f8 100644
--- a/source/java/org/alfresco/repo/admin/patch/impl/WCMPermissionPatch.java
+++ b/source/java/org/alfresco/repo/admin/patch/impl/WCMPermissionPatch.java
@@ -25,6 +25,7 @@
package org.alfresco.repo.admin.patch.impl;
import java.util.List;
+import java.util.Map;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.model.WCMAppModel;
@@ -89,11 +90,15 @@ public class WCMPermissionPatch extends AbstractPatch
@Override
protected String applyInternal() throws Exception
{
- Long toDo = aclDaoComponent.getAVMHeadNodeCount();
- Long maxId = aclDaoComponent.getMaxAclId();
+ Thread progressThread = null;
+ if (aclDaoComponent.supportsProgressTracking())
+ {
+ Long toDo = aclDaoComponent.getAVMHeadNodeCount();
+ Long maxId = aclDaoComponent.getMaxAclId();
- Thread progressThread = new Thread(new ProgressWatcher(toDo, maxId), "WCMPactchProgressWatcher");
- progressThread.start();
+ progressThread = new Thread(new ProgressWatcher(toDo, maxId), "WCMPactchProgressWatcher");
+ progressThread.start();
+ }
List stores = avmService.getStores();
for (AVMStoreDescriptor store : stores)
@@ -130,9 +135,12 @@ public class WCMPermissionPatch extends AbstractPatch
}
}
- progressThread.interrupt();
- progressThread.join();
-
+ if (progressThread != null)
+ {
+ progressThread.interrupt();
+ progressThread.join();
+ }
+
// build the result message
String msg = I18NUtil.getMessage(MSG_SUCCESS);
// done
@@ -182,6 +190,30 @@ public class WCMPermissionPatch extends AbstractPatch
NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, store.getName() + ":/www");
permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ, true);
+ QName propQName = QName.createQName(null, ".web_project.noderef");
+
+ PropertyValue pValue = avmService.getStoreProperty(store.getName(), propQName);
+
+ if (pValue != null)
+ {
+ NodeRef webProjectNodeRef = (NodeRef) pValue.getValue(DataTypeDefinition.NODE_REF);
+
+ // Apply sepcific user permissions as set on the web project
+ List userInfoRefs = nodeService.getChildAssocs(webProjectNodeRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
+ for (ChildAssociationRef ref : userInfoRefs)
+ {
+ NodeRef userInfoRef = ref.getChildRef();
+ String username = (String) nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME);
+ String userrole = (String) nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE);
+
+ if (userrole.equals("ContentManager"))
+ {
+ permissionService.setPermission(dirRef.getStoreRef(), username, PermissionService.CHANGE_PERMISSIONS, true);
+ permissionService.setPermission(dirRef.getStoreRef(), username, PermissionService.READ_PERMISSIONS, true);
+ }
+ }
+ }
+
}
private void setSandBoxMasks(AVMStoreDescriptor sandBoxStore)
@@ -195,6 +227,7 @@ public class WCMPermissionPatch extends AbstractPatch
NodeRef dirRef = AVMNodeConverter.ToNodeRef(-1, sandBoxStore.getName() + ":/www");
+ Map woof = avmService.getStoreProperties(stagingAreaName);
PropertyValue pValue = avmService.getStoreProperty(stagingAreaName, propQName);
permissionService.setPermission(dirRef.getStoreRef(), PermissionService.ALL_AUTHORITIES, PermissionService.READ, true);
diff --git a/source/java/org/alfresco/repo/admin/patch/impl/WCMPostPermissionSnapshotPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/WCMPostPermissionSnapshotPatch.java
new file mode 100644
index 0000000000..8ac90bf2cd
--- /dev/null
+++ b/source/java/org/alfresco/repo/admin/patch/impl/WCMPostPermissionSnapshotPatch.java
@@ -0,0 +1,150 @@
+/*
+ * 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.admin.patch.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.alfresco.i18n.I18NUtil;
+import org.alfresco.repo.admin.patch.AbstractPatch;
+import org.alfresco.repo.domain.hibernate.AclDaoComponentImpl;
+import org.alfresco.repo.search.AVMSnapShotTriggeredIndexingMethodInterceptor;
+import org.alfresco.repo.search.impl.lucene.AVMLuceneIndexer;
+import org.alfresco.service.cmr.avm.AVMService;
+import org.alfresco.service.cmr.avm.AVMStoreDescriptor;
+
+/**
+ * Snap shot all stores after applying the staging are permissions patch
+ *
+ * @author andyh
+ */
+public class WCMPostPermissionSnapshotPatch extends AbstractPatch
+{
+ private static final String MSG_SUCCESS = "patch.wcmPostPermissionSnapshotPatch.result";
+
+ AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor;
+
+ AVMService avmService;
+
+ AclDaoComponentImpl aclDaoComponent;
+
+ public void setAvmService(AVMService avmService)
+ {
+ this.avmService = avmService;
+ }
+
+ public void setAvmSnapShotTriggeredIndexingMethodInterceptor(AVMSnapShotTriggeredIndexingMethodInterceptor avmSnapShotTriggeredIndexingMethodInterceptor)
+ {
+ this.avmSnapShotTriggeredIndexingMethodInterceptor = avmSnapShotTriggeredIndexingMethodInterceptor;
+ }
+
+ public void setAclDaoComponent(AclDaoComponentImpl aclDaoComponent)
+ {
+ this.aclDaoComponent = aclDaoComponent;
+ }
+
+ @Override
+ protected String applyInternal() throws Exception
+ {
+ List stores = avmService.getStores();
+
+ Thread progressThread = null;
+
+ Long toDo = aclDaoComponent.getNewInStore();
+
+ List indexers = new ArrayList(stores.size());
+ for (AVMStoreDescriptor storeDesc : stores)
+ {
+ AVMLuceneIndexer indexer = avmSnapShotTriggeredIndexingMethodInterceptor.getIndexer(storeDesc.getName());
+ indexers.add(indexer);
+ }
+
+ progressThread = new Thread(new ProgressWatcher(toDo, indexers), "WCMPactchProgressWatcher");
+ progressThread.start();
+
+ for (AVMStoreDescriptor storeDesc : stores)
+ {
+ if (avmService.getStoreRoot(-1, storeDesc.getName()).getLayerID() == -1)
+ {
+ avmService.createSnapshot(storeDesc.getName(), "PermissionPatch", "Snapshot after 2.2 permission patch");
+ AVMLuceneIndexer indexer = avmSnapShotTriggeredIndexingMethodInterceptor.getIndexer(storeDesc.getName());
+ indexer.flushPending();
+ }
+ }
+
+ progressThread.interrupt();
+ progressThread.join();
+
+ // build the result message
+ String msg = I18NUtil.getMessage(MSG_SUCCESS);
+ // done
+ return msg;
+ }
+
+ private class ProgressWatcher implements Runnable
+ {
+ private boolean running = true;
+
+ Long toDo;
+
+ List indexers;
+
+ ProgressWatcher(Long toDo, List indexers)
+ {
+ this.toDo = toDo;
+ this.indexers = indexers;
+ }
+
+ public void run()
+ {
+ while (running)
+ {
+ try
+ {
+ Thread.sleep(60000);
+ }
+ catch (InterruptedException e)
+ {
+ running = false;
+ }
+
+ if (running)
+ {
+ long done = 0;
+ for(AVMLuceneIndexer indexer : indexers)
+ {
+ if(indexer != null)
+ {
+ done += indexer.getIndexedDocCount();
+ }
+ }
+
+ reportProgress(toDo, done);
+ }
+ }
+ }
+
+ }
+}
diff --git a/source/java/org/alfresco/repo/avm/hibernate/AVMStorePropertyDAOHibernate.java b/source/java/org/alfresco/repo/avm/hibernate/AVMStorePropertyDAOHibernate.java
index 82ef90f1c1..8e5c067111 100644
--- a/source/java/org/alfresco/repo/avm/hibernate/AVMStorePropertyDAOHibernate.java
+++ b/source/java/org/alfresco/repo/avm/hibernate/AVMStorePropertyDAOHibernate.java
@@ -83,7 +83,7 @@ class AVMStorePropertyDAOHibernate extends HibernateDaoSupport implements AVMSto
"asp.store = :store and " +
"asp.name = :name");
query.setEntity("store", store);
- query.setParameter("name", qnameEntity);
+ query.setEntity("name", qnameEntity);
return (AVMStoreProperty)query.uniqueResult();
}
}
diff --git a/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java b/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java
index b3cf84fc35..dae3cac2e9 100644
--- a/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java
+++ b/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java
@@ -53,6 +53,7 @@ import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.InvalidStoreRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.util.EqualsHelper;
import org.alfresco.util.Pair;
/**
@@ -232,6 +233,9 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
public void updateChangedAcls(NodeRef startingPoint, List changes)
{
+ // If their are no actual changes there is nothing to do (the changes are all in TX and have already COWed so they can just change)
+
+ boolean hasChanges = false;
Long after = null;
for (AclChange change : changes)
{
@@ -243,7 +247,22 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
{
after = change.getAfter();
}
+
+ if(!EqualsHelper.nullSafeEquals(change.getTypeBefore(), change.getTypeAfter()))
+ {
+ hasChanges = true;
+ }
+ if(!EqualsHelper.nullSafeEquals(change.getBefore(), change.getAfter()))
+ {
+ hasChanges = true;
+ }
}
+
+ if(!hasChanges)
+ {
+ return;
+ }
+
Long inherited = null;
if (after != null)
{
@@ -253,6 +272,8 @@ public class AVMAccessControlListDAO implements AccessControlListDAO
updateChangedAclsImpl(startingPoint, changes, SetMode.ALL, inherited, after, indirections);
}
+
+
private void updateChangedAclsImpl(NodeRef startingPoint, List changes, SetMode mode, Long inherited, Long setAcl, Map> indirections)
{
hibernateSessionHelper.mark();
diff --git a/source/java/org/alfresco/repo/domain/hibernate/AclDaoComponentImpl.java b/source/java/org/alfresco/repo/domain/hibernate/AclDaoComponentImpl.java
index 88f4bcae29..e77e33cf8e 100644
--- a/source/java/org/alfresco/repo/domain/hibernate/AclDaoComponentImpl.java
+++ b/source/java/org/alfresco/repo/domain/hibernate/AclDaoComponentImpl.java
@@ -101,6 +101,8 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
static String QUERY_GET_LAYERED_DIRECTORIES = "permission.GetLayeredDirectories";
static String QUERY_GET_LAYERED_FILES = "permission.GetLayeredFiles";
+
+ static String QUERY_GET_NEW_IN_STORE = "permission.GetNewInStore";
/** Access to QName entities */
private QNameDAO qnameDAO;
@@ -1825,14 +1827,22 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
try
{
Session session = getSession();
- session.connection().setTransactionIsolation(1);
- Query query = getSession().getNamedQuery("permission.GetAVMHeadNodeCount");
- Long answer = (Long) query.uniqueResult();
- return answer;
+ int isolationLevel = session.connection().getTransactionIsolation();
+ try
+ {
+ session.connection().setTransactionIsolation(1);
+ Query query = getSession().getNamedQuery("permission.GetAVMHeadNodeCount");
+ Long answer = (Long) query.uniqueResult();
+ return answer;
+ }
+ finally
+ {
+ session.connection().setTransactionIsolation(isolationLevel);
+ }
}
catch (SQLException e)
{
- throw new AlfrescoRuntimeException("Failed to set TX isolation level");
+ throw new AlfrescoRuntimeException("Failed to set TX isolation level", e);
}
}
@@ -1842,33 +1852,77 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
try
{
Session session = getSession();
- session.connection().setTransactionIsolation(1);
- Query query = getSession().getNamedQuery("permission.GetMaxAclId");
- Long answer = (Long) query.uniqueResult();
- return answer;
+ int isolationLevel = session.connection().getTransactionIsolation();
+ try
+ {
+ session.connection().setTransactionIsolation(1);
+ Query query = getSession().getNamedQuery("permission.GetMaxAclId");
+ Long answer = (Long) query.uniqueResult();
+ return answer;
+ }
+ finally
+ {
+ session.connection().setTransactionIsolation(isolationLevel);
+ }
}
catch (SQLException e)
{
- throw new AlfrescoRuntimeException("Failed to set TX isolation level");
+ throw new AlfrescoRuntimeException("Failed to set TX isolation level", e);
}
}
+ public boolean supportsProgressTracking()
+ {
+ try
+ {
+ Session session = getSession();
+ return session.connection().getMetaData().supportsTransactionIsolationLevel(1);
+ }
+ catch (SQLException e)
+ {
+ return false;
+ }
+
+ }
+
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;
+ int isolationLevel = session.connection().getTransactionIsolation();
+ try
+ {
+ session.connection().setTransactionIsolation(1);
+ Query query = getSession().getNamedQuery("permission.GetAVMHeadNodeCountWherePermissionsHaveChanged");
+ query.setParameter("above", above);
+ Long answer = (Long) query.uniqueResult();
+ return answer;
+ }
+ finally
+ {
+ session.connection().setTransactionIsolation(isolationLevel);
+ }
}
catch (SQLException e)
{
- throw new AlfrescoRuntimeException("Failed to set TX isolation level");
+ throw new AlfrescoRuntimeException("Failed to set TX isolation level", e);
}
}
+
+ public Long getNewInStore()
+ {
+ HibernateCallback callback = new HibernateCallback()
+ {
+ public Object doInHibernate(Session session)
+ {
+ Query query = session.getNamedQuery(QUERY_GET_NEW_IN_STORE);
+ return query.uniqueResult();
+ }
+ };
+ Long count = (Long) getHibernateTemplate().execute(callback);
+ return count;
+ }
@SuppressWarnings("unchecked")
public List getLayeredDirectories()
@@ -1883,16 +1937,16 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
};
List