Upgrade overhaul: Retiring ancient patches and fixing de-Hibernate problems

- Moved setting of txn isolation level to ControlDAO
 - Retired patches where target schema is < 100
  - Removed unreferenced patch implementations
  - Removed unreferenced DB scripts
 - Moved patch-specific queries (ACL upgrade counts) into patch-common-SqlMap.xml
 - Fixed count query result processing (max of nothing is NULL) leading to unboxing NPEs
 - All DM-modifying patches depend on DmPermissionsPatch i.e. it will normally run immediately after SQL scripts


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21908 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2010-08-20 14:45:18 +00:00
parent bda714b422
commit a22fdceccd
45 changed files with 654 additions and 4468 deletions

View File

@@ -94,7 +94,6 @@
</property> </property>
<property name="preUpdateScriptPatches"> <property name="preUpdateScriptPatches">
<list> <list>
<ref bean="patch.db-V2.1-NotNullColumns" />
<ref bean="patch.db-V2.2-ACL-From-2.1-A" /> <ref bean="patch.db-V2.2-ACL-From-2.1-A" />
<ref bean="patch.db-V2.2-ACL" /> <ref bean="patch.db-V2.2-ACL" />
<ref bean="patch.db-V2.2-CleanNodeStatuses" /> <ref bean="patch.db-V2.2-CleanNodeStatuses" />
@@ -114,10 +113,6 @@
</property> </property>
<property name="postUpdateScriptPatches"> <property name="postUpdateScriptPatches">
<list> <list>
<ref bean="patch.db-V2.0-ContentUrls" />
<ref bean="patch.db-V2.1-JBPMData" />
<ref bean="patch.db-V2.1-VersionColumns2" />
<ref bean="patch.db-V2.1-JBPMProcessKey" />
<ref bean="patch.db-V2.1-RemoveWcmSubmittedAspect" /> <ref bean="patch.db-V2.1-RemoveWcmSubmittedAspect" />
<ref bean="patch.db-V2.1-AuditPathIndex" /> <ref bean="patch.db-V2.1-AuditPathIndex" />
<ref bean="patch.db-V3.0-ActivityTables" /> <ref bean="patch.db-V3.0-ActivityTables" />

View File

