Merged V3.1 to HEAD

13265: Fix incorrect wiring of guest user name
   13266: Merged V2.1A to V3.1
      13252: Fix ADB-159: Generation of content model xml throws exception
   13267: Remove accidental addition of folders
   13280: IndexTransactionTracker logging changes
   13281: Added bean to push properties from repository properties into the VM properties
   13283: Added forgotten Hibernate diff file after JAWS-223 fix
   13291: Fix ETHREEOH-1340: Alfresco Repository Draft CMIS Implementation" link refers to localhost
   13297: Fix ETHREEOH-885: workflow mapAuthorityToName tests don't handle sub-classed objects correctly.
   13308: First part of JAWS-215 - permission migration from V2.1-A to V3.1
   13313: Build fix for 2.1-A to 3.1 ACL patch
   ___________________________________________________________________
   Modified: svn:mergeinfo
      Merged /alfresco/BRANCHES/V2.1-A:r13252
      Merged /alfresco/BRANCHES/V3.1:r13265-13267,13277-13283,13286,13289,13291,13295,13297,13308-13313


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13615 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2009-03-12 22:23:39 +00:00
parent 198ebe371e
commit c27b80dd53
13 changed files with 2051 additions and 1703 deletions

View File

@@ -535,7 +535,7 @@
<!-- Authentication Util initialization --> <!-- Authentication Util initialization -->
<bean id="authenticationUtil" class="org.alfresco.repo.security.authentication.AuthenticationUtil"> <bean id="authenticationUtil" class="org.alfresco.repo.security.authentication.AuthenticationUtil">
<property name="defaultAdminUserName"><value>${alfresco_user_store.adminusername}</value></property> <property name="defaultAdminUserName"><value>${alfresco_user_store.adminusername}</value></property>
<property name="defaultGuestUserName"><value>${alfresco_user_store.adminpassword}</value></property> <property name="defaultGuestUserName"><value>${alfresco_user_store.guestusername}</value></property>
</bean> </bean>
</beans> </beans>

View File

@@ -77,7 +77,8 @@
<ref bean="patch.schemaUpdateScript-V1.4-1" /> <ref bean="patch.schemaUpdateScript-V1.4-1" />
<ref bean="patch.schemaUpdateScript-V1.4-2" /> <ref bean="patch.schemaUpdateScript-V1.4-2" />
<ref bean="patch.db-V2.1-NotNullColumns" /> <ref bean="patch.db-V2.1-NotNullColumns" />
<ref bean="patch.db-V2.2-ACL" /> <ref bean="patch.db-V2.2-ACL-From-2.1-A" />
<ref bean="patch.db-V2.2-ACL" />
<ref bean="patch.db-V2.2-0-CreateMissingTables" /> <ref bean="patch.db-V2.2-0-CreateMissingTables" />
<ref bean="patch.db-V2.2-Upgrade-From-2.1" /> <ref bean="patch.db-V2.2-Upgrade-From-2.1" />
<ref bean="patch.db-V2.2-Upgrade-From-2.2SP1" /> <ref bean="patch.db-V2.2-Upgrade-From-2.2SP1" />

View File

@@ -52,6 +52,28 @@
</list> </list>
</property> </property>
</bean> </bean>
<bean id="jgroupsPropertySetter" class="org.alfresco.config.SystemPropertiesSetterBean" init-method="init">
<property name="propertyMap">
<map>
<entry key="alfresco.tcp.start_port">
<value>${alfresco.tcp.start_port}</value>
</entry>
<entry key="alfresco.tcp.initial_hosts">
<value>${alfresco.tcp.initial_hosts}</value>
</entry>
<entry key="alfresco.tcp.port_range">
<value>${alfresco.tcp.port_range}</value>
</entry>
<entry key="alfresco.udp.mcast_addr">
<value>${alfresco.udp.mcast_addr}</value>
</entry>
<entry key="alfresco.udp.mcast_port">
<value>${alfresco.udp.mcast_port}</value>
</entry>
</map>
</property>
</bean>
<!-- Custom MBeanServer --> <!-- Custom MBeanServer -->
<bean id="alfrescoMBeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"> <bean id="alfrescoMBeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">

View File

