Merged V2.2 to HEAD

8083: Merged V2.1 to V2.2
      8066: RM-31 and related issues (ACT-729)
      8068: Fix for AR-1997
   8084: Fixed script error on notify page of invite website user wizard
   8086: Merged V2.1 to V2.2
      8075: Clear()ing a hibernate session, is not always enough to guarantee that transactions not use unbounded amounts of memory
      8076: Turn off test that needs to be fixed real soon now.
   8092: Implementation for:   http://issues.alfresco.com/browse/AR-1744
   8093: Fixed upgrade scripts for V2.1.2 to V2.2 upgrades
   8096: Fix for AWC-1578 and AWC-1814
   8097: Added new indexes missing from scripts and made index names consistent.
   8098: Fix for AWC-1548
   8100: Removed use of QName from alf_permission table
   8102: Fix for AWC-1690
   8103: test was == on id that used to be long but is now a Long


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8476 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-03-10 13:11:50 +00:00
parent 72a90a14f1
commit 3e2311888b
25 changed files with 507 additions and 238 deletions

View File

@@ -170,6 +170,15 @@
<property name="allowGuestLogin"> <property name="allowGuestLogin">
<value>true</value> <value>true</value>
</property> </property>
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="personService">
<ref bean="personService" />
</property>
<property name="transactionService">
<ref bean="transactionService" />
</property>
</bean> </bean>
@@ -184,6 +193,16 @@
<property name="accept"> <property name="accept">
<value>true</value> <value>true</value>
</property> </property>
</property>
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="personService">
<ref bean="personService" />
</property>
<property name="transactionService">
<ref bean="transactionService" />
</property>
</bean> </bean>
--> -->
@@ -374,7 +393,7 @@
<!-- The period for which tickets are valid in XML duration format. --> <!-- The period for which tickets are valid in XML duration format. -->
<!-- The default is P1H for one hour. --> <!-- The default is P1H for one hour. -->
<property name="validDuration"> <property name="validDuration">
<value>P1H</value> <value>PT1H</value>
</property> </property>
<!-- Do tickets expire or live for ever? --> <!-- Do tickets expire or live for ever? -->
<property name="ticketsExpire"> <property name="ticketsExpire">

View File