@@ -1,24 +0,0 @@
--
-- Title: Indexes for alf_content_url table
-- Database: Generic
-- Since: V2.0 Schema 44
-- Author: Derek Hulley
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
-- Content URLs
SELECT COUNT(*) FROM alf_content_url;
CREATE INDEX idx_alf_con_urls ON alf_content_url (content_url);(optional)
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V2.0-ContentUrls';
INSERT INTO alf_applied_patch
(id, description, fixes_from_schema, fixes_to_schema, applied_to_schema, target_schema, applied_on_date, applied_to_server, was_executed, succeeded, report)
VALUES
(
'patch.db-V2.0-ContentUrls', 'Manually executed script upgrade V2.0: Indexes for alf_content_url table',
0, 123, -1, 124, null, 'UNKOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,29 +0,0 @@
--
-- Title: Jbpm 3.1.2 -> 3.2 Data Migration
-- Database: Generic
-- Since: V2.1 Schema 52
-- Author: David Caruana
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
UPDATE JBPM_TASK SET PRIORITY_ = 2;
UPDATE JBPM_NODE SET ISASYNCEXCL_ = ${FALSE};
UPDATE JBPM_MODULEINSTANCE SET VERSION_ = 0;
UPDATE JBPM_POOLEDACTOR SET VERSION_ = 0;
UPDATE JBPM_SWIMLANEINSTANCE SET VERSION_ = 0;
UPDATE JBPM_TASKINSTANCE SET VERSION_ = 0;
UPDATE JBPM_TOKENVARIABLEMAP SET VERSION_ = 0;
UPDATE JBPM_VARIABLEINSTANCE SET VERSION_ = 0;
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V2.1-JBPMUpdate';
INSERT INTO alf_applied_patch
(id, description, fixes_from_schema, fixes_to_schema, applied_to_schema, target_schema, applied_on_date, applied_to_server, was_executed, succeeded, report)
VALUES
(
'patch.db-V2.1-JBPMUpdate', 'Manually executed script upgrade V2.1: JBPM 3.1.2 to 3.2 Data Upgrade',
0, 51, -1, 52, null, 'UNKOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,22 +0,0 @@
--
-- Title: Jbpm 3.2 Process Instance Key
-- Database: Generic
-- Since: V2.1 Schema 63
-- Author: David Caruana
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
UPDATE JBPM_PROCESSINSTANCE SET KEY_ = ID_ WHERE KEY_ IS NULL;
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V2.1-JBPMProcessKey';
INSERT INTO alf_applied_patch
(id, description, fixes_from_schema, fixes_to_schema, applied_to_schema, target_schema, applied_on_date, applied_to_server, was_executed, succeeded, report)
VALUES
(
'patch.db-V2.1-JBPMProcessKey', 'Manually executed script upgrade V2.1: JBPM 3.2 Process Instance Key',
0, 62, -1, 63, null, 'UNKNOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,21 +0,0 @@
--
-- Title: Add text columns that allow null
-- Database: Generic
-- Since: V2.1 Schema 64
-- Author: Derek Hulley
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
-- This is a Sybase issue, so nothing is required here.
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V2.1-NotNullColumns';
INSERT INTO alf_applied_patch
(id, description, fixes_from_schema, fixes_to_schema, applied_to_schema, target_schema, applied_on_date, applied_to_server, was_executed, succeeded, report)
VALUES
(
'patch.db-V2.1-NotNullColumns', 'Manually executed script upgrade V2.1: Add nullable columns',
0, 63, -1, 64, null, 'UNKOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -1,33 +0,0 @@
--
-- Title: Fill 'version' columns with data
-- Database: Generic
-- Since: V2.1 Schema 54
-- Author: Derek Hulley
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
UPDATE alf_store SET version = 1 WHERE version IS NULL;
UPDATE alf_node SET version = 1 WHERE version IS NULL;
UPDATE alf_child_assoc SET version = 1 WHERE version IS NULL;
UPDATE alf_node_assoc SET version = 1 WHERE version IS NULL;
UPDATE alf_node_status SET version = 1 WHERE version IS NULL;
UPDATE alf_transaction SET version = 1 WHERE version IS NULL;
UPDATE alf_server SET version = 1 WHERE version IS NULL;
UPDATE alf_access_control_list SET version = 1 WHERE version IS NULL;
UPDATE alf_access_control_entry SET version = 1 WHERE version IS NULL;
UPDATE alf_permission SET version = 1 WHERE version IS NULL;
UPDATE alf_authority SET version = 1 WHERE version IS NULL;
UPDATE alf_version_count SET version = 1 WHERE version IS NULL;
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V2.1-VersionColumns2';
INSERT INTO alf_applied_patch
(id, description, fixes_from_schema, fixes_to_schema, applied_to_schema, target_schema, applied_on_date, applied_to_server, was_executed, succeeded, report)
VALUES
(
'patch.db-V2.1-VersionColumns2', 'Manually executed script upgrade V2.1: Created initial version number for ADM entities',
0, 63, -1, 64, null, 'UNKOWN', ${TRUE}, ${TRUE}, 'Script completed'
);

View File

@@ -74,6 +74,10 @@
<!-- Parameter Maps --> <!-- Parameter Maps -->
<!-- --> <!-- -->
<parameterMap id="parameter_IdMap" class="map">
<parameter property="id" jdbcType="BIGINT" javaType="long"/>
</parameterMap>
<parameterMap id="parameter_admNewContentProp" class="map"> <parameterMap id="parameter_admNewContentProp" class="map">
<parameter property="longValue" jdbcType="BIGINT" javaType="java.lang.Long"/> <parameter property="longValue" jdbcType="BIGINT" javaType="java.lang.Long"/>
<parameter property="nodeId" jdbcType="BIGINT" javaType="java.lang.Long"/> <parameter property="nodeId" jdbcType="BIGINT" javaType="java.lang.Long"/>
@@ -270,6 +274,47 @@
name not in ('alfresco-tenants', '.avm_lock_table', '.PropertyBackedBeans', '.ChainingUserRegistrySynchronizer') name not in ('alfresco-tenants', '.avm_lock_table', '.PropertyBackedBeans', '.ChainingUserRegistrySynchronizer')
</select> </select>
<select id="select_AllAclIds" resultClass="long">
select
id
from
alf_access_control_list
</select>
<!-- for patch -->
<select id="select_UsedAclIds" resultClass="long">
select acl_id from avm_nodes where acl_id is not null
union select acl_id from avm_stores where acl_id is not null
union select acl_id from alf_node where acl_id is not null
union select acl_id from alf_attributes where acl_id is not null
</select>
<!-- for patch -->
<select id="select_MaxAclId" resultClass="long">
select
max(acl.id)
from
alf_access_control_list acl
</select>
<!-- for patch -->
<select id="select_DmNodeCount">
select
count(*)
from
alf_node
</select>
<!-- for patch -->
<select id="select_DmNodeCountWherePermissionsHaveChanged" parameterMap="parameter_IdMap">
select
count(*)
from
alf_node
where
acl_id > ?
</select>
<!-- --> <!-- -->
<!-- Updates --> <!-- Updates -->
<!-- --> <!-- -->

View File

@@ -377,48 +377,6 @@
acl_id = ? acl_id = ?
</select> </select>
<!-- for patch -->
<select id="select_AllAclIds" resultClass="long">
select
id
from
alf_access_control_list
</select>
<!-- for patch -->
<select id="select_UsedAclIds" resultClass="long">
select acl_id from avm_nodes where acl_id is not null
union select acl_id from avm_stores where acl_id is not null
union select acl_id from alf_node where acl_id is not null
union select acl_id from alf_attributes where acl_id is not null
</select>
<!-- for patch -->
<select id="select_MaxAclId" resultClass="long">
select
max(acl.id)
from
alf_access_control_list acl
</select>
<!-- for patch -->
<select id="select_DmNodeCount">
select
count(*)
from
alf_node
</select>
<!-- for patch -->
<select id="select_DmNodeCountWherePermissionsHaveChanged" parameterMap="parameter_IdMap">
select
count(*)
from
alf_node
where
acl_id > ?
</select>
<select id="select_AclMembersByAclId" parameterMap="parameter_IdMap" resultMap="result_AclMember"> <select id="select_AclMembersByAclId" parameterMap="parameter_IdMap" resultMap="result_AclMember">
select select
* *

File diff suppressed because it is too large Load Diff

View File

@@ -1,79 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.List;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.domain.avm.AVMNodeDAO;
import org.alfresco.repo.domain.avm.AVMNodeEntity;
import org.alfresco.repo.domain.patch.PatchDAO;
import org.alfresco.util.GUID;
/**
* This makes sure that all GUIDs in AVM nodes are set.
* @author britt
*/
public class AVMGuidPatch extends AbstractPatch
{
private AVMNodeDAO fAVMNodeDAO;
private PatchDAO patchDAO;
private static final String MSG_SUCCESS = "patch.AVMGuidPatch.result";
public AVMGuidPatch()
{
}
public void setAvmNodeDao(AVMNodeDAO dao)
{
fAVMNodeDAO = dao;
}
public void setPatchDAO(PatchDAO dao)
{
patchDAO = dao;
}
/* (non-Javadoc)
* @see org.alfresco.repo.admin.patch.AbstractPatch#applyInternal()
*/
@Override
protected String applyInternal() throws Exception
{
while (true)
{
List<AVMNodeEntity> batch = patchDAO.getEmptyGUIDS(200);
for (AVMNodeEntity nodeEntity : batch)
{
nodeEntity.setGuid(GUID.generate());
fAVMNodeDAO.updateNode(nodeEntity);
}
if (batch.size() == 0)
{
break;
}
}
return I18NUtil.getMessage(MSG_SUCCESS);
}
}

View File

@@ -1,91 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.List;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.domain.avm.AVMNodeDAO;
import org.alfresco.repo.domain.avm.AVMNodeEntity;
import org.alfresco.repo.domain.patch.PatchDAO;
/**
* Patch for changes to Layered Node path traversal.
* @author britt
*/
public class AVMLayeredSnapshotPatch extends AbstractPatch
{
private AVMNodeDAO fAVMNodeDAO;
private PatchDAO patchDAO;
private static final String MSG_SUCCESS = "patch.AVMLayeredSnapshot.result";
public AVMLayeredSnapshotPatch()
{
}
public void setAvmNodeDao(AVMNodeDAO dao)
{
fAVMNodeDAO = dao;
}
public void setPatchDAO(PatchDAO dao)
{
patchDAO = dao;
}
/* (non-Javadoc)
* @see org.alfresco.repo.admin.patch.AbstractPatch#applyInternal()
*/
@Override
protected String applyInternal() throws Exception
{
while (true)
{
List<AVMNodeEntity> batch = patchDAO.getNullVersionLayeredDirectories(200);
for (AVMNodeEntity nodeEntity : batch)
{
nodeEntity.setIndirectionVersion(-1);
fAVMNodeDAO.updateNode(nodeEntity);
}
if (batch.size() == 0)
{
break;
}
}
while (true)
{
List<AVMNodeEntity> batch = patchDAO.getNullVersionLayeredFiles(200);
for (AVMNodeEntity nodeEntity : batch)
{
nodeEntity.setIndirectionVersion(-1);
fAVMNodeDAO.updateNode(nodeEntity);
}
if (batch.size() == 0)
{
break;
}
}
return I18NUtil.getMessage(MSG_SUCCESS);
}
}

View File

@@ -1,128 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.Serializable;
import java.util.Map;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ActionModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.rule.RuleModel;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.namespace.QName;
/**
* Patch to apply the model changes made when decoupling actions from rules.
*
* @author Roy Wetherall
*/
public class ActionRuleDecouplingPatch extends AbstractPatch
{
private static final String MSG_RESULT = "patch.actionRuleDecouplingPatch.result";
/**
* @see org.alfresco.repo.admin.patch.AbstractPatch#applyInternal()
*/
@Override
protected String applyInternal() throws Exception
{
// Get a reference to the spaces store
StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore");
// Get all the node's of type rule in the store
int updateCount = 0;
ResultSet resultSet = this.searchService.query(storeRef, "lucene", "TYPE:\"" + RuleModel.TYPE_RULE + "\"");
try
{
for (NodeRef origRuleNodeRef : resultSet.getNodeRefs())
{
// Check that this rule need updated
if (!this.nodeService.exists(origRuleNodeRef))
{
continue;
}
Map<QName, Serializable> origProperties = this.nodeService.getProperties(origRuleNodeRef);
if (origProperties.containsKey(RuleModel.PROP_EXECUTE_ASYNC) == false)
{
// 1) Change the type of the rule to be a composite action
this.nodeService.setType(origRuleNodeRef, ActionModel.TYPE_COMPOSITE_ACTION);
// 2) Create a new rule node
ChildAssociationRef parentRef = this.nodeService.getPrimaryParent(origRuleNodeRef);
NodeRef newRuleNodeRef = this.nodeService.createNode(
parentRef.getParentRef(),
parentRef.getTypeQName(),
parentRef.getQName(),
RuleModel.TYPE_RULE).getChildRef();
// 3) Move the origional rule under the new rule
this.nodeService.moveNode(
origRuleNodeRef,
newRuleNodeRef,
RuleModel.ASSOC_ACTION,
RuleModel.ASSOC_ACTION);
// 4) Move the various properties from the origional, onto the new rule
Map<QName, Serializable> newProperties = this.nodeService.getProperties(newRuleNodeRef);
// Set the rule type, execute async and applyToChildren properties on the rule
Serializable ruleType = origProperties.get(RuleModel.PROP_RULE_TYPE);
origProperties.remove(RuleModel.PROP_RULE_TYPE);
newProperties.put(RuleModel.PROP_RULE_TYPE, ruleType);
Serializable executeAsync = origProperties.get(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY);
origProperties.remove(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY);
newProperties.put(RuleModel.PROP_EXECUTE_ASYNC, executeAsync);
Serializable applyToChildren = origProperties.get(RuleModel.PROP_APPLY_TO_CHILDREN);
origProperties.remove(RuleModel.PROP_APPLY_TO_CHILDREN);
newProperties.put(RuleModel.PROP_APPLY_TO_CHILDREN, applyToChildren);
origProperties.remove(QName.createQName(RuleModel.RULE_MODEL_URI, "owningNodeRef"));
// Move the action and description values from the composite action onto the rule
Serializable title = origProperties.get(ActionModel.PROP_ACTION_TITLE);
origProperties.remove(ActionModel.PROP_ACTION_TITLE);
Serializable description = origProperties.get(ActionModel.PROP_ACTION_DESCRIPTION);
origProperties.remove(ActionModel.PROP_ACTION_DESCRIPTION);
newProperties.put(ContentModel.PROP_TITLE, title);
newProperties.put(ContentModel.PROP_DESCRIPTION, description);
// Set the updated property values
this.nodeService.setProperties(origRuleNodeRef, origProperties);
this.nodeService.setProperties(newRuleNodeRef, newProperties);
// Increment the update count
updateCount++;
}
}
}
finally
{
resultSet.close();
}
// Done
String msg = I18NUtil.getMessage(MSG_RESULT, updateCount);
return msg;
}
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.List;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.PermissionService;
/**
* Grant <b>Consumer</b> role to <b>Guest</b> in <b>Category Root</b> folder.
* <p>
* This patch expects the folder to be present.
*/
public class CategoryRootPermissionPatch extends AbstractPatch
{
private static final String MSG_RESULT = "patch.categoryRootPermission.result";
private static final String ERR_NOT_FOUND = "patch.categoryRootPermission.err.not_found";
private PermissionService permissionService;
private ImporterBootstrap spacesBootstrap;
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setSpacesBootstrap(ImporterBootstrap spacesBootstrap)
{
this.spacesBootstrap = spacesBootstrap;
}
@Override
protected String applyInternal() throws Exception
{
String categoryRootPath = "/cm:categoryRoot";
// find category root
NodeRef rootNodeRef = nodeService.getRootNode(spacesBootstrap.getStoreRef());
List<NodeRef> nodeRefs = searchService.selectNodes(rootNodeRef, categoryRootPath, null, namespaceService, false);
if (nodeRefs.size() == 0)
{
String msg = I18NUtil.getMessage(ERR_NOT_FOUND, categoryRootPath);
throw new PatchException(msg);
}
NodeRef categoryRootRef = nodeRefs.get(0);
// apply permission
permissionService.setPermission(
categoryRootRef,
AuthenticationUtil.getGuestUserName(),
PermissionService.READ,
true);
// done
String msg = I18NUtil.getMessage(MSG_RESULT, categoryRootPath);
return msg;
}
}

View File

@@ -1,114 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.WCMAppModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
/**
* Patch to update the type of all WCM content form folders to 'wca:formfolder'.
*
* @author Kevin Roast
*/
public class ContentFormTypePatch extends AbstractPatch
{
private final static String MSG_RESULT = "patch.contentFormFolderType.result";
private ImporterBootstrap importerBootstrap;
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{
this.importerBootstrap = importerBootstrap;
}
/**
* Ensure that required common properties have been set
*/
protected void checkCommonProperties() throws Exception
{
if (searchService == null)
{
throw new PatchException("'searchService' property has not been set");
}
if (nodeService == null)
{
throw new PatchException("'nodeService' property has not been set");
}
if (importerBootstrap == null)
{
throw new PatchException("'importerBootstrap' property has not been set");
}
}
/**
* @see org.alfresco.repo.admin.patch.AbstractPatch#applyInternal()
*/
@Override
protected String applyInternal() throws Exception
{
checkCommonProperties();
int count = 0;
for (NodeRef formRef : getForms())
{
// update folder type to 'wcm:formfolder'
this.nodeService.setType(formRef, WCMAppModel.TYPE_FORMFOLDER);
count++;
}
return I18NUtil.getMessage(MSG_RESULT, new Object[] {Integer.toString(count)});
}
/**
* @return all existing web form folders - marked with the 'wcm:form' aspect.
*/
private Collection<NodeRef> getForms()
{
SearchParameters sp = new SearchParameters();
sp.addStore(this.importerBootstrap.getStoreRef());
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery("ASPECT:\"" + WCMAppModel.ASPECT_FORM + "\"");
ResultSet rs = this.searchService.query(sp);
try
{
Collection<NodeRef> result = new ArrayList<NodeRef>(rs.length());
for (ResultSetRow row : rs)
{
result.add(row.getNodeRef());
}
return result;
}
finally
{
rs.close();
}
}
}

View File

@@ -1,57 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
/**
* Roles defined in permissionsDefinition.xml moved from <b>cm:content</b> to <b>sys:base</b>.
* This effects the data stored in the <b>permission</b> table.
*
* @author Derek Hulley
*/
public class ContentPermissionPatch extends AbstractPermissionChangePatch
{
private static final String MSG_SUCCESS = "patch.contentPermission.result";
private static final QName TYPE_QNAME_OLD = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "content");
private static final QName TYPE_QNAME_NEW = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "base");
private static final String[] NAMES = new String[] {"Execute", "ReadContent", "WriteContent", "ExecuteContent"};
@Override
protected String applyInternal() throws Exception
{
int updateCount = 0;
for (String permissionName : NAMES)
{
updateCount += super.renamePermission(
ContentPermissionPatch.TYPE_QNAME_OLD,
permissionName,
ContentPermissionPatch.TYPE_QNAME_NEW,
permissionName);
}
// build the result message
String msg = I18NUtil.getMessage(MSG_SUCCESS, updateCount);
// done
return msg;
}
}

View File

@@ -1,88 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
/**
* Apply Version Edition to Repository Descriptor
*
* @author David Caruana
*/
public class DescriptorUpdatePatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.descriptorUpdate.result";
private ImporterBootstrap systemBootstrap;
public void setSystemBootstrap(ImporterBootstrap systemBootstrap)
{
this.systemBootstrap = systemBootstrap;
}
@Override
protected String applyInternal() throws Exception
{
checkPropertyNotNull(systemBootstrap, "systemBootstrap");
// retrieve system descriptor location
StoreRef storeRef = systemBootstrap.getStoreRef();
Properties systemProperties = systemBootstrap.getConfiguration();
// check for the store
if (nodeService.exists(storeRef))
{
// get the current descriptor
String path = systemProperties.getProperty("system.descriptor.current.childname");
String searchPath = "/" + path;
NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
List<NodeRef> nodeRefs = searchService.selectNodes(rootNodeRef, searchPath, null, namespaceService, false);
if (nodeRefs.size() > 0)
{
NodeRef descriptorNodeRef = nodeRefs.get(0);
// set version edition
Serializable value = nodeService.getProperty(descriptorNodeRef, ContentModel.PROP_SYS_VERSION_EDITION);
if (value == null)
{
String edition = systemProperties.getProperty("version.edition");
Collection<String> editions = new ArrayList<String>();
editions.add(edition);
nodeService.setProperty(descriptorNodeRef, ContentModel.PROP_SYS_VERSION_EDITION, (Serializable)editions);
}
}
}
// done
String msg = I18NUtil.getMessage(MSG_SUCCESS);
return msg;
}
}

View File

@@ -21,11 +21,14 @@ package org.alfresco.repo.admin.patch.impl;
import java.util.Map; import java.util.Map;
import org.alfresco.repo.admin.patch.AbstractPatch; import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.domain.control.ControlDAO;
import org.alfresco.repo.domain.patch.PatchDAO; import org.alfresco.repo.domain.patch.PatchDAO;
import org.alfresco.repo.domain.permissions.AccessControlListDAO; import org.alfresco.repo.domain.permissions.AccessControlListDAO;
import org.alfresco.repo.security.permissions.ACLType; import org.alfresco.repo.security.permissions.ACLType;
import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.I18NUtil; import org.springframework.extensions.surf.util.I18NUtil;
/** /**
@@ -33,69 +36,101 @@ import org.springframework.extensions.surf.util.I18NUtil;
*/ */
public class DmPermissionsPatch extends AbstractPatch public class DmPermissionsPatch extends AbstractPatch
{ {
private static final String MSG_SUCCESS = "patch.updateDmPermissions.result"; private static final String MSG_SUCCESS = "patch.updateDmPermissions.result";
private static Log logger = LogFactory.getLog(DmPermissionsPatch.class);
private AccessControlListDAO accessControlListDao; private AccessControlListDAO accessControlListDao;
private PatchDAO patchDAO; private PatchDAO patchDAO;
private ControlDAO controlDAO;
@Override
protected String applyInternal() throws Exception
{
Thread progressThread = null;
if (this.patchDAO.supportsProgressTracking())
{
progressThread = new Thread(new ProgressWatcher(), "DMPatchProgressWatcher");
progressThread.start();
}
Map<ACLType, Integer> summary = this.accessControlListDao.patchAcls();
if (progressThread != null)
{
progressThread.interrupt();
progressThread.join();
}
// build the result message
String msg = I18NUtil.getMessage(DmPermissionsPatch.MSG_SUCCESS, summary.get(ACLType.DEFINING));
// done
return msg;
}
/**
* Set the access control list dao
*
* @param accessControlListDao
*/
public void setAccessControlListDao(AccessControlListDAO accessControlListDao) public void setAccessControlListDao(AccessControlListDAO accessControlListDao)
{ {
this.accessControlListDao = accessControlListDao; this.accessControlListDao = accessControlListDao;
} }
/**
* Set the patch dao
*
* @param patchDAO
*/
public void setPatchDAO(PatchDAO patchDAO) public void setPatchDAO(PatchDAO patchDAO)
{ {
this.patchDAO = patchDAO; this.patchDAO = patchDAO;
} }
public void setControlDAO(ControlDAO controlDAO)
{
this.controlDAO = controlDAO;
}
@Override
protected String applyInternal() throws Exception
{
Thread progressThread = null;
progressThread = new Thread(new ProgressWatcher(), "DMPatchProgressWatcher");
progressThread.start();
try
{
Map<ACLType, Integer> summary = this.accessControlListDao.patchAcls();
// build the result message
String msg = I18NUtil.getMessage(DmPermissionsPatch.MSG_SUCCESS, summary.get(ACLType.DEFINING));
// done
return msg;
}
finally
{
progressThread.interrupt();
progressThread.join();
}
}
private class ProgressWatcher implements Runnable private class ProgressWatcher implements Runnable
{ {
private boolean running = true; private boolean running = true;
Long toDo; Long toDo;
Long max; Long max;
public void run() public void run()
{ {
while (this.running) while (this.running)
{ {
if (this.running)
{
RetryingTransactionHelper txHelper = transactionService.getRetryingTransactionHelper();
txHelper.setMaxRetries(1);
RetryingTransactionCallback<Long> callback = new RetryingTransactionCallback<Long>()
{
public Long execute() throws Throwable
{
// Change isolation level
try
{
controlDAO.setTransactionIsolationLevel(1);
}
catch (IllegalStateException e)
{
// Can't be set. We're done here.
running = false;
return 0L;
}
if (toDo == null)
{
toDo = patchDAO.getDmNodeCount();
max = patchDAO.getMaxAclId();
}
return patchDAO.getDmNodeCountWithNewACLs(ProgressWatcher.this.max);
}
};
try
{
Long done = txHelper.doInTransaction(callback, true, true);
reportProgress(this.toDo, done);
}
catch (Throwable e)
{
logger.error("Failure in ProgressWatcher", e);
this.running = false;
}
}
try try
{ {
Thread.sleep(60000); Thread.sleep(60000);
@@ -104,33 +139,7 @@ public class DmPermissionsPatch extends AbstractPatch
{ {
this.running = false; this.running = false;
} }
if (this.running)
{
RetryingTransactionHelper txHelper = DmPermissionsPatch.this.transactionService
.getRetryingTransactionHelper();
txHelper.setMaxRetries(1);
Long done = txHelper.doInTransaction(new RetryingTransactionCallback<Long>()
{
public Long execute() throws Throwable
{
if (ProgressWatcher.this.toDo == null)
{
ProgressWatcher.this.toDo = DmPermissionsPatch.this.patchDAO
.getDmNodeCount();
ProgressWatcher.this.max = DmPermissionsPatch.this.patchDAO.getMaxAclId();
}
return DmPermissionsPatch.this.patchDAO
.getDmNodeCountWithNewACLs(ProgressWatcher.this.max);
}
}, true, true);
reportProgress(this.toDo, done);
}
} }
} }
} }
} }

View File

@@ -1,192 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ACPImportPackageHandler;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.view.ImporterService;
import org.alfresco.service.cmr.view.Location;
import org.springframework.context.MessageSource;
import org.springframework.core.io.ClassPathResource;
/**
* Ensures that the <b>email templates</b> are imported into the default folder.
* <p>
* This uses the bootstrap importer to get the paths to look for. If not present,
* the required structures are created.
* <p>
* This class should be replaced with a more generic <code>ImporterPatch</code>
* that can do conditional importing into given locations.
* <p>
* JIRA: {@link http://www.alfresco.org/jira/browse/AR-342 AR-342}
*
* @author Kevin Roast
*/
public class EmailTemplatesContentPatch extends AbstractPatch
{
private static final String MSG_CREATED = "patch.emailTemplatesContent.result";
public static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname";
public static final String PROPERTY_DICTIONARY_CHILDNAME = "spaces.dictionary.childname";
public static final String PROPERTY_EMAIL_TEMPLATES_CHILDNAME = "spaces.templates.email.childname";
private ImporterBootstrap importerBootstrap;
private ImporterService importerService;
private MessageSource messageSource;
protected Properties configuration;
protected NodeRef emailTemplatesNodeRef;
private String templatesACP;
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{
this.importerBootstrap = importerBootstrap;
}
public void setImporterService(ImporterService importerService)
{
this.importerService = importerService;
}
public void setMessageSource(MessageSource messageSource)
{
this.messageSource = messageSource;
}
/**
* @param templatesACP The templates ACP file to import.
*/
public void setTemplatesACP(String templatesACP)
{
this.templatesACP = templatesACP;
}
/**
* Ensure that required properties have been set
*/
protected void checkRequiredProperties() throws Exception
{
checkPropertyNotNull(importerBootstrap, "importerBootstrap");
checkPropertyNotNull(importerService, "importerService");
checkPropertyNotNull(messageSource, "messageSource");
checkPropertyNotNull(templatesACP, "templatesACP");
}
/**
* Extracts pertinent references and properties that are common to execution
* of this and derived patches.
*/
protected void setUp() throws Exception
{
// get the node store that we must work against
StoreRef storeRef = importerBootstrap.getStoreRef();
if (storeRef == null)
{
throw new PatchException("Bootstrap store has not been set");
}
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
this.configuration = importerBootstrap.getConfiguration();
// get the association names that form the path
String companyHomeChildName = configuration.getProperty(PROPERTY_COMPANY_HOME_CHILDNAME);
if (companyHomeChildName == null || companyHomeChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_COMPANY_HOME_CHILDNAME + "' is not present");
}
String dictionaryChildName = configuration.getProperty(PROPERTY_DICTIONARY_CHILDNAME);
if (dictionaryChildName == null || dictionaryChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_DICTIONARY_CHILDNAME + "' is not present");
}
String emailTemplatesChildName = configuration.getProperty(PROPERTY_EMAIL_TEMPLATES_CHILDNAME);
if (emailTemplatesChildName == null || emailTemplatesChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_EMAIL_TEMPLATES_CHILDNAME + "' is not present");
}
// build the search string to get the email templates node
StringBuilder sb = new StringBuilder(128);
sb.append("/").append(companyHomeChildName)
.append("/").append(dictionaryChildName)
.append("/").append(emailTemplatesChildName);
String xpath = sb.toString();
// get the templates node
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false);
if (nodeRefs.size() == 0)
{
throw new PatchException("Unable to locate Email Templates folder: \n" +
" root: " + storeRootNodeRef + "\n" +
" xpath: " + xpath);
}
else if (nodeRefs.size() > 1)
{
throw new PatchException("Found too many Email Templates folder results: \n" +
" root: " + storeRootNodeRef + "\n" +
" xpath: " + xpath + "\n" +
" results: " + nodeRefs);
}
this.emailTemplatesNodeRef = nodeRefs.get(0);
}
@Override
protected String applyInternal() throws Exception
{
// common properties must be set before we can continue
checkRequiredProperties();
setUp();
// import the content
RunAsWork<Object> importRunAs = new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
importContent();
return null;
}
};
AuthenticationUtil.runAs(importRunAs, authenticationContext.getSystemUserName());
// output a message to describe the result
return I18NUtil.getMessage(MSG_CREATED);
}
private void importContent() throws IOException
{
// import the content
ClassPathResource acpResource = new ClassPathResource(this.templatesACP);
ACPImportPackageHandler acpHandler = new ACPImportPackageHandler(acpResource.getFile(), null);
Location importLocation = new Location(this.emailTemplatesNodeRef);
importerService.importView(acpHandler, importLocation, null, null);
}
}

