From add74c1a59757966ec9fccacdb10fdd6c2d3e3f8 Mon Sep 17 00:00:00 2001 From: Derek Hulley Date: Wed, 20 Jan 2010 12:30:14 +0000 Subject: [PATCH] Merged V3.2 to HEAD 17332: ETHREEOH-2020: Original tag disappears after a new one has been added to a wiki page 17711: Fix ETHREEOH-3720 - blocker (upgrade from 2.x) 17712: Build/test fix (FeedCleanerTest.testConcurrentAccessAndRemoval) 17726: DownloadContentServlet wraps call in read-only RetryingTransactionHelper 17736: Fix ETHREEOH-2821 - deployment of layered file (fix for 3.2 deployment) 17745: Fixed broken PostgreSQL (AVM, audit, etc) and Oracle (audit) 17746: Merged V3.1 to V3.2 17290: Merged V2.2 to V3.1 17282: (record-only) Fix for ETWOTWO-1387: Node deletions transactions not properly detected ... 17381: (record-only) Putting explicit version name on PDFRenderer.jar 17413: (record-only) Removed dev from label 17749: Type handler fixes for PostgreSQL: Use LONGVARBINARY 17750: Fixed propval mappings for DB2 17754: Fixed "invalid character" in Oracle port of propval 17757: Re-added fix for ETHREEOH-2789 that got lost in a merge. 17762: Fix FeedCleanerTest (for Oracle 10g) + exposed feed cleaner issue (maxSize) 17765: Assorted minor build fixes for Oracle 17767: Empty String property values are persisted as '.empty' 17768: Merged DEV/BELARUS/V3.2-2009_11_24 to V3.2 17758: ETHREEOH-3757: Oracle upgrade issue: failed "inviteEmailTemplate" patch 17772: Fix build (JBPMEngineUnitTest) - fallout from r17765 17774: Fix JSONtoFmModelTest 17781: Build/test fix (AVMCrawlTestP) 17791: Fix for ETHREEOH-3793: Oracle unit test failure for JobLockServiceTest - Missing unique indexes for all DB ports 17795: ETHREEOH-3696: Attempt to navigate into any existent web-project or create new one after upgrade from Enterprise 2.1.7 ... 17799: ETHREEOH-3796: org.alfresco.repo.importer.ImporterComponentTest fails 17807: Fix ETHREEOH-3723 - MT blocker (can't restart) 17816: Merged DEV/BELARUS/V3.2-2009_12_15 to V3.2 17814: ETHREEOH-3808: Upgrade fails if content cm:name contains curly brackets ('{}') 17822: Fix for ETHREEOH-3828: Mistake porting AlfrescoPostCreate-3.2-PropertyValueTables.sql script to mssql dialect 17823: Fix for ETHREEOH-3829: SQLServer index limit reached for 'idx_alf_props_str' 17831: Fix ETHREEOH-3818 - upgrade from Community 3.2r2 to Enterprise 3.2 17862: Merged V3.1 to V3.2 17722: Fix ETHREEOH-3643 - WCM layered folders (flatten) - also add unit test 17835: ETHREEOH-3763 - fix for WCM layered folders - also add unit test 17871: Merged V3.1 to V3.2 17855: ACT 12915 - create web project performance (-> setPermission -> buildIndirections) 17863: ETHREEOH-3852 - perf tweak (WCM layered files) ------------------------------------- Modified: svn:mergeinfo Merged /alfresco/BRANCHES/DEV/BELARUS/V3.2-2009_11_24:r17758 Merged /alfresco/BRANCHES/DEV/BELARUS/V3.2-2009_12_15:r17814 Merged /alfresco/BRANCHES/V2.2:r17282 Merged /alfresco/BRANCHES/V3.1:r17290,17381,17413,17722,17835,17855,17863 Merged /alfresco/BRANCHES/V3.2:r17332,17711-17712,17726,17736,17745-17746,17749-17750,17754,17757,17762,17765,17767-17768,17772,17774,17781,17791,17795,17799,17807,17816,17822-17823,17831,17862,17871 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18169 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../AlfrescoPostCreate-3.2-LockTables.sql | 4 +- .../upgrade-from-2.1.sql | 4 +- .../remove-AVM-issuer.sql | 19 ++ .../audit-common-SqlMap.xml | 2 +- .../avm-common-SqlMap.xml | 20 ++ .../propval-common-SqlMap.xml | 49 ++-- .../avm-insert-SqlMap.xml | 5 - .../audit-insert-SqlMap.xml | 2 +- .../avm-insert-SqlMap.xml | 11 +- .../propval-insert-SqlMap.xml | 14 +- .../alfresco/patch/patch-services-context.xml | 1 + .../activities/feed/cleanup/FeedCleaner.java | 4 +- .../feed/cleanup/FeedCleanerTest.java | 75 +++-- .../repo/audit/AuditComponentTest.java | 10 +- .../repo/audit/AuditMethodInterceptor.java | 13 +- .../org/alfresco/repo/avm/AVMCrawler.java | 17 +- .../org/alfresco/repo/avm/AVMNodeImpl.java | 10 +- .../org/alfresco/repo/avm/AVMRepository.java | 7 +- .../repo/avm/AVMServiceLocalTest.java | 257 +++++++++++++++--- .../repo/avm/AVMServicePermissionsTest.java | 54 ++-- .../org/alfresco/repo/avm/AVMServiceTest.java | 226 +++++++++++++++ .../alfresco/repo/avm/AVMServiceTestBase.java | 7 +- .../org/alfresco/repo/avm/AVMStoreImpl.java | 100 +++++-- .../alfresco/repo/avm/AVMSyncServiceImpl.java | 103 +++++-- .../repo/avm/LayeredDirectoryNodeImpl.java | 7 +- source/java/org/alfresco/repo/avm/Lookup.java | 36 ++- .../alfresco/repo/avm/LookupComponent.java | 8 +- .../alfresco/repo/avm/NOOPLookupCache.java | 5 +- .../DictionaryRepositoryBootstrap.java | 54 +++- .../alfresco/repo/domain/DomainTestSuite.java | 3 +- .../hibernate/AVMAccessControlListDAO.java | 54 +++- .../propval/AbstractPropertyValueDAOImpl.java | 11 +- .../propval/PropertyStringValueEntity.java | 17 +- .../domain/propval/PropertyValueDAOTest.java | 81 ++++-- .../domain/propval/PropertyValueEntity.java | 21 +- .../repo/domain/schema/SchemaBootstrap.java | 28 +- .../repo/importer/ImporterComponentTest.java | 7 +- .../PropertyUniqueConstraintViolation.java | 8 + .../RefreshTagScopeActionExecuter.java | 2 +- .../repo/tagging/TaggingServiceImpl.java | 5 +- .../UpdateTagScopesActionExecuter.java | 2 +- .../workflow/WorkflowServiceImplTest.java | 2 +- .../repo/workflow/jbpm/JBPMEngineTest.java | 2 +- .../workflow/jbpm/JBPMEngineUnitTest.java | 14 +- .../workflow/jbpm/NodeListConverterTest.java | 2 +- .../workflow/jbpm/ReviewAndApproveTest.java | 2 +- .../java/org/alfresco/util/JSONtoFmModel.java | 11 +- .../org/alfresco/util/JSONtoFmModelTest.java | 44 +-- .../alfresco/audit/alfresco-audit-test.xml | 9 + .../jbpm-test/test-workflow-context.xml | 4 +- 50 files changed, 1160 insertions(+), 293 deletions(-) diff --git a/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-3.2-LockTables.sql b/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-3.2-LockTables.sql index 24f5c595b0..d9091725fd 100755 --- a/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-3.2-LockTables.sql +++ b/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-3.2-LockTables.sql @@ -16,7 +16,7 @@ CREATE TABLE alf_lock_resource CONSTRAINT fk_alf_lockr_ns FOREIGN KEY (qname_ns_id) REFERENCES alf_namespace (id), PRIMARY KEY (id) ); -CREATE INDEX idx_alf_lockr_key ON alf_lock_resource (qname_ns_id, qname_localname); +CREATE UNIQUE INDEX idx_alf_lockr_key ON alf_lock_resource (qname_ns_id, qname_localname); CREATE SEQUENCE alf_lock_resource_seq START WITH 1 INCREMENT BY 1; @@ -33,7 +33,7 @@ CREATE TABLE alf_lock CONSTRAINT fk_alf_lock_excl FOREIGN KEY (excl_resource_id) REFERENCES alf_lock_resource (id), PRIMARY KEY (id) ); -CREATE INDEX idx_alf_lock_key ON alf_lock (shared_resource_id, excl_resource_id); +CREATE UNIQUE INDEX idx_alf_lock_key ON alf_lock (shared_resource_id, excl_resource_id); CREATE SEQUENCE alf_lock_seq START WITH 1 INCREMENT BY 1; -- diff --git a/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.PostgreSQLDialect/upgrade-from-2.1.sql b/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.PostgreSQLDialect/upgrade-from-2.1.sql index a4f93b3c86..1bc10016e4 100644 --- a/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.PostgreSQLDialect/upgrade-from-2.1.sql +++ b/config/alfresco/dbscripts/upgrade/2.2/org.hibernate.dialect.PostgreSQLDialect/upgrade-from-2.1.sql @@ -100,7 +100,7 @@ INSERT INTO t_qnames (qname) -- Extract the namespace and localnames from the QNames UPDATE t_qnames SET namespace = 'FILLER-'||SUBSTR(qname, 2, STRPOS(qname, '}')-2); -UPDATE t_qnames SET localname = SUBSTRING(qname FROM '[^}]*$'); +UPDATE t_qnames SET localname = SUBSTRING(qname FROM position('}' in qname)+1); -- Move the Namespaces to their new home INSERT INTO alf_namespace (id, uri, version) @@ -176,7 +176,7 @@ UPDATE t_qnames_dyn SET namespace = 'FILLER-'||SUBSTR(qname, 2, STRPOS(qname, '} -- Extract the Localname -- Query OK, 415312 rows affected (16.22 sec) -UPDATE t_qnames_dyn SET local_name = SUBSTRING(qname FROM '[^}]*$'); +UPDATE t_qnames_dyn SET local_name = SUBSTRING(qname FROM position('}' in qname)+1); -- Move the namespaces to the their new home -- Query OK, 4 rows affected (34.59 sec) diff --git a/config/alfresco/dbscripts/upgrade/3.2/org.hibernate.dialect.PostgreSQLDialect/remove-AVM-issuer.sql b/config/alfresco/dbscripts/upgrade/3.2/org.hibernate.dialect.PostgreSQLDialect/remove-AVM-issuer.sql index f40abebe4a..dacd1fb965 100644 --- a/config/alfresco/dbscripts/upgrade/3.2/org.hibernate.dialect.PostgreSQLDialect/remove-AVM-issuer.sql +++ b/config/alfresco/dbscripts/upgrade/3.2/org.hibernate.dialect.PostgreSQLDialect/remove-AVM-issuer.sql @@ -13,6 +13,25 @@ SELECT SETVAL('hibernate_sequence', GREATEST((MAX(id)+1), NEXTVAL('hibernate_sequence'))) FROM avm_nodes; +insert into avm_nodes +select +(select max(id)+1 from avm_nodes), +class_type, vers, version_id, guid, creator, owner, lastModifier, createDate, modDate, accessDate, is_root, store_new_id, acl_id, deletedType, layer_id, indirection, indirection_version, primary_indirection, opacity, content_url, mime_type, encoding, length +from avm_nodes where id = 0; + +update avm_aspects set node_id = (select max(id) from avm_nodes) where node_id = 0; +update avm_child_entries set parent_id = (select max(id) from avm_nodes) where parent_id = 0; +update avm_child_entries set child_id = (select max(id) from avm_nodes) where child_id = 0; +update avm_history_links set ancestor = (select max(id) from avm_nodes) where ancestor = 0; +update avm_history_links set descendent = (select max(id) from avm_nodes) where descendent = 0; +update avm_merge_links set mfrom = (select max(id) from avm_nodes) where mfrom = 0; +update avm_merge_links set mto = (select max(id) from avm_nodes) where mto = 0; +update avm_node_properties set node_id = (select max(id) from avm_nodes) where node_id = 0; +update avm_stores set current_root_id = (select max(id) from avm_nodes) where current_root_id = 0; +update avm_version_roots set root_id = (select max(id) from avm_nodes) where root_id = 0; + +delete from avm_nodes where id = 0; + -- drop issuer table DROP TABLE avm_issuer_ids; diff --git a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/audit-common-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/audit-common-SqlMap.xml index f8ea71a6d3..2e19fbd0ee 100644 --- a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/audit-common-SqlMap.xml +++ b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/audit-common-SqlMap.xml @@ -179,7 +179,7 @@ join alf_prop_link pl on (pl.root_prop_id = entry.audit_values_id) join alf_prop_value pv on (pl.value_prop_id = pv.id) left join alf_prop_double_value dv on (dv.id = pv.long_value and pv.persisted_type = 2) - left join alf_prop_string_value sv on (sv.id = pv.long_value and (pv.persisted_type = 3 || pv.persisted_type = 5)) + left join alf_prop_string_value sv on (sv.id = pv.long_value and (pv.persisted_type = 3 OR pv.persisted_type = 5)) left join alf_prop_serializable_value serv on (serv.id = pv.long_value and pv.persisted_type = 4) diff --git a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/avm-common-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/avm-common-SqlMap.xml index 2e80c24ece..8c3406ef9b 100644 --- a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/avm-common-SqlMap.xml +++ b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/avm-common-SqlMap.xml @@ -201,6 +201,21 @@ + + + + + + + + + + + + + + + @@ -256,6 +271,11 @@ values (#versionRootId#, #md5sum#, #path#) + + insert into avm_node_properties (actual_type_n, persisted_type_n, multi_valued, boolean_value, long_value, float_value, double_value, string_value, serializable_value, node_id, qname_id) + values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + + diff --git a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/propval-common-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/propval-common-SqlMap.xml index 34b4639d3c..08ae1ef012 100644 --- a/config/alfresco/ibatis/org.hibernate.dialect.Dialect/propval-common-SqlMap.xml +++ b/config/alfresco/ibatis/org.hibernate.dialect.Dialect/propval-common-SqlMap.xml @@ -61,11 +61,19 @@ - + + + + + + + + + @@ -114,9 +122,17 @@ + + + + + + + + @@ -151,6 +167,10 @@ insert into alf_prop_root (version) values (?) + + insert into alf_prop_root (id, version) + values (?, ?) + insert into alf_prop_unique_ctx (version, value1_prop_id, value2_prop_id, value3_prop_id) @@ -274,15 +294,12 @@ - select pv.id as prop_id, pv.actual_type_id as prop_actual_type_id, pv.persisted_type as prop_persisted_type, - pv.long_value as prop_long_value, - null as prop_double_value, - null as prop_string_value, - null as prop_serializable_value + pv.long_value as prop_long_value from alf_prop_value pv where @@ -291,15 +308,13 @@ - select pv.id as prop_id, pv.actual_type_id as prop_actual_type_id, pv.persisted_type as prop_persisted_type, pv.long_value as prop_long_value, - dv.double_value as prop_double_value, - null as prop_string_value, - null as prop_serializable_value + dv.double_value as prop_double_value from alf_prop_value pv join alf_prop_double_value dv on (dv.id = pv.long_value and pv.persisted_type = #persistedType#) @@ -309,15 +324,13 @@ - select pv.id as prop_id, pv.actual_type_id as prop_actual_type_id, pv.persisted_type as prop_persisted_type, pv.long_value as prop_long_value, - null as prop_double_value, - sv.string_value as prop_string_value, - null as prop_serializable_value + sv.string_value as prop_string_value from alf_prop_value pv join alf_prop_string_value sv on (sv.id = pv.long_value and pv.persisted_type = #persistedType#) @@ -328,7 +341,7 @@ - select pv.id as prop_id, pv.actual_type_id as prop_actual_type_id, @@ -340,7 +353,7 @@ from alf_prop_value pv left join alf_prop_double_value dv on (dv.id = pv.long_value and pv.persisted_type = 2) - left join alf_prop_string_value sv on (sv.id = pv.long_value and (pv.persisted_type = 3 || pv.persisted_type = 5)) + left join alf_prop_string_value sv on (sv.id = pv.long_value and (pv.persisted_type = 3 OR pv.persisted_type = 5)) left join alf_prop_serializable_value serv on (serv.id = pv.long_value and pv.persisted_type = 4) where pv.id = #id# @@ -364,7 +377,7 @@ alf_prop_link pl join alf_prop_value pv on (pl.value_prop_id = pv.id) left join alf_prop_double_value dv on (dv.id = pv.long_value and pv.persisted_type = 2) - left join alf_prop_string_value sv on (sv.id = pv.long_value and (pv.persisted_type = 3 || pv.persisted_type = 5)) + left join alf_prop_string_value sv on (sv.id = pv.long_value and (pv.persisted_type = 3 OR pv.persisted_type = 5)) left join alf_prop_serializable_value serv on (serv.id = pv.long_value and pv.persisted_type = 4) where pl.root_prop_id = #id# @@ -389,7 +402,7 @@ alf_prop_link pl join alf_prop_value pv on (pl.value_prop_id = pv.id) left join alf_prop_double_value dv on (dv.id = pv.long_value and pv.persisted_type = 2) - left join alf_prop_string_value sv on (sv.id = pv.long_value and (pv.persisted_type = 3 || pv.persisted_type = 5)) + left join alf_prop_string_value sv on (sv.id = pv.long_value and (pv.persisted_type = 3 OR pv.persisted_type = 5)) left join alf_prop_serializable_value serv on (serv.id = pv.long_value and pv.persisted_type = 4) diff --git a/config/alfresco/ibatis/org.hibernate.dialect.MySQLInnoDBDialect/avm-insert-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.MySQLInnoDBDialect/avm-insert-SqlMap.xml index 0093ca6644..417fa2ba1c 100644 --- a/config/alfresco/ibatis/org.hibernate.dialect.MySQLInnoDBDialect/avm-insert-SqlMap.xml +++ b/config/alfresco/ibatis/org.hibernate.dialect.MySQLInnoDBDialect/avm-insert-SqlMap.xml @@ -34,9 +34,4 @@ - - insert into avm_node_properties (actual_type_n, persisted_type_n, multi_valued, boolean_value, long_value, float_value, double_value, string_value, serializable_value, node_id, qname_id) - values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - - \ No newline at end of file diff --git a/config/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/audit-insert-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/audit-insert-SqlMap.xml index 45d0121968..5f586d8734 100755 --- a/config/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/audit-insert-SqlMap.xml +++ b/config/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/audit-insert-SqlMap.xml @@ -31,7 +31,7 @@ - select nextVal('alf_audit_entry') + select nextVal('alf_audit_entry_seq') insert into alf_audit_entry (id, audit_app_id, audit_user_id, audit_time, audit_values_id) diff --git a/config/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/avm-insert-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/avm-insert-SqlMap.xml index 4134760abe..609eebedb5 100755 --- a/config/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/avm-insert-SqlMap.xml +++ b/config/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/avm-insert-SqlMap.xml @@ -17,14 +17,14 @@ - + - + select nextVal('hibernate_sequence') insert into avm_store_properties (id, actual_type_n, persisted_type_n, multi_valued, boolean_value, long_value, float_value, double_value, string_value, serializable_value, avm_store_id, qname_id) - values (#id#, #actualType#, #persistedType#, #isMultiValued#, #booleanValue#, #longValue#, #floatValue#, #doubleValue#, #stringValue#, #serializableValue#, #avmStoreId#, #qnameId#) + values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) @@ -50,9 +50,4 @@ - - insert into avm_node_properties (actual_type_n, persisted_type_n, multi_valued, boolean_value, long_value, float_value, double_value, string_value, serializable_value, node_id, qname_id) - values (#actualType#, #persistedType#, #isMultiValued#, #booleanValue#, #longValue#, #floatValue#, #doubleValue#, #stringValue#, #serializableValue#, #nodeId#, #qnameId#) - - \ No newline at end of file diff --git a/config/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/propval-insert-SqlMap.xml b/config/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/propval-insert-SqlMap.xml index fde6af82da..eda9c88559 100755 --- a/config/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/propval-insert-SqlMap.xml +++ b/config/alfresco/ibatis/org.hibernate.dialect.PostgreSQLDialect/propval-insert-SqlMap.xml @@ -38,14 +38,14 @@ - + select nextVal('alf_prop_serializable_value_seq') insert into alf_prop_serializable_value (id, serializable_value) - values (#id#, #serializableValue#) + values (?, ?) @@ -60,15 +60,11 @@ - - - + + select nextVal('alf_prop_root_seq') - - insert into alf_prop_root (id, version) - values (#id#, #version#) - + diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml index e289f8696e..78cb8993a1 100644 --- a/config/alfresco/patch/patch-services-context.xml +++ b/config/alfresco/patch/patch-services-context.xml @@ -1378,6 +1378,7 @@ /${spaces.company_home.childname}/${spaces.dictionary.childname}/${spaces.templates.email.childname} alfresco/bootstrap/invite/invite-email.xml + alfresco/messages/bootstrap-spaces diff --git a/source/java/org/alfresco/repo/activities/feed/cleanup/FeedCleaner.java b/source/java/org/alfresco/repo/activities/feed/cleanup/FeedCleaner.java index 015d427d2e..eeeb47a381 100644 --- a/source/java/org/alfresco/repo/activities/feed/cleanup/FeedCleaner.java +++ b/source/java/org/alfresco/repo/activities/feed/cleanup/FeedCleaner.java @@ -150,11 +150,11 @@ public class FeedCleaner if ((feedUserId == null) || (feedUserId.length() == 0)) { - deletedCount = feedDAO.deleteUserFeedEntries(feedUserId, format, oldestFeedEntry); + deletedCount = feedDAO.deleteSiteFeedEntries(siteId, format, oldestFeedEntry); } else { - deletedCount = feedDAO.deleteSiteFeedEntries(siteId, format, oldestFeedEntry); + deletedCount = feedDAO.deleteUserFeedEntries(feedUserId, format, oldestFeedEntry); } diff --git a/source/java/org/alfresco/repo/activities/feed/cleanup/FeedCleanerTest.java b/source/java/org/alfresco/repo/activities/feed/cleanup/FeedCleanerTest.java index c58f289f88..9e295ef531 100644 --- a/source/java/org/alfresco/repo/activities/feed/cleanup/FeedCleanerTest.java +++ b/source/java/org/alfresco/repo/activities/feed/cleanup/FeedCleanerTest.java @@ -33,7 +33,7 @@ import junit.framework.TestCase; import org.alfresco.repo.domain.activities.ActivityFeedDAO; import org.alfresco.repo.domain.activities.ActivityFeedEntity; import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.service.cmr.activities.ActivityService; +import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.service.cmr.site.SiteService; import org.alfresco.service.cmr.site.SiteVisibility; import org.alfresco.util.ApplicationContextHelper; @@ -50,15 +50,17 @@ public class FeedCleanerTest extends TestCase private ActivityFeedDAO feedDAO; private FeedCleaner cleaner; - private ActivityService activityService; private SiteService siteService; + protected RetryingTransactionHelper transactionHelper; @Override public void setUp() throws Exception { - activityService = (ActivityService) ctx.getBean("activityService"); siteService = (SiteService) ctx.getBean("SiteService"); feedDAO = (ActivityFeedDAO) ctx.getBean("feedDAO"); + transactionHelper = (RetryingTransactionHelper)ctx.getBean("retryingTransactionHelper"); + + tearDown(); AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); for (int i = 1; i <= 7; i++) @@ -75,12 +77,17 @@ public class FeedCleanerTest extends TestCase public void tearDown() throws Exception { + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); + // clean out any remaining feed entries (allows test to be re-runnable) feedDAO.deleteFeedEntries(new Date(System.currentTimeMillis()+(120*1000L))); for (int i = 1; i <= 7; i++) { - siteService.deleteSite("testSite"+i); + if (siteService.getSite("testSite"+i) != null) + { + siteService.deleteSite("testSite"+i); + } } AuthenticationUtil.clearCurrentSecurityContext(); @@ -147,15 +154,15 @@ public class FeedCleanerTest extends TestCase feedDAO.insertFeedEntry(feedEntry); - assertEquals(2, activityService.getSiteFeedEntries("testSite1", "json").size()); - assertEquals(2, activityService.getUserFeedEntries("testUserB", "json", null).size()); + assertEquals(2, feedDAO.selectSiteFeedEntries("testSite1", "json").size()); + assertEquals(2, feedDAO.selectUserFeedEntries("testUserB", "json", null, false, false).size()); // fire the cleaner cleaner.setMaxAgeMins(10); cleaner.execute(); - assertEquals(1, activityService.getSiteFeedEntries("testSite1", "json").size()); - assertEquals(1, activityService.getUserFeedEntries("testUserB", "json", null).size()); + assertEquals(1, feedDAO.selectSiteFeedEntries("testSite1", "json").size()); + assertEquals(1, feedDAO.selectUserFeedEntries("testUserB", "json", null, false, false).size()); } public void testMaxSize() throws Exception @@ -196,15 +203,15 @@ public class FeedCleanerTest extends TestCase feedDAO.insertFeedEntry(feedEntry); } - assertEquals(10, activityService.getSiteFeedEntries("testSite4", "json").size()); - assertEquals(10, activityService.getUserFeedEntries("testUserD", "json", null).size()); + assertEquals(10, feedDAO.selectSiteFeedEntries("testSite4", "json").size()); + assertEquals(10, feedDAO.selectUserFeedEntries("testUserD", "json", null, false, false).size()); // fire the cleaner cleaner.setMaxFeedSize(2); cleaner.execute(); - assertEquals(2, activityService.getSiteFeedEntries("testSite4", "json").size()); - assertEquals(2, activityService.getUserFeedEntries("testUserD", "json", null).size()); + assertEquals(2, feedDAO.selectSiteFeedEntries("testSite4", "json").size()); + assertEquals(2, feedDAO.selectUserFeedEntries("testUserD", "json", null, false, false).size()); Date sameTime = new Date(); @@ -242,16 +249,17 @@ public class FeedCleanerTest extends TestCase feedDAO.insertFeedEntry(feedEntry); } - assertEquals(10, activityService.getSiteFeedEntries("testSite6", "json").size()); - assertEquals(10, activityService.getUserFeedEntries("testUserF", "json", null).size()); + assertEquals(10, feedDAO.selectSiteFeedEntries("testSite6", "json").size()); + assertEquals(10, feedDAO.selectUserFeedEntries("testUserF", "json", null, false, false).size()); // fire the cleaner cleaner.setMaxFeedSize(2); cleaner.execute(); // note: no effect, since entries at max feed size have same time (eg. to nearest minute) - assertEquals(10, activityService.getSiteFeedEntries("testSite6", "json").size()); - assertEquals(10, activityService.getUserFeedEntries("testUserF", "json", null).size()); + + assertEquals(10, feedDAO.selectSiteFeedEntries("testSite6", "json").size()); + assertEquals(10, feedDAO.selectUserFeedEntries("testUserF", "json", null, false, false).size()); } public void testConcurrentAccessAndRemoval() throws Exception @@ -316,7 +324,7 @@ public class FeedCleanerTest extends TestCase // insert some entries for (int i = 0; i < insertCount; i++) { - ActivityFeedEntity feedEntry = new ActivityFeedEntity(); + final ActivityFeedEntity feedEntry = new ActivityFeedEntity(); feedEntry.setPostDate(new Date(System.currentTimeMillis()-(i*60*1000L))); feedEntry.setActivitySummaryFormat("json"); @@ -326,7 +334,14 @@ public class FeedCleanerTest extends TestCase feedEntry.setFeedUserId(""); feedEntry.setFeedDate(new Date()); - feedDAO.insertFeedEntry(feedEntry); + transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback() + { + public Object execute() throws Throwable + { + feedDAO.insertFeedEntry(feedEntry); + return null; + } + }); } System.out.println("["+i+"] Inserted "+insertCount+" entries"); @@ -336,8 +351,15 @@ public class FeedCleanerTest extends TestCase { AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); - // query some entries - int selectCount = activityService.getSiteFeedEntries("testSite4", "json").size(); + int selectCount = transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback() + { + public Integer execute() throws Throwable + { + // query some entries + int selectCount = feedDAO.selectSiteFeedEntries("testSite4", "json").size(); + return selectCount; + } + }); System.out.println("["+i+"] Selected "+selectCount+" entries"); } @@ -346,8 +368,15 @@ public class FeedCleanerTest extends TestCase { AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName()); - // clean some entries - int deleteCount = cleaner.execute(); + int deleteCount = transactionHelper.doInTransaction(new RetryingTransactionHelper.RetryingTransactionCallback() + { + public Integer execute() throws Throwable + { + // clean some entries + int deleteCount = cleaner.execute(); + return deleteCount; + } + }); System.out.println("["+i+"] Deleted "+deleteCount+" entries"); } @@ -362,4 +391,4 @@ public class FeedCleanerTest extends TestCase } } } -} +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/audit/AuditComponentTest.java b/source/java/org/alfresco/repo/audit/AuditComponentTest.java index 0b6f31a415..f07b76c92d 100644 --- a/source/java/org/alfresco/repo/audit/AuditComponentTest.java +++ b/source/java/org/alfresco/repo/audit/AuditComponentTest.java @@ -194,11 +194,13 @@ public class AuditComponentTest extends TestCase public Void execute() throws Throwable { Map values = new HashMap(13); - values.put("/2.1/3.1/4.1", new Long(41)); - values.put("/2.1/3.1/4.2", "42"); - values.put("/2.1/3.1/4.2", new Date()); + values.put("/3.1/4.1", new Long(41)); + values.put("/3.1/4.2", "42"); + values.put("/3.1/4.3", new Date()); + values.put("/3.1/4.4", ""); + values.put("/3.1/4.5", null); - auditComponent.recordAuditValues("/test/1.1", values); + auditComponent.recordAuditValues("/test/one.one/two.one", values); return null; } diff --git a/source/java/org/alfresco/repo/audit/AuditMethodInterceptor.java b/source/java/org/alfresco/repo/audit/AuditMethodInterceptor.java index 163ecc075b..e15c73836b 100644 --- a/source/java/org/alfresco/repo/audit/AuditMethodInterceptor.java +++ b/source/java/org/alfresco/repo/audit/AuditMethodInterceptor.java @@ -30,6 +30,7 @@ import java.util.Map; import org.alfresco.error.StackTraceUtil; import org.alfresco.repo.audit.model.AuditApplication; +import org.alfresco.repo.domain.schema.SchemaBootstrap; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.Auditable; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; @@ -318,6 +319,11 @@ public class AuditMethodInterceptor implements MethodInterceptor continue; } } + // Trim strings + if (arg instanceof String) + { + arg = SchemaBootstrap.trimStringForTextFields((String)arg); + } // It is named and recordable namedArgs.put(params[i], arg); } @@ -380,6 +386,11 @@ public class AuditMethodInterceptor implements MethodInterceptor } if (ret != null) { + if (ret instanceof String) + { + // Make sure the string fits + ret = SchemaBootstrap.trimStringForTextFields((String) ret); + } if (ret instanceof Serializable) { auditData.put(AUDIT_SNIPPET_RESULT, (Serializable) ret); @@ -404,7 +415,7 @@ public class AuditMethodInterceptor implements MethodInterceptor StringBuilder sb = new StringBuilder(1024); StackTraceUtil.buildStackTrace( thrown.getMessage(), thrown.getStackTrace(), sb, Integer.MAX_VALUE); - auditData.put(AUDIT_SNIPPET_ERROR, sb.toString()); + auditData.put(AUDIT_SNIPPET_ERROR, SchemaBootstrap.trimStringForTextFields(sb.toString())); // An exception will generally roll the current transaction back RetryingTransactionCallback> auditCallback = diff --git a/source/java/org/alfresco/repo/avm/AVMCrawler.java b/source/java/org/alfresco/repo/avm/AVMCrawler.java index 3e6db781ba..eb057b0869 100644 --- a/source/java/org/alfresco/repo/avm/AVMCrawler.java +++ b/source/java/org/alfresco/repo/avm/AVMCrawler.java @@ -45,6 +45,7 @@ import org.alfresco.service.cmr.avm.AVMStoreDescriptor; import org.alfresco.service.cmr.repository.ContentIOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.dao.ConcurrencyFailureException; /** @@ -297,20 +298,16 @@ class AVMCrawler implements Runnable } catch (Exception e) { - if (e instanceof AVMNotFoundException) + if ((e instanceof AVMNotFoundException) || + (e instanceof AVMException) || + (e instanceof ContentIOException) || + (e instanceof ConcurrencyFailureException)) { - logger.info(e.getMessage()); + logger.warn(e.getMessage()); return; } + e.printStackTrace(System.err); - if (e instanceof AVMException) - { - return; - } - if (e instanceof ContentIOException) - { - return; - } throw new AVMException("Failure", e); } } diff --git a/source/java/org/alfresco/repo/avm/AVMNodeImpl.java b/source/java/org/alfresco/repo/avm/AVMNodeImpl.java index 1dcfdb87eb..089e856cda 100644 --- a/source/java/org/alfresco/repo/avm/AVMNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMNodeImpl.java @@ -44,9 +44,9 @@ import org.apache.commons.logging.LogFactory; */ public abstract class AVMNodeImpl implements AVMNode { - private static Log fgLogger = LogFactory.getLog(AVMNodeImpl.class); + private static Log logger = LogFactory.getLog(AVMNodeImpl.class); - protected static final boolean DEBUG = fgLogger.isDebugEnabled(); + protected static final boolean DEBUG = logger.isDebugEnabled(); /** * The Object ID. @@ -579,4 +579,10 @@ public abstract class AVMNodeImpl implements AVMNode fAspects = null; AVMDAOs.Instance().fAVMNodeDAO.deleteAspect(this.getId(), aspectQName); } + + // debug + public String toString() + { + return toString(null); + } } diff --git a/source/java/org/alfresco/repo/avm/AVMRepository.java b/source/java/org/alfresco/repo/avm/AVMRepository.java index d8d6aac891..e3b30f2d5a 100644 --- a/source/java/org/alfresco/repo/avm/AVMRepository.java +++ b/source/java/org/alfresco/repo/avm/AVMRepository.java @@ -3160,7 +3160,12 @@ public class AVMRepository PlainFileNode file = (PlainFileNode) node; return file.getContentData(); } - throw new AVMWrongTypeException("Not a Plain File: " + desc); + else if (node.getType() == AVMNodeType.LAYERED_FILE) + { + LayeredFileNode file = (LayeredFileNode) node; + return file.getContentData(null); + } + throw new AVMWrongTypeException("Not a file: " + desc); } public Set getAspects(AVMNodeDescriptor desc) diff --git a/source/java/org/alfresco/repo/avm/AVMServiceLocalTest.java b/source/java/org/alfresco/repo/avm/AVMServiceLocalTest.java index be436e7776..f9be6e6958 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceLocalTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceLocalTest.java @@ -878,6 +878,9 @@ public class AVMServiceLocalTest extends TestCase // Flatten. fSyncService.flatten("main:/layer", "main:/a"); recursiveList("main"); + // Compare again. + diffs = fSyncService.compare(-1, "main:/layer", -1, "main:/a", null); + assertEquals(0, diffs.size()); } catch (Exception e) { @@ -1156,7 +1159,7 @@ public class AVMServiceLocalTest extends TestCase recursiveContents("main:/"); fService.createFile("layer:/a/b/z", "fudge").close(); fService.rename("layer:/a/b", "z", "layer:/a/b", "y"); - recursiveContents("layer:/"); + recursiveContents("layer:/"); diffs = fSyncService.compare(-1, "layer:/a", -1, "main:/a", null); assertEquals(2, diffs.size()); assertEquals("[layer:/a/b/y[-1] > main:/a/b/y[-1], layer:/a/b/z[-1] > main:/a/b/z[-1]]", diffs.toString()); @@ -1898,10 +1901,6 @@ public class AVMServiceLocalTest extends TestCase fService.createStore("mainB--layer"); - recursiveList("mainA"); - recursiveList("mainB"); - recursiveList("mainB--layer"); - List snapshots = fService.getStoreVersions("mainA"); assertEquals(1, snapshots.size()); assertEquals(0, snapshots.get(0).getVersionID()); @@ -1925,19 +1924,11 @@ public class AVMServiceLocalTest extends TestCase logger.debug("created file: mainA:/a/b/foo"); - recursiveList("mainA"); - recursiveList("mainB"); - recursiveList("mainB--layer"); - // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to mainA:/a/b) fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b"); logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b"); - recursiveList("mainA"); - recursiveList("mainB"); - recursiveList("mainB--layer"); - fService.createFile("mainB--layer:/a/b", "bar"); out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/bar")); @@ -1946,10 +1937,6 @@ public class AVMServiceLocalTest extends TestCase logger.debug("created file: mainB--layer:/a/b/bar"); - recursiveList("mainA"); - recursiveList("mainB"); - recursiveList("mainB--layer"); - List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null); assertEquals(1, diffs.size()); assertEquals("[mainB--layer:/a/b/bar[-1] > mainB:/a/b/bar[-1]]", diffs.toString()); @@ -1966,10 +1953,6 @@ public class AVMServiceLocalTest extends TestCase logger.debug("updated: created file: mainB:/a/b/bar"); - recursiveList("mainA"); - recursiveList("mainB"); - recursiveList("mainB--layer"); - snapshots = fService.getStoreVersions("mainB"); assertEquals(3, snapshots.size()); assertEquals(2, snapshots.get(snapshots.size()-1).getVersionID()); @@ -1983,18 +1966,10 @@ public class AVMServiceLocalTest extends TestCase logger.debug("created file: mainA:/a/b/baz"); - recursiveList("mainA"); - recursiveList("mainB"); - recursiveList("mainB--layer"); - fService.createSnapshot("mainB", "two", "two"); logger.debug("snapshot: mainB"); - recursiveList("mainA"); - recursiveList("mainB"); - recursiveList("mainB--layer"); - snapshots = fService.getStoreVersions("mainB"); assertEquals(4, snapshots.size()); assertEquals(3, snapshots.get(snapshots.size()-1).getVersionID()); @@ -2004,10 +1979,6 @@ public class AVMServiceLocalTest extends TestCase assertEquals(1, diffs.size()); assertEquals("[mainB:/a/b/baz[2] < mainB:/a/b/baz[3]]", diffs.toString()); - recursiveList("mainA"); - recursiveList("mainB"); - recursiveList("mainB--layer"); - logger.debug("list mainB [2]"); recursiveList("mainB", 2); @@ -2015,6 +1986,10 @@ public class AVMServiceLocalTest extends TestCase logger.debug("list mainB [3]"); recursiveList("mainB", 3); + + recursiveList("mainA"); + recursiveList("mainB"); + recursiveList("mainB--layer"); } catch (Exception e) { @@ -2029,6 +2004,222 @@ public class AVMServiceLocalTest extends TestCase } } + public void testLayeredFolder3() throws Exception + { + try + { + fService.createStore("mainA"); + fService.createStore("mainB"); + fService.createStore("mainB--layer"); + + logger.debug("created stores: mainA, mainB and mainB--layer"); + + fService.createDirectory("mainA:/", "a"); + fService.createDirectory("mainA:/a", "b"); + fService.createDirectory("mainB:/", "a"); + + logger.debug("created directories: mainA:/a/b and mainB:/a"); + + fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a"); + + logger.debug("created layered directory: mainB--layer:/a -> mainB:/a"); + + // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to mainA:/a/b) + fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b"); + + logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b"); + + fService.createDirectory("mainB--layer:/a/b", "c"); + + logger.debug("created directory: mainB--layer:/a/b/c"); + + fService.createFile("mainB--layer:/a/b/c", "foo"); + + PrintStream out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/c/foo")); + out.println("I am mainB--layer:/a/b/c/foo"); + out.close(); + + logger.debug("created file: mainB--layer:/a/b/c/foo"); + + List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[mainB--layer:/a/b/c[-1] > mainB:/a/b/c[-1]]", diffs.toString()); + + fSyncService.update(diffs, null, false, false, false, false, "one", "one"); + + logger.debug("updated: mainB--layer:/a/b/c (including 'foo') to mainB:/a/b/c"); + + diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null); + assertEquals(0, diffs.size()); + + diffs = fSyncService.compare(-1, "mainB:/a", -1, "mainA:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[mainB:/a/b/c[-1] > mainA:/a/b/c[-1]]", diffs.toString()); + + fSyncService.flatten("mainB--layer:/a", "mainB:/a"); + + logger.debug("flattened: mainB--layer:/a to mainB:/a"); + + diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null); + assertEquals(0, diffs.size()); + + diffs = fSyncService.compare(-1, "mainB:/a", -1, "mainA:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[mainB:/a/b/c[-1] > mainA:/a/b/c[-1]]", diffs.toString()); + + // ETHREEOH-3643 + out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/c/foo")); + out.println("I am mainB--layer:/a/b/c/foo V2"); + out.close(); + + logger.debug("updated file: mainB--layer:/a/b/c/foo"); + + diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[mainB--layer:/a/b/c/foo[-1] > mainB:/a/b/c/foo[-1]]", diffs.toString()); + + logger.debug("updated: mainB:/a/b/c/foo"); + + diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[mainB--layer:/a/b/c/foo[-1] > mainB:/a/b/c/foo[-1]]", diffs.toString()); + + fSyncService.update(diffs, null, false, false, false, false, "two", "two"); + + logger.debug("updated: mainB--layer:/a/b/c/foo to mainB:/a/b/c/foo"); + + fSyncService.flatten("mainB--layer:/a", "mainB:/a"); + + logger.debug("flattened: mainB--layer:/a to mainB:/a"); + + diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null); + assertEquals(0, diffs.size()); + + recursiveList("mainA"); + recursiveList("mainB"); + recursiveList("mainB--layer"); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + finally + { + fService.purgeStore("mainA"); + fService.purgeStore("mainB"); + fService.purgeStore("mainB--layer"); + } + } + + public void testLayeredFolder4() throws Exception + { + try + { + fService.createStore("mainA"); + fService.createStore("mainB"); + fService.createStore("mainB--layer"); + + logger.debug("created stores: mainA, mainB and mainB--layer"); + + fService.createDirectory("mainA:/", "a"); + fService.createDirectory("mainA:/a", "b"); + fService.createDirectory("mainA:/a/b", "c"); + fService.createDirectory("mainB:/", "a"); + + logger.debug("created directories: mainA:/a/b/c and mainB:/a"); + + fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a"); + + logger.debug("created layered directory: mainB--layer:/a -> mainB:/a"); + + // create equivalent of WCM layered folder between web project staging sandboxes (mainB:/a/b pointing to mainA:/a/b) + fService.createLayeredDirectory("mainA:/a/b", "mainB:/a", "b"); + + logger.debug("created layered directory: mainB:/a/b -> mainA:/a/b"); + + fService.createDirectory("mainB--layer:/a/b/c", "d"); + + logger.debug("created directory: mainB--layer:/a/b/c/d"); + + List diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[mainB--layer:/a/b/c/d[-1] > mainB:/a/b/c/d[-1]]", diffs.toString()); + + fSyncService.update(diffs, null, false, false, false, false, "one", "one"); + + logger.debug("updated: mainB--layer:/a/b/c/d to mainB:/a/b/c/d"); + + fSyncService.flatten("mainB--layer:/a", "mainB:/a"); + + logger.debug("flattened: mainB--layer:/a to mainB:/a"); + + fService.createFile("mainB--layer:/a/b/c/d", "foo"); + + PrintStream out = new PrintStream(fService.getFileOutputStream("mainB--layer:/a/b/c/d/foo")); + out.println("I am mainB--layer:/a/b/c/d/foo"); + out.close(); + + logger.debug("created file: mainB--layer:/a/b/c/foo"); + + fService.createStore("mainB--workflow1"); + + logger.debug("created store: mainB--workflow1"); + + fService.createLayeredDirectory("mainB:/a", "mainB--workflow1:/", "a"); + + logger.debug("created layered dir: mainB--workflow1:/a -> mainB:/a"); + + diffs = fSyncService.compare(-1, "mainB--workflow1:/a", -1, "mainB:/a", null); + assertEquals(0, diffs.size()); + + diffs = new ArrayList(1); + diffs.add(new AVMDifference(-1, "mainB--layer:/a/b/c/d/foo", -1, "mainB--workflow1:/a/b/c/d/foo", AVMDifference.NEWER)); + + assertNotNull(fService.lookup(-1, "mainB--workflow1:/a/b/c/d")); + + // ETHREEOH-3763 + fSyncService.update(diffs, null, false, false, false, false, null, null); + + logger.debug("updated: added file: mainB--workflow1:/a/b/c/d/foo"); + + diffs = fSyncService.compare(-1, "mainB--layer:/a", -1, "mainB:/a", null); + assertEquals("[mainB--layer:/a/b/c/d/foo[-1] > mainB:/a/b/c/d/foo[-1]]", diffs.toString()); + + diffs = fSyncService.compare(-1, "mainB--workflow1:/a", -1, "mainB:/a", null); + assertEquals("[mainB--workflow1:/a/b/c/d/foo[-1] > mainB:/a/b/c/d/foo[-1]]", diffs.toString()); + + fSyncService.update(diffs, null, false, false, true, true, "two", "two"); + fSyncService.flatten("mainB--workflow1:/a", "mainB:/a"); + + logger.debug("updated & flattened: added file: mainB:/a/b/c/d/foo"); + + diffs = fSyncService.compare(-1, "mainB--workflow1:/a", -1, "mainB:/a", null); + assertEquals(0, diffs.size()); + + diffs = fSyncService.compare(-1, "mainB--workflow1:/a", -1, "mainB--layer:/a", null); + assertEquals(0, diffs.size()); + + fService.purgeStore("mainB--workflow1"); + + recursiveList("mainA"); + recursiveList("mainB"); + recursiveList("mainB--layer"); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + finally + { + fService.purgeStore("mainA"); + fService.purgeStore("mainB"); + fService.purgeStore("mainB--layer"); + if (fService.getStore("mainB--workflow1") != null) { fService.purgeStore("mainB--workflow1"); } + } + } + public void testLayeredFolderDelete1() throws Exception { try diff --git a/source/java/org/alfresco/repo/avm/AVMServicePermissionsTest.java b/source/java/org/alfresco/repo/avm/AVMServicePermissionsTest.java index f8ebdc52fb..40e59e38a8 100644 --- a/source/java/org/alfresco/repo/avm/AVMServicePermissionsTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServicePermissionsTest.java @@ -3934,10 +3934,9 @@ public class AVMServicePermissionsTest extends TestCase private static final String FILE_NAME = "fileForExport"; - private static final String STORE_NAME = "TestStore1"; private static final String ROOT = "ROOT"; - private void createStaggingWithSnapshots(String storeName) + private void createStagingWithSnapshots(String storeName) { if (avmService.getStore(storeName) != null) { @@ -3964,27 +3963,40 @@ public class AVMServicePermissionsTest extends TestCase private void removeStore(String storeName) { - avmService.purgeStore(storeName); + if (avmService.getStore(storeName) != null) + { + avmService.purgeStore(storeName); + } assertNull(avmService.getStore(storeName)); } - - public void testSetInheritParentPermissions() + + public void testSetInheritParentPermissions() throws Exception { - createStaggingWithSnapshots(STORE_NAME); - - AVMNodeDescriptor nodeDescriptor = avmService.lookup(-1, STORE_NAME + ":/" + JNDIConstants.DIR_DEFAULT_WWW + "/" + JNDIConstants.DIR_DEFAULT_APPBASE + "/" + ROOT + "/" - + FILE_NAME); - assertNotNull(nodeDescriptor); - NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, nodeDescriptor.getPath()); - assertNotNull(nodeRef); - - permissionService.setInheritParentPermissions(nodeRef, false); - assertFalse(permissionService.getInheritParentPermissions(nodeRef)); - permissionService.setInheritParentPermissions(nodeRef, true); - assertTrue(permissionService.getInheritParentPermissions(nodeRef)); - - removeStore(STORE_NAME); + runAs(AuthenticationUtil.getAdminUserName()); + String storeName = "PermissionsTest-" + getName() + "-" + (new Date().getTime()); + try + { + createStagingWithSnapshots(storeName); + + AVMNodeDescriptor nodeDescriptor = avmService.lookup(-1, storeName + ":/" + JNDIConstants.DIR_DEFAULT_WWW + "/" + JNDIConstants.DIR_DEFAULT_APPBASE + "/" + ROOT + "/" + + FILE_NAME); + assertNotNull(nodeDescriptor); + NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, nodeDescriptor.getPath()); + assertNotNull(nodeRef); + + permissionService.setInheritParentPermissions(nodeRef, false); + assertFalse(permissionService.getInheritParentPermissions(nodeRef)); + permissionService.setInheritParentPermissions(nodeRef, true); + assertTrue(permissionService.getInheritParentPermissions(nodeRef)); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + finally + { + removeStore(storeName); + } } - - } diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java index 2d0cbbb704..c26c8f73cc 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java @@ -69,6 +69,7 @@ import org.alfresco.service.cmr.avmsync.AVMDifference; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.remote.RepoRemote; +import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.CrossRepositoryCopyService; import org.alfresco.service.cmr.repository.NodeRef; @@ -3985,6 +3986,84 @@ public class AVMServiceTest extends AVMServiceTestBase throw e; } } + + public void testLayeredFile4() throws Exception + { + try + { + fService.createStore("mainA"); + fService.createStore("mainB"); + fService.createStore("mainB--layer"); + + fService.createDirectory("mainA:/", "a"); + fService.createDirectory("mainB:/", "a"); + + fService.createLayeredDirectory("mainB:/a", "mainB--layer:/", "a"); + + // note: unlike WCM, edit staging directly (ie. don't bother with mainA--layer for now) + fService.createFile("mainA:/a", "foo"); + + PrintStream out = new PrintStream(fService.getFileOutputStream("mainA:/a/foo")); + out.println("I am mainA:/a/foo"); + out.close(); + + fService.createSnapshot("mainA", null, null); + + // note: WCM does not expose layered file (between web project staging sandboxes) + fService.createLayeredFile("mainA:/a/foo", "mainB:/a", "foo"); + + + AVMNodeDescriptor foo = fService.lookup(-1, "mainB--layer:/a/foo"); + assertEquals(1, foo.getVersionID()); + assertTrue(foo.isLayeredFile()); + + ContentData cData = fService.getContentDataForRead(foo); + assertNotNull(cData); + + BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB--layer:/a/foo"))); + String line = reader.readLine(); + reader.close(); + assertEquals("I am mainA:/a/foo", line); + + + foo = fService.lookup(-1, "mainB:/a/foo"); + assertEquals(1, foo.getVersionID()); + assertTrue(foo.isLayeredFile()); + + cData = fService.getContentDataForRead(foo); + assertNotNull(cData); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainB:/a/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am mainA:/a/foo", line); + + + foo = fService.lookup(-1, "mainA:/a/foo"); + assertEquals(1, foo.getVersionID()); + assertTrue(foo.isPlainFile()); + + cData = fService.getContentDataForRead(foo); + assertNotNull(cData); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "mainA:/a/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am mainA:/a/foo", line); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + finally + { + fService.purgeStore("mainA"); + fService.purgeStore("mainB"); + fService.purgeStore("mainB--layer"); + } + } + /** * Test rename. @@ -5084,6 +5163,152 @@ public class AVMServiceTest extends AVMServiceTestBase throw e; } } + + public void testVersionedRead2() throws Exception + { + try + { + assertNull(fService.lookup(-1, "main:/foo")); + assertNull(fService.lookup(-1, "main:/afoo")); + + try + { + fService.getFileInputStream(-1, "main:/afoo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + PrintStream out = new PrintStream(fService.createFile("main:/", "foo")); + out.print("version1"); + out.close(); + + BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + assertEquals("version1", reader.readLine()); + reader.close(); + + fService.createLayeredFile("main:/foo", "main:/", "afoo"); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/afoo"))); + assertEquals("version1", reader.readLine()); + reader.close(); + + fService.createSnapshot("main", null, null); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/foo"))); + assertEquals("version1", reader.readLine()); + reader.close(); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/afoo"))); + assertEquals("version1", reader.readLine()); + reader.close(); + + assertEquals(8, fService.lookup(-1, "main:/foo").getLength()); + + out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.print("version2"); + out.close(); + + fService.createSnapshot("main", null, null); + + fService.createSnapshot("main", null, null); + + fService.removeNode("main:/foo"); + + fService.createSnapshot("main", null, null); + + // check versions of the plain file (main:/foo) + + try + { + fService.getFileInputStream(0, "main:/foo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/foo"))); + assertEquals("version1", reader.readLine()); + reader.close(); + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(2, "main:/foo"))); + assertEquals("version2", reader.readLine()); + reader.close(); + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(3, "main:/foo"))); + assertEquals("version2", reader.readLine()); + reader.close(); + + try + { + fService.getFileInputStream(4, "main:/foo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + try + { + fService.getFileInputStream(-1, "main:/foo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + // check versions of the layered file (main:/afoo) + + try + { + fService.getFileInputStream(0, "main:/afoo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(1, "main:/afoo"))); + assertEquals("version1", reader.readLine()); + reader.close(); + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(2, "main:/afoo"))); + assertEquals("version2", reader.readLine()); + reader.close(); + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(3, "main:/afoo"))); + assertEquals("version2", reader.readLine()); + reader.close(); + + try + { + fService.getFileInputStream(4, "main:/afoo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + try + { + fService.getFileInputStream(-1, "main:/afoo"); + fail(); + } + catch (AVMNotFoundException nfe) + { + // expected + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } /** * Test rename of an overlayed directory contained in an overlayed directory. @@ -6011,6 +6236,7 @@ public class AVMServiceTest extends AVMServiceTestBase fService.createStore("third"); fService.setStoreProperty("third", QName.createQName("", ".dns.someUPPERcase"), new PropertyValue(null, "someUPPERcase-space")); matches = fService.queryStoresPropertyKeys(QName.createQName("", ".dns.someuppercase%")); + assertNotNull(matches.get("third")); assertEquals(1, matches.get("third").size()); assertEquals("someUPPERcase-space", matches.get("third").get(QName.createQName(null, ".dns.someUPPERcase")).getStringValue()); } diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTestBase.java b/source/java/org/alfresco/repo/avm/AVMServiceTestBase.java index a310e24612..4b1811823a 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceTestBase.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceTestBase.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -164,6 +164,11 @@ public class AVMServiceTestBase extends TestCase } fService.createStore("main"); + if (fService.getStore("layer") != null) + { + fService.purgeStore("layer"); + } + if (!fLockingService.getWebProjects().contains("main")) { fLockingService.addWebProject("main"); diff --git a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java index ddcd0ee102..fcbb9ed707 100644 --- a/source/java/org/alfresco/repo/avm/AVMStoreImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMStoreImpl.java @@ -60,6 +60,7 @@ import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; @@ -224,9 +225,14 @@ public class AVMStoreImpl implements AVMStore AVMDAOs.Instance().fVersionRootDAO.update(lastVersion); } snapShotMap.put(getName(), lastVersion.getVersionID()); + + if (logger.isTraceEnabled()) + { + logger.trace("createSnapshot: no snapshot required: "+me.getName()+(tag != null ? "("+tag+")" : "")+" [lastVersion = "+lastVersion.getVersionID()+"]"); + } + return snapShotMap; } - if (logger.isTraceEnabled()) { logger.trace("createSnapshot: snapshot: "+me.getName()+" ["+me.getId()+"] - lastVersion="+lastVersion.getVersionID()+", layeredEntries="+layeredEntries.size()); @@ -260,20 +266,9 @@ public class AVMStoreImpl implements AVMStore else if (lookup.getCurrentNode().getType() == AVMNodeType.LAYERED_FILE) { String parentName[] = AVMUtil.splitBase(entry.getPath()); - parentName[0] = parentName[0].substring(parentName[0].indexOf(':') + 1); + AVMNode child = lookup.getCurrentNode(); + DirectoryNode parent = lookup.getCurrentNodeDirectory(); - lookup = me.lookupDirectory(-1, parentName[0], true); - - DirectoryNode parent = (DirectoryNode)lookup.getCurrentNode(); - Pair temp = parent.lookupChild(lookup, parentName[1], false); - - AVMNode child = temp.getFirst(); - if (child == null) - { - throw new AVMException("Unexpected: missing child: "+entry.getPath()); - } - - lookup.add(child, parentName[1], temp.getSecond(), false); AVMNode newChild = ((LayeredFileNode)child).copyLiterally(lookup); newChild.setAncestor(child); parent.putChild(parentName[1], newChild); @@ -307,6 +302,12 @@ public class AVMStoreImpl implements AVMStore parent.putChild(parentName[1], newChild); */ } + + if (logger.isTraceEnabled()) + { + logger.trace("createSnapshot: force copy: "+me.getName()+(tag != null ? "("+tag+")" : "")+" [lastVersion="+lastVersion.getVersionID()+", layeredEntriesCnt="+layeredEntries.size()+"] in " + (System.currentTimeMillis() - start) + " msecs"); + } + // Clear out the new nodes. List allLayeredNodeIDs = AVMDAOs.Instance().fAVMNodeDAO.getNewLayeredInStoreIDs(me); @@ -366,9 +367,10 @@ public class AVMStoreImpl implements AVMStore AVMDAOs.Instance().fAVMStoreDAO.update(me); + AVMDAOs.Instance().fVersionRootDAO.save(versionRoot); + int vlneCnt = 0; - AVMDAOs.Instance().fVersionRootDAO.save(versionRoot); for (Long nodeID : layeredNodeIDs) { AVMNode node = AVMDAOs.Instance().fAVMNodeDAO.getByID(nodeID); @@ -383,14 +385,9 @@ public class AVMStoreImpl implements AVMStore vlneCnt = vlneCnt+paths.size(); } - if (logger.isTraceEnabled()) - { - logger.trace("createSnapshot: snapshot: "+me.getName()+" ["+me.getId()+"] - created new version root ["+versionRoot.getId()+"] - layeredNodeIDs="+layeredNodeIDs.size()+", versionLayeredNodeEntries="+vlneCnt); - } - if (logger.isDebugEnabled()) { - logger.debug("createSnapshot: snapshot: "+me.getName()+" ["+me.getId()+"] in "+(System.currentTimeMillis()-start)+" msecs"); + logger.debug("Raw snapshot: "+me.getName()+(tag != null ? "("+tag+")" : "")+" [versionRootId="+versionRoot.getId()+", layeredNodeIDsCnt="+layeredNodeIDs.size()+", versionLayeredNodeEntriesCnt="+vlneCnt+"] in " + (System.currentTimeMillis() - start) + " msecs"); } return snapShotMap; @@ -703,8 +700,15 @@ public class AVMStoreImpl implements AVMStore */ public ContentReader getContentReader(int version, String path) { - NodeRef nodeRef = AVMNodeConverter.ToNodeRef(version, getName() + ":" + path); - return RawServices.Instance().getContentService().getReader(nodeRef, ContentModel.PROP_CONTENT); + try + { + NodeRef nodeRef = AVMNodeConverter.ToNodeRef(version, getName() + ":" + path); + return RawServices.Instance().getContentService().getReader(nodeRef, ContentModel.PROP_CONTENT); + } + catch (InvalidNodeRefException inre) + { + throw new AVMNotFoundException("Path " + path + " not found."); + } } /** @@ -714,10 +718,17 @@ public class AVMStoreImpl implements AVMStore */ public ContentWriter createContentWriter(String path) { - NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, getName() + ":" + path); - ContentWriter writer = - RawServices.Instance().getContentService().getWriter(nodeRef, ContentModel.PROP_CONTENT, true); - return writer; + try + { + NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, getName() + ":" + path); + ContentWriter writer = + RawServices.Instance().getContentService().getWriter(nodeRef, ContentModel.PROP_CONTENT, true); + return writer; + } + catch (InvalidNodeRefException inre) + { + throw new AVMNotFoundException("Path " + path + " not found."); + } } /** @@ -1776,6 +1787,34 @@ public class AVMStoreImpl implements AVMStore Lookup lPath = lookupDirectory(-1, parentPath, true); if (lPath == null) { + String pathParts[] = AVMUtil.splitBase(parentPath); + Lookup lPath2 = lookup(-1, pathParts[0], true, false); + if (lPath2 != null) + { + DirectoryNode parent = (DirectoryNode)lPath2.getCurrentNode(); + Pair temp = parent.lookupChild(lPath2, pathParts[1], false); + if ((temp != null) && (temp.getFirst() != null)) + { + DirectoryNode dir = (DirectoryNode)temp.getFirst(); + + if (logger.isDebugEnabled()) + { + logger.debug("Found: "+dir); + } + + boolean directlyContained = false; + + if (!fAVMRepository.can(null, dir, PermissionService.ADD_CHILDREN, directlyContained)) + { + throw new AccessDeniedException("Not allowed to add children: " + parentPath); + } + + AVMNodeDescriptor desc = fAVMRepository.forceCopy(AVMUtil.buildAVMPath(this.getName(), parentPath)); + fAVMRepository.link(desc, name, toLink); + return; + } + } + throw new AVMNotFoundException("Path " + parentPath + " not found."); } DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode(); @@ -1933,4 +1972,11 @@ public class AVMStoreImpl implements AVMStore AVMDAOs.Instance().fAVMNodeDAO.update(file); } + + // for debug + @Override + public String toString() + { + return getName(); + } } diff --git a/source/java/org/alfresco/repo/avm/AVMSyncServiceImpl.java b/source/java/org/alfresco/repo/avm/AVMSyncServiceImpl.java index 9dc286c2e8..553f97f33c 100644 --- a/source/java/org/alfresco/repo/avm/AVMSyncServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/AVMSyncServiceImpl.java @@ -58,7 +58,7 @@ import org.apache.commons.logging.LogFactory; */ public class AVMSyncServiceImpl implements AVMSyncService { - private static Log fgLogger = LogFactory.getLog(AVMSyncServiceImpl.class); + private static Log logger = LogFactory.getLog(AVMSyncServiceImpl.class); /** * The AVMService. @@ -115,9 +115,11 @@ public class AVMSyncServiceImpl implements AVMSyncService int dstVersion, String dstPath, NameMatcher excluder) { - if (fgLogger.isDebugEnabled()) + long start = System.currentTimeMillis(); + + if (logger.isDebugEnabled()) { - fgLogger.debug(srcPath + " : " + dstPath); + logger.debug(srcPath + " : " + dstPath); } if (srcPath == null || dstPath == null) { @@ -142,6 +144,12 @@ public class AVMSyncServiceImpl implements AVMSyncService // Invoke the recursive implementation. compare(srcVersion, srcDesc, dstVersion, dstDesc, result, excluder, true); } + + if (logger.isDebugEnabled()) + { + logger.debug("Raw compare: ["+srcVersion+","+srcPath+"]["+dstVersion+","+dstPath+"]["+result.size()+"] in "+(System.currentTimeMillis()-start)+" msecs"); + } + return result; } @@ -403,6 +411,7 @@ public class AVMSyncServiceImpl implements AVMSyncService boolean overrideConflicts, boolean overrideOlder, String tag, String description) { long start = System.currentTimeMillis(); + Map storeVersions = new HashMap(); Set destStores = new HashSet(); for (AVMDifference diff : diffList) @@ -416,9 +425,9 @@ public class AVMSyncServiceImpl implements AVMSyncService { throw new AVMSyncException("Malformed AVMDifference."); } - if (fgLogger.isDebugEnabled()) + if (logger.isDebugEnabled()) { - fgLogger.debug("update: " + diff); + logger.debug("update: " + diff); } // Snapshot the source if needed. int version = diff.getSourceVersion(); @@ -460,13 +469,15 @@ public class AVMSyncServiceImpl implements AVMSyncService dispatchUpdate(diffCode, dstParts[0], dstParts[1], excluder, srcDesc, dstDesc, ignoreConflicts, ignoreOlder, overrideConflicts, overrideOlder); } + for (String storeName : destStores) { fAVMService.createSnapshot(storeName, tag, description); } - if (fgLogger.isDebugEnabled()) + + if (logger.isDebugEnabled()) { - fgLogger.debug("Raw Update: " + (System.currentTimeMillis() - start)); + logger.debug("Raw update: [" + diffList.size() + "] in " + (System.currentTimeMillis() - start) + " msecs"); } } @@ -558,9 +569,9 @@ public class AVMSyncServiceImpl implements AVMSyncService catch (AVMNotFoundException nfe) { // ignore - if (fgLogger.isDebugEnabled()) + if (logger.isDebugEnabled()) { - fgLogger.debug("linkIn: Does not exist: "+parentPath+"/"+name); + logger.debug("linkIn: Does not exist: "+parentPath+"/"+name); } } return; @@ -1126,6 +1137,8 @@ public class AVMSyncServiceImpl implements AVMSyncService */ public void flatten(String layerPath, String underlyingPath) { + long start = System.currentTimeMillis(); + if (layerPath == null || underlyingPath == null) { throw new AVMBadArgumentException("Illegal null path."); @@ -1140,11 +1153,13 @@ public class AVMSyncServiceImpl implements AVMSyncService { throw new AVMNotFoundException("Not found: " + underlyingPath); } - if (fgLogger.isDebugEnabled()) + + flatten(layerNode, underlyingNode); + + if (logger.isDebugEnabled()) { - fgLogger.debug("flatten: " + layerNode + " " + underlyingNode); + logger.debug("Raw flatten: " + layerNode + " " + underlyingNode + " in " + (System.currentTimeMillis() - start) + " msecs"); } - flatten(layerNode, underlyingNode); } /** @@ -1154,9 +1169,9 @@ public class AVMSyncServiceImpl implements AVMSyncService */ private boolean flatten(AVMNodeDescriptor layer, AVMNodeDescriptor underlying) { - if (fgLogger.isDebugEnabled()) + if (logger.isDebugEnabled()) { - fgLogger.debug("flatten: " + layer + " " + underlying); + logger.debug("flatten: " + layer + " " + underlying); } if (!layer.isLayeredDirectory()) { @@ -1172,6 +1187,7 @@ public class AVMSyncServiceImpl implements AVMSyncService { return false; } + Map layerListing = fAVMService.getDirectoryListingDirect(-1, layer.getPath(), true); // If the layer is empty (directly, that is) we're done. @@ -1179,26 +1195,29 @@ public class AVMSyncServiceImpl implements AVMSyncService { return true; } - List diffs = compare(-1, layer.getPath(), -1, underlying.getPath(), null); - if (diffs.size() == 0) - { - for (String name : layerListing.keySet()) - { - fAVMRepository.flatten(layer.getPath(), name); - } - return true; - } + // Grab the listing Map underListing = fAVMService.getDirectoryListing(underlying, true); + boolean flattened = true; for (String name : layerListing.keySet()) { AVMNodeDescriptor topNode = layerListing.get(name); AVMNodeDescriptor bottomNode = underListing.get(name); -// fgLogger.error("Trying to flatten out: " + name); + + if (logger.isTraceEnabled()) + { + logger.trace("Trying to flatten out: " + name); + } + if (bottomNode == null) { + if (logger.isTraceEnabled()) + { + logger.trace("Can't flatten (no bottomNode): " + name); + } + flattened = false; continue; } @@ -1206,15 +1225,38 @@ public class AVMSyncServiceImpl implements AVMSyncService if (topNode.getId() == bottomNode.getId()) { fAVMRepository.flatten(layer.getPath(), name); -// fgLogger.error("Identity flattened: " + name); + + if (logger.isTraceEnabled()) + { + logger.trace("Identity flattened: " + name); + } } else { + if (bottomNode.isLayeredDirectory()) + { + AVMNodeDescriptor lookup = fAVMService.lookup(bottomNode.getIndirectionVersion(), bottomNode.getIndirection()); + if (lookup == null) + { + if (logger.isDebugEnabled()) + { + logger.debug("Can't flatten (no bottomNode indirection): " + name); + } + + flattened = false; + continue; + } + } + // Otherwise recursively flatten the children. if (flatten(topNode, bottomNode)) { fAVMRepository.flatten(layer.getPath(), name); -// fgLogger.error("Recursively flattened: " + name); + + if (logger.isTraceEnabled()) + { + logger.trace("Recursively flattened: " + name); + } } else { @@ -1224,7 +1266,7 @@ public class AVMSyncServiceImpl implements AVMSyncService } return flattened; } - + /** * Takes a layer, deletes it and recreates it pointing at the same underlying * node. Any changes in the layer are lost (except to history if the layer has been @@ -1236,6 +1278,8 @@ public class AVMSyncServiceImpl implements AVMSyncService */ public void resetLayer(String layerPath) { + long start = System.currentTimeMillis(); + AVMNodeDescriptor desc = fAVMService.lookup(-1, layerPath); if (desc == null) { @@ -1247,6 +1291,11 @@ public class AVMSyncServiceImpl implements AVMSyncService { fAVMRepository.flatten(layerPath, name); } + + if (logger.isDebugEnabled()) + { + logger.debug("Raw resetLayer: " + layerPath + " in " + (System.currentTimeMillis() - start) + " msecs"); + } } /** diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java index d2f4c55010..595933dc70 100644 --- a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java @@ -734,11 +734,12 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer AVMNodeDescriptor desc = entry.getChild().getDescriptor(mine.getPath(), name, mine.getIndirection(), mine.getIndirectionVersion()); return desc; } - // If we are opaque don't check underneath. + // Don't check our underlying directory if we are opaque. if (getOpacity()) { return null; } + // Not here so check our indirection. Lookup lookup = AVMRepository.GetInstance().lookupDirectory(mine.getIndirectionVersion(), mine.getIndirection()); if (lookup != null) { @@ -833,9 +834,9 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer */ public String toString(Lookup lPath) { - return "[LD:" + getId() + ":" + getUnderlying(lPath) + "]"; + return "[LD:" + getId() + (lPath != null ? ":" + getUnderlying(lPath) : "") + "]"; } - + /** * Set the primary indirection. No COW. Cascade resetting of acls also does not COW * diff --git a/source/java/org/alfresco/repo/avm/Lookup.java b/source/java/org/alfresco/repo/avm/Lookup.java index bb4a86f4d0..ce818a9a72 100644 --- a/source/java/org/alfresco/repo/avm/Lookup.java +++ b/source/java/org/alfresco/repo/avm/Lookup.java @@ -29,6 +29,8 @@ import java.util.List; import org.alfresco.repo.avm.util.AVMUtil; import org.springframework.extensions.surf.util.Pair; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * This holds all the information necessary to perform operations @@ -39,7 +41,9 @@ import org.springframework.extensions.surf.util.Pair; class Lookup implements Serializable { private static final long serialVersionUID = -2844833688622561L; - + + private static Log logger = LogFactory.getLog(Lookup.class); + /** * Is this lookup valid? */ @@ -232,6 +236,11 @@ class Lookup implements Serializable // System.err.println("Bloody Murder!"); // } fDirectlyContained = directlyContained; + + if (logger.isTraceEnabled()) + { + logger.trace("add: fDirectlyContained = "+directlyContained); + } } if (!write) { @@ -265,12 +274,22 @@ class Lookup implements Serializable if (!node.getIsNew()) { fNeedsCopying = true; + + if (logger.isTraceEnabled()) + { + logger.trace("add-cow: "+this+" ("+fPosition+") (not new)"); + } } else { if (fPosition >= 0 && !fDirectlyContained) { fNeedsCopying = true; + + if (logger.isTraceEnabled()) + { + logger.trace("add: COW: "+this+" ("+fPosition+") (new, not directly contained)"); + } } } // Record various things if this is layered. @@ -548,6 +567,19 @@ class Lookup implements Serializable @Override public String toString() { - return getRepresentedPath(); + StringBuilder builder = new StringBuilder(); + + builder.append(getRepresentedPath()); + builder.append(" ["); + + for (int i = 0; i < fComponents.size(); i++) + { + builder.append(AVMUtil.AVM_PATH_SEPARATOR_CHAR); + builder.append(fComponents.get(i).toString()); + } + + builder.append("]"); + + return builder.toString(); } } diff --git a/source/java/org/alfresco/repo/avm/LookupComponent.java b/source/java/org/alfresco/repo/avm/LookupComponent.java index b81e678156..97417ea7eb 100644 --- a/source/java/org/alfresco/repo/avm/LookupComponent.java +++ b/source/java/org/alfresco/repo/avm/LookupComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -127,4 +127,10 @@ class LookupComponent { fNode = node; } + + // for debug + public String toString() + { + return (fNode != null ? fNode.toString(null) : ""); + } } diff --git a/source/java/org/alfresco/repo/avm/NOOPLookupCache.java b/source/java/org/alfresco/repo/avm/NOOPLookupCache.java index e5e6b381a4..5dbfc0bfa4 100644 --- a/source/java/org/alfresco/repo/avm/NOOPLookupCache.java +++ b/source/java/org/alfresco/repo/avm/NOOPLookupCache.java @@ -24,6 +24,7 @@ */ package org.alfresco.repo.avm; +import org.alfresco.repo.avm.util.AVMUtil; import org.alfresco.repo.avm.util.SimplePath; import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.service.cmr.security.PermissionService; @@ -94,7 +95,7 @@ public class NOOPLookupCache implements LookupCache { if (!AVMRepository.GetInstance().can(null, dir, PermissionService.READ_CHILDREN, result.getDirectlyContained())) { - throw new AccessDeniedException("Not allowed to read children: " + path.get(i)); + throw new AccessDeniedException("Not allowed to read children: " + path.get(i) + " ("+store.getName()+")"); } Pair child = dir.lookupChild(result, path.get(i), includeDeleted); if (child == null) @@ -115,7 +116,7 @@ public class NOOPLookupCache implements LookupCache // Now look up the last element. if (!AVMRepository.GetInstance().can(null, dir, PermissionService.READ_CHILDREN, result.getDirectlyContained())) { - throw new AccessDeniedException("Not allowed to read children: " + path.get(path.size() - 1)); + throw new AccessDeniedException("Not allowed to read children: " + path.get(path.size() - 1) + " ("+store.getName()+")"); } Pair child = dir.lookupChild(result, path.get(path.size() - 1), includeDeleted); diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryRepositoryBootstrap.java b/source/java/org/alfresco/repo/dictionary/DictionaryRepositoryBootstrap.java index d57ede02ee..eb1784ca7d 100644 --- a/source/java/org/alfresco/repo/dictionary/DictionaryRepositoryBootstrap.java +++ b/source/java/org/alfresco/repo/dictionary/DictionaryRepositoryBootstrap.java @@ -351,16 +351,19 @@ public class DictionaryRepositoryBootstrap extends AbstractLifecycleBean impleme folderNodeRef = resolveQNameFolderPath(rootNodeRef, pathElements); } - Set types = new HashSet(1); - types.add(nodeType); - List childAssocRefs = nodeService.getChildAssocs(folderNodeRef, types); - - if (childAssocRefs.size() > 0) + if (folderNodeRef != null) { - nodeRefs = new ArrayList(childAssocRefs.size()); - for (ChildAssociationRef childAssocRef : childAssocRefs) + Set types = new HashSet(1); + types.add(nodeType); + List childAssocRefs = nodeService.getChildAssocs(folderNodeRef, types); + + if (childAssocRefs.size() > 0) { - nodeRefs.add(childAssocRef.getChildRef()); + nodeRefs = new ArrayList(childAssocRefs.size()); + for (ChildAssociationRef childAssocRef : childAssocRefs) + { + nodeRefs.add(childAssocRef.getChildRef()); + } } } @@ -482,18 +485,43 @@ public class DictionaryRepositoryBootstrap extends AbstractLifecycleBean impleme } } - protected NodeRef resolveQNameFolderPath(NodeRef rootNodeRef, String[] pathQNames) + protected NodeRef resolveQNameFolderPath(NodeRef rootNodeRef, String[] pathPrefixQNameStrings) { - if (pathQNames.length == 0) + if (pathPrefixQNameStrings.length == 0) { throw new IllegalArgumentException("Path array is empty"); } // walk the folder tree NodeRef parentNodeRef = rootNodeRef; - for (int i = 0; i < pathQNames.length; i++) + for (int i = 0; i < pathPrefixQNameStrings.length; i++) { - String pathQName = pathQNames[i]; - List childAssocRefs = nodeService.getChildAssocs(parentNodeRef, RegexQNamePattern.MATCH_ALL, QName.createQName(pathQName, namespaceService)); + String pathPrefixQNameString = pathPrefixQNameStrings[i]; + + QName pathQName = null; + if (tenantAdminService.isEnabled()) + { + String[] parts = QName.splitPrefixedQName(pathPrefixQNameString); + if ((parts.length == 2) && (parts[0].equals(NamespaceService.APP_MODEL_PREFIX))) + { + String pathUriQNameString = new StringBuilder(64). + append(QName.NAMESPACE_BEGIN). + append(NamespaceService.APP_MODEL_1_0_URI). + append(QName.NAMESPACE_END). + append(parts[1]).toString(); + + pathQName = QName.createQName(pathUriQNameString); + } + else + { + pathQName = QName.createQName(pathPrefixQNameString, namespaceService); + } + } + else + { + pathQName = QName.createQName(pathPrefixQNameString, namespaceService); + } + + List childAssocRefs = nodeService.getChildAssocs(parentNodeRef, RegexQNamePattern.MATCH_ALL, pathQName); if (childAssocRefs.size() != 1) { return null; diff --git a/source/java/org/alfresco/repo/domain/DomainTestSuite.java b/source/java/org/alfresco/repo/domain/DomainTestSuite.java index e926c59f72..0ab5cf248c 100644 --- a/source/java/org/alfresco/repo/domain/DomainTestSuite.java +++ b/source/java/org/alfresco/repo/domain/DomainTestSuite.java @@ -34,6 +34,7 @@ import org.alfresco.repo.domain.hibernate.HibernateSessionHelperTest; import org.alfresco.repo.domain.locks.LockDAOTest; import org.alfresco.repo.domain.mimetype.MimetypeDAOTest; import org.alfresco.repo.domain.patch.AppliedPatchDAOTest; +import org.alfresco.repo.domain.propval.PropertyValueDAOTest; /** * Suite for domain-related tests. @@ -54,7 +55,7 @@ public class DomainTestSuite extends TestSuite suite.addTestSuite(LocaleDAOTest.class); suite.addTestSuite(PropertyValueTest.class); suite.addTestSuite(QNameDAOTest.class); - suite.addTestSuite(PropertyValueTest.class); + suite.addTestSuite(PropertyValueDAOTest.class); suite.addTestSuite(AuditDAOTest.class); suite.addTestSuite(AppliedPatchDAOTest.class); diff --git a/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java b/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java index c293a42e2a..47f00f4cc2 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java +++ b/source/java/org/alfresco/repo/domain/hibernate/AVMAccessControlListDAO.java @@ -32,8 +32,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.alfresco.config.JNDIConstants; import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.avm.AVMRepository; +import org.alfresco.repo.avm.util.AVMUtil; import org.alfresco.repo.domain.AccessControlListDAO; import org.alfresco.repo.domain.DbAccessControlList; import org.alfresco.repo.domain.PropertyValue; @@ -60,6 +62,7 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.namespace.QName; import org.alfresco.util.EqualsHelper; import org.springframework.extensions.surf.util.Pair; +import org.alfresco.wcm.util.WCMUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -308,7 +311,9 @@ public class AVMAccessControlListDAO implements AccessControlListDAO { inherited = aclDaoComponent.getInheritedAccessControlList(after); } - Map> indirections = buildIndirections(); + + AVMNodeDescriptor descriptor = getDesc(startingPoint); + Map> indirections = buildIndirections(descriptor); updateChangedAclsImpl(startingPoint, changes, SetMode.ALL, inherited, after, indirections); } @@ -368,9 +373,46 @@ public class AVMAccessControlListDAO implements AccessControlListDAO throw new InvalidNodeRefException(nodeRef); } } + + private AVMNodeDescriptor getDesc(NodeRef node) + { + Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(node); + int version = avmVersionPath.getFirst(); + if (version >= 0) + { + throw new InvalidNodeRefException("Read Only Node.", node); + } + String path = avmVersionPath.getSecond(); + try + { + AVMNodeDescriptor descriptor = fAVMService.lookup(version, path); + return descriptor; + + } + catch (AVMException e) + { + throw new InvalidNodeRefException(node); + } + } + + private Map> buildIndirections(AVMNodeDescriptor desc) + { + if ((desc != null) && (desc.getVersionID() == 1)) + { + String[] pathParts = AVMUtil.splitPath(desc.getPath()); + if ((pathParts[1].equals(AVMUtil.AVM_PATH_SEPARATOR+JNDIConstants.DIR_DEFAULT_WWW)) && (WCMUtil.isStagingStore(pathParts[0]))) + { + // WCM optimisation - skip when creating web project + return null; + } + } + return buildIndirections(); + } private Map> buildIndirections() { + long start = System.currentTimeMillis(); + Map> answer = new HashMap>(); List indirections = aclDaoComponent.getAvmIndirections(); @@ -389,7 +431,11 @@ public class AVMAccessControlListDAO implements AccessControlListDAO referees.add(indirection.getFrom()); } } - + + if (s_logger.isDebugEnabled()) + { + s_logger.debug("buildIndirections: ("+indirections.size()+", "+answer.size()+") in "+(System.currentTimeMillis()-start)+" msecs"); + } return answer; } @@ -405,7 +451,7 @@ public class AVMAccessControlListDAO implements AccessControlListDAO try { AVMNodeDescriptor descriptor = fAVMService.lookup(version, path); - if (descriptor == null) + if ((descriptor == null) || (indirections == null)) { return; } @@ -613,9 +659,9 @@ public class AVMAccessControlListDAO implements AccessControlListDAO String path = avmVersionPath.getSecond(); try { - Map> indirections = buildIndirections(); List changes = new ArrayList(); AVMNodeDescriptor descriptor = fAVMService.lookup(version, path); + Map> indirections = buildIndirections(descriptor); setFixedAcls(descriptor, inheritFrom, null, changes, SetMode.ALL, false, indirections); return changes; diff --git a/source/java/org/alfresco/repo/domain/propval/AbstractPropertyValueDAOImpl.java b/source/java/org/alfresco/repo/domain/propval/AbstractPropertyValueDAOImpl.java index 3501b6734d..7f313f5c0e 100644 --- a/source/java/org/alfresco/repo/domain/propval/AbstractPropertyValueDAOImpl.java +++ b/source/java/org/alfresco/repo/domain/propval/AbstractPropertyValueDAOImpl.java @@ -40,6 +40,7 @@ import org.alfresco.repo.cache.lookup.EntityLookupCache; import org.alfresco.repo.cache.lookup.EntityLookupCache.EntityLookupCallbackDAOAdaptor; import org.alfresco.repo.domain.CrcHelper; import org.alfresco.repo.domain.propval.PropertyValueEntity.PersistedType; +import org.alfresco.repo.domain.schema.SchemaBootstrap; import org.alfresco.repo.props.PropertyUniqueConstraintViolation; import org.springframework.extensions.surf.util.Pair; import org.apache.commons.logging.Log; @@ -468,6 +469,14 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO { throw new IllegalArgumentException("Persisted string values cannot be null"); } + int maxStringLen = SchemaBootstrap.getMaxStringLength(); + if (value.length() > maxStringLen) + { + throw new IllegalArgumentException( + "Persisted string values for 'alf_prop_string_value' cannot be longer than " + + maxStringLen + " characters. Increase the string column sizes and set property " + + "'system.maximumStringLength' accordingly."); + } Pair entityPair = propertyStringValueCache.getOrCreateByValue(value); return entityPair; } @@ -1149,7 +1158,7 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO } catch (Throwable e) { - throw new PropertyUniqueConstraintViolation(value1, value2, value3); + throw new PropertyUniqueConstraintViolation(value1, value2, value3, e); } } diff --git a/source/java/org/alfresco/repo/domain/propval/PropertyStringValueEntity.java b/source/java/org/alfresco/repo/domain/propval/PropertyStringValueEntity.java index fc87b34876..81e4b1a989 100644 --- a/source/java/org/alfresco/repo/domain/propval/PropertyStringValueEntity.java +++ b/source/java/org/alfresco/repo/domain/propval/PropertyStringValueEntity.java @@ -36,6 +36,9 @@ import org.springframework.extensions.surf.util.Pair; */ public class PropertyStringValueEntity { + public static final String EMPTY_STRING = ""; + public static final String EMPTY_STRING_REPLACEMENT = ".empty"; + private Long id; private String stringValue; private String stringEndLower; @@ -82,7 +85,14 @@ public class PropertyStringValueEntity public Pair getEntityPair() { - return new Pair(id, stringValue); + if (stringValue != null && stringValue.equals(PropertyStringValueEntity.EMPTY_STRING_REPLACEMENT)) + { + return new Pair(id, PropertyStringValueEntity.EMPTY_STRING); + } + else + { + return new Pair(id, stringValue); + } } /** @@ -94,6 +104,11 @@ public class PropertyStringValueEntity { throw new IllegalArgumentException("Null strings cannot be persisted"); } + if (value != null && value.equals(PropertyStringValueEntity.EMPTY_STRING)) + { + // Oracle: We can't insert empty strings into the column. + value = PropertyStringValueEntity.EMPTY_STRING_REPLACEMENT; + } stringValue = value; // Calculate the crc value from the original value Pair crcPair = CrcHelper.getStringCrcPair(value, 16, false, true); diff --git a/source/java/org/alfresco/repo/domain/propval/PropertyValueDAOTest.java b/source/java/org/alfresco/repo/domain/propval/PropertyValueDAOTest.java index 61e5b4e258..213263648b 100644 --- a/source/java/org/alfresco/repo/domain/propval/PropertyValueDAOTest.java +++ b/source/java/org/alfresco/repo/domain/propval/PropertyValueDAOTest.java @@ -222,7 +222,13 @@ public class PropertyValueDAOTest extends TestCase assertNotNull(stringUpperEntityPair.getFirst()); assertEquals(stringValueUpper, stringUpperEntityPair.getSecond()); assertNotSame("String IDs were not different", stringEntityPair.getFirst(), stringUpperEntityPair.getFirst()); - + } + + /** + * Try to catch Oracle out + */ + public void testPropertyStringValue_EmptyAndNull() throws Exception + { // Check empty string RetryingTransactionCallback emptyStringCallback = new RetryingTransactionCallback() { @@ -705,7 +711,9 @@ public class PropertyValueDAOTest extends TestCase { final String aaa = GUID.generate(); final String bbb = GUID.generate(); - RetryingTransactionCallback testCallback = new RetryingTransactionCallback() + + // Check null-null-null context + txnHelper.doInTransaction(new RetryingTransactionCallback() { public Void execute() throws Throwable { @@ -726,37 +734,66 @@ public class PropertyValueDAOTest extends TestCase { // Expected } - Long id = propertyValueDAO.createPropertyUniqueContext("A", "AA", aaa); - try + return null; + } + }, true); + // Create a well-known context ID + final Long id = txnHelper.doInTransaction(new RetryingTransactionCallback() + { + public Long execute() throws Throwable + { + return propertyValueDAO.createPropertyUniqueContext("A", "AA", aaa); + } + }, true); + // Check that duplicates are disallowed + try + { + txnHelper.doInTransaction(new RetryingTransactionCallback() + { + public Void execute() throws Throwable { propertyValueDAO.createPropertyUniqueContext("A", "AA", aaa); - fail("Failed to throw exception creating duplicate property unique context"); + return null; } - catch (PropertyUniqueConstraintViolation e) - { - // Expected - } - // Now update it - propertyValueDAO.updatePropertyUniqueContext(id, "A", "AA", bbb); - // Should be able to create the previous one ... - propertyValueDAO.createPropertyUniqueContext("A", "AA", aaa); - // ... and fail to create the second one - try + }, true); + fail("Failed to throw exception creating duplicate property unique context"); + } + catch (PropertyUniqueConstraintViolation e) + { + // Expected + } + // Check that updates work + try + { + txnHelper.doInTransaction(new RetryingTransactionCallback() + { + public Void execute() throws Throwable { + // Now update it + propertyValueDAO.updatePropertyUniqueContext(id, "A", "AA", bbb); + // Should be able to create the previous one ... + propertyValueDAO.createPropertyUniqueContext("A", "AA", aaa); + // ... and fail to create the second one propertyValueDAO.createPropertyUniqueContext("A", "AA", bbb); - fail("Failed to throw exception creating duplicate property unique context"); - } - catch (PropertyUniqueConstraintViolation e) - { - // Expected + return null; } + }, true); + fail("Failed to throw exception creating duplicate property unique context"); + } + catch (PropertyUniqueConstraintViolation e) + { + // Expected + } + txnHelper.doInTransaction(new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { // Delete propertyValueDAO.deletePropertyUniqueContext(id); propertyValueDAO.createPropertyUniqueContext("A", "AA", bbb); return null; } - }; - txnHelper.doInTransaction(testCallback, false); + }, true); } } diff --git a/source/java/org/alfresco/repo/domain/propval/PropertyValueEntity.java b/source/java/org/alfresco/repo/domain/propval/PropertyValueEntity.java index 7dc7100b69..db8b93bb5c 100644 --- a/source/java/org/alfresco/repo/domain/propval/PropertyValueEntity.java +++ b/source/java/org/alfresco/repo/domain/propval/PropertyValueEntity.java @@ -255,7 +255,14 @@ public class PropertyValueEntity case DOUBLE: return converter.convert(actualType, Double.valueOf(doubleValue)); case STRING: - return converter.convert(actualType, stringValue); + if (stringValue != null && stringValue.equals(PropertyStringValueEntity.EMPTY_STRING_REPLACEMENT)) + { + return converter.convert(actualType, PropertyStringValueEntity.EMPTY_STRING); + } + else + { + return converter.convert(actualType, stringValue); + } case SERIALIZABLE: return converter.convert(actualType, serializableValue); case CONSTRUCTABLE: @@ -298,6 +305,11 @@ public class PropertyValueEntity break; case STRING: stringValue = converter.convert(String.class, value); + if (stringValue.equals(PropertyStringValueEntity.EMPTY_STRING)) + { + // Oracle: We can't insert empty strings into the column. + stringValue = PropertyStringValueEntity.EMPTY_STRING_REPLACEMENT; + } break; case CONSTRUCTABLE: // A special case. There is no conversion, so just Store the name of the class. @@ -397,6 +409,13 @@ public class PropertyValueEntity public void setStringValue(String stringValue) { + if (stringValue == null) + { + // Oracle! It pulls nulls out in place of empty strings. + // Since we don't put nulls into the DB (the column doesn't allow it) + // we can be sure that this is an Oracle empty string + stringValue = ""; + } this.stringValue = stringValue; } diff --git a/source/java/org/alfresco/repo/domain/schema/SchemaBootstrap.java b/source/java/org/alfresco/repo/domain/schema/SchemaBootstrap.java index 6e5b1c5cb3..f765be9f38 100644 --- a/source/java/org/alfresco/repo/domain/schema/SchemaBootstrap.java +++ b/source/java/org/alfresco/repo/domain/schema/SchemaBootstrap.java @@ -161,6 +161,27 @@ public class SchemaBootstrap extends AbstractLifecycleBean return SchemaBootstrap.maxStringLength; } + /** + * Truncates or returns a string that will fit into the string columns in the schema. Text fields can + * either cope with arbitrarily long text fields or have the default limit, {@link #DEFAULT_MAX_STRING_LENGTH}. + * + * @param value the string to check + * @return Returns a string that is short enough for {@link SchemaBootstrap#getMaxStringLength()} + * + * @since 3.2 + */ + public static final String trimStringForTextFields(String value) + { + if (value != null && value.length() > maxStringLength) + { + return value.substring(0, maxStringLength); + } + else + { + return value; + } + } + /** * Sets the previously auto-detected Hibernate dialect. * @@ -327,9 +348,10 @@ public class SchemaBootstrap extends AbstractLifecycleBean /** * Optionally override the system's default maximum string length. Some databases have * limitations on how long the string_value columns can be while other do not. - * When a String value exceeds the maximum size it is persisted in the - * serializable_value column instead. Some databases have limitation on the size - * of the serializable columns as well, but usually support much more. + * Some parts of the persistence have alternatives when the string values exceed this + * length while others do not. Either way, it is possible to adjust the text column sizes + * and adjust this value manually to override the default associated with the database + * being used. *

* The system - as of V2.1.2 - will attempt to adjust the maximum string length size * automatically and therefore this method is not normally required. But it is possible diff --git a/source/java/org/alfresco/repo/importer/ImporterComponentTest.java b/source/java/org/alfresco/repo/importer/ImporterComponentTest.java index ee9dd3cf8e..ce8852827c 100644 --- a/source/java/org/alfresco/repo/importer/ImporterComponentTest.java +++ b/source/java/org/alfresco/repo/importer/ImporterComponentTest.java @@ -47,6 +47,7 @@ import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.util.BaseSpringTest; import org.alfresco.util.debug.NodeStoreInspector; +import org.springframework.extensions.surf.util.ISO8601DateFormat; public class ImporterComponentTest extends BaseSpringTest @@ -124,9 +125,9 @@ public class ImporterComponentTest extends BaseSpringTest String modifiedDate = DefaultTypeConverter.INSTANCE.convert(String.class, nodeProps.get(ContentModel.PROP_MODIFIED)); String modifier = DefaultTypeConverter.INSTANCE.convert(String.class, nodeProps.get(ContentModel.PROP_MODIFIER)); // Check that the cm:auditable properties are correct - assertEquals("cm:created not preserved during import", "2009-05-01T00:00:00.000+01:00", createdDate); + assertEquals("cm:created not preserved during import", ISO8601DateFormat.format(ISO8601DateFormat.parse("2009-05-01T00:00:00.000+01:00")), createdDate); assertEquals("cm:creator not preserved during import", "Import Creator", creator); - assertEquals("cm:modified not preserved during import", "2009-05-02T00:00:00.000+01:00", modifiedDate); + assertEquals("cm:modified not preserved during import", ISO8601DateFormat.format(ISO8601DateFormat.parse("2009-05-02T00:00:00.000+01:00")), modifiedDate); assertEquals("cm:modifier not preserved during import", "Import Modifier", modifier); nodeRef = childAssocs.get(1).getChildRef(); @@ -136,7 +137,7 @@ public class ImporterComponentTest extends BaseSpringTest modifiedDate = DefaultTypeConverter.INSTANCE.convert(String.class, nodeProps.get(ContentModel.PROP_MODIFIED)); modifier = DefaultTypeConverter.INSTANCE.convert(String.class, nodeProps.get(ContentModel.PROP_MODIFIER)); // Check that the cm:auditable properties are correct - assertEquals("cm:created not preserved during import", "2009-05-01T00:00:00.000+01:00", createdDate); + assertEquals("cm:created not preserved during import", ISO8601DateFormat.format(ISO8601DateFormat.parse("2009-05-01T00:00:00.000+01:00")), createdDate); assertEquals("cm:creator not preserved during import", "Import Creator", creator); assertEquals("cm:modifier not preserved during import", AuthenticationUtil.getSystemUserName(), modifier); } diff --git a/source/java/org/alfresco/repo/props/PropertyUniqueConstraintViolation.java b/source/java/org/alfresco/repo/props/PropertyUniqueConstraintViolation.java index a168dae347..89115bc0f4 100644 --- a/source/java/org/alfresco/repo/props/PropertyUniqueConstraintViolation.java +++ b/source/java/org/alfresco/repo/props/PropertyUniqueConstraintViolation.java @@ -50,6 +50,14 @@ public class PropertyUniqueConstraintViolation extends AlfrescoRuntimeException this.value3 = value3; } + public PropertyUniqueConstraintViolation(Serializable value1, Serializable value2, Serializable value3, Throwable cause) + { + super("Non-unique values for unique constraint: " + value1 + "-" + value2 + "-" + value3, cause); + this.value1 = value1; + this.value2 = value2; + this.value3 = value3; + } + public Serializable getValue1() { return value1; diff --git a/source/java/org/alfresco/repo/tagging/RefreshTagScopeActionExecuter.java b/source/java/org/alfresco/repo/tagging/RefreshTagScopeActionExecuter.java index 34667712cc..1ec8ebe77c 100644 --- a/source/java/org/alfresco/repo/tagging/RefreshTagScopeActionExecuter.java +++ b/source/java/org/alfresco/repo/tagging/RefreshTagScopeActionExecuter.java @@ -45,7 +45,7 @@ import org.alfresco.service.cmr.tagging.TaggingService; /** * Refresh tag scope action executer * - * NOTE: This action is used to facilitate the async refresh of a tag scope. It is not intended for genereral useage. + * NOTE: This action is used to facilitate the async refresh of a tag scope. It is not intended for general usage. * * @author Roy Wetherall */ diff --git a/source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java b/source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java index 4592c82f52..39a90c2d45 100644 --- a/source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java +++ b/source/java/org/alfresco/repo/tagging/TaggingServiceImpl.java @@ -169,8 +169,9 @@ public class TaggingServiceImpl implements TaggingService, */ public void beforeDeleteNode(NodeRef nodeRef) { - if (this.nodeService.exists(nodeRef) == true && - this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == true) + if (this.nodeService.exists(nodeRef) == true && + this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_TAGGABLE) == true && + this.nodeService.hasAspect(nodeRef, ContentModel.ASPECT_WORKING_COPY) == false) { ChildAssociationRef assocRef = this.nodeService.getPrimaryParent(nodeRef); if (assocRef != null) diff --git a/source/java/org/alfresco/repo/tagging/UpdateTagScopesActionExecuter.java b/source/java/org/alfresco/repo/tagging/UpdateTagScopesActionExecuter.java index d180faa32b..ed4ecd0593 100644 --- a/source/java/org/alfresco/repo/tagging/UpdateTagScopesActionExecuter.java +++ b/source/java/org/alfresco/repo/tagging/UpdateTagScopesActionExecuter.java @@ -49,7 +49,7 @@ import org.alfresco.service.cmr.tagging.TaggingService; /** * Update tag scopes action executer. * - * NOTE: This action is used to facilitate the async update of tag scopes. It is not intended for genereral useage. + * NOTE: This action is used to facilitate the async update of tag scopes. It is not intended for general usage. * * @author Roy Wetherall */ diff --git a/source/java/org/alfresco/repo/workflow/WorkflowServiceImplTest.java b/source/java/org/alfresco/repo/workflow/WorkflowServiceImplTest.java index c9ef5d1f08..691591d3e7 100644 --- a/source/java/org/alfresco/repo/workflow/WorkflowServiceImplTest.java +++ b/source/java/org/alfresco/repo/workflow/WorkflowServiceImplTest.java @@ -124,7 +124,7 @@ public class WorkflowServiceImplTest extends BaseSpringTest public void testAssociateWorkflowPackage() { // create workflow package - NodeRef rootRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "spacesStore")); + NodeRef rootRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore")); NodeRef nodeRef = workflowService.createPackage(null); assertNotNull(nodeRef); assertTrue(nodeService.hasAspect(nodeRef, WorkflowModel.ASPECT_WORKFLOW_PACKAGE)); diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java index e8daa274d6..8c1cc7f779 100644 --- a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java +++ b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineTest.java @@ -101,7 +101,7 @@ public class JBPMEngineTest extends BaseSpringTest // get valid node ref nodeService = (NodeService)applicationContext.getBean(ServiceRegistry.NODE_SERVICE.getLocalName()); - testNodeRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "spacesStore")); + testNodeRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore")); nodeService.setProperty(testNodeRef, ContentModel.PROP_CREATED, new Date()); } diff --git a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineUnitTest.java b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineUnitTest.java index 083ccfca7d..9ba67c5393 100644 --- a/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineUnitTest.java +++ b/source/java/org/alfresco/repo/workflow/jbpm/JBPMEngineUnitTest.java @@ -82,20 +82,21 @@ public class JBPMEngineUnitTest extends AbstractTransactionalSpringContextTests private JBPMEngine engine = new JBPMEngine(); private WorkflowDefinition workflowDef; - + public void testDeployWorkflow() throws Exception { ClassPathResource processDef = new ClassPathResource("jbpmresources/test_processdefinition.xml"); List workflowDefs = engine.getDefinitions(); assertFalse(engine.isDefinitionDeployed(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML)); assertNotNull(workflowDefs); - assertTrue(workflowDefs.size() == 0); + + int workflowDefCnt = workflowDefs.size(); deployTestDefinition(); assertTrue(engine.isDefinitionDeployed(processDef.getInputStream(), MimetypeMap.MIMETYPE_XML)); workflowDefs = engine.getDefinitions(); assertNotNull(workflowDefs); - assertTrue(workflowDefs.size() == 1); + assertEquals(workflowDefCnt+1, workflowDefs.size()); assertNotNull(workflowDef); assertEquals(TEST_JBPM_ENGINE + "$test", workflowDef.name); @@ -390,8 +391,13 @@ public class JBPMEngineUnitTest extends AbstractTransactionalSpringContextTests { NamespaceServiceMemoryImpl namespace = new NamespaceServiceMemoryImpl(); namespace.registerNamespace(NamespaceService.DEFAULT_PREFIX, NamespaceService.DEFAULT_URI); + namespace.registerNamespace("wf", "http://www.alfresco.org/model/bpm/1.0"); namespace.registerNamespace("cm", "http://www.alfresco.org/model/content/1.0"); + namespace.registerNamespace("wcmwf", "http://www.alfresco.org/model/wcmworkflow/1.0"); + namespace.registerNamespace("imwf", "http://www.alfresco.org/model/workflow/invite/moderated/1.0"); + namespace.registerNamespace("inwf", "http://www.alfresco.org/model/workflow/invite/nominated/1.0"); + return namespace; } @@ -435,7 +441,7 @@ public class JBPMEngineUnitTest extends AbstractTransactionalSpringContextTests @Override protected String[] getConfigLocations() { - String[] locations = new String[] { "classpath:jbpm-test/test-database-context.xml", + String[] locations = new String[] { "classpath:jbpm-test/test-workflow-context.xml", }; return locations; } diff --git a/source/java/org/alfresco/repo/workflow/jbpm/NodeListConverterTest.java b/source/java/org/alfresco/repo/workflow/jbpm/NodeListConverterTest.java index bcfa369e58..d65134f3f5 100644 --- a/source/java/org/alfresco/repo/workflow/jbpm/NodeListConverterTest.java +++ b/source/java/org/alfresco/repo/workflow/jbpm/NodeListConverterTest.java @@ -89,7 +89,7 @@ public class NodeListConverterTest extends BaseSpringTest // get valid node ref NodeService nodeService = (NodeService)applicationContext.getBean(ServiceRegistry.NODE_SERVICE.getLocalName()); - testNodeRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "spacesStore")); + testNodeRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore")); } diff --git a/source/java/org/alfresco/repo/workflow/jbpm/ReviewAndApproveTest.java b/source/java/org/alfresco/repo/workflow/jbpm/ReviewAndApproveTest.java index c500a7ba95..8ff791e62a 100644 --- a/source/java/org/alfresco/repo/workflow/jbpm/ReviewAndApproveTest.java +++ b/source/java/org/alfresco/repo/workflow/jbpm/ReviewAndApproveTest.java @@ -89,7 +89,7 @@ public class ReviewAndApproveTest extends BaseSpringTest // get valid node ref NodeService nodeService = (NodeService)applicationContext.getBean(ServiceRegistry.NODE_SERVICE.getLocalName()); - testNodeRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "spacesStore")); + testNodeRef = nodeService.getRootNode(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore")); } @Override diff --git a/source/java/org/alfresco/util/JSONtoFmModel.java b/source/java/org/alfresco/util/JSONtoFmModel.java index b2c78792b7..9855ec2c0b 100644 --- a/source/java/org/alfresco/util/JSONtoFmModel.java +++ b/source/java/org/alfresco/util/JSONtoFmModel.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -29,6 +29,8 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; import java.util.regex.Pattern; import org.json.JSONArray; @@ -157,14 +159,14 @@ public final class JSONtoFmModel return model; } - // for debugging + // for debugging only public static String toString(Map map) { return JSONtoFmModel.toStringBuffer(map, 0).toString(); } @SuppressWarnings("unchecked") - private static StringBuffer toStringBuffer(Map map, int indent) + private static StringBuffer toStringBuffer(Map unsortedMap, int indent) { StringBuffer tabs = new StringBuffer(); for (int i = 0; i < indent; i++) @@ -174,6 +176,9 @@ public final class JSONtoFmModel StringBuffer sb = new StringBuffer(); + SortedMap map = new TreeMap(); + map.putAll(unsortedMap); + for (Map.Entry entry : map.entrySet()) { if (entry.getValue() instanceof Map) diff --git a/source/java/org/alfresco/util/JSONtoFmModelTest.java b/source/java/org/alfresco/util/JSONtoFmModelTest.java index c1a7c420b9..669a149e69 100644 --- a/source/java/org/alfresco/util/JSONtoFmModelTest.java +++ b/source/java/org/alfresco/util/JSONtoFmModelTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2008 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -76,12 +76,12 @@ public class JSONtoFmModelTest extends TestCase String test3_expected_out = "doc:class java.util.HashMap\n" + - "\tghi:123:class java.lang.Integer\n" + - "\tmno:true:class java.lang.Boolean\n" + - "\tqrs:Sat Nov 05 13:15:30 GMT 1994:class java.util.Date\n" + - "\tdef:world:class java.lang.String\n" + "\tabc:hello:class java.lang.String\n" + - "\tjkl:123.456:class java.lang.Double\n"; + "\tdef:world:class java.lang.String\n" + + "\tghi:123:class java.lang.Integer\n" + + "\tjkl:123.456:class java.lang.Double\n" + + "\tmno:true:class java.lang.Boolean\n" + + "\tqrs:Sat Nov 05 13:15:30 GMT 1994:class java.util.Date\n"; String test4_in = "{" + @@ -109,29 +109,29 @@ public class JSONtoFmModelTest extends TestCase String test4_expected_out = "glossary:class java.util.HashMap\n" + - "\ttitle:example glossary:class java.lang.String\n" + "\tGlossDiv:class java.util.HashMap\n" + - "\t\ttitle:S:class java.lang.String\n" + "\t\tGlossList:class java.util.HashMap\n" + "\t\t\tGlossEntry:class java.util.HashMap\n" + - "\t\t\t\tGlossTerm:Standard Generalized Markup Language:class java.lang.String\n" + - "\t\t\t\tSortAs:SGML:class java.lang.String\n" + "\t\t\t\tAbbrev:ISO 8879:1986:class java.lang.String\n" + + "\t\t\t\tAcronym:SGML:class java.lang.String\n" + "\t\t\t\tGlossDef:class java.util.HashMap\n" + - "\t\t\t\t\tpara:A meta-markup language, used to create markup languages such as DocBook.:class java.lang.String\n" + "\t\t\t\t\t[\n" + "\t\t\t\t\tGML:class java.lang.String\n" + "\t\t\t\t\tXML:class java.lang.String\n" + "\t\t\t\t\tANO1:class java.lang.String\n" + "\t\t\t\t\tANO2:class java.lang.String\n" + "\t\t\t\t\t]\n" + - "\t\t\t\tAcronym:SGML:class java.lang.String\n" + + "\t\t\t\t\tpara:A meta-markup language, used to create markup languages such as DocBook.:class java.lang.String\n" + "\t\t\t\tGlossSee:markup:class java.lang.String\n" + - "\t\t\t\tID:SGML:class java.lang.String\n"; + "\t\t\t\tGlossTerm:Standard Generalized Markup Language:class java.lang.String\n" + + "\t\t\t\tID:SGML:class java.lang.String\n" + + "\t\t\t\tSortAs:SGML:class java.lang.String\n" + + "\t\ttitle:S:class java.lang.String\n" + + "\ttitle:example glossary:class java.lang.String\n"; try { - Configuration cfg = new Configuration(); + Configuration cfg = new Configuration(); cfg.setObjectWrapper(ObjectWrapper.DEFAULT_WRAPPER); String userDir = System.getProperty("user.dir"); @@ -148,7 +148,7 @@ public class JSONtoFmModelTest extends TestCase //System.out.println(JSONtoFmModel.toString(root)); assertEquals(test1_expected_out, JSONtoFmModel.toString(root)); - Template temp = cfg.getTemplate("test1.ftl"); + Template temp = cfg.getTemplate("test1.ftl"); Writer out = new OutputStreamWriter(System.out); temp.process(root, out); out.flush(); @@ -162,14 +162,14 @@ public class JSONtoFmModelTest extends TestCase root = JSONtoFmModel.convertJSONObjectToMap(test2_in); //System.out.println(JSONtoFmModel.toString(root)); assertEquals(test2_expected_out, JSONtoFmModel.toString(root)); - - temp = cfg.getTemplate("test2.ftl"); + + temp = cfg.getTemplate("test2.ftl"); out = new OutputStreamWriter(System.out); temp.process(root, out); out.flush(); System.out.println("\n\n\n"); - + // Test 3 System.out.println("TEST 3"); //System.out.println(test3_in); @@ -178,10 +178,10 @@ public class JSONtoFmModelTest extends TestCase //System.out.println(JSONtoFmModel.toString(root)); assertEquals(test3_expected_out, JSONtoFmModel.toString(root)); - temp = cfg.getTemplate("test3.ftl"); + temp = cfg.getTemplate("test3.ftl"); out = new OutputStreamWriter(System.out); temp.process(root, out); - out.flush(); + out.flush(); // Test 4 System.out.println("TEST 4"); @@ -191,10 +191,10 @@ public class JSONtoFmModelTest extends TestCase //System.out.println(JSONtoFmModel.toString(root)); assertEquals(test4_expected_out, JSONtoFmModel.toString(root)); - temp = cfg.getTemplate("test4.ftl"); + temp = cfg.getTemplate("test4.ftl"); out = new OutputStreamWriter(System.out); temp.process(root, out); - out.flush(); + out.flush(); } catch (Exception e) { diff --git a/source/test-resources/alfresco/audit/alfresco-audit-test.xml b/source/test-resources/alfresco/audit/alfresco-audit-test.xml index 4fee4a1ce7..c6da38addf 100644 --- a/source/test-resources/alfresco/audit/alfresco-audit-test.xml +++ b/source/test-resources/alfresco/audit/alfresco-audit-test.xml @@ -40,6 +40,15 @@ + + + + + + + + + diff --git a/source/test-resources/jbpm-test/test-workflow-context.xml b/source/test-resources/jbpm-test/test-workflow-context.xml index ae4f5e6202..3a32919815 100644 --- a/source/test-resources/jbpm-test/test-workflow-context.xml +++ b/source/test-resources/jbpm-test/test-workflow-context.xml @@ -3,6 +3,8 @@ + + @@ -20,7 +22,7 @@ - +