@@ -0,0 +1,191 @@
--
-- Title: Update for permissions schema changes
-- Database: MySQL InnoDB
-- Since: V2.2 Schema 85
-- Author: Andy Hind
--
-- Please contact support@alfresco.com if you need assistance with the upgrade.
--
CREATE TABLE alf_acl_change_set (
id BIGINT NOT NULL AUTO_INCREMENT,
version BIGINT NOT NULL,
primary key (id)
) ENGINE=InnoDB;
-- Add to ACL
ALTER TABLE alf_access_control_list
ADD COLUMN type INT NOT NULL DEFAULT 0,
ADD COLUMN latest BOOLEAN NOT NULL DEFAULT TRUE,
ADD COLUMN acl_id VARCHAR(36) NOT NULL DEFAULT 'UNSET',
ADD COLUMN acl_version BIGINT NOT NULL DEFAULT 1,
ADD COLUMN inherited_acl BIGINT,
ADD COLUMN is_versioned BOOLEAN NOT NULL DEFAULT FALSE,
ADD COLUMN requires_version BOOLEAN NOT NULL DEFAULT FALSE,
ADD COLUMN acl_change_set BIGINT,
ADD COLUMN inherits_from BIGINT,
ADD INDEX fk_alf_acl_acs (acl_change_set),
ADD CONSTRAINT fk_alf_acl_acs FOREIGN KEY (acl_change_set) REFERENCES alf_acl_change_set (id),
ADD INDEX idx_alf_acl_inh (inherits, inherits_from);
UPDATE alf_access_control_list acl
set acl_id = (acl.id);
ALTER TABLE alf_access_control_list
ADD UNIQUE (acl_id, latest, acl_version);
-- Create ACL member list
CREATE TABLE alf_acl_member (
id BIGINT NOT NULL AUTO_INCREMENT,
version BIGINT NOT NULL,
acl_id BIGINT NOT NULL,
ace_id BIGINT NOT NULL,
pos INT NOT NULL,
INDEX fk_alf_aclm_acl (acl_id),
CONSTRAINT fk_alf_aclm_acl FOREIGN KEY (acl_id) REFERENCES alf_access_control_list (id),
INDEX fk_alf_aclm_ace (ace_id),
CONSTRAINT fk_alf_aclm_ace FOREIGN KEY (ace_id) REFERENCES alf_access_control_entry (id),
primary key (id),
unique(acl_id, ace_id, pos)
) ENGINE=InnoDB;
ALTER TABLE alf_access_control_entry DROP INDEX acl_id;
-- Extend ACE
-- not required from 2.1-A
-- ADD COLUMN auth_id BIGINT NOT NULL DEFAULT -1,
ALTER TABLE alf_access_control_entry
ADD COLUMN applies INT NOT NULL DEFAULT 0,
ADD COLUMN context_id BIGINT;
-- remove unused
DROP TABLE alf_auth_ext_keys;
-- not required from 2.1-A
-- remove authority constraint
ALTER TABLE alf_access_control_entry DROP INDEX FKFFF41F99B25A50BF, DROP FOREIGN KEY FKFFF41F99B25A50BF; -- (optional)
-- not required from 2.1-A
-- restructure authority
-- ALTER TABLE alf_authority
-- DROP PRIMARY KEY,
-- ADD COLUMN id BIGINT NOT NULL AUTO_INCREMENT,
-- ADD COLUMN crc BIGINT,
-- CHANGE recipient authority VARCHAR(100),
-- ADD INDEX idx_alf_auth_aut (authority),
-- ADD primary key (id),
-- ADD UNIQUE (authority, crc);
-- migrate data - fix up FK refs to authority
-- UPDATE alf_access_control_entry ace
-- set auth_id = (select id from alf_authority a where a.authority = ace.authority_id);
-- migrate data - build equivalent ACL entries
INSERT INTO alf_acl_member (version, acl_id, ace_id, pos)
select 1, ace.acl_id, ace.id, 0 from alf_access_control_entry ace join alf_access_control_list acl on acl.id = ace.acl_id;
-- Create ACE context
CREATE TABLE alf_ace_context (
id BIGINT NOT NULL AUTO_INCREMENT,
version BIGINT NOT NULL,
class_context VARCHAR(1024),
property_context VARCHAR(1024),
kvp_context VARCHAR(1024),
primary key (id)
) ENGINE=InnoDB;
-- Create auth aliases table
CREATE TABLE alf_authority_alias (
id BIGINT NOT NULL AUTO_INCREMENT,
version BIGINT NOT NULL,
auth_id BIGINT NOT NULL,
alias_id BIGINT NOT NULL,
INDEX fk_alf_autha_ali (alias_id),
CONSTRAINT fk_alf_autha_ali FOREIGN KEY (alias_id) REFERENCES alf_authority (id),
INDEX fk_alf_autha_aut (auth_id),
CONSTRAINT fk_alf_autha_aut FOREIGN KEY (auth_id) REFERENCES alf_authority (id),
primary key (id),
UNIQUE (auth_id, alias_id)
) ENGINE=InnoDB;
-- Tidy up unused cols on ace table and add the FK contstraint back
-- finish take out of ACL_ID
-- DROP COLUMN authority_id,
-- not required from 2.1-A
-- CHANGE auth_id authority_id BIGINT NOT NULL,
ALTER TABLE alf_access_control_entry
DROP INDEX FKFFF41F99B9553F6C, DROP FOREIGN KEY FKFFF41F99B9553F6C,
DROP INDEX FKFFF41F9960601995, DROP FOREIGN KEY FKFFF41F9960601995,
DROP COLUMN acl_id,
ADD INDEX fk_alf_ace_auth (authority_id),
ADD CONSTRAINT fk_alf_ace_auth FOREIGN KEY (authority_id) REFERENCES alf_authority (id),
ADD INDEX fk_alf_ace_perm (permission_id),
ADD CONSTRAINT fk_alf_ace_perm FOREIGN KEY (permission_id) REFERENCES alf_permission (id),
ADD INDEX fk_alf_ace_ctx (context_id),
ADD CONSTRAINT fk_alf_ace_ctx FOREIGN KEY (context_id) REFERENCES alf_ace_context (id)
;
CREATE TABLE alf_tmp_min_ace (
min BIGINT NOT NULL,
permission_id BIGINT NOT NULL,
authority_id BIGINT NOT NULL,
allowed BIT(1) NOT NULL,
applies INT NOT NULL,
UNIQUE (permission_id, authority_id, allowed, applies)
) ENGINE=InnoDB;
INSERT INTO alf_tmp_min_ace (min, permission_id, authority_id, allowed, applies)
SELECT
min(ace1.id),
ace1.permission_id,
ace1.authority_id,
ace1.allowed,
ace1.applies
FROM
alf_access_control_entry ace1
GROUP BY
ace1.permission_id, ace1.authority_id, ace1.allowed, ace1.applies
;
-- Update members to point to the first use of an access control entry
UPDATE alf_acl_member mem
SET ace_id = (SELECT help.min FROM alf_access_control_entry ace
JOIN alf_tmp_min_ace help
ON help.permission_id = ace.permission_id AND
help.authority_id = ace.authority_id AND
help.allowed = ace.allowed AND
help.applies = ace.applies
WHERE ace.id = mem.ace_id );
DROP TABLE alf_tmp_min_ace;
-- Remove duplicate aces the mysql way (as you can not use the deleted table in the where clause ...)
CREATE TABLE tmp_to_delete SELECT ace.id FROM alf_acl_member mem RIGHT OUTER JOIN alf_access_control_entry ace ON mem.ace_id = ace.id WHERE mem.ace_id IS NULL;
DELETE FROM ace USING alf_access_control_entry ace JOIN tmp_to_delete t ON ace.id = t.id;
DROP TABLE tmp_to_delete;
-- Add constraint for duplicate acls
ALTER TABLE alf_access_control_entry
ADD UNIQUE (permission_id, authority_id, allowed, applies, context_id);
--
-- Record script finish
--
DELETE FROM alf_applied_patch WHERE id = 'patch.db-V2.2-ACL';
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.2-ACL-From-2.1-A', 'Manually executed script upgrade V2.2: Update acl schema',
81, 82, -1, 120, null, 'UNKOWN', 1, 1, 'Script completed'
);