View File

@@ -1,240 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName;
import org.springframework.context.MessageSource;
/**
* Ensures that the <b>email templates</b> folder is present.
* <p>
* This uses the bootstrap importer to get the paths to look for. If not present,
* the required structures are created.
* <p>
* This class should be replaced with a more generic <code>ImporterPatch</code>
* that can do conditional importing into given locations.
* <p>
* JIRA: {@link http://www.alfresco.org/jira/browse/AR-342 AR-342}
*
* @author Kevin Roast
*/
public class EmailTemplatesFolderPatch extends AbstractPatch
{
private static final String MSG_EXISTS = "patch.emailTemplatesFolder.result.exists";
private static final String MSG_CREATED = "patch.emailTemplatesFolder.result.created";
public static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname";
public static final String PROPERTY_DICTIONARY_CHILDNAME = "spaces.dictionary.childname";
public static final String PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME = "spaces.templates.email.childname";
private static final String PROPERTY_EMAIL_TEMPLATES_FOLDER_NAME = "spaces.templates.email.name";
private static final String PROPERTY_EMAIL_TEMPLATES_FOLDER_DESCRIPTION = "spaces.templates.email.description";
private static final String PROPERTY_ICON = "space-icon-default";
private ImporterBootstrap importerBootstrap;
private MessageSource messageSource;
protected NodeRef dictionaryNodeRef;
protected Properties configuration;
protected NodeRef emailTemplatesFolderNodeRef;
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{
this.importerBootstrap = importerBootstrap;
}
public void setMessageSource(MessageSource messageSource)
{
this.messageSource = messageSource;
}
/**
* Ensure that required common properties have been set
*/
protected void checkCommonProperties() throws Exception
{
checkPropertyNotNull(importerBootstrap, "importerBootstrap");
checkPropertyNotNull(messageSource, "messageSource");
}
/**
* Extracts pertinent references and properties that are common to execution
* of this and derived patches.
*/
protected void setUp() throws Exception
{
// get the node store that we must work against
StoreRef storeRef = importerBootstrap.getStoreRef();
if (storeRef == null)
{
throw new PatchException("Bootstrap store has not been set");
}
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
this.configuration = importerBootstrap.getConfiguration();
// get the association names that form the path
String companyHomeChildName = configuration.getProperty(PROPERTY_COMPANY_HOME_CHILDNAME);
if (companyHomeChildName == null || companyHomeChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_COMPANY_HOME_CHILDNAME + "' is not present");
}
String dictionaryChildName = configuration.getProperty(PROPERTY_DICTIONARY_CHILDNAME);
if (dictionaryChildName == null || dictionaryChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_DICTIONARY_CHILDNAME + "' is not present");
}
String emailTemplatesChildName = configuration.getProperty(PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME);
if (emailTemplatesChildName == null || emailTemplatesChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME + "' is not present");
}
// build the search string to get the dictionary node
StringBuilder sb = new StringBuilder(128);
sb.append("/").append(companyHomeChildName)
.append("/").append(dictionaryChildName);
String xpath = sb.toString();
// get the dictionary node
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false);
if (nodeRefs.size() == 0)
{
throw new PatchException("XPath didn't return any results: \n" +
" root: " + storeRootNodeRef + "\n" +
" xpath: " + xpath);
}
else if (nodeRefs.size() > 1)
{
throw new PatchException("XPath returned too many results: \n" +
" root: " + storeRootNodeRef + "\n" +
" xpath: " + xpath + "\n" +
" results: " + nodeRefs);
}
this.dictionaryNodeRef = nodeRefs.get(0);
// Now we have the optional part. Check for the existence of the email templates folder
xpath = emailTemplatesChildName;
nodeRefs = searchService.selectNodes(dictionaryNodeRef, xpath, null, namespaceService, false);
if (nodeRefs.size() > 1)
{
throw new PatchException("XPath returned too many results: \n" +
" dictionary node: " + dictionaryNodeRef + "\n" +
" xpath: " + xpath + "\n" +
" results: " + nodeRefs);
}
else if (nodeRefs.size() == 0)
{
// the node does not exist
this.emailTemplatesFolderNodeRef = null;
}
else
{
// we have the email templates folder noderef
this.emailTemplatesFolderNodeRef = nodeRefs.get(0);
}
}
@Override
protected String applyInternal() throws Exception
{
// common properties must be set before we can continue
checkCommonProperties();
if (messageSource == null)
{
throw new PatchException("'messageSource' property has not been set");
}
setUp();
// create the folder if needed - output a message to describe the result
String msg = null;
if (emailTemplatesFolderNodeRef == null)
{
createFolder();
msg = I18NUtil.getMessage(MSG_CREATED, emailTemplatesFolderNodeRef);
}
else
{
msg = I18NUtil.getMessage(MSG_EXISTS, emailTemplatesFolderNodeRef);
}
return msg;
}
private void createFolder()
{
// get required properties
String emailTemplatesChildName = configuration.getProperty(PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME);
if (emailTemplatesChildName == null)
{
throw new PatchException("Bootstrap property '" + PROPERTY_EMAIL_TEMPLATES_FOLDER_CHILDNAME + "' is not present");
}
String emailTemplatesName = messageSource.getMessage(
PROPERTY_EMAIL_TEMPLATES_FOLDER_NAME,
null,
I18NUtil.getLocale());
if (emailTemplatesName == null || emailTemplatesName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_EMAIL_TEMPLATES_FOLDER_NAME + "' is not present");
}
String emailTemplatesDescription = messageSource.getMessage(
PROPERTY_EMAIL_TEMPLATES_FOLDER_DESCRIPTION,
null,
I18NUtil.getLocale());
if (emailTemplatesDescription == null || emailTemplatesDescription.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_EMAIL_TEMPLATES_FOLDER_DESCRIPTION + "' is not present");
}
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(7);
properties.put(ContentModel.PROP_NAME, emailTemplatesName);
properties.put(ContentModel.PROP_TITLE, emailTemplatesName);
properties.put(ContentModel.PROP_DESCRIPTION, emailTemplatesDescription);
properties.put(ApplicationModel.PROP_ICON, PROPERTY_ICON);
// create the node
ChildAssociationRef childAssocRef = nodeService.createNode(
dictionaryNodeRef,
ContentModel.ASSOC_CONTAINS,
QName.resolveToQName(namespaceService, emailTemplatesChildName),
ContentModel.TYPE_FOLDER,
properties);
emailTemplatesFolderNodeRef = childAssocRef.getChildRef();
// add the required aspects
nodeService.addAspect(emailTemplatesFolderNodeRef, ApplicationModel.ASPECT_UIFACETS, null);
}
}

View File

@@ -1,117 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.Serializable;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ForumModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.QName;
/**
* Patch to remove the '_large' from the icon property for all the forums
* based space types i.e. fm:forums, fm:forum and fm:topic.
*
* @author gavinc
*/
public class ForumsIconsPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.forumsIcons.result";
private ImporterBootstrap importerBootstrap;
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{
this.importerBootstrap = importerBootstrap;
}
@Override
protected String applyInternal() throws Exception
{
int iconsChanged = 0;
// change all the fm:forums nodes
iconsChanged += changeIcons(ForumModel.TYPE_FORUMS);
// change all the fm:forum nodes
iconsChanged += changeIcons(ForumModel.TYPE_FORUM);
// change all the topic nodes
iconsChanged += changeIcons(ForumModel.TYPE_TOPIC);
// return success message
return I18NUtil.getMessage(MSG_SUCCESS, new Object[] {iconsChanged});
}
/**
* Removes the '_large' from the icon property for the nodes of the given type
*
* @param typeName The qname of the type to change the icon property for
* @return Returns the number of icons changed
*/
private int changeIcons(QName typeName)
{
int changed = 0;
String query = "TYPE:\"" + typeName.toString() + "\"";
ResultSet results = null;
try
{
results = this.searchService.query(this.importerBootstrap.getStoreRef(),
SearchService.LANGUAGE_LUCENE, query);
// if there are any results iterate through nodes and update icon property
if (results.length() > 0)
{
for (NodeRef node : results.getNodeRefs())
{
if (this.nodeService.exists(node))
{
String icon = (String)this.nodeService.getProperty(node, ApplicationModel.PROP_ICON);
if (icon != null && icon.length() > 0)
{
int idx = icon.indexOf("_large");
if (idx != -1)
{
String newIcon = icon.substring(0, idx);
this.nodeService.setProperty(node, ApplicationModel.PROP_ICON, (Serializable)newIcon);
changed++;
}
}
}
}
}
}
finally
{
if (results != null)
{
results.close();
}
}
return changed;
}
}