@@ -134,24 +134,74 @@
<bean id="log4JHierarchyInit" class="org.alfresco.repo.admin.Log4JHierarchyInit" init-method="init"> <bean id="log4JHierarchyInit" class="org.alfresco.repo.admin.Log4JHierarchyInit" init-method="init">
<property name="log4jHierarchy" ref="log4jHierarchy"/> <property name="log4jHierarchy" ref="log4jHierarchy"/>
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- Incorporate supplementary log4j.properties files --> <!-- Supplementary log4j.properties files -->
<!-- --> <!-- -->
<!-- Properties in these files will augment/override --> <!-- Log4j settings specified here augment/override the webapp's main -->
<!-- those within WEB-INF/classes/log4j.properties --> <!-- log4j configuration file: WEB-INF/classes/log4j.properties -->
<!-- --> <!-- -->
<!-- This mechanism allows modules to have their own local --> <!-- This allows modules to maintain their own log4j.properties file, -->
<!-- log4j.properties file within: --> <!-- which is typically deployed to: -->
<!-- --> <!-- WEB-INF/classes/alfresco/module/{module.id}/log4j.properties -->
<!-- WEB-INF/classes/alfresco/module/{module.id}/log4j.properties --> <!-- -->
<!-- --> <!-- Where: module.id is whatever value is set within the AMP's -->
<!-- Where: module.id is whatever value is set within the AMP's --> <!-- 'module.properties' file. -->
<!-- 'module.properties' file. --> <!-- -->
<!-- --> <!-- Example: -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --> <!-- WEB-INF/classes/alfresco/module/com.example.x.Y/log4j.properties -->
<!-- -->
<!-- Those who wish to configure log4j properties in Alfresco extensions -->
<!-- that aren't packaged as AMP modules can create log4j.properties file -->
<!-- of the form: {name}-log4j.properties and place it within some -->
<!-- alfresco/extension directory on the server's classpath. -->
<!-- -->
<!-- For example: -->
<!-- WEB-INF/classes/alfresco/extension/SIMPLE_EXAMPLE-log4j.properties -->
<!-- -->
<!-- That said, you are strongly encouraged to use the modular form -->
<!-- (i.e.: the first one), and use the AMP mechanism for packaging -->
<!-- whenever possible. This makes customizations easier to manage. -->
<!-- Note: {name}-log4j.properties files override/augment the -->
<!-- log4j.properties files packaged within modules. -->
<!-- -->
<!-- Developers may also wish to maintain a dev-log4j.properties file -->
<!-- outside of the webapp. This allows for changing log4j settings -->
<!-- without touching the "shipping product", or any of a customer's -->
<!-- local settings. Your optional dev-log4j.properties file should be -->
<!-- in some alfresco/extension directory within the server's classpath, -->
<!-- and outside the webapp itself (so you don't accidentally delete it). -->
<!-- Note: the dev-log4j.properties file augments/overrides all others. -->
<!-- -->
<!-- Example: -->
<!-- $TOMCAT_HOME/shared/classes/alfresco/extension/dev-log4j.properties -->
<!-- -->
<!-- -->
<!-- Best practices: -->
<!-- -->
<!-- Local customizations/licences are kept outside of the webapp. -->
<!-- Example: -->
<!-- $TOMCAT_HOME/shared/classes/alfresco/extension/...-log4j.properties -->
<!-- -->
<!-- Shipping config files should be kept/installed within webapp: -->
<!-- Example: -->
<!-- WEB-INF/classes/alfresco/extension/...-log4j.properties -->
<!-- -->
<!-- A dev-log4j.properties file should never be used in an ongoing -->
<!-- during production, nor packaged as a part of any product. -->
<!-- -->
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<property name="overriding_log4j_properties"> <property name="overriding_log4j_properties">
<list> <list>
<!-- NOTE: value entries are listed from lowest precedence to highest. -->
<!-- Installed AMP modules -->
<value>classpath*:alfresco/module/*/log4j.properties</value> <value>classpath*:alfresco/module/*/log4j.properties</value>
<!-- Other installed extensions -->
<value>classpath*:alfresco/extension/*-log4j.properties</value>
<!-- private developer overrides -->
<value>classpath*:alfresco/extension/dev-log4j.properties</value>
</list> </list>
</property> </property>
</bean> </bean>

View File

@@ -7,12 +7,6 @@
-- Please contact support@alfresco.com if you need assistance with the upgrade. -- Please contact support@alfresco.com if you need assistance with the upgrade.
-- --
-- Add index support for AVM
-- Ideally we would have the indirection in the index but it is too long for mysql which needs additional options
-- CREATE INDEX idx_avm_lyr_indn on avm_nodes (primary_indirection, indirection(128));
-- This matches the hibernate schema and should be good enough for the standard WCM use cases
CREATE INDEX idx_avm_lyr_indn on avm_nodes (primary_indirection);
CREATE TABLE alf_acl_change_set ( CREATE TABLE alf_acl_change_set (
id BIGINT NOT NULL AUTO_INCREMENT, id BIGINT NOT NULL AUTO_INCREMENT,
version BIGINT NOT NULL, version BIGINT NOT NULL,
@@ -32,8 +26,8 @@ ALTER TABLE alf_access_control_list
ADD COLUMN acl_change_set BIGINT, ADD COLUMN acl_change_set BIGINT,
ADD COLUMN inherits_from BIGINT; ADD COLUMN inherits_from BIGINT;
CREATE INDEX fk_alf_acl_acs ON alf_access_control_list (acl_change_set); CREATE INDEX fk_alf_acl_acs ON alf_access_control_list (acl_change_set);
CREATE INDEX idx_pm_acl_inh ON alf_access_control_list (inherits, inherits_from);
ALTER TABLE alf_access_control_list ADD CONSTRAINT fk_alf_acl_acs FOREIGN KEY (acl_change_set) REFERENCES alf_acl_change_set (id); ALTER TABLE alf_access_control_list ADD CONSTRAINT fk_alf_acl_acs FOREIGN KEY (acl_change_set) REFERENCES alf_acl_change_set (id);
CREATE INDEX idx_alf_acl_inh ON alf_access_control_list (inherits, inherits_from);
UPDATE alf_access_control_list acl UPDATE alf_access_control_list acl
set acl_id = (acl.id); set acl_id = (acl.id);
@@ -69,7 +63,7 @@ ALTER TABLE alf_access_control_entry
DROP TABLE alf_auth_ext_keys; DROP TABLE alf_auth_ext_keys;
-- remove authority constraint -- remove authority constraint
ALTER TABLE alf_access_control_entry DROP INDEX FKFFF41F99B25A50BF, DROP FOREIGN KEY FKFFF41F99B25A50BF; ALTER TABLE alf_access_control_entry DROP INDEX FKFFF41F99B25A50BF, DROP FOREIGN KEY FKFFF41F99B25A50BF; -- (optional)
-- restructure authority -- restructure authority
ALTER TABLE alf_authority ALTER TABLE alf_authority
@@ -79,7 +73,7 @@ ALTER TABLE alf_authority
CHANGE recipient authority VARCHAR(100), CHANGE recipient authority VARCHAR(100),
ADD primary key (id), ADD primary key (id),
ADD UNIQUE (authority, crc); ADD UNIQUE (authority, crc);
CREATE INDEX idx_authority on alf_authority (authority); CREATE INDEX idx_alf_auth_aut on alf_authority (authority);
-- migrate data - fix up FK refs to authority -- migrate data - fix up FK refs to authority
UPDATE alf_access_control_entry ace UPDATE alf_access_control_entry ace

View File

@@ -15,6 +15,8 @@ ALTER TABLE alf_access_control_entry DROP INDEX fk_alf_ace_auth, DROP FOREIGN KE
ALTER TABLE alf_access_control_list DROP INDEX fk_alf_acl_acs, DROP FOREIGN KEY fk_alf_acl_acs; ALTER TABLE alf_access_control_list DROP INDEX fk_alf_acl_acs, DROP FOREIGN KEY fk_alf_acl_acs;
ALTER TABLE alf_access_control_list DROP INDEX idx_alf_acl_inh;
ALTER TABLE alf_acl_member DROP INDEX fk_alf_aclm_acl, DROP FOREIGN KEY fk_alf_aclm_acl; ALTER TABLE alf_acl_member DROP INDEX fk_alf_aclm_acl, DROP FOREIGN KEY fk_alf_aclm_acl;
ALTER TABLE alf_acl_member DROP INDEX fk_alf_aclm_ace, DROP FOREIGN KEY fk_alf_aclm_ace; ALTER TABLE alf_acl_member DROP INDEX fk_alf_aclm_ace, DROP FOREIGN KEY fk_alf_aclm_ace;
@@ -57,6 +59,12 @@ ALTER TABLE alf_audit_source DROP INDEX app_source_ser_idx; -- (optional)
ALTER TABLE alf_audit_source DROP INDEX app_source_met_idx; -- (optional) ALTER TABLE alf_audit_source DROP INDEX app_source_met_idx; -- (optional)
ALTER TABLE alf_authority DROP INDEX idx_alf_auth_aut;
ALTER TABLE alf_authority_alias DROP INDEX fk_alf_autha_ali, DROP FOREIGN KEY fk_alf_autha_ali;
ALTER TABLE alf_authority_alias DROP INDEX fk_alf_autha_aut, DROP FOREIGN KEY fk_alf_autha_aut;
ALTER TABLE alf_child_assoc DROP INDEX FKFFC5468E8E50E582, DROP FOREIGN KEY FKFFC5468E8E50E582; ALTER TABLE alf_child_assoc DROP INDEX FKFFC5468E8E50E582, DROP FOREIGN KEY FKFFC5468E8E50E582;
ALTER TABLE alf_child_assoc DROP INDEX FKFFC5468E74173FF4, DROP FOREIGN KEY FKFFC5468E74173FF4; ALTER TABLE alf_child_assoc DROP INDEX FKFFC5468E74173FF4, DROP FOREIGN KEY FKFFC5468E74173FF4;
@@ -108,6 +116,8 @@ ALTER TABLE avm_history_links DROP INDEX fk_avm_hl_desc, DROP FOREIGN KEY fk_avm
ALTER TABLE avm_history_links DROP INDEX fk_avm_hl_ancestor, DROP FOREIGN KEY fk_avm_hl_ancestor; --(optional) ALTER TABLE avm_history_links DROP INDEX fk_avm_hl_ancestor, DROP FOREIGN KEY fk_avm_hl_ancestor; --(optional)
ALTER TABLE avm_history_links DROP INDEX idx_avm_hl_revpk; --(optional)
ALTER TABLE avm_merge_links DROP INDEX fk_avm_ml_to, DROP FOREIGN KEY fk_avm_ml_to; --(optional) ALTER TABLE avm_merge_links DROP INDEX fk_avm_ml_to, DROP FOREIGN KEY fk_avm_ml_to; --(optional)
ALTER TABLE avm_merge_links DROP INDEX fk_avm_ml_from, DROP FOREIGN KEY fk_avm_ml_from; --(optional) ALTER TABLE avm_merge_links DROP INDEX fk_avm_ml_from, DROP FOREIGN KEY fk_avm_ml_from; --(optional)
@@ -122,6 +132,8 @@ ALTER TABLE avm_nodes DROP INDEX fk_avm_n_acl, DROP FOREIGN KEY fk_avm_n_acl; --
ALTER TABLE avm_nodes DROP INDEX fk_avm_n_store, DROP FOREIGN KEY fk_avm_n_store; --(optional) ALTER TABLE avm_nodes DROP INDEX fk_avm_n_store, DROP FOREIGN KEY fk_avm_n_store; --(optional)
ALTER TABLE avm_nodes DROP INDEX idx_avm_n_pi; --(optional)
ALTER TABLE avm_store_properties DROP INDEX idx_avm_sp_name; --(optional) ALTER TABLE avm_store_properties DROP INDEX idx_avm_sp_name; --(optional)
ALTER TABLE avm_store_properties DROP INDEX fk_avm_sp_store, DROP FOREIGN KEY fk_avm_sp_store; --(optional) ALTER TABLE avm_store_properties DROP INDEX fk_avm_sp_store, DROP FOREIGN KEY fk_avm_sp_store; --(optional)
@@ -132,6 +144,8 @@ ALTER TABLE avm_version_layered_node_entry DROP INDEX FK182E672DEB9D70C, DROP FO
ALTER TABLE avm_version_roots DROP INDEX idx_avm_vr_version; --(optional) ALTER TABLE avm_version_roots DROP INDEX idx_avm_vr_version; --(optional)
ALTER TABLE avm_version_roots DROP INDEX idx_avm_vr_revuq; --(optional)
ALTER TABLE avm_version_roots DROP INDEX fk_avm_vr_root, DROP FOREIGN KEY fk_avm_vr_root; --(optional) ALTER TABLE avm_version_roots DROP INDEX fk_avm_vr_root, DROP FOREIGN KEY fk_avm_vr_root; --(optional)
ALTER TABLE avm_version_roots DROP INDEX fk_avm_vr_store, DROP FOREIGN KEY fk_avm_vr_store; --(optional) ALTER TABLE avm_version_roots DROP INDEX fk_avm_vr_store, DROP FOREIGN KEY fk_avm_vr_store; --(optional)

View File

@@ -109,6 +109,10 @@ INSERT INTO t_qnames (qname)
( (
SELECT DISTINCT type_qname FROM alf_child_assoc SELECT DISTINCT type_qname FROM alf_child_assoc
); );
INSERT INTO t_qnames (qname)
(
SELECT DISTINCT type_qname FROM alf_permission
);
-- Extract the namespace and localnames from the QNames -- Extract the namespace and localnames from the QNames
UPDATE t_qnames SET namespace = SUBSTR(SUBSTRING_INDEX(qname, '}', 1), 2); UPDATE t_qnames SET namespace = SUBSTR(SUBSTRING_INDEX(qname, '}', 1), 2);
UPDATE t_qnames SET localname = SUBSTRING_INDEX(qname, '}', -1); UPDATE t_qnames SET localname = SUBSTRING_INDEX(qname, '}', -1);
@@ -316,6 +320,20 @@ UPDATE alf_node_assoc na set na.type_qname_id =
ALTER TABLE alf_node_assoc DROP COLUMN type_qname; ALTER TABLE alf_node_assoc DROP COLUMN type_qname;
ALTER TABLE alf_node_assoc MODIFY COLUMN type_qname_id BIGINT NOT NULL AFTER target_node_id; ALTER TABLE alf_node_assoc MODIFY COLUMN type_qname_id BIGINT NOT NULL AFTER target_node_id;
--
-- DATA REPLACEMENT: alf_permission.type_qname
--
ALTER TABLE alf_permission ADD COLUMN type_qname_id BIGINT NULL AFTER id;
UPDATE alf_permission p set p.type_qname_id =
(
SELECT q.id
FROM alf_qname q
JOIN alf_namespace ns ON (q.ns_id = ns.id)
WHERE CONCAT('{', ns.uri, '}', q.local_name) = p.type_qname
);
ALTER TABLE alf_permission DROP COLUMN type_qname;
ALTER TABLE alf_permission MODIFY COLUMN type_qname_id BIGINT NOT NULL AFTER id;
-- Drop the temporary indexes and constraints -- Drop the temporary indexes and constraints
ALTER TABLE alf_qname DROP INDEX t_fk_alf_qn_ns; ALTER TABLE alf_qname DROP INDEX t_fk_alf_qn_ns;
ALTER TABLE alf_qname DROP FOREIGN KEY t_fk_alf_qn_ns; ALTER TABLE alf_qname DROP FOREIGN KEY t_fk_alf_qn_ns;

View File

@@ -41,6 +41,9 @@ CREATE INDEX idx_alf_ca_qn_ln ON alf_child_assoc (qname_localname);
CREATE INDEX idx_alf_txn_ctms ON alf_transaction (commit_time_ms); CREATE INDEX idx_alf_txn_ctms ON alf_transaction (commit_time_ms);
-- The was 'idx_avm_lyr_indn'. Rename it if you have the old name.
CREATE INDEX idx_avm_n_pi on avm_nodes (primary_indirection);
CREATE INDEX idx_avm_np_name ON avm_node_properties (qname); CREATE INDEX idx_avm_np_name ON avm_node_properties (qname);
CREATE INDEX idx_avm_vr_version ON avm_version_roots (version_id); CREATE INDEX idx_avm_vr_version ON avm_version_roots (version_id);
@@ -49,6 +52,8 @@ CREATE INDEX idx_avm_vr_version ON avm_version_roots (version_id);
-- Explicit indexes and constraints not declared in the mappings -- Explicit indexes and constraints not declared in the mappings
-- --
CREATE INDEX idx_alf_acl_inh ON alf_access_control_list (inherits, inherits_from);
CREATE INDEX fk_alf_na_qn ON alf_node_aspects (qname_id); CREATE INDEX fk_alf_na_qn ON alf_node_aspects (qname_id);
ALTER TABLE alf_node_aspects ADD CONSTRAINT fk_alf_na_qn FOREIGN KEY (qname_id) REFERENCES alf_qname (id); ALTER TABLE alf_node_aspects ADD CONSTRAINT fk_alf_na_qn FOREIGN KEY (qname_id) REFERENCES alf_qname (id);

View File

@@ -15,6 +15,15 @@
<property name="jaasConfigEntryName"> <property name="jaasConfigEntryName">
<value>Alfresco</value> <value>Alfresco</value>
</property> </property>
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="personService">
<ref bean="personService" />
</property>
<property name="transactionService">
<ref bean="transactionService" />
</property>
</bean> </bean>
<!-- DAO that rejects changes - JAAS is read only at the moment. --> <!-- DAO that rejects changes - JAAS is read only at the moment. -->

View File

@@ -53,6 +53,15 @@
--> -->
<value>${ldap.authentication.userNameFormat}</value> <value>${ldap.authentication.userNameFormat}</value>
</property> </property>
<property name="nodeService">
<ref bean="nodeService" />
</property>
<property name="personService">
<ref bean="personService" />
</property>
<property name="transactionService">
<ref bean="transactionService" />
</property>
</bean> </bean>
<!-- <!--

View File

@@ -259,6 +259,9 @@
<bean id="aclDaoComponent" class="org.alfresco.repo.domain.hibernate.AclDaoComponentImpl"> <bean id="aclDaoComponent" class="org.alfresco.repo.domain.hibernate.AclDaoComponentImpl">
<property name="sessionFactory"> <property name="sessionFactory">
<ref bean="sessionFactory" /> <ref bean="sessionFactory" />
</property>
<property name="qnameDAO">
<ref bean="qnameDAO" />
</property> </property>
<property name="aclCache"> <property name="aclCache">
<ref bean="aclCache" /> <ref bean="aclCache" />

View File

@@ -169,6 +169,9 @@
<property name="sessionFactory"> <property name="sessionFactory">
<ref bean="sessionFactory" /> <ref bean="sessionFactory" />
</property> </property>
<property name="qnameDAO">
<ref bean="qnameDAO" />
</property>
</bean> </bean>
<bean id="patch.guestUser" class="org.alfresco.repo.admin.patch.impl.GuestUserPatch" parent="basePatch" > <bean id="patch.guestUser" class="org.alfresco.repo.admin.patch.impl.GuestUserPatch" parent="basePatch" >
<property name="id"><value>patch.guestUser</value></property> <property name="id"><value>patch.guestUser</value></property>
@@ -211,6 +214,9 @@
<property name="sessionFactory"> <property name="sessionFactory">
<ref bean="sessionFactory"/> <ref bean="sessionFactory"/>
</property> </property>
<property name="qnameDAO">
<ref bean="qnameDAO" />
</property>
<property name="dependsOn"> <property name="dependsOn">
<list> <list>
<ref bean="patch.guestUser"/> <ref bean="patch.guestUser"/>
@@ -279,6 +285,9 @@
<property name="sessionFactory"> <property name="sessionFactory">
<ref bean="sessionFactory" /> <ref bean="sessionFactory" />
</property> </property>
<property name="qnameDAO">
<ref bean="qnameDAO" />
</property>
<property name="dependsOn"> <property name="dependsOn">
<list> <list>
<ref bean="patch.updateGuestPermission" /> <ref bean="patch.updateGuestPermission" />
@@ -1240,6 +1249,9 @@
<property name="sessionFactory"> <property name="sessionFactory">
<ref bean="sessionFactory" /> <ref bean="sessionFactory" />
</property> </property>
<property name="qnameDAO">
<ref bean="qnameDAO" />
</property>
<property name="dependsOn" > <property name="dependsOn" >
<list> <list>
<ref bean="patch.db-V2.2-ACL" /> <ref bean="patch.db-V2.2-ACL" />

View File

@@ -24,11 +24,10 @@
*/ */
package org.alfresco.repo.admin.patch.impl; package org.alfresco.repo.admin.patch.impl;
import java.util.List;
import org.alfresco.repo.admin.patch.AbstractPatch; import org.alfresco.repo.admin.patch.AbstractPatch;
import org.alfresco.repo.domain.DbAccessControlEntry;
import org.alfresco.repo.domain.DbPermission; import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.QNameDAO;
import org.alfresco.repo.domain.QNameEntity;
import org.alfresco.repo.domain.hibernate.DbPermissionImpl; import org.alfresco.repo.domain.hibernate.DbPermissionImpl;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.hibernate.Query; import org.hibernate.Query;
@@ -56,6 +55,11 @@ public abstract class AbstractPermissionChangePatch extends AbstractPatch
this.helper.setSessionFactory(sessionFactory); this.helper.setSessionFactory(sessionFactory);
} }
public void setQnameDAO(QNameDAO qnameDAO)
{
helper.setQnameDAO(qnameDAO);
}
/** /**
* Helper method to rename (move) a permission. This involves checking for the existence of the * Helper method to rename (move) a permission. This involves checking for the existence of the
* new permission and then moving all the entries to point to the new permission. * new permission and then moving all the entries to point to the new permission.
@@ -74,11 +78,11 @@ public abstract class AbstractPermissionChangePatch extends AbstractPatch
/** Helper to get a permission entity */ /** Helper to get a permission entity */
private static class GetPermissionCallback implements HibernateCallback private static class GetPermissionCallback implements HibernateCallback
{ {
private QName typeQName; private QNameEntity typeQNameEntity;
private String name; private String name;
public GetPermissionCallback(QName typeQName, String name) public GetPermissionCallback(QNameEntity typeQNameEntity, String name)
{ {
this.typeQName = typeQName; this.typeQNameEntity = typeQNameEntity;
this.name = name; this.name = name;
} }
public Object doInHibernate(Session session) public Object doInHibernate(Session session)
@@ -87,7 +91,7 @@ public abstract class AbstractPermissionChangePatch extends AbstractPatch
session.flush(); session.flush();
Query query = session.getNamedQuery(HibernateHelper.QUERY_GET_PERMISSION); Query query = session.getNamedQuery(HibernateHelper.QUERY_GET_PERMISSION);
query.setParameter("permissionTypeQName", typeQName) query.setParameter("permissionTypeQName", typeQNameEntity)
.setString("permissionName", name); .setString("permissionName", name);
return query.uniqueResult(); return query.uniqueResult();
} }
@@ -97,6 +101,13 @@ public abstract class AbstractPermissionChangePatch extends AbstractPatch
{ {
private static final String QUERY_GET_PERMISSION = "permission.GetPermission"; private static final String QUERY_GET_PERMISSION = "permission.GetPermission";
private QNameDAO qnameDAO;
public void setQnameDAO(QNameDAO qnameDAO)
{
this.qnameDAO = qnameDAO;
}
public int createAndUpdatePermission( public int createAndUpdatePermission(
final QName oldTypeQName, final QName oldTypeQName,
final String oldName, final String oldName,
@@ -108,20 +119,24 @@ public abstract class AbstractPermissionChangePatch extends AbstractPatch
throw new IllegalArgumentException("Cannot move permission to itself: " + oldTypeQName + "-" + oldName); throw new IllegalArgumentException("Cannot move permission to itself: " + oldTypeQName + "-" + oldName);
} }
HibernateCallback getNewPermissionCallback = new GetPermissionCallback(oldTypeQName, oldName); // Get the QName entities
QNameEntity oldTypeQNameEntity = qnameDAO.getOrCreateQNameEntity(oldTypeQName);
QNameEntity newTypeQNameEntity = qnameDAO.getOrCreateQNameEntity(newTypeQName);
HibernateCallback getNewPermissionCallback = new GetPermissionCallback(oldTypeQNameEntity, oldName);
DbPermission permission = (DbPermission) getHibernateTemplate().execute(getNewPermissionCallback); DbPermission permission = (DbPermission) getHibernateTemplate().execute(getNewPermissionCallback);
if (permission == null) if (permission == null)
{ {
// create the permission // create the permission
permission = new DbPermissionImpl(); permission = new DbPermissionImpl();
permission.setTypeQname(newTypeQName); permission.setTypeQName(newTypeQNameEntity);
permission.setName(newName); permission.setName(newName);
// save // save
getHibernateTemplate().save(permission); getHibernateTemplate().save(permission);
} }
else else
{ {
permission.setTypeQname(newTypeQName); permission.setTypeQName(newTypeQNameEntity);
permission.setName(newName); permission.setName(newName);
} }
// done // done

View File

@@ -102,6 +102,19 @@ public interface AVMNodeDAO
*/ */
public List<Long> getNewInStoreIDs(AVMStore store); public List<Long> getNewInStoreIDs(AVMStore store);
/**
* Clear newInStore field for a store. (Snapshot)
* @param store
*/
public void clearNewInStore(AVMStore store);
/**
* Get any new layered entries in a store.
* @param store
* @return
*/
public List<Long> getNewLayeredInStoreIDs(AVMStore store);
/** /**
* Inappropriate hack to get Hibernate to play nice. * Inappropriate hack to get Hibernate to play nice.
*/ */
@@ -111,25 +124,40 @@ public interface AVMNodeDAO
* Get a batch * Get a batch
* @return An iterator over all nodes. * @return An iterator over all nodes.
*/ */
List<AVMNode> getEmptyGUIDS(int count); public List<AVMNode> getEmptyGUIDS(int count);
/** /**
* Get a batch of LayeredDirectories which have null indirectionVersions. * Get a batch of LayeredDirectories which have null indirectionVersions.
* @param count * @param count
* @return * @return
*/ */
List<LayeredDirectoryNode> getNullVersionLayeredDirectories(int count); public List<LayeredDirectoryNode> getNullVersionLayeredDirectories(int count);
/** /**
* Get a batch of LayeredFiles which have null indirectionVersions. * Get a batch of LayeredFiles which have null indirectionVersions.
* @param count * @param count
* @return * @return
*/ */
List<LayeredFileNode> getNullVersionLayeredFiles(int count); public List<LayeredFileNode> getNullVersionLayeredFiles(int count);
/** /**
* Evict an AVMNode that is no longer going to be used. * Evict an AVMNode that is no longer going to be used.
* @param node * @param node
*/ */
public void evict(AVMNode node); public void evict(AVMNode node);
/**
* Clear the hibernate session cache.
*/
public void clear();
/**
* Turn off 2nd level caching.
*/
public void noCache();
/**
* Turn on 2nd level caching.
*/
public void yesCache();
} }