File diff suppressed because it is too large Load Diff

View File

@@ -306,3 +306,7 @@ img.root=./ImageMagick
img.dyn=${img.root}/lib img.dyn=${img.root}/lib
img.exe=${img.root}/bin/convert img.exe=${img.root}/bin/convert
swf.exe=./bin/pdf2swf swf.exe=./bin/pdf2swf
# Property to enable upgrade from 2.1-A
V2.1-A.fixes.to.schema=0
#V2.1-A.fixes.to.schema=82

View File

@@ -24,6 +24,10 @@
*/ */
package org.alfresco.repo.dictionary; package org.alfresco.repo.dictionary;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -33,6 +37,7 @@ import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager; import net.sf.ehcache.CacheManager;
import org.alfresco.i18n.I18NUtil; import org.alfresco.i18n.I18NUtil;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cache.EhCacheAdapter; import org.alfresco.repo.cache.EhCacheAdapter;
import org.alfresco.repo.dictionary.constraint.RegexConstraint; import org.alfresco.repo.dictionary.constraint.RegexConstraint;
import org.alfresco.repo.dictionary.constraint.StringLengthConstraint; import org.alfresco.repo.dictionary.constraint.StringLengthConstraint;
@@ -44,10 +49,12 @@ import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.Constraint; import org.alfresco.service.cmr.dictionary.Constraint;
import org.alfresco.service.cmr.dictionary.ConstraintDefinition; import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryException;
import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.ModelDefinition; import org.alfresco.service.cmr.dictionary.ModelDefinition;
import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
@@ -372,4 +379,82 @@ public class DictionaryDAOTest extends TestCase
childAssocDef = (ChildAssociationDefinition) assocDef; childAssocDef = (ChildAssociationDefinition) assocDef;
assertTrue("Expected 'true' for timestamp propagation", childAssocDef.getPropagateTimestamps()); assertTrue("Expected 'true' for timestamp propagation", childAssocDef.getPropagateTimestamps());
} }
public void testADB159() throws UnsupportedEncodingException
{
// source dictionary
TenantService tenantService = new SingleTServiceImpl();
NamespaceDAOImpl namespaceDAO = new NamespaceDAOImpl();
namespaceDAO.setTenantService(tenantService);
initNamespaceCaches(namespaceDAO);
DictionaryDAOImpl dictionaryDAO = new DictionaryDAOImpl(namespaceDAO);
dictionaryDAO.setTenantService(tenantService);
initDictionaryCaches(dictionaryDAO);
// destination dictionary
NamespaceDAOImpl namespaceDAO2 = new NamespaceDAOImpl();
namespaceDAO2.setTenantService(tenantService);
initNamespaceCaches(namespaceDAO2);
DictionaryDAOImpl dictionaryDAO2 = new DictionaryDAOImpl(namespaceDAO2);
dictionaryDAO2.setTenantService(tenantService);
initDictionaryCaches(dictionaryDAO2);
List<String> models = new ArrayList<String>();
models.add("alfresco/model/dictionaryModel.xml");
models.add("alfresco/model/systemModel.xml");
models.add("alfresco/model/contentModel.xml");
models.add("alfresco/model/wcmModel.xml");
models.add("alfresco/model/applicationModel.xml");
models.add("org/alfresco/repo/security/authentication/userModel.xml");
models.add("org/alfresco/repo/action/actionModel.xml");
models.add("org/alfresco/repo/rule/ruleModel.xml");
models.add("org/alfresco/repo/version/version_model.xml");
// round-trip default models
for (String bootstrapModel : models)
{
InputStream modelStream = getClass().getClassLoader().getResourceAsStream(bootstrapModel);
if (modelStream == null)
{
throw new DictionaryException("Could not find bootstrap model " + bootstrapModel);
}
try
{
// parse model from xml
M2Model model = M2Model.createModel(modelStream);
dictionaryDAO.putModel(model);
// regenerate xml from model
ByteArrayOutputStream xml1 = new ByteArrayOutputStream();
model.toXML(xml1);
// register regenerated xml with other dictionary
M2Model model2 = M2Model.createModel(new ByteArrayInputStream(xml1.toByteArray()));
dictionaryDAO2.putModel(model2);
}
catch(DictionaryException e)
{
throw new DictionaryException("Could not import bootstrap model " + bootstrapModel, e);
}
}
// specific test case
M2Model model = M2Model.createModel("test:adb25");
model.createNamespace(TEST_URL, "test");
model.createImport(NamespaceService.DICTIONARY_MODEL_1_0_URI, NamespaceService.DICTIONARY_MODEL_PREFIX);
model.createImport(NamespaceService.SYSTEM_MODEL_1_0_URI, NamespaceService.SYSTEM_MODEL_PREFIX);
model.createImport(NamespaceService.CONTENT_MODEL_1_0_URI, NamespaceService.CONTENT_MODEL_PREFIX);
M2Type testType = model.createType("test:adb25" );
testType.setParentName("cm:" + ContentModel.TYPE_CONTENT.getLocalName());
M2Property prop1 = testType.createProperty("test:prop1");
prop1.setMandatory(false);
prop1.setType("d:" + DataTypeDefinition.TEXT.getLocalName());
prop1.setMultiValued(false);
ByteArrayOutputStream xml1 = new ByteArrayOutputStream();
model.toXML(xml1);
}
} }