View File

@@ -1,94 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.search.Indexer;
import org.alfresco.repo.search.IndexerAndSearcher;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
/**
* Patch usr:user and cm:person objects so that the user name properties are in the
* index in untokenized form. If not authentication may fail in mixed language use.
*
* @author andyh
*
*/
public class GroupTokenisationPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.groupNamesAsIdentifiers.result";
private ImporterBootstrap userImporterBootstrap;
private IndexerAndSearcher indexerAndSearcher;
public GroupTokenisationPatch()
{
}
public void setUserImporterBootstrap(ImporterBootstrap userImporterBootstrap)
{
this.userImporterBootstrap = userImporterBootstrap;
}
public void setIndexerAndSearcher(IndexerAndSearcher indexerAndSearcher)
{
this.indexerAndSearcher = indexerAndSearcher;
}
@Override
protected String applyInternal() throws Exception
{
reindex("TYPE:\"usr:authorityContainer\"", userImporterBootstrap.getStoreRef());
return I18NUtil.getMessage(MSG_SUCCESS);
}
private void reindex(String query, StoreRef store)
{
SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery(query);
sp.addStore(store);
ResultSet rs = null;
try
{
rs = searchService.query(sp);
for(ResultSetRow row : rs)
{
Indexer indexer = indexerAndSearcher.getIndexer(row.getNodeRef().getStoreRef());
indexer.updateNode(row.getNodeRef());
}
}
finally
{
if(rs != null)
{
rs.close();
}
}
}
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
/**
* Change Guest Person permission from Guest to Read
*
* Guest (now Consumer) permission is not valid for cm:person type.
*/
public class GuestPersonPermissionPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.guestPersonPermission.result";
private PersonService personService;
private PermissionService permissionService;
public GuestPersonPermissionPatch()
{
super();
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
@Override
protected String applyInternal() throws Exception
{
String guestId = AuthenticationUtil.getGuestUserName();
if (personService.personExists(guestId))
{
NodeRef personRef = personService.getPerson(guestId);
permissionService.setInheritParentPermissions(personRef, false);
permissionService.deletePermission(personRef, guestId, PermissionService.CONSUMER);
permissionService.setPermission(personRef, guestId, PermissionService.READ, true);
}
return I18NUtil.getMessage(MSG_SUCCESS);
}
}

View File

@@ -1,69 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
/**
* Change Guest Person permission to make visible to all users as 'Consumer'.
*
* This allows users other than admin to select the Guest user for Invite to a Space.
*/
public class GuestPersonPermissionPatch2 extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.guestPersonPermission2.result";
private PersonService personService;
private PermissionService permissionService;
public GuestPersonPermissionPatch2()
{
super();
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
@Override
protected String applyInternal() throws Exception
{
String guestId = AuthenticationUtil.getGuestUserName();
if (personService.personExists(guestId))
{
NodeRef personRef = personService.getPerson(guestId);
permissionService.setInheritParentPermissions(personRef, true);
}
return I18NUtil.getMessage(MSG_SUCCESS);
}
}

View File

@@ -1,242 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.namespace.QName;
import org.springframework.context.MessageSource;
/**
* Ensures that the <b>guest</b> user homespace exists.<br/> A guest user homespace is now created during bootstrap. It is required for guest user access, but in older databases
* will not exist.
*
* @author Andy Hind
*/
public class GuestUserPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.guestUser.result";
private static final String COMPANY_HOME_CHILD_NAME = "spaces.company_home.childname";
private static final String GUEST_HOME_CHILD_NAME = "spaces.guest_home.childname";
private static final String GUEST_HOME_NAME = "spaces.guest_home.name";
private static final String GUEST_HOME_DESCRIPTION = "spaces.guest_home.description";
private PersonService personService;
private PermissionService permissionService;
private ImporterBootstrap importerBootstrap;
private MessageSource messageSource;
public GuestUserPatch()
{
super();
}
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{
this.importerBootstrap = importerBootstrap;
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
public void setMessageSource(MessageSource messageSource)
{
this.messageSource = messageSource;
}
@Override
protected String applyInternal() throws Exception
{
// Config
StoreRef storeRef = importerBootstrap.getStoreRef();
if (storeRef == null)
{
throw new PatchException("Bootstrap store has not been set");
}
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
Properties configuration = importerBootstrap.getConfiguration();
String companyHomeChildName = configuration.getProperty(COMPANY_HOME_CHILD_NAME);
if (companyHomeChildName == null || companyHomeChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + COMPANY_HOME_CHILD_NAME + "' is not present");
}
String guestHomeChildName = configuration.getProperty(GUEST_HOME_CHILD_NAME);
if (guestHomeChildName == null || guestHomeChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + GUEST_HOME_CHILD_NAME + "' is not present");
}
// Set company home space permissions
NodeRef companyHomeRef = setCompanyHomeSpacePermissions(storeRootNodeRef, companyHomeChildName);
// Add the guest home space
NodeRef guestHomeRef = addGuestHomeSpace(storeRootNodeRef, configuration, companyHomeChildName,
guestHomeChildName, companyHomeRef);
// Add the guest user and fix read access to the created person
addGuestUser(guestHomeRef);
return I18NUtil.getMessage(MSG_SUCCESS);
}
private void addGuestUser(NodeRef guestHomeRef)
{
String guestId = AuthenticationUtil.getGuestUserName();
if (!personService.personExists(guestId))
{
HashMap<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_USERNAME, guestId);
properties.put(ContentModel.PROP_HOMEFOLDER, guestHomeRef);
properties.put(ContentModel.PROP_FIRSTNAME, "Guest");
properties.put(ContentModel.PROP_LASTNAME, "");
properties.put(ContentModel.PROP_EMAIL, "");
properties.put(ContentModel.PROP_ORGID, "");
personService.createPerson(properties);
}
NodeRef personRef = personService.getPerson(guestId);
permissionService.setInheritParentPermissions(personRef, false);
permissionService.setPermission(personRef, guestId, PermissionService.CONSUMER, true);
}
private NodeRef addGuestHomeSpace(NodeRef storeRootNodeRef, Properties configuration, String companyHomeChildName,
String guestHomeChildName, NodeRef companyHomeRef)
{
List<NodeRef> nodeRefs = searchService.selectNodes(companyHomeRef, guestHomeChildName, null, namespaceService,
false);
if (nodeRefs.size() == 0)
{
// create
String guestHomeName = messageSource.getMessage(GUEST_HOME_NAME, null, I18NUtil.getLocale());
if (guestHomeName == null || guestHomeName.length() == 0)
{
throw new PatchException("Bootstrap property '" + GUEST_HOME_NAME + "' is not present");
}
String guestHomeDescription = messageSource.getMessage(GUEST_HOME_DESCRIPTION, null, I18NUtil.getLocale());
if (guestHomeDescription == null || guestHomeDescription.length() == 0)
{
throw new PatchException("Bootstrap property '" + GUEST_HOME_DESCRIPTION + "' is not present");
}
HashMap<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_NAME, guestHomeName);
properties.put(ContentModel.PROP_TITLE, guestHomeName);
properties.put(ContentModel.PROP_DESCRIPTION, guestHomeDescription);
properties.put(ApplicationModel.PROP_ICON, "space-icon-default");
ChildAssociationRef childAssocRef = nodeService.createNode(companyHomeRef, ContentModel.ASSOC_CONTAINS,
QName.createQName(guestHomeChildName, namespaceService), ContentModel.TYPE_FOLDER, properties);
NodeRef nodeRef = childAssocRef.getChildRef();
// add the required aspects
nodeService.addAspect(nodeRef, ApplicationModel.ASPECT_UIFACETS, null);
setGuestHomePermissions(nodeRef);
return nodeRef;
}
else if (nodeRefs.size() == 1)
{
NodeRef nodeRef = nodeRefs.get(0);
setGuestHomePermissions(nodeRef);
return nodeRef;
}
else
{
throw new PatchException("XPath returned too many results: \n"
+ " root: " + storeRootNodeRef + "\n" + " xpath: " + companyHomeChildName + "\n"
+ " results: " + nodeRefs);
}
}
private void setGuestHomePermissions(NodeRef nodeRef)
{
String guestId = AuthenticationUtil.getGuestUserName();
permissionService.setInheritParentPermissions(nodeRef, false);
permissionService.setPermission(nodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.CONSUMER, true);
permissionService.setPermission(nodeRef, guestId, PermissionService.CONSUMER, true);
}
private NodeRef setCompanyHomeSpacePermissions(NodeRef storeRootNodeRef, String companyHomeChildName)
{
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, companyHomeChildName, null,
namespaceService, false);
if (nodeRefs.size() == 0)
{
throw new PatchException("XPath didn't return any results: \n"
+ " root: " + storeRootNodeRef + "\n" + " xpath: " + companyHomeChildName);
}
else if (nodeRefs.size() > 1)
{
throw new PatchException("XPath returned too many results: \n"
+ " root: " + storeRootNodeRef + "\n" + " xpath: " + companyHomeChildName + "\n"
+ " results: " + nodeRefs);
}
NodeRef companyHomeRef = nodeRefs.get(0);
permissionService.setInheritParentPermissions(companyHomeRef, false);
permissionService.setPermission(companyHomeRef, PermissionService.ALL_AUTHORITIES, PermissionService.CONSUMER,
true);
return companyHomeRef;
}
}

View File

@@ -1,160 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.Serializable;
import java.util.List;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
import org.alfresco.service.cmr.dictionary.ConstraintException;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.repository.datatype.TypeConversionException;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.QName;
/**
* Patch usr:user and cm:person objects so that the user name properties are in the index in untokenized form. If not authentication may fail in mixed language use.
*
* @author andyh
*/
public class InvalidUserPersonAndGroupPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.invalidUserPersonAndGroup.result";
private ImporterBootstrap spacesImporterBootstrap;
private ImporterBootstrap userImporterBootstrap;
private DictionaryService dictionaryService;
public InvalidUserPersonAndGroupPatch()
{
}
public void setSpacesImporterBootstrap(ImporterBootstrap spacesImporterBootstrap)
{
this.spacesImporterBootstrap = spacesImporterBootstrap;
}
public void setUserImporterBootstrap(ImporterBootstrap userImporterBootstrap)
{
this.userImporterBootstrap = userImporterBootstrap;
}
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
@Override
protected String applyInternal() throws Exception
{
int users = deleteInvalid(ContentModel.PROP_USER_USERNAME, userImporterBootstrap.getStoreRef(), "USER_");
int people = deleteInvalid(ContentModel.PROP_USERNAME, spacesImporterBootstrap.getStoreRef(), "USER_");
int authorities = deleteInvalid(ContentModel.PROP_AUTHORITY_NAME, userImporterBootstrap.getStoreRef(), "GROUP_");
return I18NUtil.getMessage(MSG_SUCCESS, users, people, authorities);
}
private int deleteInvalid(QName property, StoreRef store, String prefix)
{
PropertyDefinition propDef = dictionaryService.getProperty(property);
if (propDef == null)
{
return 0;
}
ClassDefinition typeDef = propDef.getContainerClass();
String query;
if (typeDef.isAspect())
{
query = "ASPECT:\"" + typeDef.getName() + "\"";
}
else
{
query = "TYPE:\"" + typeDef.getName() + "\"";
}
List<ConstraintDefinition> conDefs = propDef.getConstraints();
SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery(query);
sp.addStore(store);
ResultSet rs = null;
int invalidCount = 0;
try
{
rs = searchService.query(sp);
for (ResultSetRow row : rs)
{
NodeRef nodeRef = row.getNodeRef();
boolean valid = true;
Serializable value = nodeService.getProperty(nodeRef, property);
String checkValue = null;
try
{
checkValue = DefaultTypeConverter.INSTANCE.convert(String.class, value);
}
catch (TypeConversionException e)
{
continue;
}
for (ConstraintDefinition con : conDefs)
{
try
{
con.getConstraint().evaluate(value);
}
catch (ConstraintException e)
{
valid = false;
}
}
if(!valid)
{
nodeService.setProperty(nodeRef, property, prefix+checkValue);
invalidCount++;
}
}
}
finally
{
if (rs != null)
{
rs.close();
}
}
return invalidCount;
}
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
/**
* The roles defined in permissionsDefinition.xml moved from <b>cm:folder</b> to <b>cm:cmobject</b>.
* This effects the data stored in the <b>permission</b> table.
* <p>
* JIRA: {@link http://www.alfresco.org/jira/browse/AR-344 AR-344}
*
* @author Derek Hulley
*/
public class PermissionDataPatch extends AbstractPermissionChangePatch
{
private static final String MSG_SUCCESS = "patch.updatePermissionData.result";
private static final QName TYPE_QNAME_OLD = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "folder");
private static final QName TYPE_QNAME_NEW = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "cmobject");
private static final String[] NAMES = new String[] {"Coordinator", "Contributor", "Editor", "Guest"};
@Override
protected String applyInternal() throws Exception
{
int updateCount = 0;
for (String permissionName : NAMES)
{
updateCount += super.renamePermission(
PermissionDataPatch.TYPE_QNAME_OLD,
permissionName,
PermissionDataPatch.TYPE_QNAME_NEW,
permissionName);
}
// build the result message
String msg = I18NUtil.getMessage(MSG_SUCCESS, updateCount);
// done
return msg;
}
}

View File