View File

@@ -920,19 +920,27 @@ public class AVMRepository
*/ */
public Map<String, Integer> createSnapshot(String storeName, String tag, String description) public Map<String, Integer> createSnapshot(String storeName, String tag, String description)
{ {
AlfrescoTransactionSupport.bindListener(fCreateVersionTxnListener); try
AVMStore store = getAVMStoreByName(storeName);
if (store == null)
{ {
throw new AVMNotFoundException("Store not found."); fAVMNodeDAO.noCache();
AlfrescoTransactionSupport.bindListener(fCreateVersionTxnListener);
AVMStore store = getAVMStoreByName(storeName);
if (store == null)
{
throw new AVMNotFoundException("Store not found.");
}
Map<String, Integer> result = store.createSnapshot(tag, description, new HashMap<String, Integer>());
for (Map.Entry<String, Integer> entry : result.entrySet())
{
fLookupCache.onSnapshot(entry.getKey());
fCreateVersionTxnListener.versionCreated(entry.getKey(), entry.getValue());
}
return result;
} }
Map<String, Integer> result = store.createSnapshot(tag, description, new HashMap<String, Integer>()); finally
for (Map.Entry<String, Integer> entry : result.entrySet())
{ {
fLookupCache.onSnapshot(entry.getKey()); fAVMNodeDAO.yesCache();
fCreateVersionTxnListener.versionCreated(entry.getKey(), entry.getValue());
} }
return result;
} }
/** /**

View File

@@ -520,13 +520,13 @@ public class AVMServicePermissionsTest extends TestCase
node = avmNodeDAO.getByID(desc.getId()); node = avmNodeDAO.getByID(desc.getId());
DbAccessControlList dirAcl = node.getAcl(); DbAccessControlList dirAcl = node.getAcl();
assertNotNull(dirAcl); assertNotNull(dirAcl);
assertTrue(acl.getId() == dirAcl.getId()); assertEquals(acl.getId(), dirAcl.getId());
desc = avmService.lookup(-1, storeName + "-layer-base:/layer-to-base/update-dir/update-file"); desc = avmService.lookup(-1, storeName + "-layer-base:/layer-to-base/update-dir/update-file");
node = avmNodeDAO.getByID(desc.getId()); node = avmNodeDAO.getByID(desc.getId());
DbAccessControlList fileAcl = node.getAcl(); DbAccessControlList fileAcl = node.getAcl();
assertNotNull(fileAcl); assertNotNull(fileAcl);
assertTrue(acl.getId() == fileAcl.getId()); assertEquals(acl.getId(), fileAcl.getId());
avmService.createSnapshot(storeName, "store", "store"); avmService.createSnapshot(storeName, "store", "store");
avmService.createSnapshot(storeName + "-layer-base", "store", "store"); avmService.createSnapshot(storeName + "-layer-base", "store", "store");
@@ -549,7 +549,7 @@ public class AVMServicePermissionsTest extends TestCase
node = avmNodeDAO.getByID(desc.getId()); node = avmNodeDAO.getByID(desc.getId());
dirAcl = node.getAcl(); dirAcl = node.getAcl();
assertNotNull(dirAcl); assertNotNull(dirAcl);
assertTrue(acl.getId() == dirAcl.getId()); assertEquals(acl.getId(), dirAcl.getId());
desc = avmService.lookup(-1, storeName + "-layer-base:/layer-to-base/update-dir/update-file"); desc = avmService.lookup(-1, storeName + "-layer-base:/layer-to-base/update-dir/update-file");
node = avmNodeDAO.getByID(desc.getId()); node = avmNodeDAO.getByID(desc.getId());
@@ -597,13 +597,13 @@ public class AVMServicePermissionsTest extends TestCase
node = avmNodeDAO.getByID(desc.getId()); node = avmNodeDAO.getByID(desc.getId());
DbAccessControlList dirAcl = node.getAcl(); DbAccessControlList dirAcl = node.getAcl();
assertNotNull(dirAcl); assertNotNull(dirAcl);
assertTrue(acl.getId() == dirAcl.getId()); assertEquals(acl.getId(), dirAcl.getId());
desc = avmService.lookup(-1, storeName + "-layer-base:/layer-to-base/update-dir/update-file"); desc = avmService.lookup(-1, storeName + "-layer-base:/layer-to-base/update-dir/update-file");
node = avmNodeDAO.getByID(desc.getId()); node = avmNodeDAO.getByID(desc.getId());
DbAccessControlList fileAcl = node.getAcl(); DbAccessControlList fileAcl = node.getAcl();
assertNotNull(fileAcl); assertNotNull(fileAcl);
assertTrue(acl.getId() == fileAcl.getId()); assertEquals(acl.getId(), fileAcl.getId());
avmService.createSnapshot(storeName, "store", "store"); avmService.createSnapshot(storeName, "store", "store");
avmService.createSnapshot(storeName + "-layer-base", "store", "store"); avmService.createSnapshot(storeName + "-layer-base", "store", "store");
@@ -628,7 +628,7 @@ public class AVMServicePermissionsTest extends TestCase
node = avmNodeDAO.getByID(desc.getId()); node = avmNodeDAO.getByID(desc.getId());
dirAcl = node.getAcl(); dirAcl = node.getAcl();
assertNotNull(dirAcl); assertNotNull(dirAcl);
assertTrue(acl.getId() == dirAcl.getId()); assertEquals(acl.getId(), dirAcl.getId());
desc = avmService.lookup(-1, storeName + "-layer-base:/layer-to-base/update-dir/update-file"); desc = avmService.lookup(-1, storeName + "-layer-base:/layer-to-base/update-dir/update-file");
node = avmNodeDAO.getByID(desc.getId()); node = avmNodeDAO.getByID(desc.getId());

View File

@@ -569,6 +569,7 @@ public class AVMServiceTest extends AVMServiceTestBase
/** /**
* Test Deployment. * Test Deployment.
*/ */
/*
public void testDeployment() throws Exception public void testDeployment() throws Exception
{ {
try try
@@ -673,7 +674,7 @@ public class AVMServiceTest extends AVMServiceTestBase
throw e; throw e;
} }
} }
*/
protected void runQueriesForCreateAndDeploy(String store) throws Exception protected void runQueriesForCreateAndDeploy(String store) throws Exception
{ {
StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); StoreRef storeRef = AVMNodeConverter.ToStoreRef(store);

View File

@@ -190,11 +190,14 @@ public class AVMStoreImpl implements AVMStore, Serializable
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public Map<String, Integer> createSnapshot(String tag, String description, Map<String, Integer> snapShotMap) public Map<String, Integer> createSnapshot(String tag, String description, Map<String, Integer> snapShotMap)
{ {
VersionRoot lastVersion = AVMDAOs.Instance().fVersionRootDAO.getMaxVersion(this); long rootID = fRoot.getId();
AVMStoreImpl me = (AVMStoreImpl)AVMDAOs.Instance().fAVMStoreDAO.getByID(fID);
VersionRoot lastVersion = AVMDAOs.Instance().fVersionRootDAO.getMaxVersion(me);
List<VersionLayeredNodeEntry> layeredEntries = List<VersionLayeredNodeEntry> layeredEntries =
AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.get(lastVersion); AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.get(lastVersion);
// Is there no need for a snapshot? // Is there no need for a snapshot?
if (!fRoot.getIsNew() && layeredEntries.size() == 0) DirectoryNode root = (DirectoryNode)AVMDAOs.Instance().fAVMNodeDAO.getByID(rootID);
if (!root.getIsNew() && layeredEntries.size() == 0)
{ {
// So, we set the tag and description fields of the latest version. // So, we set the tag and description fields of the latest version.
if (tag != null || description != null) if (tag != null || description != null)
@@ -205,13 +208,13 @@ public class AVMStoreImpl implements AVMStore, Serializable
snapShotMap.put(fName, lastVersion.getVersionID()); snapShotMap.put(fName, lastVersion.getVersionID());
return snapShotMap; return snapShotMap;
} }
snapShotMap.put(fName, fNextVersionID); snapShotMap.put(fName, me.fNextVersionID);
// Force copies on all the layered nodes from last snapshot. // Force copies on all the layered nodes from last snapshot.
for (VersionLayeredNodeEntry entry : layeredEntries) for (VersionLayeredNodeEntry entry : layeredEntries)
{ {
String path = entry.getPath(); String path = entry.getPath();
path = path.substring(path.indexOf(':') + 1); path = path.substring(path.indexOf(':') + 1);
Lookup lookup = lookup(-1, path, false, false); Lookup lookup = me.lookup(-1, path, false, false);
if (lookup == null) if (lookup == null)
{ {
continue; continue;
@@ -255,59 +258,50 @@ public class AVMStoreImpl implements AVMStore, Serializable
*/ */
} }
// Clear out the new nodes. // Clear out the new nodes.
List<Long> newInRep = AVMDAOs.Instance().fAVMNodeDAO.getNewInStoreIDs(this); List<Long> allLayeredNodeIDs = AVMDAOs.Instance().fAVMNodeDAO.getNewLayeredInStoreIDs(me);
List<AVMNode> layeredNodes = new ArrayList<AVMNode>(); AVMDAOs.Instance().fAVMNodeDAO.clearNewInStore(me);
for (Long newGuyID : newInRep) AVMDAOs.Instance().fAVMNodeDAO.clear();
List<Long> layeredNodeIDs = new ArrayList<Long>();
for (Long layeredID : allLayeredNodeIDs)
{ {
AVMNode newGuy = AVMDAOs.Instance().fAVMNodeDAO.getByID(newGuyID); Layered layered = (Layered)AVMDAOs.Instance().fAVMNodeDAO.getByID(layeredID);
newGuy.setStoreNew(null); String indirection = layered.getIndirection();
Layered layered = null; if (indirection == null)
if (newGuy.getType() == AVMNodeType.LAYERED_DIRECTORY &&
((LayeredDirectoryNode)newGuy).getPrimaryIndirection())
{ {
layered = (Layered)AVMNodeUnwrapper.Unwrap(newGuy); continue;
} }
if (newGuy.getType() == AVMNodeType.LAYERED_FILE) layeredNodeIDs.add(layeredID);
String storeName = indirection.substring(0, indirection.indexOf(':'));
if (!snapShotMap.containsKey(storeName))
{ {
layered = (Layered)AVMNodeUnwrapper.Unwrap(newGuy); AVMStore store = AVMDAOs.Instance().fAVMStoreDAO.getByName(storeName);
} if (store == null)
if (layered != null)
{
layeredNodes.add(newGuy);
String indirection = layered.getIndirection();
String storeName = indirection.substring(0, indirection.indexOf(':'));
if (!snapShotMap.containsKey(storeName))
{ {
AVMStore store = AVMDAOs.Instance().fAVMStoreDAO.getByName(storeName); layered.setIndirectionVersion(-1);
if (store == null)
{
layered.setIndirectionVersion(-1);
}
else
{
store.createSnapshot(null, null, snapShotMap);
layered.setIndirectionVersion(snapShotMap.get(storeName));
}
} }
else else
{ {
store.createSnapshot(null, null, snapShotMap);
layered = (Layered)AVMDAOs.Instance().fAVMNodeDAO.getByID(layeredID);
layered.setIndirectionVersion(snapShotMap.get(storeName)); layered.setIndirectionVersion(snapShotMap.get(storeName));
} }
} }
else else
{ {
AVMDAOs.Instance().fAVMNodeDAO.evict(newGuy); layered.setIndirectionVersion(snapShotMap.get(storeName));
} }
} }
AVMDAOs.Instance().fAVMNodeDAO.flush();
// Make up a new version record. // Make up a new version record.
String user = RawServices.Instance().getAuthenticationComponent().getCurrentUserName(); String user = RawServices.Instance().getAuthenticationComponent().getCurrentUserName();
if (user == null) if (user == null)
{ {
user = RawServices.Instance().getAuthenticationComponent().getSystemUserName(); user = RawServices.Instance().getAuthenticationComponent().getSystemUserName();
} }
VersionRoot versionRoot = new VersionRootImpl(this, me = (AVMStoreImpl)AVMDAOs.Instance().fAVMStoreDAO.getByID(fID);
fRoot, VersionRoot versionRoot = new VersionRootImpl(me,
fNextVersionID++, me.fRoot,
me.fNextVersionID++,
System.currentTimeMillis(), System.currentTimeMillis(),
user, user,
tag, tag,
@@ -315,8 +309,9 @@ public class AVMStoreImpl implements AVMStore, Serializable
// Another embarassing flush needed. // Another embarassing flush needed.
AVMDAOs.Instance().fAVMNodeDAO.flush(); AVMDAOs.Instance().fAVMNodeDAO.flush();
AVMDAOs.Instance().fVersionRootDAO.save(versionRoot); AVMDAOs.Instance().fVersionRootDAO.save(versionRoot);
for (AVMNode node : layeredNodes) for (Long nodeID : layeredNodeIDs)
{ {
AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(nodeID);
List<String> paths = fAVMRepository.getVersionPaths(versionRoot, node); List<String> paths = fAVMRepository.getVersionPaths(versionRoot, node);
for (String path : paths) for (String path : paths)
{ {
@@ -325,7 +320,6 @@ public class AVMStoreImpl implements AVMStore, Serializable
AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.save(entry); AVMDAOs.Instance().fVersionLayeredNodeEntryDAO.save(entry);
} }
} }
// Increment the version id.
return snapShotMap; return snapShotMap;
} }

View File

@@ -92,9 +92,11 @@
<property name="indirectionVersion" type="int" column="indirection_version"/> <property name="indirectionVersion" type="int" column="indirection_version"/>
<!-- This marks a layered directory as either knowing itself what <!-- This marks a layered directory as either knowing itself what
it points at (true) or inheriting what it points at from its it points at (true) or inheriting what it points at from its
container (false). --> container (false).
Ideally we would have the column 'indirection' in the index but it is too long.
-->
<property name="primaryIndirection" <property name="primaryIndirection"
column="primary_indirection" type="boolean" index="idx_avm_lyr_indn" /> column="primary_indirection" type="boolean" index="idx_avm_n_pi" />
<property name="opacity" column="opacity" type="boolean"/> <property name="opacity" column="opacity" type="boolean"/>
<!-- Map of names to DirectoryEntries. --> <!-- Map of names to DirectoryEntries. -->
</subclass> </subclass>
@@ -281,6 +283,27 @@
where an.storeNew = :store where an.storeNew = :store
]]> ]]>
</query> </query>
<query name="AVMNode.ClearNewInStore">
<![CDATA[
update versioned AVMNodeImpl an
set an.storeNew = null
where an.storeNew = :store
]]>
</query>
<query name="AVMNode.GetNewLayeredDirectory">
<![CDATA[
select an.id
from LayeredDirectoryNodeImpl an
where an.storeNew = :store
]]>
</query>
<query name="AVMNode.GetNewLayeredFile">
<![CDATA[
select an.id
from LayeredFileNodeImpl an
where an.storeNew = :store
]]>
</query>
<query name="AVMNode.GetDescendents"> <query name="AVMNode.GetDescendents">
<![CDATA[ <![CDATA[
select hl.descendent select hl.descendent

View File

@@ -33,7 +33,12 @@ import org.alfresco.repo.avm.AVMStore;
import org.alfresco.repo.avm.DirectoryNode; import org.alfresco.repo.avm.DirectoryNode;
import org.alfresco.repo.avm.LayeredDirectoryNode; import org.alfresco.repo.avm.LayeredDirectoryNode;
import org.alfresco.repo.avm.LayeredFileNode; import org.alfresco.repo.avm.LayeredFileNode;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.CacheMode;
import org.hibernate.Query; import org.hibernate.Query;
import org.hibernate.impl.SessionImpl;
import org.hibernate.stat.SessionStatistics;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
/** /**
@@ -43,6 +48,8 @@ import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
class AVMNodeDAOHibernate extends HibernateDaoSupport implements class AVMNodeDAOHibernate extends HibernateDaoSupport implements
AVMNodeDAO AVMNodeDAO
{ {
private static Log fgLogger = LogFactory.getLog(AVMNodeDAOHibernate.class);
/** /**
* Do nothing constructor. * Do nothing constructor.
*/ */
@@ -232,4 +239,57 @@ class AVMNodeDAOHibernate extends HibernateDaoSupport implements
getSession().flush(); getSession().flush();
getSession().evict(node); getSession().evict(node);
} }
/* (non-Javadoc)
* @see org.alfresco.repo.avm.AVMNodeDAO#clear()
*/
public void clear()
{
fgLogger.error(getSession().getStatistics());
getSession().flush();
getSession().clear();
fgLogger.error(getSession().getStatistics());
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.AVMNodeDAO#noCache()
*/
public void noCache()
{
getSession().getSessionFactory().evict(AVMNodeImpl.class);
getSession().setCacheMode(CacheMode.IGNORE);
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.AVMNodeDAO#yesCache()
*/
public void yesCache()
{
getSession().setCacheMode(CacheMode.NORMAL);
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.AVMNodeDAO#clearNewInStore(org.alfresco.repo.avm.AVMStore)
*/
public void clearNewInStore(AVMStore store)
{
Query query = getSession().getNamedQuery("AVMNode.ClearNewInStore");
query.setEntity("store", store);
query.executeUpdate();
}
/* (non-Javadoc)
* @see org.alfresco.repo.avm.AVMNodeDAO#getNewLayeredInStoreIDs(org.alfresco.repo.avm.AVMStore)
*/
@SuppressWarnings("unchecked")
public List<Long> getNewLayeredInStoreIDs(AVMStore store)
{
Query query = getSession().getNamedQuery("AVMNode.GetNewLayeredDirectory");
query.setEntity("store", store);
List<Long> ids = (List<Long>)query.list();
query = getSession().getNamedQuery("AVMNode.GetNewLayeredFile");
query.setEntity("store", store);
ids.addAll((List<Long>)query.list());
return ids;
}
} }

View File

@@ -26,8 +26,6 @@ package org.alfresco.repo.domain;
import java.io.Serializable; import java.io.Serializable;
import org.alfresco.service.namespace.QName;
/** /**
* The interface against which permission references are persisted in hibernate. * The interface against which permission references are persisted in hibernate.
* *
@@ -48,12 +46,12 @@ public interface DbPermission extends Serializable
/** /**
* @return Returns the qualified name of this permission * @return Returns the qualified name of this permission
*/ */
public QName getTypeQname(); public QNameEntity getTypeQName();
/** /**
* @param qname the entity representing the qname for this instance * @param qname the entity representing the qname for this instance
*/ */
public void setTypeQname(QName qname); public void setTypeQName(QNameEntity typeQNameEntity);
/** /**
* @return Returns the permission name * @return Returns the permission name

View File

@@ -39,6 +39,8 @@ import org.alfresco.repo.domain.DbAccessControlListChangeSet;
import org.alfresco.repo.domain.DbAccessControlListMember; import org.alfresco.repo.domain.DbAccessControlListMember;
import org.alfresco.repo.domain.DbAuthority; import org.alfresco.repo.domain.DbAuthority;
import org.alfresco.repo.domain.DbPermission; import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.QNameDAO;
import org.alfresco.repo.domain.QNameEntity;
import org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl; import org.alfresco.repo.node.db.hibernate.HibernateNodeDaoServiceImpl;
import org.alfresco.repo.security.permissions.ACLCopyMode; import org.alfresco.repo.security.permissions.ACLCopyMode;
import org.alfresco.repo.security.permissions.ACLType; import org.alfresco.repo.security.permissions.ACLType;
@@ -54,6 +56,7 @@ import org.alfresco.repo.security.permissions.impl.AclDaoComponent;
import org.alfresco.repo.security.permissions.impl.SimplePermissionReference; import org.alfresco.repo.security.permissions.impl.SimplePermissionReference;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport; import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.security.AccessStatus; import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID; import org.alfresco.util.GUID;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -93,6 +96,8 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
static String QUERY_GET_LATEST_ACL_BY_ACLID = "permission.FindLatestAclByGuid"; static String QUERY_GET_LATEST_ACL_BY_ACLID = "permission.FindLatestAclByGuid";
/** Access to QName entities */
private QNameDAO qnameDAO;
/** a transactionally-safe cache to be injected */ /** a transactionally-safe cache to be injected */
private SimpleCache<Long, AccessControlList> aclCache; private SimpleCache<Long, AccessControlList> aclCache;
@@ -107,6 +112,14 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
DbAccessControlListImpl.setAclDaoComponent(this); DbAccessControlListImpl.setAclDaoComponent(this);
} }
/**
* Set the DAO for accessing QName entities
*/
public void setQnameDAO(QNameDAO qnameDAO)
{
this.qnameDAO = qnameDAO;
}
public void setAclCache(SimpleCache<Long, AccessControlList> aclCache) public void setAclCache(SimpleCache<Long, AccessControlList> aclCache)
{ {
this.aclCache = aclCache; this.aclCache = aclCache;
@@ -1002,8 +1015,8 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
context.setPropertyContext(member.getAccessControlEntry().getContext().getPropertyContext()); context.setPropertyContext(member.getAccessControlEntry().getContext().getPropertyContext());
entry.setContext(context); entry.setContext(context);
} }
SimplePermissionReference permissionRefernce = new SimplePermissionReference(member.getAccessControlEntry().getPermission().getTypeQname(), member DbPermission perm = member.getAccessControlEntry().getPermission();
.getAccessControlEntry().getPermission().getName()); SimplePermissionReference permissionRefernce = new SimplePermissionReference(perm.getTypeQName().getQName(), perm.getName());
entry.setPermission(permissionRefernce); entry.setPermission(permissionRefernce);
entry.setPosition(member.getPosition()); entry.setPosition(member.getPosition());
@@ -1176,6 +1189,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
} }
@SuppressWarnings("unchecked")
public List<AclChange> setAccessControlEntry(Long id, final AccessControlEntry ace) public List<AclChange> setAccessControlEntry(Long id, final AccessControlEntry ace)
{ {
DbAccessControlList target = (DbAccessControlList) getHibernateTemplate().get(DbAccessControlListImpl.class, id); DbAccessControlList target = (DbAccessControlList) getHibernateTemplate().get(DbAccessControlListImpl.class, id);
@@ -1222,13 +1236,17 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
// Find permission // Find permission
final QName permissionQName = ace.getPermission().getQName();
final String permissionName = ace.getPermission().getName();
final QNameEntity permissionQNameEntity = qnameDAO.getOrCreateQNameEntity(permissionQName);
callback = new HibernateCallback() callback = new HibernateCallback()
{ {
public Object doInHibernate(Session session) public Object doInHibernate(Session session)
{ {
Query query = session.getNamedQuery(QUERY_GET_PERMISSION); Query query = session.getNamedQuery(QUERY_GET_PERMISSION);
query.setParameter("permissionTypeQName", ace.getPermission().getQName()); query.setParameter("permissionTypeQName", permissionQNameEntity);
query.setParameter("permissionName", ace.getPermission().getName()); query.setParameter("permissionName", permissionName);
return query.uniqueResult(); return query.uniqueResult();
} }
}; };
@@ -1236,8 +1254,8 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
if (permission == null) if (permission == null)
{ {
DbPermissionImpl newPermission = new DbPermissionImpl(); DbPermissionImpl newPermission = new DbPermissionImpl();
newPermission.setTypeQname(ace.getPermission().getQName()); newPermission.setTypeQName(permissionQNameEntity);
newPermission.setName(ace.getPermission().getName()); newPermission.setName(permissionName);
permission = newPermission; permission = newPermission;
getHibernateTemplate().save(newPermission); getHibernateTemplate().save(newPermission);
} }
@@ -1536,6 +1554,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
return avmNodeIds; return avmNodeIds;
} }
@SuppressWarnings("unchecked")
private List<AclChange> disableInheritanceImpl(Long id, boolean setInheritedOnAcl, DbAccessControlList acl) private List<AclChange> disableInheritanceImpl(Long id, boolean setInheritedOnAcl, DbAccessControlList acl)
{ {
List<AclChange> changes = new ArrayList<AclChange>(); List<AclChange> changes = new ArrayList<AclChange>();
@@ -1583,8 +1602,8 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
context.setPropertyContext(member.getAccessControlEntry().getContext().getPropertyContext()); context.setPropertyContext(member.getAccessControlEntry().getContext().getPropertyContext());
entry.setContext(context); entry.setContext(context);
} }
SimplePermissionReference permissionRefernce = new SimplePermissionReference(member.getAccessControlEntry().getPermission().getTypeQname(), member DbPermission perm = member.getAccessControlEntry().getPermission();
.getAccessControlEntry().getPermission().getName()); SimplePermissionReference permissionRefernce = new SimplePermissionReference(perm.getTypeQName().getQName(), perm.getName());
entry.setPermission(permissionRefernce); entry.setPermission(permissionRefernce);
entry.setPosition(Integer.valueOf(0)); entry.setPosition(Integer.valueOf(0));
@@ -1676,11 +1695,13 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo
if (pattern.getPermission() != null) if (pattern.getPermission() != null)
{ {
if ((pattern.getPermission().getQName() != null) && (!pattern.getPermission().getQName().equals(entry.getPermission().getTypeQname()))) final QName patternQName = pattern.getPermission().getQName();
if ((patternQName != null) && (!patternQName.equals(entry.getPermission().getTypeQName().getQName())))
{ {
return false; return false;
} }
if ((pattern.getPermission().getName() != null) && (!pattern.getPermission().getName().equals(entry.getPermission().getName()))) final String patternName = pattern.getPermission().getName();
if ((patternName != null) && (!patternName.equals(entry.getPermission().getName())))
{ {
return false; return false;
} }

View File

@@ -32,8 +32,6 @@ import org.alfresco.repo.domain.DbAuthority;
import org.alfresco.repo.domain.DbPermission; import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.DbPermissionKey; import org.alfresco.repo.domain.DbPermissionKey;
import org.alfresco.repo.security.permissions.ACEType; import org.alfresco.repo.security.permissions.ACEType;
import org.alfresco.service.namespace.QName;
import org.hibernate.CallbackException;
import org.hibernate.Session; import org.hibernate.Session;
/** /**
@@ -71,9 +69,15 @@ public class DbAccessControlEntryImpl implements DbAccessControlEntry, Serializa
public String toString() public String toString()
{ {
StringBuilder sb = new StringBuilder(128); StringBuilder sb = new StringBuilder(128);
sb.append("DbAccessControlEntryImpl").append("[ id=").append(id).append(", version=").append(version).append(", permission=").append(permission.getKey()).append( sb.append("DbAccessControlEntryImpl")
", authority=").append(authority.getAuthority()).append(", allowed=").append(allowed).append(", authorityDeleted=").append(", aceType=") .append("[ id=").append(id)
.append(ACEType.getACETypeFromId(aceType)).append(", context=").append(context).append("]"); .append(", version=").append(version)
.append(", permission=").append(permission.getKey())
.append(", authority=").append(authority.getAuthority())
.append(", allowed=").append(allowed)
.append(", aceType=").append(ACEType.getACETypeFromId(aceType))
.append(", context=").append(context)
.append("]");
return sb.toString(); return sb.toString();
} }

View File

@@ -28,12 +28,9 @@ import java.io.Serializable;
import org.alfresco.repo.domain.DbPermission; import org.alfresco.repo.domain.DbPermission;
import org.alfresco.repo.domain.DbPermissionKey; import org.alfresco.repo.domain.DbPermissionKey;
import org.alfresco.repo.domain.QNameEntity;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.EqualsHelper; import org.alfresco.util.EqualsHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.CallbackException;
import org.hibernate.Query;
import org.hibernate.Session; import org.hibernate.Session;
/** /**
@@ -45,14 +42,9 @@ public class DbPermissionImpl implements DbPermission, Serializable
{ {
private static final long serialVersionUID = -6352566900815035461L; private static final long serialVersionUID = -6352566900815035461L;
private static Log logger = LogFactory.getLog(DbPermissionImpl.class);
private Long id; private Long id;
private Long version; private Long version;
private QNameEntity typeQName;
private QName typeQname;
private String name; private String name;
public DbPermissionImpl() public DbPermissionImpl()
@@ -64,8 +56,12 @@ public class DbPermissionImpl implements DbPermission, Serializable
public String toString() public String toString()
{ {
StringBuilder sb = new StringBuilder(128); StringBuilder sb = new StringBuilder(128);
sb.append("DbPermissionImpl").append("[ id=").append(id).append(", version=").append(version).append(", typeQname=").append(typeQname).append(", name=").append(getName()) sb.append("DbPermissionImpl")
.append("]"); .append("[ id=").append(id)
.append(", version=").append(version)
.append(", typeQName=").append(typeQName.getQName())
.append(", name=").append(getName())
.append("]");
return sb.toString(); return sb.toString();
} }
@@ -81,13 +77,13 @@ public class DbPermissionImpl implements DbPermission, Serializable
return false; return false;
} }
DbPermission other = (DbPermission) o; DbPermission other = (DbPermission) o;
return (EqualsHelper.nullSafeEquals(typeQname, other.getTypeQname())) && (EqualsHelper.nullSafeEquals(name, other.getName())); return (EqualsHelper.nullSafeEquals(typeQName, other.getTypeQName())) && (EqualsHelper.nullSafeEquals(name, other.getName()));
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
return typeQname.hashCode() + (37 * name.hashCode()); return typeQName.hashCode() + (37 * name.hashCode());
} }
public Long getId() public Long getId()
@@ -118,14 +114,14 @@ public class DbPermissionImpl implements DbPermission, Serializable
this.version = version; this.version = version;
} }
public QName getTypeQname() public QNameEntity getTypeQName()
{ {
return typeQname; return typeQName;
} }
public void setTypeQname(QName typeQname) public void setTypeQName(QNameEntity typeQName)
{ {
this.typeQname = typeQname; this.typeQName = typeQName;
} }
public String getName() public String getName()
@@ -140,7 +136,7 @@ public class DbPermissionImpl implements DbPermission, Serializable
public DbPermissionKey getKey() public DbPermissionKey getKey()
{ {
return new DbPermissionKey(typeQname, name); return new DbPermissionKey(typeQName.getQName(), name);
} }
/** /**

View File

@@ -6,8 +6,6 @@
<hibernate-mapping> <hibernate-mapping>
<typedef class="org.alfresco.repo.domain.hibernate.QNameUserType" name="QName" />
<class <class
name="org.alfresco.repo.domain.hibernate.DbAccessControlListChangeSetImpl" name="org.alfresco.repo.domain.hibernate.DbAccessControlListChangeSetImpl"
proxy="org.alfresco.repo.domain.DbAccessControlListChangeSet" proxy="org.alfresco.repo.domain.DbAccessControlListChangeSet"
@@ -54,9 +52,9 @@
<version column="version" name="version" type="long" /> <version column="version" name="version" type="long" />
<property name="inherits" column="inherits" type="boolean" not-null="true" index="idx_pm_acl_inh" /> <property name="inherits" column="inherits" type="boolean" not-null="true" index="idx_alf_acl_inh" />
<property name="inheritsFrom" column="inherits_from" type="long" not-null="false" index="idx_pm_acl_inh" /> <property name="inheritsFrom" column="inherits_from" type="long" not-null="false" index="idx_alf_acl_inh" />
<property name="type" column="type" type="int" not-null="true" /> <property name="type" column="type" type="int" not-null="true" />
@@ -174,8 +172,17 @@
<generator class="native" /> <generator class="native" />
</id> </id>
<natural-id mutable="true"> <natural-id mutable="true" >
<property name="typeQname" column="type_qname" type="QName" length="200" /> <many-to-one
name="typeQName"
class="org.alfresco.repo.domain.hibernate.QNameEntityImpl"
column="type_qname_id"
foreign-key="fk_alf_perm_tqn"
lazy="proxy"
fetch="select"
unique="false"
not-null="true"
cascade="none" />
<property name="name" type="string" length="100" column="name" /> <property name="name" type="string" length="100" column="name" />
</natural-id> </natural-id>
@@ -199,9 +206,9 @@
<version column="version" name="version" type="long" /> <version column="version" name="version" type="long" />
<property name="authority" column="authority" type="string" length="100" unique-key="uidx_auth_name" index="idx_authority" /> <property name="authority" column="authority" type="string" length="100" unique-key="uidx_auth_name" index="idx_alf_auth_aut" />
<property name="crc" column="crc" type="long" unique-key="uidx_auth_name" /> <property name="crc" column="crc" type="long" unique-key="uidx_auth_name" />
</class> </class>
@@ -268,7 +275,7 @@
from from
org.alfresco.repo.domain.hibernate.DbPermissionImpl as permission org.alfresco.repo.domain.hibernate.DbPermissionImpl as permission
where where
permission.typeQname = :permissionTypeQName and permission.typeQName = :permissionTypeQName and
permission.name = :permissionName permission.name = :permissionName
</query> </query>
@@ -402,7 +409,7 @@
ace.authority.recipient = :authorityRecipient and ace.authority.recipient = :authorityRecipient and
ace.allowed = :allow and ace.allowed = :allow and
ace.permission.name = :permissionName and ace.permission.name = :permissionName and
ace.permission.typeQname = :permissionTypeQname ace.permission.typeQName = :permissionTypeQname
</query> </query>
--> -->
</hibernate-mapping> </hibernate-mapping>

View File

@@ -32,8 +32,14 @@ import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import net.sf.acegisecurity.providers.dao.User; import net.sf.acegisecurity.providers.dao.User;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.transaction.TransactionService;
/** /**
* This class abstract the support required to set up and query the Acegi context for security enforcement. There are * This class abstract the support required to set up and query the Acegi context for security enforcement. There are
@@ -50,6 +56,12 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
private TenantService tenantService; private TenantService tenantService;
private PersonService personService;
private NodeService nodeService;
private TransactionService transactionService;
public AbstractAuthenticationComponent() public AbstractAuthenticationComponent()
{ {
super(); super();
@@ -70,6 +82,26 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
this.tenantService = tenantService; this.tenantService = tenantService;
} }
public void setPersonService(PersonService personService)
{
this.personService = personService;
}
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
public void setTransactionService(TransactionService transactionService)
{
this.transactionService = transactionService;
}
public TransactionService getTransactionService()
{
return transactionService;
}
public void authenticate(String userName, char[] password) throws AuthenticationException public void authenticate(String userName, char[] password) throws AuthenticationException
{ {
// Support guest login from the login screen // Support guest login from the login screen
@@ -84,9 +116,9 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
} }
/** /**
* Default unsupported authentication implementation * Default unsupported authentication implementation - as of 2.1 this is the best way to implement your own
* - as of 2.1 this is the best way to implement your own authentication component as it will support guest login * authentication component as it will support guest login - prior to this direct over ride for authenticate(String ,
* - prior to this direct over ride for authenticate(String , char[]) was used. This will still work. * char[]) was used. This will still work.
* *
* @param userName * @param userName
* @param password * @param password
@@ -96,6 +128,37 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public Authentication setCurrentUser(final String userName) throws AuthenticationException
{
if (AuthenticationUtil.getSystemUserName().equals(userName))
{
return setCurrentUserImpl(userName);
}
else
{
return transactionService.getRetryingTransactionHelper().doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback<Authentication>()
{
public Authentication execute() throws Throwable
{
NodeRef userNode = personService.getPerson(userName);
if (userNode != null)
{
// Get the person name and use that as the current user to line up with permission checks
String personName = (String) nodeService.getProperty(userNode, ContentModel.PROP_USERNAME);
return setCurrentUserImpl(personName);
}
else
{
// Set using the user name
return setCurrentUserImpl(userName);
}
}
}, false, false);
}
}
/** /**
* Explicitly set the current user to be authenticated. * Explicitly set the current user to be authenticated.
* *
@@ -103,7 +166,7 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
* String * String
* @return Authentication * @return Authentication
*/ */
public Authentication setCurrentUser(String userName) throws AuthenticationException private Authentication setCurrentUserImpl(String userName) throws AuthenticationException
{ {
if (userName == null) if (userName == null)
{ {

View File

@@ -118,12 +118,6 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
private PassthruReaperThread m_reaperThread; private PassthruReaperThread m_reaperThread;
// Person service, used to map passthru usernames to Alfresco person names
private PersonService m_personService;
private NodeService m_nodeService;
private TransactionService m_transactionService;
/** /**
* Passthru Session Reaper Thread * Passthru Session Reaper Thread
*/ */
@@ -467,36 +461,6 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
} }
} }
/**
* Set the person service
*
* @param personService PersonService
*/
public final void setPersonService(PersonService personService)
{
m_personService = personService;
}
/**
* Set the node service
*
* @param nodeService NodeService
*/
public final void setNodeService(NodeService nodeService)
{
m_nodeService = nodeService;
}
/**
* Set the transaction service
*
* @param transService TransactionService
*/
public final void setTransactionService(TransactionService transService)
{
m_transactionService = transService;
}
/** /**
* Return the authentication session timeout, in milliseconds * Return the authentication session timeout, in milliseconds
* *
@@ -693,31 +657,7 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
// Map the passthru username to an Alfresco person // Map the passthru username to an Alfresco person
NodeRef userNode = m_personService.getPerson(username); setCurrentUser( username);
if ( userNode != null)
{
// Get the person name and use that as the current user to line up with permission checks
String personName = (String) m_nodeService.getProperty(userNode, ContentModel.PROP_USERNAME);
setCurrentUser(personName);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Setting current user using person " + personName + " (username " + username + ")");
}
else
{
// Set using the user name
setCurrentUser( username);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Setting current user using username " + username);
}
// Debug // Debug
@@ -875,35 +815,13 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
// Wrap the service calls in a transaction // Wrap the service calls in a transaction
tx = m_transactionService.getUserTransaction( false); tx = getTransactionService().getUserTransaction( false);
tx.begin(); tx.begin();
// Map the passthru username to an Alfresco person // Map the passthru username to an Alfresco person
NodeRef userNode = m_personService.getPerson(username); setCurrentUser( username);
if ( userNode != null)
{
// Get the person name and use that as the current user to line up with permission checks
String personName = (String) m_nodeService.getProperty(userNode, ContentModel.PROP_USERNAME);
setCurrentUser(personName);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Setting current user using person " + personName + " (username " + username + ")");
}
else
{
// Set using the user name
setCurrentUser( username);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug("Setting current user using username " + username);
}
} }
catch (NoSuchPersonException ex) catch (NoSuchPersonException ex)
{ {