View File

@@ -171,6 +171,10 @@ public abstract class M2ClassAssociation
this.targetRoleName = name; this.targetRoleName = name;
} }
public Boolean getTargetMandatory()
{
return isTargetMandatory();
}
public boolean isTargetMandatory() public boolean isTargetMandatory()
{ {
@@ -183,6 +187,10 @@ public abstract class M2ClassAssociation
this.isTargetMandatory = isTargetMandatory; this.isTargetMandatory = isTargetMandatory;
} }
public Boolean getTargetMandatoryEnforced()
{
return isTargetMandatoryEnforced();
}
public boolean isTargetMandatoryEnforced() public boolean isTargetMandatoryEnforced()
{ {

View File

@@ -34,8 +34,8 @@ import java.util.List;
public class M2NamedValue public class M2NamedValue
{ {
private String name; private String name;
private String simpleValue; private String simpleValue = null;
private List<String> listValue; private List<String> listValue = null;
/*package*/ M2NamedValue() /*package*/ M2NamedValue()
{ {

View File

@@ -61,7 +61,6 @@
<value name="description" field="description" usage="optional"/> <value name="description" field="description" usage="optional"/>
<value name="parent" field="parentName" usage="optional"/> <value name="parent" field="parentName" usage="optional"/>
<value name="archive" field="archive" usage="optional"/> <value name="archive" field="archive" usage="optional"/>
<structure name="properties" usage="optional"> <structure name="properties" usage="optional">
<collection field="properties" item-type="org.alfresco.repo.dictionary.M2Property" factory="org.alfresco.repo.dictionary.M2Model.createList"/> <collection field="properties" item-type="org.alfresco.repo.dictionary.M2Property" factory="org.alfresco.repo.dictionary.M2Model.createList"/>
</structure> </structure>
@@ -74,18 +73,18 @@
<value style="attribute" name="name" field="name"/> <value style="attribute" name="name" field="name"/>
<structure name="mandatory" usage="optional"> <structure name="mandatory" usage="optional">
<value style="attribute" name="enforced" field="isMandatoryEnforced" usage="optional" /> <value style="attribute" name="enforced" field="isMandatoryEnforced" usage="optional" />
<value style="text" field="isMandatory" /> <value style="text" field="isMandatory" usage="optional"/>
</structure> </structure>
<value name="default" field="defaultValue" usage="optional"/> <value name="default" field="defaultValue" usage="optional"/>
<structure name="constraints" usage="optional"> <structure name="constraints" usage="optional">
<collection field="constraints" item-type="org.alfresco.repo.dictionary.M2Constraint" factory="org.alfresco.repo.dictionary.M2Model.createList"/> <collection field="constraints" item-type="org.alfresco.repo.dictionary.M2Constraint" usage="optional" factory="org.alfresco.repo.dictionary.M2Model.createList"/>
</structure> </structure>
</structure> </structure>
</collection> </collection>
</structure> </structure>
<structure name="mandatory-aspects" usage="optional"> <structure name="mandatory-aspects" usage="optional">
<collection field="mandatoryAspects" factory="org.alfresco.repo.dictionary.M2Model.createList"> <collection field="mandatoryAspects" factory="org.alfresco.repo.dictionary.M2Model.createList">
<value name="aspect"/> <value name="aspect" type="java.lang.String"/>
</collection> </collection>
</structure> </structure>
</mapping> </mapping>
@@ -94,7 +93,7 @@
<structure map-as="org.alfresco.repo.dictionary.M2Class"/> <structure map-as="org.alfresco.repo.dictionary.M2Class"/>
</mapping> </mapping>
<mapping name="aspect" class="org.alfresco.repo.dictionary.M2Aspect" extends="org.alfresco.repo.dictionary.M2Class"> <mapping name="aspect" class="org.alfresco.repo.dictionary.M2Aspect" extends="org.alfresco.repo.dictionary.M2Class">
<structure map-as="org.alfresco.repo.dictionary.M2Class"/> <structure map-as="org.alfresco.repo.dictionary.M2Class"/>
</mapping> </mapping>
@@ -117,20 +116,16 @@
<value name="tokenised" field="indexTokenisationMode" usage="optional" serializer="org.alfresco.repo.dictionary.IndexTokenisationMode.serializer" deserializer="org.alfresco.repo.dictionary.IndexTokenisationMode.deserializer"/> <value name="tokenised" field="indexTokenisationMode" usage="optional" serializer="org.alfresco.repo.dictionary.IndexTokenisationMode.serializer" deserializer="org.alfresco.repo.dictionary.IndexTokenisationMode.deserializer"/>
</structure> </structure>
<structure name="constraints" usage="optional"> <structure name="constraints" usage="optional">
<collection field="constraints" item-type="org.alfresco.repo.dictionary.M2Constraint" factory="org.alfresco.repo.dictionary.M2Model.createList"/> <collection field="constraints" item-type="org.alfresco.repo.dictionary.M2Constraint" factory="org.alfresco.repo.dictionary.M2Model.createList" usage="optional"/>
</structure> </structure>
</mapping> </mapping>
<mapping abstract="true" class="org.alfresco.repo.dictionary.M2NamedValue"> <mapping abstract="true" class="org.alfresco.repo.dictionary.M2NamedValue">
<value style="attribute" name="name" field="name" /> <value style="attribute" name="name" field="name" />
<structure name="value" usage="optional"> <value name="value" field="simpleValue" usage="optional" />
<value style="text" field="simpleValue" />
</structure>
<structure name="list" usage="optional"> <structure name="list" usage="optional">
<collection field="listValue" factory="org.alfresco.repo.dictionary.M2Model.createList" usage="optional" > <collection field="listValue" factory="org.alfresco.repo.dictionary.M2Model.createList" usage="optional">
<structure name="value" usage="optional" > <value name="value" style="element" usage="optional" type="java.lang.String"/>
<value style="text" />
</structure>
</collection> </collection>
</structure> </structure>
</mapping> </mapping>
@@ -158,8 +153,8 @@
<value name="class" field="targetClassName"/> <value name="class" field="targetClassName"/>
<value name="role" field="targetRoleName" usage="optional"/> <value name="role" field="targetRoleName" usage="optional"/>
<structure name="mandatory" usage="optional"> <structure name="mandatory" usage="optional">
<value style="attribute" name="enforced" field="isTargetMandatoryEnforced" usage="optional"/> <value style="attribute" name="enforced" field="isTargetMandatoryEnforced" get-method="getTargetMandatoryEnforced" usage="optional"/>
<value style="text" field="isTargetMandatory" /> <value style="text" field="isTargetMandatory" get-method="getTargetMandatory"/>
</structure> </structure>
<value name="many" field="isTargetMany" usage="optional"/> <value name="many" field="isTargetMany" usage="optional"/>
</structure> </structure>

View File

@@ -1,26 +1,26 @@
/* /*
* Copyright (C) 2005-2009 Alfresco Software Limited. * Copyright (C) 2005-2009 Alfresco Software Limited.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of * As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre * the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's * and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing * FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here: * the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" * http://www.alfresco.com/legal/licensing"
*/ */
package org.alfresco.repo.node.index; package org.alfresco.repo.node.index;
@@ -36,7 +36,7 @@ import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.domain.Transaction; import org.alfresco.repo.domain.Transaction;
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.alfresco.util.ISO8601DateFormat; import org.alfresco.util.ISO8601DateFormat;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
@@ -65,10 +65,10 @@ public class IndexTransactionTracker extends AbstractReindexComponent
private Map<Long, TxnRecord> voids; private Map<Long, TxnRecord> voids;
private boolean forceReindex; private boolean forceReindex;
private long fromTxnId; private long fromTxnId;
private String statusMsg; private String statusMsg;
private static final String NO_REINDEX = "No reindex in progress"; private static final String NO_REINDEX = "No reindex in progress";
/** /**
* Set the defaults. * Set the defaults.
* <ul> * <ul>
@@ -86,16 +86,16 @@ public class IndexTransactionTracker extends AbstractReindexComponent
maxRecordSetSize = 1000; maxRecordSetSize = 1000;
maxTransactionsPerLuceneCommit = 100; maxTransactionsPerLuceneCommit = 100;
disableInTransactionIndexing = false; disableInTransactionIndexing = false;
started = false; started = false;
previousTxnIds = Collections.<Long>emptyList(); previousTxnIds = Collections.<Long>emptyList();
lastMaxTxnId = Long.MAX_VALUE; lastMaxTxnId = Long.MAX_VALUE;
fromTimeInclusive = -1L; fromTimeInclusive = -1L;
voids = new TreeMap<Long, TxnRecord>(); voids = new TreeMap<Long, TxnRecord>();
forceReindex = false; forceReindex = false;
fromTxnId = 0L; fromTxnId = 0L;
statusMsg = NO_REINDEX; statusMsg = NO_REINDEX;
} }
public synchronized void setListener(IndexTransactionTrackerListener listener) public synchronized void setListener(IndexTransactionTrackerListener listener)
@@ -195,26 +195,29 @@ public class IndexTransactionTracker extends AbstractReindexComponent
return reindexInTransaction(); return reindexInTransaction();
} }
}; };
public void resetFromTxn(long txnId) public void resetFromTxn(long txnId)
{ {
logger.info("resetFromTxn: "+txnId); if (logger.isInfoEnabled())
{
this.fromTxnId = txnId; logger.info("resetFromTxn: " + txnId);
this.started = false; // this will cause index tracker to break out (so that it can be re-started) }
}
this.fromTxnId = txnId;
this.started = false; // this will cause index tracker to break out (so that it can be re-started)
}
@Override @Override
protected void reindexImpl() protected void reindexImpl()
{ {
if (logger.isDebugEnabled()) if (logger.isInfoEnabled())
{ {
logger.debug("reindexImpl started: " + this); logger.info("reindexImpl started: " + this);
} }
RetryingTransactionHelper retryingTransactionHelper = transactionService.getRetryingTransactionHelper(); RetryingTransactionHelper retryingTransactionHelper = transactionService.getRetryingTransactionHelper();
if (!started) if (!started)
{ {
// Disable in-transaction indexing // Disable in-transaction indexing
if (disableInTransactionIndexing && nodeIndexer != null) if (disableInTransactionIndexing && nodeIndexer != null)
@@ -226,29 +229,37 @@ public class IndexTransactionTracker extends AbstractReindexComponent
voids.clear(); voids.clear();
previousTxnIds = new ArrayList<Long>(maxRecordSetSize); previousTxnIds = new ArrayList<Long>(maxRecordSetSize);
lastMaxTxnId = null; // So that it is ignored at first lastMaxTxnId = null; // So that it is ignored at first
if (this.fromTxnId != 0L) if (this.fromTxnId != 0L)
{ {
logger.info("reindexImpl: start fromTxnId: "+fromTxnId+" "+this); if (logger.isInfoEnabled())
{
Long fromTxnCommitTime = getTxnCommitTime(this.fromTxnId); logger.info("reindexImpl: start fromTxnId: " + fromTxnId);
}
if (fromTxnCommitTime == null)
{ Long fromTxnCommitTime = getTxnCommitTime(this.fromTxnId);
return;
} if (fromTxnCommitTime == null)
{
fromTimeInclusive = fromTxnCommitTime; return;
} }
else
{ fromTimeInclusive = fromTxnCommitTime;
fromTimeInclusive = retryingTransactionHelper.doInTransaction(getStartingCommitTimeWork, true, true); }
} else
{
fromTxnId = 0L; fromTimeInclusive = retryingTransactionHelper.doInTransaction(getStartingCommitTimeWork, true, true);
}
fromTxnId = 0L;
started = true; started = true;
logger.info("reindexImpl: start fromTimeInclusive: "+ISO8601DateFormat.format(new Date(fromTimeInclusive))+" "+this); if (logger.isInfoEnabled())
{
logger.info(
"reindexImpl: start fromTimeInclusive: " +
ISO8601DateFormat.format(new Date(fromTimeInclusive)));
}
} }
while (true) while (true)
@@ -262,36 +273,36 @@ public class IndexTransactionTracker extends AbstractReindexComponent
} }
// Wait for the asynchronous reindexing to complete // Wait for the asynchronous reindexing to complete
waitForAsynchronousReindexing(); waitForAsynchronousReindexing();
if (logger.isTraceEnabled()) if (logger.isTraceEnabled())
{ {
logger.trace("reindexImpl: completed: "+this); logger.trace("reindexImpl: completed: "+this);
} }
statusMsg = NO_REINDEX; statusMsg = NO_REINDEX;
}
private Long getTxnCommitTime(final long txnId)
{
RetryingTransactionHelper retryingTransactionHelper = transactionService.getRetryingTransactionHelper();
RetryingTransactionCallback<Long> getTxnCommitTimeWork = new RetryingTransactionCallback<Long>()
{
public Long execute() throws Exception
{
Transaction txn = nodeDaoService.getTxnById(txnId);
if (txn != null)
{
return txn.getCommitTimeMs();
}
logger.warn("Txn not found: "+txnId);
return null;
}
};
return retryingTransactionHelper.doInTransaction(getTxnCommitTimeWork, true, true);
} }
private Long getTxnCommitTime(final long txnId)
{
RetryingTransactionHelper retryingTransactionHelper = transactionService.getRetryingTransactionHelper();
RetryingTransactionCallback<Long> getTxnCommitTimeWork = new RetryingTransactionCallback<Long>()
{
public Long execute() throws Exception
{
Transaction txn = nodeDaoService.getTxnById(txnId);
if (txn != null)
{
return txn.getCommitTimeMs();
}
logger.warn("Txn not found: "+txnId);
return null;
}
};
return retryingTransactionHelper.doInTransaction(getTxnCommitTimeWork, true, true);
}
/** /**
* @return Returns <tt>true</tt> if the reindex process can exit otherwise <tt>false</tt> if * @return Returns <tt>true</tt> if the reindex process can exit otherwise <tt>false</tt> if
@@ -299,8 +310,8 @@ public class IndexTransactionTracker extends AbstractReindexComponent
*/ */
private boolean reindexInTransaction() private boolean reindexInTransaction()
{ {
List<Transaction> txns = null; List<Transaction> txns = null;
long toTimeExclusive = System.currentTimeMillis() - reindexLagMs; long toTimeExclusive = System.currentTimeMillis() - reindexLagMs;
// Check that the voids haven't been filled // Check that the voids haven't been filled
@@ -316,7 +327,7 @@ public class IndexTransactionTracker extends AbstractReindexComponent
} }
// get next transactions to index // get next transactions to index
txns = getNextTransactions(fromTimeInclusive, toTimeExclusive, previousTxnIds); txns = getNextTransactions(fromTimeInclusive, toTimeExclusive, previousTxnIds);
// If there are no transactions, then all the work is done // If there are no transactions, then all the work is done
if (txns.size() == 0) if (txns.size() == 0)
@@ -327,15 +338,15 @@ public class IndexTransactionTracker extends AbstractReindexComponent
return false; return false;
} }
statusMsg = String.format( statusMsg = String.format(
"Reindexing batch of %d transactions from %s (txnId=%s)", "Reindexing batch of %d transactions from %s (txnId=%s)",
txns.size(), txns.size(),
(new Date(fromTimeInclusive)).toString(), (new Date(fromTimeInclusive)).toString(),
txns.isEmpty() ? "---" : txns.get(0).getId().toString()); txns.isEmpty() ? "---" : txns.get(0).getId().toString());
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logger.debug(statusMsg); logger.debug(statusMsg);
} }
// Reindex the transactions. Voids between the last set of transactions and this // Reindex the transactions. Voids between the last set of transactions and this
@@ -372,9 +383,9 @@ public class IndexTransactionTracker extends AbstractReindexComponent
previousTxnIds.add(txn.getId()); previousTxnIds.add(txn.getId());
} }
if (isShuttingDown() || (! started)) if (isShuttingDown() || (! started))
{ {
// break out if the VM is shutting down or tracker has been reset (ie. !started) // break out if the VM is shutting down or tracker has been reset (ie. !started)
return false; return false;
} }
else else
@@ -384,11 +395,11 @@ public class IndexTransactionTracker extends AbstractReindexComponent
} }
} }
public String getReindexStatus() public String getReindexStatus()
{ {
return statusMsg; return statusMsg;
} }
private static final long ONE_HOUR_MS = 3600*1000; private static final long ONE_HOUR_MS = 3600*1000;
/** /**
* Find a transaction time to start indexing from (inclusive). The last recorded transaction by ID * Find a transaction time to start indexing from (inclusive). The last recorded transaction by ID
@@ -633,9 +644,9 @@ found:
} }
} }
if (isShuttingDown() || (! started)) if (isShuttingDown() || (! started))
{ {
// break out if the VM is shutting down or tracker has been reset (ie. !started) // break out if the VM is shutting down or tracker has been reset (ie. !started)
break; break;
} }
// Flush the reindex buffer, if it is full or if we are on the last transaction and there are no more // Flush the reindex buffer, if it is full or if we are on the last transaction and there are no more

View File

@@ -32,6 +32,7 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.jscript.ScriptNode; import org.alfresco.repo.jscript.ScriptNode;
import org.alfresco.repo.security.authority.AuthorityDAO; import org.alfresco.repo.security.authority.AuthorityDAO;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.workflow.WorkflowException; import org.alfresco.service.cmr.workflow.WorkflowException;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.dom4j.Element; import org.dom4j.Element;
@@ -50,6 +51,7 @@ public class AlfrescoAssignment extends JBPMSpringAssignmentHandler
{ {
private static final long serialVersionUID = 1025667849552265719L; private static final long serialVersionUID = 1025667849552265719L;
private ServiceRegistry services; private ServiceRegistry services;
private DictionaryService dictionaryService;
private AuthorityDAO authorityDAO; private AuthorityDAO authorityDAO;
private Element actor; private Element actor;
@@ -63,6 +65,7 @@ public class AlfrescoAssignment extends JBPMSpringAssignmentHandler
protected void initialiseHandler(BeanFactory factory) protected void initialiseHandler(BeanFactory factory)
{ {
services = (ServiceRegistry)factory.getBean(ServiceRegistry.SERVICE_REGISTRY); services = (ServiceRegistry)factory.getBean(ServiceRegistry.SERVICE_REGISTRY);
dictionaryService = services.getDictionaryService();
authorityDAO = (AuthorityDAO)factory.getBean("authorityDAO"); authorityDAO = (AuthorityDAO)factory.getBean("authorityDAO");
} }
@@ -162,6 +165,10 @@ public class AlfrescoAssignment extends JBPMSpringAssignmentHandler
if (node instanceof ScriptNode) if (node instanceof ScriptNode)
{ {
String actor = mapAuthorityToName((ScriptNode)node, true); String actor = mapAuthorityToName((ScriptNode)node, true);
if (actor == null)
{
throw new WorkflowException("pooledactors expression does not evaluate to a collection of authorities");
}
actors.add(actor); actors.add(actor);
} }
} }
@@ -218,15 +225,16 @@ public class AlfrescoAssignment extends JBPMSpringAssignmentHandler
{ {
String name = null; String name = null;
QName type = authority.getQNameType(); QName type = authority.getQNameType();
if (type.equals(ContentModel.TYPE_PERSON))
if (dictionaryService.isSubClass(type, ContentModel.TYPE_PERSON))
{ {
name = (String)authority.getProperties().get(ContentModel.PROP_USERNAME); name = (String)authority.getProperties().get(ContentModel.PROP_USERNAME);
} }
else if (type.equals(ContentModel.TYPE_AUTHORITY)) else if (allowGroup && dictionaryService.isSubClass(type, ContentModel.TYPE_AUTHORITY_CONTAINER))
{ {
name = authorityDAO.getAuthorityName(authority.getNodeRef()); name = authorityDAO.getAuthorityName(authority.getNodeRef());
} }
else if (allowGroup && type.equals(ContentModel.TYPE_AUTHORITY_CONTAINER)) else if (type.equals(ContentModel.TYPE_AUTHORITY))
{ {
name = authorityDAO.getAuthorityName(authority.getNodeRef()); name = authorityDAO.getAuthorityName(authority.getNodeRef());
} }

View File

@@ -2576,7 +2576,8 @@ public class JBPMEngine extends BPMEngine
{ {
String name = null; String name = null;
QName type = nodeService.getType(authority); QName type = nodeService.getType(authority);
if (type.equals(ContentModel.TYPE_PERSON))
if (dictionaryService.isSubClass(type, ContentModel.TYPE_PERSON))
{ {
name = (String)nodeService.getProperty(authority, ContentModel.PROP_USERNAME); name = (String)nodeService.getProperty(authority, ContentModel.PROP_USERNAME);
} }