@@ -1,307 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ACPImportPackageHandler;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.view.ImporterService;
import org.alfresco.service.cmr.view.Location;
import org.alfresco.service.namespace.QName;
import org.springframework.context.MessageSource;
import org.springframework.core.io.ClassPathResource;
/**
* Ensures that the <b>RSS Templates</b> folder is present.
* <p>
* This uses the bootstrap importer to get the paths to look for. If not present,
* the required structures are created.
* <p>
* This class should be replaced with a more generic <code>ImporterPatch</code>
* that can do conditional importing into given locations.
* <p>
* JIRA: {@link http://www.alfresco.org/jira/browse/AR-342 AR-342}
*
* @author Kevin Roast
*/
public class RSSTemplatesFolderPatch extends AbstractPatch
{
private static final String MSG_EXISTS = "patch.rssTemplatesFolder.result.exists";
private static final String MSG_CREATED = "patch.rssTemplatesFolder.result.created";
public static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname";
public static final String PROPERTY_DICTIONARY_CHILDNAME = "spaces.dictionary.childname";
public static final String PROPERTY_RSS_FOLDER_CHILDNAME = "spaces.templates.rss.childname";
private static final String PROPERTY_RSS_FOLDER_NAME = "spaces.templates.rss.name";
private static final String PROPERTY_RSS_FOLDER_DESCRIPTION = "spaces.templates.rss.description";
private static final String PROPERTY_ICON = "space-icon-default";
private ImporterBootstrap importerBootstrap;
private ImporterService importerService;
private MessageSource messageSource;
private PermissionService permissionService;
protected NodeRef dictionaryNodeRef;
protected Properties configuration;
protected NodeRef rssFolderNodeRef;
private String rssTemplatesACP;
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{
this.importerBootstrap = importerBootstrap;
}
public void setImporterService(ImporterService importerService)
{
this.importerService = importerService;
}
public void setMessageSource(MessageSource messageSource)
{
this.messageSource = messageSource;
}
public void setRssTemplatesACP(String rssTemplatesACP)
{
this.rssTemplatesACP = rssTemplatesACP;
}
/**
* Ensure that required common properties have been set
*/
protected void checkCommonProperties() throws Exception
{
checkPropertyNotNull(importerBootstrap, "importerBootstrap");
checkPropertyNotNull(importerService, "importerService");
checkPropertyNotNull(messageSource, "messageSource");
if (namespaceService == null)
{
throw new PatchException("'namespaceService' property has not been set");
}
else if (searchService == null)
{
throw new PatchException("'searchService' property has not been set");
}
else if (nodeService == null)
{
throw new PatchException("'nodeService' property has not been set");
}
checkPropertyNotNull(rssTemplatesACP, "rssTemplatesACP");
}
/**
* Extracts pertinent references and properties that are common to execution
* of this and derived patches.
*/
protected void setUp() throws Exception
{
// get the node store that we must work against
StoreRef storeRef = importerBootstrap.getStoreRef();
if (storeRef == null)
{
throw new PatchException("Bootstrap store has not been set");
}
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
this.configuration = importerBootstrap.getConfiguration();
// get the association names that form the path
String companyHomeChildName = configuration.getProperty(PROPERTY_COMPANY_HOME_CHILDNAME);
if (companyHomeChildName == null || companyHomeChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_COMPANY_HOME_CHILDNAME + "' is not present");
}
String dictionaryChildName = configuration.getProperty(PROPERTY_DICTIONARY_CHILDNAME);
if (dictionaryChildName == null || dictionaryChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_DICTIONARY_CHILDNAME + "' is not present");
}
String rssChildName = configuration.getProperty(PROPERTY_RSS_FOLDER_CHILDNAME);
if (rssChildName == null || rssChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_RSS_FOLDER_CHILDNAME + "' is not present");
}
// build the search string to get the dictionary node
StringBuilder sb = new StringBuilder(256);
sb.append("/").append(companyHomeChildName)
.append("/").append(dictionaryChildName);
String xpath = sb.toString();
// get the dictionary node
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false);
if (nodeRefs.size() == 0)
{
throw new PatchException("XPath didn't return any results: \n" +
" root: " + storeRootNodeRef + "\n" +
" xpath: " + xpath);
}
else if (nodeRefs.size() > 1)
{
throw new PatchException("XPath returned too many results: \n" +
" root: " + storeRootNodeRef + "\n" +
" xpath: " + xpath + "\n" +
" results: " + nodeRefs);
}
this.dictionaryNodeRef = nodeRefs.get(0);
// Now we have the optional part - check for the existence of the RSS Templates folder
xpath = rssChildName;
nodeRefs = searchService.selectNodes(dictionaryNodeRef, xpath, null, namespaceService, false);
if (nodeRefs.size() > 1)
{
throw new PatchException("XPath returned too many results: \n" +
" dictionary node: " + dictionaryNodeRef + "\n" +
" xpath: " + xpath + "\n" +
" results: " + nodeRefs);
}
else if (nodeRefs.size() == 0)
{
// the node does not exist
this.rssFolderNodeRef = null;
}
else
{
// we have the RSS Templates folder noderef
this.rssFolderNodeRef = nodeRefs.get(0);
}
}
@Override
protected String applyInternal() throws Exception
{
// properties must be set
checkCommonProperties();
if (messageSource == null)
{
throw new PatchException("'messageSource' property has not been set");
}
// get useful values
setUp();
String msg = null;
if (rssFolderNodeRef == null)
{
// create it
createFolder();
// apply Guest permission to the folder
permissionService.setPermission(
rssFolderNodeRef,
AuthenticationUtil.getGuestUserName(),
PermissionService.CONSUMER,
true);
// import the content
importContent();
msg = I18NUtil.getMessage(MSG_CREATED, rssFolderNodeRef);
}
else
{
// it already exists
permissionService.setPermission(
rssFolderNodeRef,
AuthenticationUtil.getGuestUserName(),
PermissionService.CONSUMER,
true);
msg = I18NUtil.getMessage(MSG_EXISTS, rssFolderNodeRef);
}
// done
return msg;
}
private void createFolder()
{
// get required properties
String rssChildName = configuration.getProperty(PROPERTY_RSS_FOLDER_CHILDNAME);
if (rssChildName == null)
{
throw new PatchException("Bootstrap property '" + PROPERTY_RSS_FOLDER_CHILDNAME + "' is not present");
}
String folderName = messageSource.getMessage(
PROPERTY_RSS_FOLDER_NAME,
null,
I18NUtil.getLocale());
if (folderName == null || folderName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_RSS_FOLDER_NAME + "' is not present");
}
String folderDescription = messageSource.getMessage(
PROPERTY_RSS_FOLDER_DESCRIPTION,
null,
I18NUtil.getLocale());
if (folderDescription == null || folderDescription.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_RSS_FOLDER_DESCRIPTION + "' is not present");
}
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(7);
properties.put(ContentModel.PROP_NAME, folderName);
properties.put(ContentModel.PROP_TITLE, folderName);
properties.put(ContentModel.PROP_DESCRIPTION, folderDescription);
properties.put(ApplicationModel.PROP_ICON, PROPERTY_ICON);
// create the node
ChildAssociationRef childAssocRef = nodeService.createNode(
dictionaryNodeRef,
ContentModel.ASSOC_CONTAINS,
QName.resolveToQName(namespaceService, rssChildName),
ContentModel.TYPE_FOLDER,
properties);
this.rssFolderNodeRef = childAssocRef.getChildRef();
// finally add the required aspects
nodeService.addAspect(rssFolderNodeRef, ApplicationModel.ASPECT_UIFACETS, null);
}
private void importContent() throws IOException
{
// import the content
ClassPathResource acpResource = new ClassPathResource(this.rssTemplatesACP);
ACPImportPackageHandler acpHandler = new ACPImportPackageHandler(acpResource.getFile(), null);
Location importLocation = new Location(this.rssFolderNodeRef);
importerService.importView(acpHandler, importLocation, null, null);
}
}

View File

@@ -1,254 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName;
import org.springframework.context.MessageSource;
/**
* Ensures that the <b>savedsearches</b> folder is present.
* <p>
* This uses the bootstrap importer to get the paths to look for. If not present,
* the required structures are created.
* <p>
* This class should be replaced with a more generic <code>ImporterPatch</code>
* that can do conditional importing into given locations.
* <p>
* JIRA: {@link http://www.alfresco.org/jira/browse/AR-342 AR-342}
*
* @author Derek Hulley
*/
public class SavedSearchFolderPatch extends AbstractPatch
{
private static final String MSG_EXISTS = "patch.savedSearchesFolder.result.exists";
private static final String MSG_CREATED = "patch.savedSearchesFolder.result.created";
public static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname";
public static final String PROPERTY_DICTIONARY_CHILDNAME = "spaces.dictionary.childname";
public static final String PROPERTY_SAVED_SEARCHES_FOLDER_CHILDNAME = "spaces.savedsearches.childname";
private static final String PROPERTY_SAVED_SEARCHES_FOLDER_NAME = "spaces.savedsearches.name";
private static final String PROPERTY_SAVED_SEARCHES_FOLDER_DESCRIPTION = "spaces.savedsearches.description";
private static final String PROPERTY_ICON = "space-icon-default";
private ImporterBootstrap importerBootstrap;
private MessageSource messageSource;
protected NodeRef dictionaryNodeRef;
protected Properties configuration;
protected NodeRef savedSearchesFolderNodeRef;
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{
this.importerBootstrap = importerBootstrap;
}
public void setMessageSource(MessageSource messageSource)
{
this.messageSource = messageSource;
}
/**
* Ensure that required common properties have been set
*/
protected void checkCommonProperties() throws Exception
{
if (importerBootstrap == null)
{
throw new PatchException("'importerBootstrap' property has not been set");
}
else if (namespaceService == null)
{
throw new PatchException("'namespaceService' property has not been set");
}
else if (searchService == null)
{
throw new PatchException("'searchService' property has not been set");
}
else if (nodeService == null)
{
throw new PatchException("'nodeService' property has not been set");
}
}
/**
* Extracts pertinent references and properties that are common to execution
* of this and derived patches.
*/
protected void setUp() throws Exception
{
// get the node store that we must work against
StoreRef storeRef = importerBootstrap.getStoreRef();
if (storeRef == null)
{
throw new PatchException("Bootstrap store has not been set");
}
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
this.configuration = importerBootstrap.getConfiguration();
// get the association names that form the path
String companyHomeChildName = configuration.getProperty(PROPERTY_COMPANY_HOME_CHILDNAME);
if (companyHomeChildName == null || companyHomeChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_COMPANY_HOME_CHILDNAME + "' is not present");
}
String dictionaryChildName = configuration.getProperty(PROPERTY_DICTIONARY_CHILDNAME);
if (dictionaryChildName == null || dictionaryChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_DICTIONARY_CHILDNAME + "' is not present");
}
String savedSearchesChildName = configuration.getProperty(PROPERTY_SAVED_SEARCHES_FOLDER_CHILDNAME);
if (savedSearchesChildName == null || savedSearchesChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_SAVED_SEARCHES_FOLDER_CHILDNAME + "' is not present");
}
// build the search string to get the dictionary node
StringBuilder sb = new StringBuilder(512);
sb.append("/").append(companyHomeChildName)
.append("/").append(dictionaryChildName);
String xpath = sb.toString();
// get the dictionary node
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false);
if (nodeRefs.size() == 0)
{
throw new PatchException("XPath didn't return any results: \n" +
" root: " + storeRootNodeRef + "\n" +
" xpath: " + xpath);
}
else if (nodeRefs.size() > 1)
{
throw new PatchException("XPath returned too many results: \n" +
" root: " + storeRootNodeRef + "\n" +
" xpath: " + xpath + "\n" +
" results: " + nodeRefs);
}
this.dictionaryNodeRef = nodeRefs.get(0);
// Now we have the optional part. Check for the existence of the saved searches folder
xpath = savedSearchesChildName;
nodeRefs = searchService.selectNodes(dictionaryNodeRef, xpath, null, namespaceService, false);
if (nodeRefs.size() > 1)
{
throw new PatchException("XPath returned too many results: \n" +
" dictionary node: " + dictionaryNodeRef + "\n" +
" xpath: " + xpath + "\n" +
" results: " + nodeRefs);
}
else if (nodeRefs.size() == 0)
{
// the node does not exist
this.savedSearchesFolderNodeRef = null;
}
else
{
// we have the saved searches folder noderef
this.savedSearchesFolderNodeRef = nodeRefs.get(0);
}
}
@Override
protected String applyInternal() throws Exception
{
// properties must be set
checkCommonProperties();
if (messageSource == null)
{
throw new PatchException("'messageSource' property has not been set");
}
// get useful values
setUp();
String msg = null;
if (savedSearchesFolderNodeRef == null)
{
// create it
createFolder();
msg = I18NUtil.getMessage(MSG_CREATED, savedSearchesFolderNodeRef);
}
else
{
// it already exists
msg = I18NUtil.getMessage(MSG_EXISTS, savedSearchesFolderNodeRef);
}
// done
return msg;
}
private void createFolder()
{
// get required properties
String savedSearchesChildName = configuration.getProperty(PROPERTY_SAVED_SEARCHES_FOLDER_CHILDNAME);
if (savedSearchesChildName == null)
{
throw new PatchException("Bootstrap property '" + PROPERTY_SAVED_SEARCHES_FOLDER_CHILDNAME + "' is not present");
}
String savedSearchesName = messageSource.getMessage(
PROPERTY_SAVED_SEARCHES_FOLDER_NAME,
null,
I18NUtil.getLocale());
if (savedSearchesName == null || savedSearchesName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_SAVED_SEARCHES_FOLDER_NAME + "' is not present");
}
String savedSearchesDescription = messageSource.getMessage(
PROPERTY_SAVED_SEARCHES_FOLDER_DESCRIPTION,
null,
I18NUtil.getLocale());
if (savedSearchesDescription == null || savedSearchesDescription.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_SAVED_SEARCHES_FOLDER_DESCRIPTION + "' is not present");
}
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(7);
properties.put(ContentModel.PROP_NAME, savedSearchesName);
properties.put(ContentModel.PROP_TITLE, savedSearchesName);
properties.put(ContentModel.PROP_DESCRIPTION, savedSearchesDescription);
properties.put(ApplicationModel.PROP_ICON, PROPERTY_ICON);
// create the node
ChildAssociationRef childAssocRef = nodeService.createNode(
dictionaryNodeRef,
ContentModel.ASSOC_CONTAINS,
QName.resolveToQName(namespaceService, savedSearchesChildName),
ContentModel.TYPE_FOLDER,
properties);
savedSearchesFolderNodeRef = childAssocRef.getChildRef();
// add the required aspects
nodeService.addAspect(savedSearchesFolderNodeRef, ApplicationModel.ASPECT_UIFACETS, null);
// done
}
}

View File

@@ -1,77 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.security.PermissionService;
/**
* Grant <b>CONTRIBUTOR</b> role to <b>EVERYONE</b> in <b>savedsearches</b> folder.
* <p>
* This patch expects the folder to be present.
* <p>
* JIRA: {@link http://www.alfresco.org/jira/browse/AWC-487 AR-487}
*
* @see org.alfresco.repo.admin.patch.impl.SavedSearchFolderPatch
* @author Derek Hulley
*/
public class SavedSearchPermissionPatch extends SavedSearchFolderPatch
{
private static final String MSG_CREATED = "patch.savedSearchesPermission.result.applied";
private static final String ERR_NOT_FOUND = "patch.savedSearchesPermission.err.not_found";
private PermissionService permissionService;
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
@Override
protected String applyInternal() throws Exception
{
// properties must be set
checkCommonProperties();
if (permissionService == null)
{
throw new PatchException("'permissionService' property has not been set");
}
// get useful values
setUp();
if (savedSearchesFolderNodeRef == null)
{
// it doesn't exist
String msg = I18NUtil.getMessage(ERR_NOT_FOUND);
throw new PatchException(msg);
}
// apply permission
permissionService.setPermission(
savedSearchesFolderNodeRef,
PermissionService.ALL_AUTHORITIES,
PermissionService.CONTRIBUTOR,
true);
String msg = I18NUtil.getMessage(MSG_CREATED, savedSearchesFolderNodeRef);
// done
return msg;
}
}

View File

@@ -1,296 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ApplicationModel;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ACPImportPackageHandler;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.view.ImporterService;
import org.alfresco.service.cmr.view.Location;
import org.alfresco.service.namespace.QName;
import org.springframework.context.MessageSource;
import org.springframework.core.io.ClassPathResource;
/**
* Ensures that the <b>scripts</b> folder is present.
* <p>
* This uses the bootstrap importer to get the paths to look for. If not present,
* the required structures are created.
* <p>
* This class should be replaced with a more generic <code>ImporterPatch</code>
* that can do conditional importing into given locations.
* <p>
* JIRA: {@link http://www.alfresco.org/jira/browse/AR-342 AR-342}
*
* @author Kevin Roast
*/
public class ScriptsFolderPatch extends AbstractPatch
{
private static final String MSG_EXISTS = "patch.scriptsFolder.result.exists";
private static final String MSG_CREATED = "patch.scriptsFolder.result.created";
public static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname";
public static final String PROPERTY_DICTIONARY_CHILDNAME = "spaces.dictionary.childname";
public static final String PROPERTY_SCRIPTS_FOLDER_CHILDNAME = "spaces.scripts.childname";
private static final String PROPERTY_SCRIPTS_FOLDER_NAME = "spaces.scripts.name";
private static final String PROPERTY_SCRIPTS_FOLDER_DESCRIPTION = "spaces.scripts.description";
private static final String PROPERTY_ICON = "space-icon-default";
private ImporterBootstrap importerBootstrap;
private ImporterService importerService;
private MessageSource messageSource;
protected NodeRef dictionaryNodeRef;
protected Properties configuration;
protected NodeRef scriptsFolderNodeRef;
private String scriptsACP;
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{
this.importerBootstrap = importerBootstrap;
}
public void setImporterService(ImporterService importerService)
{
this.importerService = importerService;
}
public void setMessageSource(MessageSource messageSource)
{
this.messageSource = messageSource;
}
public void setScriptsACP(String scriptsACP)
{
this.scriptsACP = scriptsACP;
}
/**
* Ensure that required common properties have been set
*/
protected void checkCommonProperties() throws Exception
{
checkPropertyNotNull(importerBootstrap, "importerBootstrap");
checkPropertyNotNull(importerService, "importerService");
checkPropertyNotNull(messageSource, "messageSource");
if (namespaceService == null)
{
throw new PatchException("'namespaceService' property has not been set");
}
else if (searchService == null)
{
throw new PatchException("'searchService' property has not been set");
}
else if (nodeService == null)
{
throw new PatchException("'nodeService' property has not been set");
}
checkPropertyNotNull(scriptsACP, "scriptsACP");
}
/**
* Extracts pertinent references and properties that are common to execution
* of this and derived patches.
*/
protected void setUp() throws Exception
{
// get the node store that we must work against
StoreRef storeRef = importerBootstrap.getStoreRef();
if (storeRef == null)
{
throw new PatchException("Bootstrap store has not been set");
}
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
this.configuration = importerBootstrap.getConfiguration();
// get the association names that form the path
String companyHomeChildName = configuration.getProperty(PROPERTY_COMPANY_HOME_CHILDNAME);
if (companyHomeChildName == null || companyHomeChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_COMPANY_HOME_CHILDNAME + "' is not present");
}
String dictionaryChildName = configuration.getProperty(PROPERTY_DICTIONARY_CHILDNAME);
if (dictionaryChildName == null || dictionaryChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_DICTIONARY_CHILDNAME + "' is not present");
}
String scriptsChildName = configuration.getProperty(PROPERTY_SCRIPTS_FOLDER_CHILDNAME);
if (scriptsChildName == null || scriptsChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_SCRIPTS_FOLDER_CHILDNAME + "' is not present");
}
// build the search string to get the dictionary node
StringBuilder sb = new StringBuilder(256);
sb.append("/").append(companyHomeChildName)
.append("/").append(dictionaryChildName);
String xpath = sb.toString();
// get the dictionary node
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false);
if (nodeRefs.size() == 0)
{
throw new PatchException("XPath didn't return any results: \n" +
" root: " + storeRootNodeRef + "\n" +
" xpath: " + xpath);
}
else if (nodeRefs.size() > 1)
{
throw new PatchException("XPath returned too many results: \n" +
" root: " + storeRootNodeRef + "\n" +
" xpath: " + xpath + "\n" +
" results: " + nodeRefs);
}
this.dictionaryNodeRef = nodeRefs.get(0);
// Now we have the optional part. Check for the existence of the scripts folder
xpath = scriptsChildName;
nodeRefs = searchService.selectNodes(dictionaryNodeRef, xpath, null, namespaceService, false);
if (nodeRefs.size() > 1)
{
throw new PatchException("XPath returned too many results: \n" +
" dictionary node: " + dictionaryNodeRef + "\n" +
" xpath: " + xpath + "\n" +
" results: " + nodeRefs);
}
else if (nodeRefs.size() == 0)
{
// the node does not exist
this.scriptsFolderNodeRef = null;
}
else
{
// we have the scripts folder noderef
this.scriptsFolderNodeRef = nodeRefs.get(0);
}
}
@Override
protected String applyInternal() throws Exception
{
// properties must be set
checkCommonProperties();
if (messageSource == null)
{
throw new PatchException("'messageSource' property has not been set");
}
// get useful values
setUp();
String msg = null;
if (scriptsFolderNodeRef == null)
{
// create it
createFolder();
// import the content
RunAsWork<Object> importRunAs = new RunAsWork<Object>()
{
public Object doWork() throws Exception
{
importContent();
return null;
}
};
AuthenticationUtil.runAs(importRunAs, authenticationContext.getSystemUserName());
msg = I18NUtil.getMessage(MSG_CREATED, scriptsFolderNodeRef);
}
else
{
// it already exists
msg = I18NUtil.getMessage(MSG_EXISTS, scriptsFolderNodeRef);
}
// done
return msg;
}
private void createFolder()
{
// get required properties
String scriptsChildName = configuration.getProperty(PROPERTY_SCRIPTS_FOLDER_CHILDNAME);
if (scriptsChildName == null)
{
throw new PatchException("Bootstrap property '" + PROPERTY_SCRIPTS_FOLDER_CHILDNAME + "' is not present");
}
String folderName = messageSource.getMessage(
PROPERTY_SCRIPTS_FOLDER_NAME,
null,
I18NUtil.getLocale());
if (folderName == null || folderName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_SCRIPTS_FOLDER_NAME + "' is not present");
}
String folderDescription = messageSource.getMessage(
PROPERTY_SCRIPTS_FOLDER_DESCRIPTION,
null,
I18NUtil.getLocale());
if (folderDescription == null || folderDescription.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_SCRIPTS_FOLDER_DESCRIPTION + "' is not present");
}
Map<QName, Serializable> properties = new HashMap<QName, Serializable>(7);
properties.put(ContentModel.PROP_NAME, folderName);
properties.put(ContentModel.PROP_TITLE, folderName);
properties.put(ContentModel.PROP_DESCRIPTION, folderDescription);
properties.put(ApplicationModel.PROP_ICON, PROPERTY_ICON);
// create the node
ChildAssociationRef childAssocRef = nodeService.createNode(
dictionaryNodeRef,
ContentModel.ASSOC_CONTAINS,
QName.resolveToQName(namespaceService, scriptsChildName),
ContentModel.TYPE_FOLDER,
properties);
scriptsFolderNodeRef = childAssocRef.getChildRef();
// finally add the required aspects
nodeService.addAspect(scriptsFolderNodeRef, ApplicationModel.ASPECT_UIFACETS, null);
}
private void importContent() throws IOException
{
// import the content
ClassPathResource acpResource = new ClassPathResource(this.scriptsACP);
ACPImportPackageHandler acpHandler = new ACPImportPackageHandler(acpResource.getFile(), null);
Location importLocation = new Location(this.scriptsFolderNodeRef);
importerService.importView(acpHandler, importLocation, null, null);
}
}

View File

@@ -1,73 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PermissionService;
/**
* Change Spaces Root Node permission from Guest to Read
*
* Guest (now Consumer) permission is not valid for sys:store_root type.
*/
public class SpacesRootPermissionPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.spacesRootPermission.result";
private ImporterBootstrap spacesBootstrap;
private NodeService nodeService;
private PermissionService permissionService;
public SpacesRootPermissionPatch()
{
super();
}
public void setSpacesBootstrap(ImporterBootstrap spacesBootstrap)
{
this.spacesBootstrap = spacesBootstrap;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setPermissionService(PermissionService permissionService)
{
this.permissionService = permissionService;
}
@Override
protected String applyInternal() throws Exception
{
NodeRef rootNodeRef = nodeService.getRootNode(spacesBootstrap.getStoreRef());
permissionService.deletePermission(rootNodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.CONSUMER);
permissionService.setPermission(rootNodeRef, PermissionService.ALL_AUTHORITIES, PermissionService.READ, true);
return I18NUtil.getMessage(MSG_SUCCESS);
}
}

View File

@@ -1,139 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.InputStream;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.ConfigurationChecker;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
/**
* Ensures that the required content snippet is added to the system descriptor
* to enable robust checking of the content store by the configuration checker.
*
* @author Derek Hulley
*/
public class SystemDescriptorContentPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.systemDescriptorContent.result";
private static final String ERR_NO_VERSION_PROPERTIES = "patch.systemDescriptorContent.err.no_version_properties";
private static final String ERR_NO_SYSTEM_DESCRIPTOR = "patch.systemDescriptorContent.err.no_descriptor";
private ConfigurationChecker configurationChecker;
private ContentService contentService;
public SystemDescriptorContentPatch()
{
}
public void setConfigurationChecker(ConfigurationChecker configurationChecker)
{
this.configurationChecker = configurationChecker;
}
public void setContentService(ContentService contentService)
{
this.contentService = contentService;
}
@Override
protected void checkProperties()
{
super.checkProperties();
checkPropertyNotNull(configurationChecker, "configurationChecker");
checkPropertyNotNull(contentService, "contentService");
}
@Override
protected String applyInternal() throws Exception
{
InputStream is = null;
try
{
// get the version.properties
ResourceLoader resourceLoader = new DefaultResourceLoader();
Resource resource = resourceLoader.getResource("classpath:alfresco/version.properties");
if (!resource.exists())
{
throw new PatchException(ERR_NO_VERSION_PROPERTIES);
}
is = resource.getInputStream();
// get the system descriptor
NodeRef descriptorNodeRef = configurationChecker.getSystemDescriptor();
if (descriptorNodeRef == null)
{
throw new PatchException(ERR_NO_SYSTEM_DESCRIPTOR);
}
// get the writer
ContentWriter writer = contentService.getWriter(descriptorNodeRef, ContentModel.PROP_SYS_VERSION_PROPERTIES, true);
// upload
writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN);
writer.setEncoding("UTF8");
writer.putContent(is);
// done
String msg = I18NUtil.getMessage(MSG_SUCCESS);
return msg;
}
finally
{
if (is != null)
{
try { is.close(); } catch (Throwable e) {}
}
}
}
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.workflow.WorkflowPackageImpl;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Ensures the system folder for Workflows is created.
*
* @author davidc
*/
public class SystemWorkflowFolderPatch extends AbstractPatch
{
private static final String MSG_CREATED = "patch.systemWorkflowFolder.result.created";
private WorkflowPackageImpl workflowPackageImpl;
public void setWorkflowPackageImpl(WorkflowPackageImpl workflowPackageImpl)
{
this.workflowPackageImpl = workflowPackageImpl;
}
/* (non-Javadoc)
* @see org.alfresco.repo.admin.patch.AbstractPatch#applyInternal()
*/
@Override
protected String applyInternal() throws Exception
{
NodeRef systemContainer = workflowPackageImpl.createSystemWorkflowContainer();
return I18NUtil.getMessage(MSG_CREATED, systemContainer);
}
}

View File

@@ -1,94 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
public class TopLevelGroupParentChildAssociationTypePatch extends AbstractPatch
{
private static final String MSG_RESULT = "patch.topLevelGroupParentChildAssociationTypePatch.result";
private static final String ERR_SYS_PATH_NOT_FOUND = "patch.topLevelGroupParentChildAssociationTypePatch.err.sys_path_not_found";
private static final String ERR_AUTH_PATH_NOT_FOUND = "patch.topLevelGroupParentChildAssociationTypePatch.err.auth_path_not_found";
public TopLevelGroupParentChildAssociationTypePatch()
{
super();
}
@Override
protected String applyInternal() throws Exception
{
NodeRef nodeRef = getAuthorityContainer();
List<ChildAssociationRef> results = nodeService.getChildAssocs(nodeRef);
for (ChildAssociationRef car : results)
{
if (!car.getTypeQName().equals(ContentModel.ASSOC_CHILDREN))
{
nodeService.moveNode(
car.getChildRef(),
car.getParentRef(),
ContentModel.ASSOC_CHILDREN,
car.getQName());
}
}
return I18NUtil.getMessage(MSG_RESULT, results.size());
}
private NodeRef getAuthorityContainer()
{
QName qnameAssocSystem = QName.createQName("sys", "system", namespaceService);
QName qnameAssocAuthorities = QName.createQName("sys", "authorities", this.namespaceService);
NodeRef rootNodeRef = nodeService.getRootNode(new StoreRef("user", "alfrescoUserStore"));
List<ChildAssociationRef> results = nodeService.getChildAssocs(rootNodeRef, RegexQNamePattern.MATCH_ALL,
qnameAssocSystem);
NodeRef sysNodeRef = null;
if (results.size() == 0)
{
throw new AlfrescoRuntimeException(ERR_SYS_PATH_NOT_FOUND, new Object[] {qnameAssocSystem});
}
else
{
sysNodeRef = results.get(0).getChildRef();
}
results = nodeService.getChildAssocs(sysNodeRef, RegexQNamePattern.MATCH_ALL, qnameAssocAuthorities);
NodeRef authNodeRef = null;
if (results.size() == 0)
{
throw new AlfrescoRuntimeException(ERR_AUTH_PATH_NOT_FOUND, new Object[] {qnameAssocAuthorities});
}
else
{
authNodeRef = results.get(0).getChildRef();
}
return authNodeRef;
}
}

View File

@@ -1,150 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ApplicationModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ACPImportPackageHandler;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.admin.PatchException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.view.ImporterService;
import org.alfresco.service.cmr.view.Location;
import org.springframework.context.MessageSource;
import org.springframework.core.io.ClassPathResource;
/**
* Removes the <b>uifacets</b> aspect incorrectly applied to the default set of Presentation
* Templates loaded during bootstrap. For new installs the bootstrap XML file has been modified
* to no longer apply the aspect.
* <p>
* This uses the bootstrap importer to get the paths to look for.
*
* @author Kevin Roast
*/
public class UIFacetsAspectRemovalPatch extends AbstractPatch
{
private static final String MSG_UPDATED = "patch.uifacetsAspectRemovalPatch.updated";
public static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname";
public static final String PROPERTY_DICTIONARY_CHILDNAME = "spaces.dictionary.childname";
public static final String PROPERTY_TEMPLATES_CHILDNAME = "spaces.templates.content.childname";
private ImporterBootstrap importerBootstrap;
private MessageSource messageSource;
protected Properties configuration;
protected NodeRef templatesNodeRef;
public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
{
this.importerBootstrap = importerBootstrap;
}
public void setMessageSource(MessageSource messageSource)
{
this.messageSource = messageSource;
}
/**
* Ensure that required properties have been set
*/
protected void checkRequiredProperties() throws Exception
{
checkPropertyNotNull(importerBootstrap, "importerBootstrap");
checkPropertyNotNull(messageSource, "messageSource");
}
/**
* Extracts pertinent references and properties that are common to execution
* of this and derived patches.
*
* @return the number of updated template files
*/
protected int removeAspectFromTemplates() throws Exception
{
// get the node store that we must work against
StoreRef storeRef = importerBootstrap.getStoreRef();
if (storeRef == null)
{
throw new PatchException("Bootstrap store has not been set");
}
NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
this.configuration = importerBootstrap.getConfiguration();
// get the association names that form the path
String companyHomeChildName = configuration.getProperty(PROPERTY_COMPANY_HOME_CHILDNAME);
if (companyHomeChildName == null || companyHomeChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_COMPANY_HOME_CHILDNAME + "' is not present");
}
String dictionaryChildName = configuration.getProperty(PROPERTY_DICTIONARY_CHILDNAME);
if (dictionaryChildName == null || dictionaryChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_DICTIONARY_CHILDNAME + "' is not present");
}
String templatesChildName = configuration.getProperty(PROPERTY_TEMPLATES_CHILDNAME);
if (templatesChildName == null || templatesChildName.length() == 0)
{
throw new PatchException("Bootstrap property '" + PROPERTY_TEMPLATES_CHILDNAME + "' is not present");
}
// build the search string to get the email templates node
StringBuilder sb = new StringBuilder(128);
sb.append("/").append(companyHomeChildName)
.append("/").append(dictionaryChildName)
.append("/").append(templatesChildName)
.append("//*[subtypeOf('cm:content')]");
String xpath = sb.toString();
// get the template content nodes
int updated = 0;
List<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, xpath, null, namespaceService, false);
for (NodeRef ref : nodeRefs)
{
// if the content has the uifacets aspect, then remove it and meaningless icon reference
if (nodeService.hasAspect(ref, ApplicationModel.ASPECT_UIFACETS))
{
nodeService.removeAspect(ref, ApplicationModel.ASPECT_UIFACETS);
nodeService.setProperty(ref, ApplicationModel.PROP_ICON, null);
updated++;
}
}
return updated;
}
@Override
protected String applyInternal() throws Exception
{
// common properties must be set before we can continue
checkRequiredProperties();
int updated = removeAspectFromTemplates();
// output a message to describe the result
return I18NUtil.getMessage(MSG_UPDATED, updated);
}
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ContentModel;
/**
* The permission 'Guest' has been renamed to 'Consumer'.
*
* @author David Caruana
* @author Derek Hulley
*/
public class UpdateGuestPermissionPatch extends AbstractPermissionChangePatch
{
private static final String MSG_SUCCESS = "patch.updateGuestPermission.result";
@Override
protected String applyInternal() throws Exception
{
int updateCount = super.renamePermission(ContentModel.TYPE_CMOBJECT, "Guest", ContentModel.TYPE_CMOBJECT, "Consumer");
// build the result message
String msg = I18NUtil.getMessage(MSG_SUCCESS, updateCount);
// done
return msg;
}
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.search.Indexer;
import org.alfresco.repo.search.IndexerAndSearcher;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
/**
* Patch usr:user and cm:person objects so that the user name properties are in the
* index in untokenized form. If not authentication may fail in mixed language use.
*
* @author andyh
*
*/
public class UserAndPersonTokenisationPatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.userAndPersonUserNamesAsIdentifiers.result";
private ImporterBootstrap spacesImporterBootstrap;
private ImporterBootstrap userImporterBootstrap;
private IndexerAndSearcher indexerAndSearcher;
public UserAndPersonTokenisationPatch()
{
}
public void setSpacesImporterBootstrap(ImporterBootstrap spacesImporterBootstrap)
{
this.spacesImporterBootstrap = spacesImporterBootstrap;
}
public void setUserImporterBootstrap(ImporterBootstrap userImporterBootstrap)
{
this.userImporterBootstrap = userImporterBootstrap;
}
public void setIndexerAndSearcher(IndexerAndSearcher indexerAndSearcher)
{
this.indexerAndSearcher = indexerAndSearcher;
}
@Override
protected String applyInternal() throws Exception
{
reindex("TYPE:\"usr:user\"", userImporterBootstrap.getStoreRef());
reindex("TYPE:\"cm:person\"", spacesImporterBootstrap.getStoreRef());
return I18NUtil.getMessage(MSG_SUCCESS);
}
private void reindex(String query, StoreRef store)
{
SearchParameters sp = new SearchParameters();
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
sp.setQuery(query);
sp.addStore(store);
ResultSet rs = null;
try
{
rs = searchService.query(sp);
for(ResultSetRow row : rs)
{
Indexer indexer = indexerAndSearcher.getIndexer(row.getNodeRef().getStoreRef());
indexer.updateNode(row.getNodeRef());
}
}
finally
{
if(rs != null)
{
rs.close();
}
}
}
}

View File

@@ -1,83 +0,0 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
package org.alfresco.repo.admin.patch.impl;
import java.util.List;
import org.springframework.extensions.surf.util.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.version.VersionModel;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.version.VersionService;
import org.alfresco.service.namespace.QName;
public class VersionHistoryPerformancePatch extends AbstractPatch
{
private static final String MSG_SUCCESS = "patch.versionHistoryPerformance.result";
private VersionService versionService;
public void setVersionService(VersionService versionService)
{
this.versionService = versionService;
}
@Override
protected String applyInternal() throws Exception
{
// Set the aspect on the root node of the version store
StoreRef versionStoreRef = this.versionService.getVersionStoreReference();
NodeRef rootNodeRef = this.nodeService.getRootNode(versionStoreRef);
this.nodeService.addAspect(rootNodeRef, VersionModel.ASPECT_VERSION_STORE_ROOT, null);
List<ChildAssociationRef> assocs = this.nodeService.getChildAssocs(rootNodeRef);
int updateCount = 0;
for(ChildAssociationRef childAssocRef : assocs)
{
NodeRef nodeRef = childAssocRef.getChildRef();
if (VersionModel.TYPE_QNAME_VERSION_HISTORY.equals(this.nodeService.getType(nodeRef)) == true)
{
// Get the id
String versionedNodeId = (String)this.nodeService.getProperty(nodeRef, VersionModel.PROP_QNAME_VERSIONED_NODE_ID);
if (versionedNodeId != null)
{
// Set the cm:name
this.nodeService.setProperty(nodeRef, ContentModel.PROP_NAME, versionedNodeId);
// Move the node
this.nodeService.moveNode( nodeRef,
rootNodeRef,
VersionModel.CHILD_QNAME_VERSION_HISTORIES,
QName.createQName(VersionModel.NAMESPACE_URI, versionedNodeId));
}
updateCount++;
}
}
// Build the result message
return I18NUtil.getMessage(MSG_SUCCESS, updateCount);
}
}

View File

@@ -39,18 +39,27 @@ public abstract class AbstractControlDAOImpl implements ControlDAO
/** /**
* @return Returns <tt>null</tt> by default i.e. not supported * @return Returns <tt>null</tt> by default i.e. not supported
*/ */
@Override
public Savepoint createSavepoint(String savepoint) public Savepoint createSavepoint(String savepoint)
{ {
return null; return null;
} }
/** No-op */ /** No-op */
@Override
public void rollbackToSavepoint(Savepoint savepoint) public void rollbackToSavepoint(Savepoint savepoint)
{ {
} }
/** No-op */ /** No-op */
@Override
public void releaseSavepoint(Savepoint savepoint) public void releaseSavepoint(Savepoint savepoint)
{ {
} }
@Override
public int setTransactionIsolationLevel(int isolationLevel)
{
throw new UnsupportedOperationException("Method not implemented by the DAO");
}
} }

View File

@@ -96,4 +96,16 @@ public interface ControlDAO
* @see #createSavepoint(String) * @see #createSavepoint(String)
*/ */
public void releaseSavepoint(Savepoint savepoint); public void releaseSavepoint(Savepoint savepoint);
/**
* Change the current transaction isolation level.
* <p/>
* <b>Note:</b> The isolation level should not - and for some DBs, cannot - be changed
* except at the very start of the transaction
*
* @param isolationLevel the transaction isolation level
* @return Returns the previously-set isolation
* @throws IllegalStateException if the isolation level is invalid or cannot be changed
*/
public int setTransactionIsolationLevel(int isolationLevel);
} }

View File

@@ -145,4 +145,28 @@ public class ControlDAOImpl extends AbstractControlDAOImpl
} }
} }
} }
@Override
public int setTransactionIsolationLevel(int isolationLevel)
{
Connection connection = DataSourceUtils.getConnection(template.getDataSource());
if (connection == null)
{
throw new NullPointerException("There is no current connection");
}
try
{
if (!connection.getMetaData().supportsTransactionIsolationLevel(isolationLevel))
{
throw new IllegalStateException("Transaction isolation level not supported: " + isolationLevel);
}
int isolationLevelWas = connection.getTransactionIsolation();
connection.setTransactionIsolation(isolationLevel);
return isolationLevelWas;
}
catch (SQLException e)
{
throw new IllegalStateException("Failed to set transaction isolation level: " + isolationLevel, e);
}
}
} }

View File

@@ -57,15 +57,7 @@ public abstract class AbstractPatchDAOImpl implements PatchDAO, BatchingDAO
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public boolean supportsProgressTracking() public long getAVMNodesCountWhereNewInStore()
{
return supportsProgressTrackingImpl();
}
/**
* {@inheritDoc}
*/
public Long getAVMNodesCountWhereNewInStore()
{ {
return getAVMNodeEntitiesCountWhereNewInStore(); return getAVMNodeEntitiesCountWhereNewInStore();
} }
@@ -95,15 +87,14 @@ public abstract class AbstractPatchDAOImpl implements PatchDAO, BatchingDAO
return updateAVMNodeEntitiesSetAcl(aclId, nodeIds); return updateAVMNodeEntitiesSetAcl(aclId, nodeIds);
} }
protected abstract boolean supportsProgressTrackingImpl(); protected abstract long getAVMNodeEntitiesCountWhereNewInStore();
protected abstract Long getAVMNodeEntitiesCountWhereNewInStore();
protected abstract List<AVMNodeEntity> getAVMNodeEntitiesWithEmptyGUID(int maxResults); protected abstract List<AVMNodeEntity> getAVMNodeEntitiesWithEmptyGUID(int maxResults);
protected abstract List<AVMNodeEntity> getNullVersionLayeredDirectoryNodeEntities(int maxResults); protected abstract List<AVMNodeEntity> getNullVersionLayeredDirectoryNodeEntities(int maxResults);
protected abstract List<AVMNodeEntity> getNullVersionLayeredFileNodeEntities(int maxResults); protected abstract List<AVMNodeEntity> getNullVersionLayeredFileNodeEntities(int maxResults);
protected abstract int updateAVMNodeEntitiesNullifyAcl(List<Long> nodeIds); protected abstract int updateAVMNodeEntitiesNullifyAcl(List<Long> nodeIds);
protected abstract int updateAVMNodeEntitiesSetAcl(long aclId, List<Long> nodeIds); protected abstract int updateAVMNodeEntitiesSetAcl(long aclId, List<Long> nodeIds);
public Long getMaxAclId() public long getMaxAclId()
{ {
return getMaxAclEntityId(); return getMaxAclEntityId();
} }
@@ -225,7 +216,7 @@ public abstract class AbstractPatchDAOImpl implements PatchDAO, BatchingDAO
Long localeId, Long localeId,
Long longValue); Long longValue);
protected abstract Long getMaxAclEntityId(); protected abstract long getMaxAclEntityId();
protected abstract long getDmNodeEntitiesCount(); protected abstract long getDmNodeEntitiesCount();
protected abstract long getDmNodeEntitiesCountWithNewACLs(Long above); protected abstract long getDmNodeEntitiesCountWithNewACLs(Long above);
protected abstract List<Long> selectAllAclEntityIds(); protected abstract List<Long> selectAllAclEntityIds();

View File

@@ -40,16 +40,9 @@ import com.ibatis.sqlmap.client.event.RowHandler;
*/ */
public interface PatchDAO public interface PatchDAO
{ {
/**
* Does the underlying connection support isolation level 1 (dirty read)
*
* @return true if we can do a dirty db read and so track changes (Oracle can not)
*/
public boolean supportsProgressTracking();
// AVM-related // AVM-related
public Long getAVMNodesCountWhereNewInStore(); public long getAVMNodesCountWhereNewInStore();
public List<AVMNodeEntity> getEmptyGUIDS(int count); public List<AVMNodeEntity> getEmptyGUIDS(int count);
@@ -57,7 +50,7 @@ public interface PatchDAO
public List<AVMNodeEntity> getNullVersionLayeredFiles(int count); public List<AVMNodeEntity> getNullVersionLayeredFiles(int count);
public Long getMaxAvmNodeID(); public long getMaxAvmNodeID();
public List<Long> getAvmNodesWithOldContentProperties(Long minNodeId, Long maxNodeId); public List<Long> getAvmNodesWithOldContentProperties(Long minNodeId, Long maxNodeId);
@@ -67,7 +60,7 @@ public interface PatchDAO
// DM-related // DM-related
public Long getMaxAdmNodeID(); public long getMaxAdmNodeID();
/** /**
* Migrates DM content properties from the old V3.1 format (String-based {@link ContentData#toString()}) * Migrates DM content properties from the old V3.1 format (String-based {@link ContentData#toString()})
@@ -111,7 +104,7 @@ public interface PatchDAO
* *
* @return - max acl id * @return - max acl id
*/ */
public Long getMaxAclId(); public long getMaxAclId();
/** /**
* How many DM nodes are there? * How many DM nodes are there?

View File

@@ -18,7 +18,6 @@
*/ */
package org.alfresco.repo.domain.patch.ibatis; package org.alfresco.repo.domain.patch.ibatis;
import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -26,7 +25,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.ibatis.IdsEntity; import org.alfresco.ibatis.IdsEntity;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.domain.CrcHelper; import org.alfresco.repo.domain.CrcHelper;
@@ -41,7 +39,6 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.orm.ibatis.SqlMapClientTemplate; import org.springframework.orm.ibatis.SqlMapClientTemplate;
import com.ibatis.sqlmap.client.SqlMapSession;
import com.ibatis.sqlmap.client.event.RowHandler; import com.ibatis.sqlmap.client.event.RowHandler;
import com.ibatis.sqlmap.engine.execution.SqlExecutor; import com.ibatis.sqlmap.engine.execution.SqlExecutor;
@@ -65,8 +62,11 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
private static final String SELECT_ADM_OLD_CONTENT_PROPERTIES = "alfresco.patch.select_admOldContentProperties"; private static final String SELECT_ADM_OLD_CONTENT_PROPERTIES = "alfresco.patch.select_admOldContentProperties";
private static final String SELECT_USERS_WITHOUT_USAGE_PROP = "alfresco.usage.select_GetUsersWithoutUsageProp"; private static final String SELECT_USERS_WITHOUT_USAGE_PROP = "alfresco.usage.select_GetUsersWithoutUsageProp";
private static final String SELECT_AUTHORITIES_AND_CRC = "alfresco.patch.select_authoritiesAndCrc"; private static final String SELECT_AUTHORITIES_AND_CRC = "alfresco.patch.select_authoritiesAndCrc";
private static final String SELECT_PERMISSIONS_ALL_ACL_IDS = "alfresco.permissions.select_AllAclIds"; private static final String SELECT_PERMISSIONS_ALL_ACL_IDS = "alfresco.patch.select_AllAclIds";
private static final String SELECT_PERMISSIONS_USED_ACL_IDS = "alfresco.permissions.select_UsedAclIds"; private static final String SELECT_PERMISSIONS_USED_ACL_IDS = "alfresco.patch.select_UsedAclIds";
private static final String SELECT_PERMISSIONS_MAX_ACL_ID = "alfresco.patch.select_MaxAclId";
private static final String SELECT_PERMISSIONS_DM_NODE_COUNT = "alfresco.patch.select_DmNodeCount";
private static final String SELECT_PERMISSIONS_DM_NODE_COUNT_WITH_NEW_ACLS = "alfresco.patch.select_DmNodeCountWherePermissionsHaveChanged";
private static final String SELECT_CHILD_ASSOCS_COUNT = "alfresco.patch.select_allChildAssocsCount"; private static final String SELECT_CHILD_ASSOCS_COUNT = "alfresco.patch.select_allChildAssocsCount";
private static final String SELECT_CHILD_ASSOCS_FOR_CRCS = "alfresco.patch.select_allChildAssocsForCrcs"; private static final String SELECT_CHILD_ASSOCS_FOR_CRCS = "alfresco.patch.select_allChildAssocsForCrcs";
private static final String SELECT_NODES_BY_TYPE_AND_NAME_PATTERN = "alfresco.patch.select_nodesByTypeAndNamePattern"; private static final String SELECT_NODES_BY_TYPE_AND_NAME_PATTERN = "alfresco.patch.select_nodesByTypeAndNamePattern";
@@ -77,10 +77,6 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
private static final String UPDATE_AVM_NODE_LIST_SET_ACL = "alfresco.avm.update_AVMNodeList_setAcl"; private static final String UPDATE_AVM_NODE_LIST_SET_ACL = "alfresco.avm.update_AVMNodeList_setAcl";
private static final String UPDATE_CHILD_ASSOC_CRC = "alfresco.patch.update_childAssocCrc"; private static final String UPDATE_CHILD_ASSOC_CRC = "alfresco.patch.update_childAssocCrc";
private static final String SELECT_PERMISSIONS_MAX_ACL_ID = "alfresco.permissions.select_MaxAclId";
private static final String SELECT_PERMISSIONS_DM_NODE_COUNT = "alfresco.permissions.select_DmNodeCount";
private static final String SELECT_PERMISSIONS_DM_NODE_COUNT_WITH_NEW_ACLS = "alfresco.permissions.select_DmNodeCountWherePermissionsHaveChanged";
private static final String DELETE_PERMISSIONS_UNUSED_ACES = "alfresco.permissions.delete_UnusedAces"; private static final String DELETE_PERMISSIONS_UNUSED_ACES = "alfresco.permissions.delete_UnusedAces";
private static final String DELETE_PERMISSIONS_ACL_LIST = "alfresco.permissions.delete_AclList"; private static final String DELETE_PERMISSIONS_ACL_LIST = "alfresco.permissions.delete_AclList";
private static final String DELETE_PERMISSIONS_ACL_MEMBERS_FOR_ACL_LIST = "alfresco.permissions.delete_AclMembersForAclList"; private static final String DELETE_PERMISSIONS_ACL_MEMBERS_FOR_ACL_LIST = "alfresco.permissions.delete_AclMembersForAclList";
@@ -134,22 +130,10 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
} }
@Override @Override
protected boolean supportsProgressTrackingImpl() protected long getAVMNodeEntitiesCountWhereNewInStore()
{ {
try Long count = (Long) template.queryForObject(SELECT_AVM_NODE_ENTITIES_COUNT_WHERE_NEW_IN_STORE);
{ return count == null ? 0L : count;
return template.getSqlMapClient().getCurrentConnection().getMetaData().supportsTransactionIsolationLevel(1);
}
catch (SQLException e)
{
return false;
}
}
@Override
protected Long getAVMNodeEntitiesCountWhereNewInStore()
{
return (Long) template.queryForObject(SELECT_AVM_NODE_ENTITIES_COUNT_WHERE_NEW_IN_STORE);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -188,9 +172,10 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
return (List<AVMNodeEntity>) template.queryForList(SELECT_AVM_LF_NODE_ENTITIES_NULL_VERSION, 0, maxResults); return (List<AVMNodeEntity>) template.queryForList(SELECT_AVM_LF_NODE_ENTITIES_NULL_VERSION, 0, maxResults);
} }
public Long getMaxAvmNodeID() public long getMaxAvmNodeID()
{ {
return (Long) template.queryForObject(SELECT_AVM_MAX_NODE_ID); Long count = (Long) template.queryForObject(SELECT_AVM_MAX_NODE_ID);
return count == null ? 0L : count;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -202,9 +187,10 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
return (List<Long>) template.queryForList(SELECT_AVM_NODES_WITH_OLD_CONTENT_PROPERTIES, ids); return (List<Long>) template.queryForList(SELECT_AVM_NODES_WITH_OLD_CONTENT_PROPERTIES, ids);
} }
public Long getMaxAdmNodeID() public long getMaxAdmNodeID()
{ {
return (Long) template.queryForObject(SELECT_ADM_MAX_NODE_ID); Long count = (Long) template.queryForObject(SELECT_ADM_MAX_NODE_ID);
return count == null ? 0L : count;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -301,104 +287,26 @@ public class PatchDAOImpl extends AbstractPatchDAOImpl
} }
@Override @Override
protected Long getMaxAclEntityId() protected long getMaxAclEntityId()
{ {
SqlMapSession session = null; Long count = (Long) template.queryForObject(SELECT_PERMISSIONS_MAX_ACL_ID, null);
try return count == null ? 0L : count;
{
session = template.getSqlMapClient().openSession();
Connection conn = template.getSqlMapClient().getCurrentConnection();
int isolationLevel = conn.getTransactionIsolation();
try
{
conn.setTransactionIsolation(1);
return (Long)template.queryForObject(SELECT_PERMISSIONS_MAX_ACL_ID, null);
}
finally
{
conn.setTransactionIsolation(isolationLevel);
}
}
catch (SQLException e)
{
throw new AlfrescoRuntimeException("Failed to set TX isolation level", e);
}
finally
{
if (session != null)
{
session.close();
}
}
} }
@Override @Override
protected long getDmNodeEntitiesCount() protected long getDmNodeEntitiesCount()
{ {
SqlMapSession session = null; Long count = (Long) template.queryForObject(SELECT_PERMISSIONS_DM_NODE_COUNT, null);
try return count == null ? 0L : count;
{
session = template.getSqlMapClient().openSession();
Connection conn = template.getSqlMapClient().getCurrentConnection();
int isolationLevel = conn.getTransactionIsolation();
try
{
conn.setTransactionIsolation(1);
return (Long)template.queryForObject(SELECT_PERMISSIONS_DM_NODE_COUNT, null);
}
finally
{
conn.setTransactionIsolation(isolationLevel);
}
}
catch (SQLException e)
{
throw new AlfrescoRuntimeException("Failed to set TX isolation level", e);
}
finally
{
if (session != null)
{
session.close();
}
}
} }
@Override @Override
protected long getDmNodeEntitiesCountWithNewACLs(Long above) protected long getDmNodeEntitiesCountWithNewACLs(Long above)
{ {
SqlMapSession session = null; Map<String, Object> params = new HashMap<String, Object>(1);
try params.put("id", above);
{ Long count = (Long) template.queryForObject(SELECT_PERMISSIONS_DM_NODE_COUNT_WITH_NEW_ACLS, params);
session = template.getSqlMapClient().openSession(); return count == null ? 0L : count;
Connection conn = template.getSqlMapClient().getCurrentConnection();
int isolationLevel = conn.getTransactionIsolation();
try
{
conn.setTransactionIsolation(1);
Map<String, Object> params = new HashMap<String, Object>(1);
params.put("id", above);
return (Long)template.queryForObject(SELECT_PERMISSIONS_DM_NODE_COUNT_WITH_NEW_ACLS, params);
}
finally
{
conn.setTransactionIsolation(isolationLevel);
}
}
catch (SQLException e)
{
throw new AlfrescoRuntimeException("Failed to set TX isolation level", e);
}
finally
{
if (session != null)
{
session.close();
}
}
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@@ -159,6 +159,11 @@ public class ADMAccessControlListDAO implements AccessControlListDAO
// Do the children first // Do the children first
Long aclId = nodeDAO.getNodeAclId(nodeId); Long aclId = nodeDAO.getNodeAclId(nodeId);
if (aclId == null)
{
// TODO: What happens here? It's causing NPEs
throw new IllegalStateException("Null aclId is causing NPEs. Node: " + nodeId);
}
Acl existingAcl = aclDaoComponent.getAcl(aclId); Acl existingAcl = aclDaoComponent.getAcl(aclId);
Long toInherit = null; Long toInherit = null;