diff --git a/config/alfresco/bootstrap-context.xml b/config/alfresco/bootstrap-context.xml index 26f4227f84..3c6f71a5c3 100644 --- a/config/alfresco/bootstrap-context.xml +++ b/config/alfresco/bootstrap-context.xml @@ -73,7 +73,6 @@ - classpath:alfresco/dbscripts/create/2.2/${db.script.dialect}/AlfrescoPostCreate-2.2-MappedFKIndexes.sql classpath:alfresco/dbscripts/create/2.2/${db.script.dialect}/AlfrescoPostCreate-2.2-Extra.sql classpath:alfresco/dbscripts/create/2.2/${db.script.dialect}/post-create-indexes-04.sql classpath:alfresco/dbscripts/create/3.0/${db.script.dialect}/create-activities-extras.sql @@ -296,6 +295,14 @@ + + + + + true + + @@ -457,12 +464,7 @@ - - - - true - - + diff --git a/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.Dialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql b/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.Dialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql deleted file mode 100644 index dcc69b3183..0000000000 --- a/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.Dialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql +++ /dev/null @@ -1,85 +0,0 @@ --- --- Title: Post-Create Indexes --- Database: Generic --- Since: V2.2 Schema 86 --- Author: Derek Hulley --- --- Hibernate only generates indexes on foreign key columns for MySQL. --- --- Please contact support@alfresco.com if you need assistance with the upgrade. --- - -CREATE INDEX fk_alf_ace_auth ON alf_access_control_entry (authority_id); -CREATE INDEX fk_alf_ace_perm ON alf_access_control_entry (permission_id); -CREATE INDEX fk_alf_ace_ctx ON alf_access_control_entry (context_id); - -CREATE INDEX fk_alf_acl_acs ON alf_access_control_list (acl_change_set); - -CREATE INDEX fk_alf_aclm_acl ON alf_acl_member (acl_id); -CREATE INDEX fk_alf_aclm_ace ON alf_acl_member (ace_id); - -CREATE INDEX fk_alf_attr_acl ON alf_attributes (acl_id); - -CREATE INDEX fk_alf_adtf_src ON alf_audit_fact (audit_source_id); -CREATE INDEX fk_alf_adtf_date ON alf_audit_fact (audit_date_id); -CREATE INDEX fk_alf_adtf_conf ON alf_audit_fact (audit_conf_id); - -CREATE INDEX fk_alf_autha_ali ON alf_authority_alias (alias_id); -CREATE INDEX fk_alf_autha_aut ON alf_authority_alias (auth_id); - -CREATE INDEX fk_alf_cass_pnode ON alf_child_assoc (parent_node_id); -CREATE INDEX fk_alf_cass_cnode ON alf_child_assoc (child_node_id); - --- alf_global_attributes.attribute is declared unique. Indexes may automatically have been created. -CREATE INDEX fk_alf_gatt_att ON alf_global_attributes (attribute); -- (optional) - -CREATE INDEX fk_alf_lent_att ON alf_list_attribute_entries (attribute_id); -CREATE INDEX fk_alf_lent_latt ON alf_list_attribute_entries (list_id); - -CREATE INDEX fk_alf_matt_matt ON alf_map_attribute_entries (map_id); -CREATE INDEX fk_alf_matt_att ON alf_map_attribute_entries (attribute_id); - -CREATE INDEX fk_alf_node_acl ON alf_node (acl_id); -CREATE INDEX fk_alf_node_txn ON alf_node (transaction_id); -CREATE INDEX fk_alf_node_store ON alf_node (store_id); - -CREATE INDEX fk_alf_nasp_n ON alf_node_aspects (node_id); - -CREATE INDEX fk_alf_nass_snode ON alf_node_assoc (source_node_id); -CREATE INDEX fk_alf_nass_tnode ON alf_node_assoc (target_node_id); - -CREATE INDEX fk_alf_nprop_n ON alf_node_properties (node_id); - -CREATE INDEX fk_alf_qname_ns ON alf_qname (ns_id); - -CREATE INDEX fk_alf_store_root ON alf_store (root_node_id); - -CREATE INDEX fk_alf_txn_svr ON alf_transaction (server_id); - -CREATE INDEX fk_alf_usaged_n ON alf_usage_delta (node_id); - -CREATE INDEX fk_avm_nasp_n ON avm_aspects (node_id); - -CREATE INDEX fk_avm_ce_child ON avm_child_entries (child_id); -CREATE INDEX fk_avm_ce_parent ON avm_child_entries (parent_id); - -CREATE INDEX fk_avm_hl_desc ON avm_history_links (descendent); -CREATE INDEX fk_avm_hl_ancestor ON avm_history_links (ancestor); - -CREATE INDEX fk_avm_ml_to ON avm_merge_links (mto); -CREATE INDEX fk_avm_ml_from ON avm_merge_links (mfrom); - -CREATE INDEX fk_avm_nprop_n ON avm_node_properties (node_id); - -CREATE INDEX fk_avm_n_acl ON avm_nodes (acl_id); -CREATE INDEX fk_avm_n_store ON avm_nodes (store_new_id); - -CREATE INDEX fk_avm_sprop_store ON avm_store_properties (avm_store_id); - -CREATE INDEX fk_avm_s_acl ON avm_stores (acl_id); -CREATE INDEX fk_avm_s_root ON avm_stores (current_root_id); - -CREATE INDEX fk_avm_vlne_vr ON avm_version_layered_node_entry (version_root_id); - -CREATE INDEX fk_avm_vr_root ON avm_version_roots (root_id); -CREATE INDEX fk_avm_vr_store ON avm_version_roots (avm_store_id); diff --git a/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-2.2-Indexes.sql b/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-2.2-Indexes.sql deleted file mode 100644 index bb646416c2..0000000000 --- a/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-2.2-Indexes.sql +++ /dev/null @@ -1,29 +0,0 @@ --- --- Title: Post-Create Indexes --- Database: MySQL --- Since: V2.2 Schema 84 --- Author: Derek Hulley --- --- Hibernate only generates indexes on foreign key columns for MySQL. --- There are also certain relationships that can not be declared in Hibernate but --- still need to be maintained and need indexes. --- --- Please contact support@alfresco.com if you need assistance with the upgrade. --- - --- --- Explicit indexes not declared in the mappings --- - -CREATE INDEX fk_alf_na_qn ON alf_node_aspects (qname_id); - -CREATE INDEX fk_alf_np_qn ON alf_node_properties (qname_id); - -CREATE INDEX fk_avm_na_qn ON avm_aspects_new (qname_id); - -CREATE INDEX fk_avm_np_qn ON avm_node_properties_new (qname_id); - --- --- Foreign Key indexes --- These are auto-generated for MySQL --- diff --git a/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql b/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql deleted file mode 100644 index d226a575fc..0000000000 --- a/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql +++ /dev/null @@ -1,10 +0,0 @@ --- --- Title: Post-Create Indexes --- Database: MySQL --- Since: V2.2 Schema 86 --- Author: Derek Hulley --- --- Hibernate only generates indexes on foreign key columns for MySQL. --- --- Please contact support@alfresco.com if you need assistance with the upgrade. --- diff --git a/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql b/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql deleted file mode 100755 index 71fd470079..0000000000 --- a/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql +++ /dev/null @@ -1,10 +0,0 @@ --- --- Title: Post-Create Indexes --- Database: PostgreSQL --- Since: V2.2 Schema 86 --- Author: Pavel Yurkevich --- --- Hibernate only generates indexes on foreign key columns for Oracle. --- --- Please contact support@alfresco.com if you need assistance with the upgrade. --- diff --git a/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-3.2-AuditTables.sql b/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-3.2-AuditTables.sql index df68a02832..0ecd515b5d 100644 --- a/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-3.2-AuditTables.sql +++ b/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-3.2-AuditTables.sql @@ -12,7 +12,7 @@ CREATE TABLE alf_audit_model id BIGINT NOT NULL AUTO_INCREMENT, content_data_id BIGINT NOT NULL, content_crc BIGINT NOT NULL, - UNIQUE INDEX idx_alf_audit_cfg_crc (content_crc), + UNIQUE INDEX idx_alf_aud_mod_cr (content_crc), CONSTRAINT fk_alf_aud_mod_cd FOREIGN KEY (content_data_id) REFERENCES alf_content_data (id), PRIMARY KEY (id) ) ENGINE=InnoDB; @@ -24,8 +24,8 @@ CREATE TABLE alf_audit_app app_name_id BIGINT NOT NULL, audit_model_id BIGINT NOT NULL, disabled_paths_id BIGINT NOT NULL, - CONSTRAINT fk_alf_aud_app_app FOREIGN KEY (app_name_id) REFERENCES alf_prop_value (id), - CONSTRAINT UNIQUE id_alf_aud_app_app (app_name_id), + CONSTRAINT fk_alf_aud_app_an FOREIGN KEY (app_name_id) REFERENCES alf_prop_value (id), + CONSTRAINT UNIQUE idx_alf_aud_app_an (app_name_id), CONSTRAINT fk_alf_aud_app_mod FOREIGN KEY (audit_model_id) REFERENCES alf_audit_model (id) ON DELETE CASCADE, CONSTRAINT fk_alf_aud_app_dis FOREIGN KEY (disabled_paths_id) REFERENCES alf_prop_root (id), PRIMARY KEY (id) @@ -39,7 +39,7 @@ CREATE TABLE alf_audit_entry audit_user_id BIGINT NULL, audit_values_id BIGINT NULL, CONSTRAINT fk_alf_aud_ent_app FOREIGN KEY (audit_app_id) REFERENCES alf_audit_app (id) ON DELETE CASCADE, - INDEX idx_alf_audit_ent_time (audit_time), + INDEX idx_alf_aud_ent_tm (audit_time), CONSTRAINT fk_alf_aud_ent_use FOREIGN KEY (audit_user_id) REFERENCES alf_prop_value (id), CONSTRAINT fk_alf_aud_ent_pro FOREIGN KEY (audit_values_id) REFERENCES alf_prop_root (id), PRIMARY KEY (id) diff --git a/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-3.2-PropertyValueTables.sql b/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-3.2-PropertyValueTables.sql index a6696b2a0a..6d9ab59542 100644 --- a/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-3.2-PropertyValueTables.sql +++ b/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.MySQLInnoDBDialect/AlfrescoPostCreate-3.2-PropertyValueTables.sql @@ -13,8 +13,8 @@ CREATE TABLE alf_prop_class java_class_name VARCHAR(255) NOT NULL, java_class_name_short VARCHAR(32) NOT NULL, java_class_name_crc BIGINT NOT NULL, - UNIQUE INDEX idx_alf_prop_class_crc (java_class_name_crc, java_class_name_short), - INDEX idx_alf_prop_class_class (java_class_name), + UNIQUE INDEX idx_alf_propc_crc (java_class_name_crc, java_class_name_short), + INDEX idx_alf_propc_clas (java_class_name), PRIMARY KEY (id) ) ENGINE=InnoDB; @@ -30,7 +30,7 @@ CREATE TABLE alf_prop_date_value day_of_year SMALLINT NOT NULL, day_of_month TINYINT NOT NULL, day_of_week TINYINT NOT NULL, - INDEX idx_alf_prop_date_units (full_year, month_of_year, day_of_month), + INDEX idx_alf_propdt_dt (full_year, month_of_year, day_of_month), PRIMARY KEY (date_value) ) ENGINE=InnoDB; @@ -38,7 +38,7 @@ CREATE TABLE alf_prop_double_value ( id BIGINT NOT NULL AUTO_INCREMENT, double_value DOUBLE NOT NULL, - UNIQUE INDEX idx_alf_prop_dbl_val (double_value), + UNIQUE INDEX idx_alf_propd_val (double_value), PRIMARY KEY (id) ) ENGINE=InnoDB; @@ -49,8 +49,8 @@ CREATE TABLE alf_prop_string_value string_value TEXT NOT NULL, string_end_lower VARCHAR(16) NOT NULL, string_crc BIGINT NOT NULL, - INDEX idx_alf_prop_str (string_value(32)), - UNIQUE INDEX idx_alf_prop_crc (string_end_lower, string_crc), + INDEX idx_alf_props_str (string_value(32)), + UNIQUE INDEX idx_alf_props_crc (string_end_lower, string_crc), PRIMARY KEY (id) ) ENGINE=InnoDB; @@ -67,8 +67,8 @@ CREATE TABLE alf_prop_value actual_type_id BIGINT NOT NULL, persisted_type TINYINT NOT NULL, long_value BIGINT NOT NULL, - INDEX idx_alf_prop_per (persisted_type, long_value), - UNIQUE INDEX idx_alf_prop_act (actual_type_id, long_value), + INDEX idx_alf_propv_per (persisted_type, long_value), + UNIQUE INDEX idx_alf_propv_act (actual_type_id, long_value), PRIMARY KEY (id) ) ENGINE=InnoDB; @@ -86,10 +86,10 @@ CREATE TABLE alf_prop_link contained_in BIGINT NOT NULL, key_prop_id BIGINT NOT NULL, value_prop_id BIGINT NOT NULL, - CONSTRAINT fk_alf_pr_li_root FOREIGN KEY (root_prop_id) REFERENCES alf_prop_root (id) ON DELETE CASCADE, - CONSTRAINT fk_alf_pr_li_key FOREIGN KEY (key_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, - CONSTRAINT fk_alf_pr_li_val FOREIGN KEY (value_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, - INDEX idx_alf_prop_link_for (root_prop_id, key_prop_id, value_prop_id), + CONSTRAINT fk_alf_propln_root FOREIGN KEY (root_prop_id) REFERENCES alf_prop_root (id) ON DELETE CASCADE, + CONSTRAINT fk_alf_propln_key FOREIGN KEY (key_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, + CONSTRAINT fk_alf_propln_val FOREIGN KEY (value_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, + INDEX idx_alf_propln_for (root_prop_id, key_prop_id, value_prop_id), PRIMARY KEY (root_prop_id, contained_in, prop_index) ) ENGINE=InnoDB; @@ -100,10 +100,10 @@ CREATE TABLE alf_prop_unique_ctx value1_prop_id BIGINT NOT NULL, value2_prop_id BIGINT NOT NULL, value3_prop_id BIGINT NOT NULL, - UNIQUE INDEX idx_alf_prop_unique_ctx (value1_prop_id, value2_prop_id, value3_prop_id), - CONSTRAINT fk_alf_pr_un_ctx_1 FOREIGN KEY (value1_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, - CONSTRAINT fk_alf_pr_un_ctx_2 FOREIGN KEY (value2_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, - CONSTRAINT fk_alf_pr_un_ctx_3 FOREIGN KEY (value3_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, + UNIQUE INDEX idx_alf_propuctx (value1_prop_id, value2_prop_id, value3_prop_id), + CONSTRAINT fk_alf_propuctx_v1 FOREIGN KEY (value1_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, + CONSTRAINT fk_alf_propuctx_v2 FOREIGN KEY (value2_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, + CONSTRAINT fk_alf_propuctx_v3 FOREIGN KEY (value3_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, PRIMARY KEY (id) ) ENGINE=InnoDB; diff --git a/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-3.2-AuditTables.sql b/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-3.2-AuditTables.sql index 9f8fe75845..d59151d75e 100755 --- a/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-3.2-AuditTables.sql +++ b/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-3.2-AuditTables.sql @@ -15,7 +15,7 @@ CREATE TABLE alf_audit_model CONSTRAINT fk_alf_aud_mod_cd FOREIGN KEY (content_data_id) REFERENCES alf_content_data (id), PRIMARY KEY (id) ); -CREATE UNIQUE INDEX idx_alf_audit_cfg_crc ON alf_audit_model(content_crc); +CREATE UNIQUE INDEX idx_alf_aud_mod_cr ON alf_audit_model(content_crc); CREATE SEQUENCE alf_audit_model_seq START WITH 1 INCREMENT BY 1; @@ -23,10 +23,10 @@ CREATE TABLE alf_audit_app ( id INT8 NOT NULL, version INT4 NOT NULL, - app_name_id INT8 NOT NULL CONSTRAINT id_alf_aud_app_app UNIQUE, + app_name_id INT8 NOT NULL CONSTRAINT idx_alf_aud_app_an UNIQUE, audit_model_id INT8 NOT NULL, disabled_paths_id INT8 NOT NULL, - CONSTRAINT fk_alf_aud_app_app FOREIGN KEY (app_name_id) REFERENCES alf_prop_value (id), + CONSTRAINT fk_alf_aud_app_an FOREIGN KEY (app_name_id) REFERENCES alf_prop_value (id), CONSTRAINT fk_alf_aud_app_mod FOREIGN KEY (audit_model_id) REFERENCES alf_audit_model (id) ON DELETE CASCADE, CONSTRAINT fk_alf_aud_app_dis FOREIGN KEY (disabled_paths_id) REFERENCES alf_prop_root (id), PRIMARY KEY (id) @@ -45,7 +45,7 @@ CREATE TABLE alf_audit_entry CONSTRAINT fk_alf_aud_ent_pro FOREIGN KEY (audit_values_id) REFERENCES alf_prop_root (id), PRIMARY KEY (id) ); -CREATE INDEX idx_alf_audit_ent_time ON alf_audit_entry(audit_time); +CREATE INDEX idx_alf_aud_ent_tm ON alf_audit_entry(audit_time); CREATE SEQUENCE alf_audit_entry_seq START WITH 1 INCREMENT BY 1; diff --git a/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-3.2-PropertyValueTables.sql b/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-3.2-PropertyValueTables.sql index f52d3ec1e3..45193dc455 100755 --- a/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-3.2-PropertyValueTables.sql +++ b/config/alfresco/dbscripts/create/3.2/org.hibernate.dialect.PostgreSQLDialect/AlfrescoPostCreate-3.2-PropertyValueTables.sql @@ -15,8 +15,8 @@ CREATE TABLE alf_prop_class java_class_name_crc INT8 NOT NULL, PRIMARY KEY (id) ); -CREATE UNIQUE INDEX idx_alf_prop_class_crc ON alf_prop_class(java_class_name_crc, java_class_name_short); -CREATE INDEX idx_alf_prop_class_class ON alf_prop_class(java_class_name); +CREATE UNIQUE INDEX idx_alf_propc_crc ON alf_prop_class(java_class_name_crc, java_class_name_short); +CREATE INDEX idx_alf_propc_clas ON alf_prop_class(java_class_name); CREATE SEQUENCE alf_prop_class_seq START WITH 1 INCREMENT BY 1; @@ -34,7 +34,7 @@ CREATE TABLE alf_prop_date_value day_of_week INT2 NOT NULL, PRIMARY KEY (date_value) ); -CREATE INDEX idx_alf_prop_date_units ON alf_prop_date_value(full_year, month_of_year, day_of_month); +CREATE INDEX idx_alf_propdt_dt ON alf_prop_date_value(full_year, month_of_year, day_of_month); CREATE TABLE alf_prop_double_value ( @@ -42,7 +42,7 @@ CREATE TABLE alf_prop_double_value double_value FLOAT8 NOT NULL, PRIMARY KEY (id) ); -CREATE UNIQUE INDEX idx_alf_prop_dbl_val ON alf_prop_double_value(double_value); +CREATE UNIQUE INDEX idx_alf_propd_val ON alf_prop_double_value(double_value); CREATE SEQUENCE alf_prop_double_value_seq START WITH 1 INCREMENT BY 1; @@ -55,8 +55,8 @@ CREATE TABLE alf_prop_string_value string_crc INT8 NOT NULL, PRIMARY KEY (id) ); -CREATE INDEX idx_alf_prop_str ON alf_prop_string_value(string_value); -CREATE UNIQUE INDEX idx_alf_prop_crc ON alf_prop_string_value(string_end_lower, string_crc); +CREATE INDEX idx_alf_props_str ON alf_prop_string_value(string_value); +CREATE UNIQUE INDEX idx_alf_props_crc ON alf_prop_string_value(string_end_lower, string_crc); CREATE SEQUENCE alf_prop_string_value_seq START WITH 1 INCREMENT BY 1; @@ -76,8 +76,8 @@ CREATE TABLE alf_prop_value long_value INT8 NOT NULL, PRIMARY KEY (id) ); -CREATE INDEX idx_alf_prop_per ON alf_prop_value(persisted_type, long_value); -CREATE UNIQUE INDEX idx_alf_prop_act ON alf_prop_value(actual_type_id, long_value); +CREATE INDEX idx_alf_propv_per ON alf_prop_value(persisted_type, long_value); +CREATE UNIQUE INDEX idx_alf_propv_act ON alf_prop_value(actual_type_id, long_value); CREATE SEQUENCE alf_prop_value_seq START WITH 1 INCREMENT BY 1; @@ -96,12 +96,12 @@ CREATE TABLE alf_prop_link contained_in INT8 NOT NULL, key_prop_id INT8 NOT NULL, value_prop_id INT8 NOT NULL, - CONSTRAINT fk_alf_pr_li_root FOREIGN KEY (root_prop_id) REFERENCES alf_prop_root (id) ON DELETE CASCADE, - CONSTRAINT fk_alf_pr_li_key FOREIGN KEY (key_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, - CONSTRAINT fk_alf_pr_li_val FOREIGN KEY (value_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, + CONSTRAINT fk_alf_propln_root FOREIGN KEY (root_prop_id) REFERENCES alf_prop_root (id) ON DELETE CASCADE, + CONSTRAINT fk_alf_propln_key FOREIGN KEY (key_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, + CONSTRAINT fk_alf_propln_val FOREIGN KEY (value_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, PRIMARY KEY (root_prop_id, contained_in, prop_index) ); -CREATE INDEX idx_alf_prop_link_for ON alf_prop_link(root_prop_id, key_prop_id, value_prop_id); +CREATE INDEX idx_alf_propln_for ON alf_prop_link(root_prop_id, key_prop_id, value_prop_id); CREATE TABLE alf_prop_unique_ctx ( @@ -110,12 +110,12 @@ CREATE TABLE alf_prop_unique_ctx value1_prop_id INT8 NOT NULL, value2_prop_id INT8 NOT NULL, value3_prop_id INT8 NOT NULL, - CONSTRAINT fk_alf_pr_un_ctx_1 FOREIGN KEY (value1_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, - CONSTRAINT fk_alf_pr_un_ctx_2 FOREIGN KEY (value2_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, - CONSTRAINT fk_alf_pr_un_ctx_3 FOREIGN KEY (value3_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, + CONSTRAINT fk_alf_propuctx_v1 FOREIGN KEY (value1_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, + CONSTRAINT fk_alf_propuctx_v2 FOREIGN KEY (value2_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, + CONSTRAINT fk_alf_propuctx_v3 FOREIGN KEY (value3_prop_id) REFERENCES alf_prop_value (id) ON DELETE CASCADE, PRIMARY KEY (id) ); -CREATE UNIQUE INDEX idx_alf_prop_unique_ctx ON alf_prop_unique_ctx(value1_prop_id, value2_prop_id, value3_prop_id); +CREATE UNIQUE INDEX idx_alf_propuctx ON alf_prop_unique_ctx(value1_prop_id, value2_prop_id, value3_prop_id); CREATE SEQUENCE alf_prop_unique_ctx_seq START WITH 1 INCREMENT BY 1; diff --git a/config/alfresco/dbscripts/upgrade/3.2/org.hibernate.dialect.MySQLInnoDBDialect/child-assoc-qname-crc.sql b/config/alfresco/dbscripts/upgrade/3.2/org.hibernate.dialect.MySQLInnoDBDialect/child-assoc-qname-crc.sql index 3daecc51dd..bed38565f7 100644 --- a/config/alfresco/dbscripts/upgrade/3.2/org.hibernate.dialect.MySQLInnoDBDialect/child-assoc-qname-crc.sql +++ b/config/alfresco/dbscripts/upgrade/3.2/org.hibernate.dialect.MySQLInnoDBDialect/child-assoc-qname-crc.sql @@ -1,13 +1,13 @@ -- --- Title: Upgrade to V3.2 - Add qname_crc column to alf_child_assoc +-- Title: Upgrade to V3.2 - Add qname_crc column to alf_child_assoc -- Database: MySQL --- Since: V3.2 schema 2023 +-- Since: V3.2 schema 3006 -- Author: davew -- -- Add qname_crc column to alf_child_assoc and change indexes -- -- Please contact support@alfresco.com if you need assistance with the upgrade. --- +-- ALTER TABLE alf_child_assoc ADD COLUMN qname_crc BIGINT NOT NULL DEFAULT 0 AFTER qname_localname @@ -40,5 +40,5 @@ INSERT INTO alf_applied_patch VALUES ( 'patch.db-V3.2-Child-Assoc-QName-CRC', 'Manually executed script upgrade V3.2 to Add qname_crc column to alf_child_assoc and change indexes', - 0, 3005, -1, 3006, null, 'UNKOWN', 1, 1, 'Script completed' + 0, 3005, -1, 3006, null, 'UNKOWN', 1, 1, 'Script completed' ); diff --git a/config/alfresco/dbscripts/upgrade/3.2/org.hibernate.dialect.PostgreSQLDialect/child-assoc-qname-crc.sql b/config/alfresco/dbscripts/upgrade/3.2/org.hibernate.dialect.PostgreSQLDialect/child-assoc-qname-crc.sql index ab6dd133b5..8d8aa46a88 100755 --- a/config/alfresco/dbscripts/upgrade/3.2/org.hibernate.dialect.PostgreSQLDialect/child-assoc-qname-crc.sql +++ b/config/alfresco/dbscripts/upgrade/3.2/org.hibernate.dialect.PostgreSQLDialect/child-assoc-qname-crc.sql @@ -1,7 +1,7 @@ -- -- Title: Upgrade to V3.2 - Add qname_crc column to alf_child_assoc -- Database: PostgreSQL --- Since: V3.2 schema 2023 +-- Since: V3.2 schema 3006 -- Author: Pavel Yurkevich -- -- Add qname_crc column to alf_child_assoc and change indexes diff --git a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java index 99e860289e..48b9cc6e9d 100644 --- a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java +++ b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java @@ -1,971 +1,968 @@ -/* - * 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 - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - * As a special exception to the terms and conditions of version 2.0 of - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: - * http://www.alfresco.com/legal/licensing - */ - -package org.alfresco.repo.avm; - -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; - -import org.alfresco.repo.avm.util.AVMUtil; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.service.cmr.avm.AVMBadArgumentException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.cmr.avm.LayeringDescriptor; -import org.alfresco.service.cmr.avm.VersionDescriptor; -import org.alfresco.service.cmr.avm.locking.AVMLock; -import org.alfresco.service.cmr.avm.locking.AVMLockingException; -import org.alfresco.service.cmr.avm.locking.AVMLockingService; -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.security.AuthenticationService; -import org.alfresco.service.namespace.QName; -import org.springframework.extensions.surf.util.Pair; -import org.alfresco.wcm.util.WCMUtil; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; - -/** - * An AVMLockingService aware implemantation of AVMService. - * @author britt - */ -public class AVMLockingAwareService implements AVMService, ApplicationContextAware -{ - public static final String STORE_SEPARATOR = "--"; - - private AVMService fService; - - private AVMLockingService fLockingService; - - private AuthenticationService fAuthenticationService; - - private ApplicationContext fContext; - - public AVMLockingAwareService() - { - } - - /* (non-Javadoc) - * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) - */ - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException - { - fContext = applicationContext; - } - - public void init() - { - fService = (AVMService)fContext.getBean("avmService"); - fLockingService = (AVMLockingService)fContext.getBean("avmLockingService"); - fAuthenticationService = (AuthenticationService)fContext.getBean("authenticationService"); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#addAspect(java.lang.String, org.alfresco.service.namespace.QName) - */ - public void addAspect(String path, QName aspectName) - { - grabLock(path); - fService.addAspect(path, aspectName); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#copy(int, java.lang.String, java.lang.String, java.lang.String) - */ - public void copy(int srcVersion, String srcPath, String dstPath, String name) - { - fService.copy(srcVersion, srcPath, dstPath, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createBranch(int, java.lang.String, java.lang.String, java.lang.String) - */ - public void createBranch(int version, String srcPath, String dstPath, - String name) - { - fService.createBranch(version, srcPath, dstPath, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createDirectory(java.lang.String, java.lang.String) - */ - public void createDirectory(String path, String name) - { - fService.createDirectory(path, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createFile(java.lang.String, java.lang.String) - */ - public OutputStream createFile(String path, String name) - { - grabLock(path + '/' + name); - return fService.createFile(path, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createFile(java.lang.String, java.lang.String, java.io.InputStream) - */ - public void createFile(String path, String name, InputStream in) - { - grabLock(path + '/' + name); - fService.createFile(path, name, in); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createLayeredDirectory(java.lang.String, java.lang.String, java.lang.String) - */ - public void createLayeredDirectory(String targetPath, String parent, - String name) - { - fService.createLayeredDirectory(targetPath, parent, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createLayeredFile(java.lang.String, java.lang.String, java.lang.String) - */ - public void createLayeredFile(String targetPath, String parent, String name) - { - grabLock(parent + '/' + name); - fService.createLayeredFile(targetPath, parent, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createSnapshot(java.lang.String, java.lang.String, java.lang.String) - */ - public Map createSnapshot(String store, String tag, String description) - { - return fService.createSnapshot(store, tag, description); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createStore(java.lang.String) - */ - public void createStore(String name) - { - fService.createStore(name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createStore(java.lang.String, java.util.Map) - */ - public void createStore(String name, Map props) - { - fService.createStore(name, props); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#deleteNodeProperties(java.lang.String) - */ - public void deleteNodeProperties(String path) - { - grabLock(path); - fService.deleteNodeProperties(path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#deleteNodeProperty(java.lang.String, org.alfresco.service.namespace.QName) - */ - public void deleteNodeProperty(String path, QName name) - { - grabLock(path); - fService.deleteNodeProperty(path, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#deleteStoreProperty(java.lang.String, org.alfresco.service.namespace.QName) - */ - public void deleteStoreProperty(String store, QName name) - { - fService.deleteStoreProperty(store, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#forceCopy(java.lang.String) - */ - public AVMNodeDescriptor forceCopy(String path) - { - grabLock(path); - return fService.forceCopy(path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getAPath(org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public Pair getAPath(AVMNodeDescriptor desc) - { - return fService.getAPath(desc); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getPathsInStoreVersion(org.alfresco.service.cmr.avm.AVMNodeDescriptor, java.lang.String, int) - */ - public List getPathsInStoreVersion(AVMNodeDescriptor desc, String store, int version) - { - return fService.getPathsInStoreVersion(desc, store, version); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getAspects(int, java.lang.String) - */ - public Set getAspects(int version, String path) - { - return fService.getAspects(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getAspects(org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public Set getAspects(AVMNodeDescriptor desc) - { - return fService.getAspects(desc); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getCommonAncestor(org.alfresco.service.cmr.avm.AVMNodeDescriptor, org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public AVMNodeDescriptor getCommonAncestor(AVMNodeDescriptor left, - AVMNodeDescriptor right) - { - return fService.getCommonAncestor(left, right); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getContentDataForRead(int, java.lang.String) - */ - public ContentData getContentDataForRead(int version, String path) - { - return fService.getContentDataForRead(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getContentDataForRead(org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public ContentData getContentDataForRead(AVMNodeDescriptor desc) - { - return fService.getContentDataForRead(desc); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getContentDataForWrite(java.lang.String) - */ - public ContentData getContentDataForWrite(String path) - { - grabLock(path); - return fService.getContentDataForWrite(path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getContentReader(int, java.lang.String) - */ - public ContentReader getContentReader(int version, String path) - { - return fService.getContentReader(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getContentWriter(java.lang.String) - */ - public ContentWriter getContentWriter(String path) - { - grabLock(path); - return fService.getContentWriter(path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getDeleted(int, java.lang.String) - */ - public List getDeleted(int version, String path) - { - return fService.getDeleted(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListing(int, java.lang.String) - */ - public SortedMap getDirectoryListing( - int version, String path) - { - return fService.getDirectoryListing(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListing(int, java.lang.String, boolean) - */ - public SortedMap getDirectoryListing( - int version, String path, boolean includeDeleted) - { - return fService.getDirectoryListing(version, path, includeDeleted); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListing(org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public SortedMap getDirectoryListing( - AVMNodeDescriptor dir) - { - return fService.getDirectoryListing(dir); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListing(org.alfresco.service.cmr.avm.AVMNodeDescriptor, String) - */ - public SortedMap getDirectoryListing( - AVMNodeDescriptor dir, String childNamePattern) - { - return fService.getDirectoryListing(dir, childNamePattern); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListing(org.alfresco.service.cmr.avm.AVMNodeDescriptor, boolean) - */ - public SortedMap getDirectoryListing( - AVMNodeDescriptor dir, boolean includeDeleted) - { - return fService.getDirectoryListing(dir, includeDeleted); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListingArray(int, java.lang.String, boolean) - */ - public AVMNodeDescriptor[] getDirectoryListingArray(int version, - String path, boolean includeDeleted) - { - return fService.getDirectoryListingArray(version, path, includeDeleted); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListingArray(org.alfresco.service.cmr.avm.AVMNodeDescriptor, boolean) - */ - public AVMNodeDescriptor[] getDirectoryListingArray(AVMNodeDescriptor dir, - boolean includeDeleted) - { - return fService.getDirectoryListingArray(dir, includeDeleted); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListingDirect(int, java.lang.String) - */ - public SortedMap getDirectoryListingDirect( - int version, String path) - { - return fService.getDirectoryListingDirect(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListingDirect(int, java.lang.String, boolean) - */ - public SortedMap getDirectoryListingDirect( - int version, String path, boolean includeDeleted) - { - return fService.getDirectoryListingDirect(version, path, includeDeleted); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListingDirect(org.alfresco.service.cmr.avm.AVMNodeDescriptor, boolean) - */ - public SortedMap getDirectoryListingDirect( - AVMNodeDescriptor dir, boolean includeDeleted) - { - return fService.getDirectoryListingDirect(dir, includeDeleted); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getFileInputStream(int, java.lang.String) - */ - public InputStream getFileInputStream(int version, String path) - { - return fService.getFileInputStream(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getFileInputStream(org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public InputStream getFileInputStream(AVMNodeDescriptor desc) - { - return fService.getFileInputStream(desc); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getFileOutputStream(java.lang.String) - */ - public OutputStream getFileOutputStream(String path) - { - grabLock(path); - return fService.getFileOutputStream(path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getHeadPaths(org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public List> getHeadPaths(AVMNodeDescriptor desc) - { - return fService.getHeadPaths(desc); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getHistory(org.alfresco.service.cmr.avm.AVMNodeDescriptor, int) - */ - public List getHistory(AVMNodeDescriptor desc, int count) - { - return fService.getHistory(desc, count); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getIndirectionPath(int, java.lang.String) - */ - public String getIndirectionPath(int version, String path) - { - return fService.getIndirectionPath(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getLatestSnapshotID(java.lang.String) - */ - public int getLatestSnapshotID(String storeName) - { - return fService.getLatestSnapshotID(storeName); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getLayeringInfo(int, java.lang.String) - */ - public LayeringDescriptor getLayeringInfo(int version, String path) - { - return fService.getLayeringInfo(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getNextVersionID(java.lang.String) - */ - public int getNextVersionID(String storeName) - { - return fService.getNextVersionID(storeName); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getNodeProperties(int, java.lang.String) - */ - public Map getNodeProperties(int version, String path) - { - return fService.getNodeProperties(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getNodeProperties(org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public Map getNodeProperties(AVMNodeDescriptor desc) - { - return fService.getNodeProperties(desc); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getNodeProperty(int, java.lang.String, org.alfresco.service.namespace.QName) - */ - public PropertyValue getNodeProperty(int version, String path, QName name) - { - return fService.getNodeProperty(version, path, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getPaths(org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public List> getPaths(AVMNodeDescriptor desc) - { - return fService.getPaths(desc); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getPathsInStoreHead(org.alfresco.service.cmr.avm.AVMNodeDescriptor, java.lang.String) - */ - public List> getPathsInStoreHead( - AVMNodeDescriptor desc, String store) - { - return fService.getPathsInStoreHead(desc, store); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getStore(java.lang.String) - */ - public AVMStoreDescriptor getStore(String name) - { - return fService.getStore(name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getStoreProperties(java.lang.String) - */ - public Map getStoreProperties(String store) - { - return fService.getStoreProperties(store); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getStoreProperty(java.lang.String, org.alfresco.service.namespace.QName) - */ - public PropertyValue getStoreProperty(String store, QName name) - { - return fService.getStoreProperty(store, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getStoreRoot(int, java.lang.String) - */ - public AVMNodeDescriptor getStoreRoot(int version, String name) - { - return fService.getStoreRoot(version, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getStoreVersions(java.lang.String) - */ - public List getStoreVersions(String name) - { - return fService.getStoreVersions(name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getStoreVersions(java.lang.String, java.util.Date, java.util.Date) - */ - public List getStoreVersions(String name, Date from, - Date to) - { - return fService.getStoreVersions(name, from, to); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getStores() - */ - public List getStores() - { - return fService.getStores(); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#getSystemStore() - */ - public AVMStoreDescriptor getSystemStore() - { - return fService.getSystemStore(); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#hasAspect(int, java.lang.String, org.alfresco.service.namespace.QName) - */ - public boolean hasAspect(int version, String path, QName aspectName) - { - return fService.hasAspect(version, path, aspectName); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#link(java.lang.String, java.lang.String, org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public void link(String parentPath, String name, AVMNodeDescriptor toLink) - { - // TODO Does this need a lock? I don't think so, but revisit. - fService.link(parentPath, name, toLink); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#updateLink(java.lang.String, java.lang.String, org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public void updateLink(String parentPath, String name, AVMNodeDescriptor toLink) - { - // TODO Does this need a lock? I don't think so, but revisit. - fService.updateLink(parentPath, name, toLink); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#lookup(int, java.lang.String) - */ - public AVMNodeDescriptor lookup(int version, String path) - { - return fService.lookup(version, path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#lookup(int, java.lang.String, boolean) - */ - public AVMNodeDescriptor lookup(int version, String path, - boolean includeDeleted) - { - return fService.lookup(version, path, includeDeleted); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#lookup(org.alfresco.service.cmr.avm.AVMNodeDescriptor, java.lang.String) - */ - public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name) - { - return fService.lookup(dir, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#lookup(org.alfresco.service.cmr.avm.AVMNodeDescriptor, java.lang.String, boolean) - */ - public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name, - boolean includeDeleted) - { - return fService.lookup(dir, name, includeDeleted); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#makePrimary(java.lang.String) - */ - public void makePrimary(String path) - { - fService.makePrimary(path); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#makeTransparent(java.lang.String, java.lang.String) - */ - public void makeTransparent(String dirPath, String name) - { - fService.makeTransparent(dirPath, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#purgeStore(java.lang.String) - */ - public void purgeStore(String name) - { - fService.purgeStore(name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#purgeVersion(int, java.lang.String) - */ - public void purgeVersion(int version, String name) - { - fService.purgeVersion(version, name); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#queryStorePropertyKey(java.lang.String, org.alfresco.service.namespace.QName) - */ - public Map queryStorePropertyKey(String store, - QName keyPattern) - { - return fService.queryStorePropertyKey(store, keyPattern); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#queryStoresPropertyKeys(org.alfresco.service.namespace.QName) - */ - public Map> queryStoresPropertyKeys( - QName keyPattern) - { - return fService.queryStoresPropertyKeys(keyPattern); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#removeAspect(java.lang.String, org.alfresco.service.namespace.QName) - */ - public void removeAspect(String path, QName aspectName) - { - grabLock(path); - fService.removeAspect(path, aspectName); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#removeNode(java.lang.String, java.lang.String) - */ - public void removeNode(String parent, String name) - { - String path = AVMUtil.extendAVMPath(parent, name); - grabLock(path); - fService.removeNode(parent, name); - String[] storePath = parent.split(":"); - fService.createSnapshot(storePath[0], null, "Removed "+path); - String webProject = getWebProject(storePath[0]); - if (webProject != null) - { - fLockingService.removeLocksInDirectory(webProject, storePath[0], storePath[1] + '/' + name); - } - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#removeNode(java.lang.String) - */ - public void removeNode(String path) - { - grabLock(path); - fService.removeNode(path); - String[] storePath = path.split(":"); - fService.createSnapshot(storePath[0], null, "Removed "+path); - String webProject = getWebProject(storePath[0]); - if (webProject != null) - { - fLockingService.removeLocksInDirectory(webProject, storePath[0], storePath[1]); - } - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#rename(java.lang.String, java.lang.String, java.lang.String, java.lang.String) - */ - public void rename(String srcParent, String srcName, String dstParent, - String dstName) - { - // TODO Unresolved: how to deal with directory level locking. - // TODO This assumes that the rename occurs within the same web project. - - String srcPath = srcParent + '/' + srcName; - - AVMNodeDescriptor desc = fService.lookup(-1, srcPath, false); - if (! (desc != null && desc.isDirectory())) - { - grabLock(srcParent + '/' + srcName); - } - - fService.rename(srcParent, srcName, dstParent, dstName); - - if (! (desc != null && desc.isDirectory())) - { - String[] srcStorePath = splitPath(srcParent + '/' + srcName); - String[] dstStorePath = splitPath(dstParent + '/' + dstName); - String webProject = getWebProject(dstStorePath[0]); - if (webProject != null) - { - fLockingService.modifyLock(webProject, srcStorePath[1], dstStorePath[1], dstStorePath[0], null, null); - } - } - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#renameStore(java.lang.String, java.lang.String) - */ - public void renameStore(String sourceName, String destName) - { - fService.renameStore(sourceName, destName); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#retargetLayeredDirectory(java.lang.String, java.lang.String) - */ - public void retargetLayeredDirectory(String path, String target) - { - // TODO This assumes that directories are not locked. - fService.retargetLayeredDirectory(path, target); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#revert(java.lang.String, org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public void revert(String path, AVMNodeDescriptor toRevertTo) - { - grabLock(path); - fService.revert(path, toRevertTo); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setContentData(java.lang.String, org.alfresco.service.cmr.repository.ContentData) - */ - public void setContentData(String path, ContentData data) - { - grabLock(path); - fService.setContentData(path, data); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setEncoding(java.lang.String, java.lang.String) - */ - public void setEncoding(String path, String encoding) - { - grabLock(path); - fService.setEncoding(path, encoding); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setGuid(java.lang.String, java.lang.String) - */ - public void setGuid(String path, String guid) - { - grabLock(path); - fService.setGuid(path, guid); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setMetaDataFrom(java.lang.String, org.alfresco.service.cmr.avm.AVMNodeDescriptor) - */ - public void setMetaDataFrom(String path, AVMNodeDescriptor from) - { - grabLock(path); - fService.setMetaDataFrom(path, from); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setMimeType(java.lang.String, java.lang.String) - */ - public void setMimeType(String path, String mimeType) - { - grabLock(path); - fService.setMimeType(path, mimeType); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setNodeProperties(java.lang.String, java.util.Map) - */ - public void setNodeProperties(String path, - Map properties) - { - grabLock(path); - fService.setNodeProperties(path, properties); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setNodeProperty(java.lang.String, org.alfresco.service.namespace.QName, org.alfresco.repo.domain.PropertyValue) - */ - public void setNodeProperty(String path, QName name, PropertyValue value) - { - grabLock(path); - fService.setNodeProperty(path, name, value); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setOpacity(java.lang.String, boolean) - */ - public void setOpacity(String path, boolean opacity) - { - // TODO Assumes no directory locking. - fService.setOpacity(path, opacity); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setStoreProperties(java.lang.String, java.util.Map) - */ - public void setStoreProperties(String store, Map props) - { - fService.setStoreProperties(store, props); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#setStoreProperty(java.lang.String, org.alfresco.service.namespace.QName, org.alfresco.repo.domain.PropertyValue) - */ - public void setStoreProperty(String store, QName name, PropertyValue value) - { - fService.setStoreProperty(store, name, value); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#uncover(java.lang.String, java.lang.String) - */ - public void uncover(String dirPath, String name) - { - // TODO What about when this is a directory? - grabLock(dirPath + '/' + name); - fService.uncover(dirPath, name); - } - - private String[] splitPath(String path) - { - String[] storePath = path.split(":"); - if (storePath.length != 2) - { - throw new AVMBadArgumentException("Invalid Path: " + path); - } - return storePath; - } - - private String getWebProject(String name) - { - String wpStoreId = WCMUtil.getWebProjectStoreId(name); - if (WCMUtil.getWebProjectNodeFromWebProjectStore(fService, wpStoreId) != null) - { - return wpStoreId; - } - return null; - } - - private void grabLock(String path) - { - AVMNodeDescriptor desc = fService.lookup(-1, path, false); - if (desc != null && desc.isDirectory()) - { - return; - } - String[] storePath = splitPath(path); - String webProject = getWebProject(storePath[0]); - if (webProject != null && webProject.equals(storePath[0])) - { - // Don't do locking in staging. - return; - } - if (webProject != null) - { - String userName = fAuthenticationService.getCurrentUserName(); - - boolean hasAccess = fLockingService.hasAccess(webProject, path, userName); - AVMLock lock = fLockingService.getLock(webProject, storePath[1]); - - if (!hasAccess) - { - String owners = null; - if (lock == null) - { - owners = null; - } - else - { - owners = lock.getOwners().toString(); // eg. '[alice]' or '[alice, bob]' - } - throw new AVMLockingException("avmlockservice.locked", new Object[]{path, owners}); - } - if (lock == null) - { - List owners = new ArrayList(1); - owners.add(userName); - lock = new AVMLock(webProject, storePath[0], storePath[1], AVMLockingService.Type.DISCRETIONARY, owners); - fLockingService.lockPath(lock); - } - } - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createDirectory(java.lang.String, java.lang.String, java.util.List, java.util.Map) - */ - public void createDirectory(String path, String name, List aspects, Map properties) - { - fService.createDirectory(path, name, aspects, properties); - } - - /* (non-Javadoc) - * @see org.alfresco.service.cmr.avm.AVMService#createFile(java.lang.String, java.lang.String, java.io.InputStream, java.util.List, java.util.Map) - */ - public void createFile(String path, String name, InputStream in, List aspects, Map properties) - { - grabLock(path + '/' + name); - fService.createFile(path, name, in, aspects, properties); - } -} +/* + * 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ + +package org.alfresco.repo.avm; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; + +import org.alfresco.repo.avm.util.AVMUtil; +import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.service.cmr.avm.AVMNodeDescriptor; +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avm.AVMStoreDescriptor; +import org.alfresco.service.cmr.avm.LayeringDescriptor; +import org.alfresco.service.cmr.avm.VersionDescriptor; +import org.alfresco.service.cmr.avm.locking.AVMLock; +import org.alfresco.service.cmr.avm.locking.AVMLockingException; +import org.alfresco.service.cmr.avm.locking.AVMLockingService; +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.security.AuthenticationService; +import org.alfresco.service.namespace.QName; +import org.springframework.extensions.surf.util.Pair; +import org.alfresco.wcm.util.WCMUtil; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * An AVMLockingService aware implementation of AVMService. + * @author britt + */ +public class AVMLockingAwareService implements AVMService, ApplicationContextAware +{ + public static final String STORE_SEPARATOR = "--"; + + private AVMService fService; + + private AVMLockingService fLockingService; + + private AuthenticationService fAuthenticationService; + + private ApplicationContext fContext; + + public AVMLockingAwareService() + { + } + + /* (non-Javadoc) + * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) + */ + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException + { + fContext = applicationContext; + } + + public void init() + { + fService = (AVMService)fContext.getBean("avmService"); + fLockingService = (AVMLockingService)fContext.getBean("avmLockingService"); + fAuthenticationService = (AuthenticationService)fContext.getBean("authenticationService"); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#addAspect(java.lang.String, org.alfresco.service.namespace.QName) + */ + public void addAspect(String path, QName aspectName) + { + grabLock(path); + fService.addAspect(path, aspectName); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#copy(int, java.lang.String, java.lang.String, java.lang.String) + */ + public void copy(int srcVersion, String srcPath, String dstPath, String name) + { + fService.copy(srcVersion, srcPath, dstPath, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#createBranch(int, java.lang.String, java.lang.String, java.lang.String) + */ + public void createBranch(int version, String srcPath, String dstPath, + String name) + { + fService.createBranch(version, srcPath, dstPath, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#createDirectory(java.lang.String, java.lang.String) + */ + public void createDirectory(String path, String name) + { + fService.createDirectory(path, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#createFile(java.lang.String, java.lang.String) + */ + public OutputStream createFile(String path, String name) + { + grabLock(AVMUtil.extendAVMPath(path, name)); + return fService.createFile(path, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#createFile(java.lang.String, java.lang.String, java.io.InputStream) + */ + public void createFile(String path, String name, InputStream in) + { + grabLock(AVMUtil.extendAVMPath(path, name)); + fService.createFile(path, name, in); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#createLayeredDirectory(java.lang.String, java.lang.String, java.lang.String) + */ + public void createLayeredDirectory(String targetPath, String parent, + String name) + { + fService.createLayeredDirectory(targetPath, parent, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#createLayeredFile(java.lang.String, java.lang.String, java.lang.String) + */ + public void createLayeredFile(String targetPath, String parent, String name) + { + grabLock(AVMUtil.extendAVMPath(parent, name)); + fService.createLayeredFile(targetPath, parent, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#createSnapshot(java.lang.String, java.lang.String, java.lang.String) + */ + public Map createSnapshot(String store, String tag, String description) + { + return fService.createSnapshot(store, tag, description); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#createStore(java.lang.String) + */ + public void createStore(String name) + { + fService.createStore(name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#createStore(java.lang.String, java.util.Map) + */ + public void createStore(String name, Map props) + { + fService.createStore(name, props); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#deleteNodeProperties(java.lang.String) + */ + public void deleteNodeProperties(String path) + { + grabLock(path); + fService.deleteNodeProperties(path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#deleteNodeProperty(java.lang.String, org.alfresco.service.namespace.QName) + */ + public void deleteNodeProperty(String path, QName name) + { + grabLock(path); + fService.deleteNodeProperty(path, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#deleteStoreProperty(java.lang.String, org.alfresco.service.namespace.QName) + */ + public void deleteStoreProperty(String store, QName name) + { + fService.deleteStoreProperty(store, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#forceCopy(java.lang.String) + */ + public AVMNodeDescriptor forceCopy(String path) + { + grabLock(path); + return fService.forceCopy(path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getAPath(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public Pair getAPath(AVMNodeDescriptor desc) + { + return fService.getAPath(desc); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getPathsInStoreVersion(org.alfresco.service.cmr.avm.AVMNodeDescriptor, java.lang.String, int) + */ + public List getPathsInStoreVersion(AVMNodeDescriptor desc, String store, int version) + { + return fService.getPathsInStoreVersion(desc, store, version); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getAspects(int, java.lang.String) + */ + public Set getAspects(int version, String path) + { + return fService.getAspects(version, path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getAspects(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public Set getAspects(AVMNodeDescriptor desc) + { + return fService.getAspects(desc); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getCommonAncestor(org.alfresco.service.cmr.avm.AVMNodeDescriptor, org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public AVMNodeDescriptor getCommonAncestor(AVMNodeDescriptor left, + AVMNodeDescriptor right) + { + return fService.getCommonAncestor(left, right); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getContentDataForRead(int, java.lang.String) + */ + public ContentData getContentDataForRead(int version, String path) + { + return fService.getContentDataForRead(version, path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getContentDataForRead(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public ContentData getContentDataForRead(AVMNodeDescriptor desc) + { + return fService.getContentDataForRead(desc); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getContentDataForWrite(java.lang.String) + */ + public ContentData getContentDataForWrite(String path) + { + grabLock(path); + return fService.getContentDataForWrite(path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getContentReader(int, java.lang.String) + */ + public ContentReader getContentReader(int version, String path) + { + return fService.getContentReader(version, path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getContentWriter(java.lang.String) + */ + public ContentWriter getContentWriter(String path) + { + grabLock(path); + return fService.getContentWriter(path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getDeleted(int, java.lang.String) + */ + public List getDeleted(int version, String path) + { + return fService.getDeleted(version, path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListing(int, java.lang.String) + */ + public SortedMap getDirectoryListing( + int version, String path) + { + return fService.getDirectoryListing(version, path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListing(int, java.lang.String, boolean) + */ + public SortedMap getDirectoryListing( + int version, String path, boolean includeDeleted) + { + return fService.getDirectoryListing(version, path, includeDeleted); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListing(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public SortedMap getDirectoryListing( + AVMNodeDescriptor dir) + { + return fService.getDirectoryListing(dir); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListing(org.alfresco.service.cmr.avm.AVMNodeDescriptor, String) + */ + public SortedMap getDirectoryListing( + AVMNodeDescriptor dir, String childNamePattern) + { + return fService.getDirectoryListing(dir, childNamePattern); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListing(org.alfresco.service.cmr.avm.AVMNodeDescriptor, boolean) + */ + public SortedMap getDirectoryListing( + AVMNodeDescriptor dir, boolean includeDeleted) + { + return fService.getDirectoryListing(dir, includeDeleted); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListingArray(int, java.lang.String, boolean) + */ + public AVMNodeDescriptor[] getDirectoryListingArray(int version, + String path, boolean includeDeleted) + { + return fService.getDirectoryListingArray(version, path, includeDeleted); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListingArray(org.alfresco.service.cmr.avm.AVMNodeDescriptor, boolean) + */ + public AVMNodeDescriptor[] getDirectoryListingArray(AVMNodeDescriptor dir, + boolean includeDeleted) + { + return fService.getDirectoryListingArray(dir, includeDeleted); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListingDirect(int, java.lang.String) + */ + public SortedMap getDirectoryListingDirect( + int version, String path) + { + return fService.getDirectoryListingDirect(version, path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListingDirect(int, java.lang.String, boolean) + */ + public SortedMap getDirectoryListingDirect( + int version, String path, boolean includeDeleted) + { + return fService.getDirectoryListingDirect(version, path, includeDeleted); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getDirectoryListingDirect(org.alfresco.service.cmr.avm.AVMNodeDescriptor, boolean) + */ + public SortedMap getDirectoryListingDirect( + AVMNodeDescriptor dir, boolean includeDeleted) + { + return fService.getDirectoryListingDirect(dir, includeDeleted); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getFileInputStream(int, java.lang.String) + */ + public InputStream getFileInputStream(int version, String path) + { + return fService.getFileInputStream(version, path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getFileInputStream(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public InputStream getFileInputStream(AVMNodeDescriptor desc) + { + return fService.getFileInputStream(desc); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getFileOutputStream(java.lang.String) + */ + public OutputStream getFileOutputStream(String path) + { + grabLock(path); + return fService.getFileOutputStream(path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getHeadPaths(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public List> getHeadPaths(AVMNodeDescriptor desc) + { + return fService.getHeadPaths(desc); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getHistory(org.alfresco.service.cmr.avm.AVMNodeDescriptor, int) + */ + public List getHistory(AVMNodeDescriptor desc, int count) + { + return fService.getHistory(desc, count); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getIndirectionPath(int, java.lang.String) + */ + public String getIndirectionPath(int version, String path) + { + return fService.getIndirectionPath(version, path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getLatestSnapshotID(java.lang.String) + */ + public int getLatestSnapshotID(String storeName) + { + return fService.getLatestSnapshotID(storeName); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getLayeringInfo(int, java.lang.String) + */ + public LayeringDescriptor getLayeringInfo(int version, String path) + { + return fService.getLayeringInfo(version, path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getNextVersionID(java.lang.String) + */ + public int getNextVersionID(String storeName) + { + return fService.getNextVersionID(storeName); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getNodeProperties(int, java.lang.String) + */ + public Map getNodeProperties(int version, String path) + { + return fService.getNodeProperties(version, path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getNodeProperties(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public Map getNodeProperties(AVMNodeDescriptor desc) + { + return fService.getNodeProperties(desc); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getNodeProperty(int, java.lang.String, org.alfresco.service.namespace.QName) + */ + public PropertyValue getNodeProperty(int version, String path, QName name) + { + return fService.getNodeProperty(version, path, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getPaths(org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public List> getPaths(AVMNodeDescriptor desc) + { + return fService.getPaths(desc); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getPathsInStoreHead(org.alfresco.service.cmr.avm.AVMNodeDescriptor, java.lang.String) + */ + public List> getPathsInStoreHead( + AVMNodeDescriptor desc, String store) + { + return fService.getPathsInStoreHead(desc, store); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getStore(java.lang.String) + */ + public AVMStoreDescriptor getStore(String name) + { + return fService.getStore(name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getStoreProperties(java.lang.String) + */ + public Map getStoreProperties(String store) + { + return fService.getStoreProperties(store); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getStoreProperty(java.lang.String, org.alfresco.service.namespace.QName) + */ + public PropertyValue getStoreProperty(String store, QName name) + { + return fService.getStoreProperty(store, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getStoreRoot(int, java.lang.String) + */ + public AVMNodeDescriptor getStoreRoot(int version, String name) + { + return fService.getStoreRoot(version, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getStoreVersions(java.lang.String) + */ + public List getStoreVersions(String name) + { + return fService.getStoreVersions(name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getStoreVersions(java.lang.String, java.util.Date, java.util.Date) + */ + public List getStoreVersions(String name, Date from, + Date to) + { + return fService.getStoreVersions(name, from, to); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getStores() + */ + public List getStores() + { + return fService.getStores(); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#getSystemStore() + */ + public AVMStoreDescriptor getSystemStore() + { + return fService.getSystemStore(); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#hasAspect(int, java.lang.String, org.alfresco.service.namespace.QName) + */ + public boolean hasAspect(int version, String path, QName aspectName) + { + return fService.hasAspect(version, path, aspectName); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#link(java.lang.String, java.lang.String, org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public void link(String parentPath, String name, AVMNodeDescriptor toLink) + { + // TODO Does this need a lock? I don't think so, but revisit. + fService.link(parentPath, name, toLink); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#updateLink(java.lang.String, java.lang.String, org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public void updateLink(String parentPath, String name, AVMNodeDescriptor toLink) + { + // TODO Does this need a lock? I don't think so, but revisit. + fService.updateLink(parentPath, name, toLink); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#lookup(int, java.lang.String) + */ + public AVMNodeDescriptor lookup(int version, String path) + { + return fService.lookup(version, path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#lookup(int, java.lang.String, boolean) + */ + public AVMNodeDescriptor lookup(int version, String path, + boolean includeDeleted) + { + return fService.lookup(version, path, includeDeleted); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#lookup(org.alfresco.service.cmr.avm.AVMNodeDescriptor, java.lang.String) + */ + public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name) + { + return fService.lookup(dir, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#lookup(org.alfresco.service.cmr.avm.AVMNodeDescriptor, java.lang.String, boolean) + */ + public AVMNodeDescriptor lookup(AVMNodeDescriptor dir, String name, + boolean includeDeleted) + { + return fService.lookup(dir, name, includeDeleted); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#makePrimary(java.lang.String) + */ + public void makePrimary(String path) + { + fService.makePrimary(path); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#makeTransparent(java.lang.String, java.lang.String) + */ + public void makeTransparent(String dirPath, String name) + { + fService.makeTransparent(dirPath, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#purgeStore(java.lang.String) + */ + public void purgeStore(String name) + { + fService.purgeStore(name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#purgeVersion(int, java.lang.String) + */ + public void purgeVersion(int version, String name) + { + fService.purgeVersion(version, name); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#queryStorePropertyKey(java.lang.String, org.alfresco.service.namespace.QName) + */ + public Map queryStorePropertyKey(String store, + QName keyPattern) + { + return fService.queryStorePropertyKey(store, keyPattern); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#queryStoresPropertyKeys(org.alfresco.service.namespace.QName) + */ + public Map> queryStoresPropertyKeys( + QName keyPattern) + { + return fService.queryStoresPropertyKeys(keyPattern); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#removeAspect(java.lang.String, org.alfresco.service.namespace.QName) + */ + public void removeAspect(String path, QName aspectName) + { + grabLock(path); + fService.removeAspect(path, aspectName); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#removeNode(java.lang.String, java.lang.String) + */ + public void removeNode(String parent, String name) + { + String path = AVMUtil.extendAVMPath(parent, name); + grabLock(path); + fService.removeNode(parent, name); + String[] storePath = AVMUtil.splitPath(parent); + fService.createSnapshot(storePath[0], null, "Removed "+path); + String webProject = getWebProject(storePath[0]); + if (webProject != null) + { + fLockingService.removeLocksInDirectory(webProject, storePath[0], AVMUtil.extendAVMPath(storePath[1], name)); + } + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#removeNode(java.lang.String) + */ + public void removeNode(String path) + { + grabLock(path); + fService.removeNode(path); + String[] storePath = AVMUtil.splitPath(path); + fService.createSnapshot(storePath[0], null, "Removed "+path); + String webProject = getWebProject(storePath[0]); + if (webProject != null) + { + fLockingService.removeLocksInDirectory(webProject, storePath[0], storePath[1]); + } + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#rename(java.lang.String, java.lang.String, java.lang.String, java.lang.String) + */ + public void rename(String srcParent, String srcName, String dstParent, + String dstName) + { + // TODO Unresolved: how to deal with directory level locking. + + String srcPath = AVMUtil.extendAVMPath(srcParent, srcName); + String dstPath = AVMUtil.extendAVMPath(dstParent, dstName); + + AVMNodeDescriptor desc = fService.lookup(-1, srcPath, false); + if (! (desc != null && desc.isDirectory())) + { + grabLock(srcPath); + } + + fService.rename(srcParent, srcName, dstParent, dstName); + + if (! (desc != null && desc.isDirectory())) + { + String[] srcStorePath = AVMUtil.splitPath(srcPath); + String[] dstStorePath = AVMUtil.splitPath(dstPath); + + String srcWebProject = getWebProject(srcStorePath[0]); + String dstWebProject = getWebProject(dstStorePath[0]); + + if ((dstWebProject != null) && (dstWebProject.equals(srcWebProject))) + { + fLockingService.modifyLock(dstWebProject, srcStorePath[1], dstStorePath[1], dstStorePath[0], null, null); + } + else + { + fLockingService.removeLock(srcWebProject, srcStorePath[1]); + grabLock(dstPath); + } + } + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#renameStore(java.lang.String, java.lang.String) + */ + public void renameStore(String sourceName, String destName) + { + fService.renameStore(sourceName, destName); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#retargetLayeredDirectory(java.lang.String, java.lang.String) + */ + public void retargetLayeredDirectory(String path, String target) + { + // TODO This assumes that directories are not locked. + fService.retargetLayeredDirectory(path, target); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#revert(java.lang.String, org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public void revert(String path, AVMNodeDescriptor toRevertTo) + { + grabLock(path); + fService.revert(path, toRevertTo); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#setContentData(java.lang.String, org.alfresco.service.cmr.repository.ContentData) + */ + public void setContentData(String path, ContentData data) + { + grabLock(path); + fService.setContentData(path, data); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#setEncoding(java.lang.String, java.lang.String) + */ + public void setEncoding(String path, String encoding) + { + grabLock(path); + fService.setEncoding(path, encoding); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#setGuid(java.lang.String, java.lang.String) + */ + public void setGuid(String path, String guid) + { + grabLock(path); + fService.setGuid(path, guid); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#setMetaDataFrom(java.lang.String, org.alfresco.service.cmr.avm.AVMNodeDescriptor) + */ + public void setMetaDataFrom(String path, AVMNodeDescriptor from) + { + grabLock(path); + fService.setMetaDataFrom(path, from); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#setMimeType(java.lang.String, java.lang.String) + */ + public void setMimeType(String path, String mimeType) + { + grabLock(path); + fService.setMimeType(path, mimeType); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#setNodeProperties(java.lang.String, java.util.Map) + */ + public void setNodeProperties(String path, + Map properties) + { + grabLock(path); + fService.setNodeProperties(path, properties); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#setNodeProperty(java.lang.String, org.alfresco.service.namespace.QName, org.alfresco.repo.domain.PropertyValue) + */ + public void setNodeProperty(String path, QName name, PropertyValue value) + { + grabLock(path); + fService.setNodeProperty(path, name, value); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#setOpacity(java.lang.String, boolean) + */ + public void setOpacity(String path, boolean opacity) + { + // TODO Assumes no directory locking. + fService.setOpacity(path, opacity); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#setStoreProperties(java.lang.String, java.util.Map) + */ + public void setStoreProperties(String store, Map props) + { + fService.setStoreProperties(store, props); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#setStoreProperty(java.lang.String, org.alfresco.service.namespace.QName, org.alfresco.repo.domain.PropertyValue) + */ + public void setStoreProperty(String store, QName name, PropertyValue value) + { + fService.setStoreProperty(store, name, value); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#uncover(java.lang.String, java.lang.String) + */ + public void uncover(String dirPath, String name) + { + // TODO What about when this is a directory? + grabLock(AVMUtil.extendAVMPath(dirPath, name)); + fService.uncover(dirPath, name); + } + + private String getWebProject(String name) + { + String wpStoreId = WCMUtil.getWebProjectStoreId(name); + if (WCMUtil.getWebProjectNodeFromWebProjectStore(fService, wpStoreId) != null) + { + return wpStoreId; + } + return null; + } + + private void grabLock(String path) + { + AVMNodeDescriptor desc = fService.lookup(-1, path, false); + if (desc != null && desc.isDirectory()) + { + return; + } + String[] storePath = AVMUtil.splitPath(path); + String webProject = getWebProject(storePath[0]); + if (webProject != null && webProject.equals(storePath[0])) + { + // Don't do locking in staging. + return; + } + if (webProject != null) + { + String userName = fAuthenticationService.getCurrentUserName(); + + boolean hasAccess = fLockingService.hasAccess(webProject, path, userName); + AVMLock lock = fLockingService.getLock(webProject, storePath[1]); + + if (!hasAccess) + { + String owners = null; + if (lock == null) + { + owners = null; + } + else + { + owners = lock.getOwners().toString(); // eg. '[alice]' or '[alice, bob]' + } + throw new AVMLockingException("avmlockservice.locked", new Object[]{path, owners}); + } + if (lock == null) + { + List owners = new ArrayList(1); + owners.add(userName); + lock = new AVMLock(webProject, storePath[0], storePath[1], AVMLockingService.Type.DISCRETIONARY, owners); + fLockingService.lockPath(lock); + } + } + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#createDirectory(java.lang.String, java.lang.String, java.util.List, java.util.Map) + */ + public void createDirectory(String path, String name, List aspects, Map properties) + { + fService.createDirectory(path, name, aspects, properties); + } + + /* (non-Javadoc) + * @see org.alfresco.service.cmr.avm.AVMService#createFile(java.lang.String, java.lang.String, java.io.InputStream, java.util.List, java.util.Map) + */ + public void createFile(String path, String name, InputStream in, List aspects, Map properties) + { + grabLock(AVMUtil.extendAVMPath(path, name)); + fService.createFile(path, name, in, aspects, properties); + } +} diff --git a/source/java/org/alfresco/repo/avm/AVMServiceTest.java b/source/java/org/alfresco/repo/avm/AVMServiceTest.java index f40618154c..2d0cbbb704 100644 --- a/source/java/org/alfresco/repo/avm/AVMServiceTest.java +++ b/source/java/org/alfresco/repo/avm/AVMServiceTest.java @@ -1,6078 +1,6030 @@ -/* - * 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 - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * As a special exception to the terms and conditions of version 2.0 of - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: - * http://www.alfresco.com/legal/licensing" */ - -package org.alfresco.repo.avm; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -import org.alfresco.config.JNDIConstants; -import org.alfresco.model.ContentModel; -import org.alfresco.model.WCMModel; -import org.alfresco.repo.action.ActionImpl; -import org.alfresco.repo.avm.actions.AVMRevertListAction; -import org.alfresco.repo.avm.actions.AVMRevertStoreAction; -import org.alfresco.repo.avm.actions.AVMRevertToVersionAction; -import org.alfresco.repo.avm.actions.AVMUndoSandboxListAction; -import org.alfresco.repo.avm.actions.SimpleAVMPromoteAction; -import org.alfresco.repo.avm.actions.SimpleAVMSubmitAction; -import org.alfresco.repo.avm.util.BulkLoader; -import org.alfresco.repo.content.MimetypeMap; -import org.alfresco.repo.domain.PropertyValue; -import org.alfresco.repo.search.impl.lucene.LuceneQueryParser; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.transaction.RetryingTransactionHelper; -import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; -import org.alfresco.service.cmr.avm.AVMBadArgumentException; -import org.alfresco.service.cmr.avm.AVMCycleException; -import org.alfresco.service.cmr.avm.AVMException; -import org.alfresco.service.cmr.avm.AVMExistsException; -import org.alfresco.service.cmr.avm.AVMNodeDescriptor; -import org.alfresco.service.cmr.avm.AVMNotFoundException; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.avm.AVMStoreDescriptor; -import org.alfresco.service.cmr.avm.LayeringDescriptor; -import org.alfresco.service.cmr.avm.VersionDescriptor; -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.ContentWriter; -import org.alfresco.service.cmr.repository.CrossRepositoryCopyService; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.search.ResultSet; -import org.alfresco.service.cmr.search.ResultSetRow; -import org.alfresco.service.cmr.search.SearchService; -import org.alfresco.service.cmr.security.AccessPermission; -import org.alfresco.service.cmr.security.AuthenticationService; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.service.transaction.TransactionService; -import org.alfresco.util.GUID; -import org.springframework.extensions.surf.util.Pair; -import org.alfresco.wcm.sandbox.SandboxConstants; - -/** - * Big test of AVM behavior. - * - * @author britt - */ -public class AVMServiceTest extends AVMServiceTestBase -{ - public void testSetup() throws Exception - { - super.testSetup(); - } - - public void testDiffOrder() - { - try - { - fService.createStore("Bottom"); - fService.createStore("Top"); - - fService.createDirectory("Bottom:/", "www"); - fService.createLayeredDirectory("Bottom:/www", "Top:/", "www"); - - fService.createFile("Bottom:/www", "newInBottom"); - fService.createSnapshot("Bottom", null, null); - fService.createFile("Top:/www", "newInTop"); - fService.createSnapshot("Top", null, null); - fService.createFile("Bottom:/www", "file"); - fService.createSnapshot("Bottom", null, null); - fService.forceCopy("Top:/www/file"); - fService.createSnapshot("Top", null, null); - fService.forceCopy("Bottom:/www/file"); - fService.createSnapshot("Bottom", null, null); - - - List diffs = fSyncService.compare(-1, "Top:/", -1, "Bottom:/", null); - assertEquals( - 2, diffs.size()); - Collections.sort(diffs); - AVMDifference last = null; - for(AVMDifference current : diffs) - { - if(last != null) - { - assert(last.getOrderValue() < current.getOrderValue()); - } - last = current; - } - - diffs.add(new AVMDifference(1, null, -1, null, 0)); - diffs.add(new AVMDifference(1, null, -1, null, 1)); - diffs.add(new AVMDifference(1, null, -1, null, 2)); - diffs.add(new AVMDifference(1, null, -1, null, 3)); - diffs.add(new AVMDifference(1, null, -1, null, 4)); - diffs.add(new AVMDifference(1, null, -1, null, 5)); - diffs.add(new AVMDifference(1, null, -1, null, 6)); - - Collections.sort(diffs); - last = null; - for(AVMDifference current : diffs) - { - if(last != null) - { - assert(last.getOrderValue() < current.getOrderValue()); - } - last = current; - } - } - finally - { - fService.purgeStore("Bottom"); - fService.purgeStore("Top"); - } - - } - - public void test_ETWOTWO_570() throws Exception - { - // Check that read-write methods are properly intercepted - RetryingTransactionCallback readOnlyCallback = new RetryingTransactionCallback() - { - public Object execute() throws Throwable - { - fService.createStore("StagingArea" + "-" + getName() + "-" + System.currentTimeMillis()); - return null; - } - }; - fTransactionService.getRetryingTransactionHelper().doInTransaction(readOnlyCallback, false, true); - } - - public void test_WCM_949() throws Exception - { - try - { - fService.createStore("StagingArea"); - fService.createStore("SandBox"); - - fService.createDirectory("StagingArea:/", "www"); - fService.createLayeredDirectory("StagingArea:/www", "SandBox:/", "www"); - - fService.createDirectory("SandBox:/www", "TestFolder"); - fService.createFile("SandBox:/www/TestFolder", "test1").close(); - - List diffs = fSyncService.compare(-1, "SandBox:/www", -1, "StagingArea:/www", null); - assertEquals(1, diffs.size()); - assertEquals("[SandBox:/www/TestFolder[-1] > StagingArea:/www/TestFolder[-1]]", diffs.toString()); - fSyncService.update(diffs, null, true, true, false, false, "one", "one"); - fSyncService.flatten("SandBox:/www", "StagingArea:/www"); - - StoreRef storeRef = AVMNodeConverter.ToStoreRef("StagingArea"); - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - ResultSet results = searchService.query(storeRef, "lucene", "@cm\\:name:test1"); - assertEquals(1, results.length()); - results.close(); - - fService.removeNode("SandBox:/www/TestFolder"); - - diffs = fSyncService.compare(-1, "SandBox:/www", -1, "StagingArea:/www", null); - assertEquals(1, diffs.size()); - assertEquals("[SandBox:/www/TestFolder[-1] > StagingArea:/www/TestFolder[-1]]", diffs.toString()); - fSyncService.update(diffs, null, true, true, false, false, "one", "one"); - fSyncService.flatten("SandBox:/www", "StagingArea:/www"); - - results = searchService.query(storeRef, "lucene", "@cm\\:name:test1"); - assertEquals(0, results.length()); - results.close(); - - fService.createDirectory("SandBox:/www", "TestFolder"); - fService.createFile("SandBox:/www/TestFolder", "test1").close(); - - diffs = fSyncService.compare(-1, "SandBox:/www", -1, "StagingArea:/www", null); - assertEquals(1, diffs.size()); - assertEquals("[SandBox:/www/TestFolder[-1] > StagingArea:/www/TestFolder[-1]]", diffs.toString()); - fSyncService.update(diffs, null, true, true, false, false, "one", "one"); - fSyncService.flatten("SandBox:/www", "StagingArea:/www"); - - results = searchService.query(storeRef, "lucene", "@cm\\:name:test1"); - assertEquals(1, results.length()); - results.close(); - } - finally - { - fService.purgeStore("StagingArea"); - fService.purgeStore("SandBox"); - } - - } - - public void testPathEncoding() throws Throwable - { - try - { - setupBasicTree(); - fService.createFile("main:/", "2007").close(); - fService.createFile("main:/", "meep meep").close(); - fService.createDirectory("main:/", "my space"); - fService.createFile("main:/my space", "my file"); - fService.createDirectory("main:/", "2001"); - fService.createFile("main:/2001", "2002"); - fService.createSnapshot("main", null, null); - - StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - ResultSet results = searchService.query(storeRef, "lucene", "PATH:\"/meep_x0020_meep\""); - assertEquals(1, results.length()); - System.out.println(results.getNodeRef(0)); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/_x0032_007\""); - assertEquals(1, results.length()); - System.out.println(results.getNodeRef(0)); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/my_x0020_space/my_x0020_file\""); - assertEquals(1, results.length()); - System.out.println(results.getNodeRef(0)); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/_x0032_001/_x0032_002\""); - assertEquals(1, results.length()); - System.out.println(results.getNodeRef(0)); - results.close(); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - } - - public void testSpacesInStoreNames() throws Exception - { - try - { - fService.createStore("I have spaces"); - fService.createFile("I have spaces:/", "in my name.txt").close(); - assertNotNull(fService.lookup(-1, "I have spaces:/in my name.txt")); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - finally - { - fService.purgeStore("I have spaces"); - } - } - - public void testHeadPathsInLayers() throws Exception - { - try - { - setupBasicTree(); - fService.createStore("user"); - fService.createLayeredDirectory("main:/a", "user:/", "a"); - fService.createStore("sandbox"); - fService.createLayeredDirectory("main:/a", "sandbox:/", "a"); - fService.createDirectory("user:/a/b", "newdir"); - fService.createFile("user:/a/b/newdir", "bibble.txt").close(); - List diffs = fSyncService.compare(-1, "user:/a", -1, "sandbox:/a", null); - assertEquals(1, diffs.size()); - assertEquals("[user:/a/b/newdir[-1] > sandbox:/a/b/newdir[-1]]", diffs.toString()); - fSyncService.update(diffs, null, false, false, false, false, null, null); - AVMNodeDescriptor dir = fService.lookup(-1, "user:/a/b/newdir"); - List> paths = fService.getHeadPaths(dir); - System.out.println(paths); - AVMNodeDescriptor file = fService.lookup(-1, "user:/a/b/newdir/bibble.txt"); - paths = fService.getHeadPaths(file); - System.out.println(paths); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - finally - { - fService.purgeStore("user"); - fService.purgeStore("sandbox"); - } - } - - /** - * Minimal testing of Locking Aware service. - */ - public void testLockingAwareService() throws Exception - { - AVMService oldService = fService; - fService = (AVMService) fContext.getBean("AVMLockingAwareService"); - AuthenticationService authService = (AuthenticationService) fContext.getBean("AuthenticationService"); - - try - { - // note: locking applies to WCM web projects, hence relies on WCM sandbox conventions (naming and properties) - fService.setStoreProperty("main", SandboxConstants.PROP_WEB_PROJECT_NODE_REF, new PropertyValue(DataTypeDefinition.NODE_REF, new NodeRef("workspace://SpacesStore/dummy"))); - - fService.createStore("main--admin"); - - setupBasicTree0(); - - - List diffs = fSyncService.compare(-1, "main:/", -1, "main--admin:/", null); - assertEquals(2, diffs.size()); - assertEquals("[main:/a[-1] > main--admin:/a[-1], main:/d[-1] > main--admin:/d[-1]]", diffs.toString()); - - fSyncService.update(diffs, null, false, false, false, false, null, null); - RetryingTransactionHelper.RetryingTransactionCallback cb = new RetryingTransactionHelper.RetryingTransactionCallback() - { - public Object execute() throws Exception - { - BulkLoader loader = new BulkLoader(); - loader.setAvmService(fService); - loader.recursiveLoad("source/java/org/alfresco/repo/avm", "main--admin:/"); - return null; - } - }; - RetryingTransactionHelper helper = (RetryingTransactionHelper) fContext.getBean("retryingTransactionHelper"); - helper.doInTransaction(cb); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - finally - { - fService = oldService; - fLockingService.removeStoreLocks("main"); - fLockingService.removeWebProject("main"); - authService.authenticate(AuthenticationUtil.getAdminUserName(), "admin".toCharArray()); - fService.purgeStore("main--admin"); - } - } - - /** - * Test version by date lookup. - */ - public void testVersionByDate() throws Exception - { - try - { - ArrayList times = new ArrayList(); - BulkLoader loader = new BulkLoader(); - loader.setAvmService(fService); - loader.recursiveLoad("source/java/org/alfresco/repo/avm", "main:/"); - times.add(System.currentTimeMillis()); - assertEquals(1, fService.createSnapshot("main", null, null).get("main").intValue()); - loader.recursiveLoad("source/java/org/alfresco/repo/action", "main:/"); - times.add(System.currentTimeMillis()); - assertEquals(2, fService.createSnapshot("main", null, null).get("main").intValue()); - loader.recursiveLoad("source/java/org/alfresco/repo/audit", "main:/"); - times.add(System.currentTimeMillis()); - assertEquals(3, fService.createSnapshot("main", null, null).get("main").intValue()); - assertEquals(1, fService.getStoreVersions("main", null, new Date(times.get(0))).size()); - assertEquals(3, fService.getStoreVersions("main", new Date(times.get(0)), null).size()); - assertEquals(2, fService.getStoreVersions("main", new Date(times.get(1)), new Date(System.currentTimeMillis())).size()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test (node) properties. - */ - public void testProperties() throws Exception - { - try - { - setupBasicTree(); - - StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - ResultSet results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}SillyProperty") + ":\"Silly\""); - assertEquals(0, results.length()); - results.close(); - - QName name = QName.createQName("silly.uri", "SillyProperty"); - PropertyValue value = new PropertyValue(DataTypeDefinition.TEXT, "Silly Property Value"); - fService.setNodeProperty("main:/a/b/c/foo", name, value); - fService.createSnapshot("main", null, null); - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}SillyProperty") + ":\"Silly\""); - assertEquals(1, results.length()); - results.close(); - PropertyValue returned = fService.getNodeProperty(-1, "main:/a/b/c/foo", name); - assertEquals(value.toString(), returned.toString()); - Map props = fService.getNodeProperties(-1, "main:/a/b/c/foo"); - assertEquals(1, props.size()); - assertEquals(value.toString(), props.get(name).toString()); - - props = new HashMap(); - QName n1 = QName.createQName("silly.uri", "Prop1"); - PropertyValue p1 = new PropertyValue(DataTypeDefinition.DATETIME, new Date(System.currentTimeMillis())); - props.put(n1, p1); - QName n2 = QName.createQName("silly.uri", "Prop2"); - PropertyValue p2 = new PropertyValue(DataTypeDefinition.TEXT, "A String Property."); - props.put(n2, p2); - QName n3 = QName.createQName("silly.uri", "Prop3"); - PropertyValue p3 = new PropertyValue(DataTypeDefinition.INT, 42); - props.put(n3, p3); - QName n4 = QName.createQName("silly.uri", "Prop4"); - PropertyValue p4 = new PropertyValue(null, new Boolean(false)); - props.put(n4, p4); - QName n5 = QName.createQName("silly.uri", "Prop5"); - List strList = new ArrayList(2); - strList.add("hello"); - strList.add("world"); - PropertyValue p5 = new PropertyValue(DataTypeDefinition.TEXT, (Serializable)strList); - props.put(n5, p5); - fService.setNodeProperties("main:/a/b/c/bar", props); - fService.createSnapshot("main", null, null); - props = fService.getNodeProperties(-1, "main:/a/b/c/bar"); - assertEquals(5, props.size()); - assertEquals(p1.toString(), props.get(n1).toString()); - assertEquals(p2.toString(), props.get(n2).toString()); - assertEquals(p3.toString(), props.get(n3).toString()); - assertEquals(p4.toString(), props.get(n4).toString()); - assertEquals(p5.toString(), props.get(n5).toString()); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1") + ":\"" + props.get(n1).getStringValue() + "\""); - assertEquals(1, results.length()); - results.close(); - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2") + ":\"" + props.get(n2).getStringValue() + "\""); - assertEquals(1, results.length()); - results.close(); - - props = new HashMap(); - n1 = QName.createQName("silly.uri", "Prop1"); - p1 = new PropertyValue(DataTypeDefinition.DATETIME, new Date(System.currentTimeMillis())); - props.put(n1, p1); - n2 = QName.createQName("silly.uri", "Prop2"); - p2 = new PropertyValue(DataTypeDefinition.TEXT, "A String Property - updated."); - props.put(n2, p2); - n3 = QName.createQName("silly.uri", "Prop3"); - p3 = new PropertyValue(DataTypeDefinition.INT, -42); - props.put(n3, p3); - n4 = QName.createQName("silly.uri", "Prop4"); - p4 = new PropertyValue(null, new Boolean(true)); - props.put(n4, p4); - n5 = QName.createQName("silly.uri", "Prop5"); - strList = new ArrayList(2); - strList.add("goodbye"); - strList.add("world"); - p5 = new PropertyValue(DataTypeDefinition.TEXT, (Serializable)strList); - props.put(n5, p5); - fService.setNodeProperties("main:/a/b/c/bar", props); - fService.createSnapshot("main", null, null); - props = fService.getNodeProperties(-1, "main:/a/b/c/bar"); - assertEquals(5, props.size()); - assertEquals(p1.toString(), props.get(n1).toString()); - assertEquals(p2.toString(), props.get(n2).toString()); - assertEquals(p3.toString(), props.get(n3).toString()); - assertEquals(p4.toString(), props.get(n4).toString()); - assertEquals(p5.toString(), props.get(n5).toString()); - - fService.deleteNodeProperty("main:/a/b/c/bar", n1); - fService.createSnapshot("main", null, null); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1") + ":\"" + props.get(n1).getStringValue() + "\""); - assertEquals(0, results.length()); - results.close(); - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2") + ":\"" + props.get(n2).getStringValue() + "\""); - assertEquals(1, results.length()); - results.close(); - - props = fService.getNodeProperties(-1, "main:/a/b/c/bar"); - assertEquals(4, props.size()); - assertEquals(p2.toString(), props.get(n2).toString()); - assertEquals(p3.toString(), props.get(n3).toString()); - assertEquals(p4.toString(), props.get(n4).toString()); - assertEquals(p5.toString(), props.get(n5).toString()); - fService.deleteNodeProperties("main:/a/b/c/bar"); - fService.createSnapshot("main", null, null); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1") + ":\"" + p1.getStringValue() + "\""); - assertEquals(0, results.length()); - results.close(); - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2") + ":\"" + props.get(n2).getStringValue() + "\""); - assertEquals(0, results.length()); - results.close(); - - props = fService.getNodeProperties(-1, "main:/a/b/c/bar"); - assertEquals(0, props.size()); - fService.removeNode("main:/a/b/c/foo"); - fService.setNodeProperty("main:/a/b/c/foo", QName.createQName("silly.uri", "Prop1"), new PropertyValue(null, 42)); - assertEquals(1, fService.getNodeProperties(-1, "main:/a/b/c/foo").size()); - fService.createSnapshot("main", null, null); - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1") + ":\"" + p1.getStringValue() + "\""); - assertEquals(0, results.length()); - results.close(); - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2") + ":\"" + p2.getStringValue() + "\""); - assertEquals(0, results.length()); - results.close(); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test getStoreVersionRootPaths(). - */ - public void testGetStoreVersionRootPaths() throws Exception - { - try - { - setupBasicTree(); - AVMNodeDescriptor desc = fService.lookup(-1, "main:/a/b/c/foo"); - List paths = fService.getPathsInStoreVersion(desc, "main", 1); - assertEquals(1, paths.size()); - assertEquals("main:/a/b/c/foo", paths.get(0)); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - fService.createSnapshot("main", null, null); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - fService.createSnapshot("main", null, null); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - fService.createSnapshot("main", null, null); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - fService.createSnapshot("main", null, null); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - fService.createSnapshot("main", null, null); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - fService.createSnapshot("main", null, null); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - fService.createSnapshot("main", null, null); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - fService.createSnapshot("main", null, null); - paths = fService.getPathsInStoreVersion(desc, "main", 1); - assertEquals(1, paths.size()); - assertEquals("main:/a/b/c/foo", paths.get(0)); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - } - - public void testForceCopyDeleted() throws Exception - { - try - { - setupBasicTree(); - fService.removeNode("main:/a/b/c/foo"); - fService.createSnapshot("main", null, null); - AVMNodeDescriptor desc = fService.forceCopy("main:/a/b/c/foo"); - assertTrue(desc.isDeleted()); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - } - - public void testLayerSnapshots() throws Exception - { - try - { - // Layers are not yet indexed - setupBasicTree(); - assertEquals(1, fService.createSnapshot("main", null, null).get("main").intValue()); - runQueriesAgainstBasicTree("main"); - fService.createStore("layer"); - fService.createLayeredDirectory("main:/a", "layer:/", "a"); - fService.createSnapshot("layer", null, null); - runQueriesAgainstBasicTree("main"); - fService.createFile("main:/a", "Xander"); - fService.createSnapshot("layer", null, null); - - assertEquals(2, fService.lookup(2, "layer:/a").getIndirectionVersion()); - Map listing =fService.getDirectoryListing(2, "layer:/"); - assertEquals(1, listing.size()); - assertEquals(2, listing.values().iterator().next().getIndirectionVersion()); - assertEquals(fService.lookup(2, "main:/a/Xander").getId(), fService.lookup(2, "layer:/a/Xander").getId()); - - assertNull(fService.lookup(1, "layer:/a/Xander")); - listing = fService.getDirectoryListing(1, "layer:/"); - assertEquals(1, listing.size()); - assertEquals(1, listing.values().iterator().next().getIndirectionVersion()); - - assertEquals(-1, fService.lookup(-1, "layer:/a").getIndirectionVersion()); - listing = fService.getDirectoryListing(-1, "layer:/"); - assertEquals(1, listing.size()); - assertEquals(-1, listing.values().iterator().next().getIndirectionVersion()); - assertEquals(fService.lookup(-1, "main:/a/Xander").getId(), fService.lookup(-1, "layer:/a/Xander").getId()); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - finally - { - fService.purgeStore("layer"); - } - } - - public void testBranchLayerSnapshot() throws Exception - { - try - { - // layers are not yet indexed - setupBasicTree(); - fService.createStore("layer"); - fService.createDirectory("layer:/", "root"); - fService.createLayeredDirectory("main:/a", "layer:/root", "layer"); - fService.createSnapshot("layer", null, null); - fService.createFile("main:/a", "dummy").close(); - fService.createFile("layer:/root/layer", "pygmy"); - fService.createSnapshot("layer", null, null); - fService.createStore("branch"); - fService.createBranch(1, "layer:/root", "branch:/", "branch"); - fService.createSnapshot("branch", null, null); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - System.out.println("main 1"); - System.out.println(recursiveList("main", 1, true)); - System.out.println("branch 1"); - System.out.println(recursiveList("branch", 1, true)); - assertEquals(fService.lookup(1, "main:/a/b/c/foo").getId(), fService.lookup(1, "branch:/branch/layer/b/c/foo").getId()); - System.out.println("main -1"); - System.out.println(recursiveList("main", -1, true)); - System.out.println("branch -1"); - System.out.println(recursiveList("branch", -1, true)); - assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getId(), fService.lookup(-1, "branch:/branch/layer/b/c/foo").getId()); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - finally - { - fService.purgeStore("layer"); - fService.purgeStore("branch"); - } - } - - /** - * Test Deployment. - */ -/* - public void testDeployment() throws Exception - { - try - { - final DeploymentService depService = (DeploymentService) fContext.getBean("DeploymentService"); - NameMatcher matcher = (NameMatcher) fContext.getBean("globalPathExcluder"); - setupBasicTree(); - fService.addAspect("main:/a", ContentModel.ASPECT_REFERENCEABLE); - fService.addAspect("main:/a/b", ContentModel.ASPECT_REFERENCEABLE); - fService.addAspect("main:/a/b/c", ContentModel.ASPECT_REFERENCEABLE); - fService.addAspect("main:/a/b/c/foo", ContentModel.ASPECT_REFERENCEABLE); - fService.addAspect("main:/a/b/c/bar", ContentModel.ASPECT_REFERENCEABLE); - fService.createFile("main:/a/b", "snarl.bak").close(); - // TestDeploymentCallback callback = new TestDeploymentCallback(); - fService.createStore("target"); - DeploymentReport report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, false, null); - assertNull(fService.lookup(-1, "target:/a/b/snarl.bak")); - runQueriesAgainstBasicTreeWithAOnly("target"); - System.out.println(report); - ActionService actionService = depService.getRemoteActionService("localhost", 50500, "admin", "admin"); - Map params = new HashMap(); - params.put("property", ContentModel.PROP_ADDRESSEE); - params.put("value", "Santa Claus"); - assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getGuid(), fService.lookup(-1, "target:/a/b/c/foo").getGuid()); - assertEquals(fService.lookup(-1, "main:/a/b/c/bar").getGuid(), fService.lookup(-1, "target:/a/b/c/bar").getGuid()); - NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, "target:/a/b/c/foo"); - Action action = new ActionImpl(nodeRef, "set-property-value", "set-property-value", params); - actionService.executeAction(action, nodeRef, false, false); - assertEquals("Santa Claus", fService.getNodeProperty(-1, "target:/a/b/c/foo", ContentModel.PROP_ADDRESSEE).getStringValue()); - ContentData srcCD = fService.getContentDataForRead(-1, "main:/a/b/c/bar"); - ContentData dstCD = fService.getContentDataForRead(-1, "target:/a/b/c/bar"); - assertEquals(srcCD.getMimetype(), dstCD.getMimetype()); - fService.createFile("main:/a/b", "biz").close(); - report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, true, null); - // Nothing was done - runQueriesAgainstBasicTreeWithAOnly("target"); - System.out.println(report); - System.out.println(recursiveList("target", -1, true)); - assertNull(fService.lookup(-1, "target:/a/b/biz")); - report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, false, null); - System.out.println(report); - runQueriesForCreateAndDeploy("target"); - assertEquals(fService.lookup(-1, "main:/a/b/biz").getGuid(), fService.lookup(-1, "target:/a/b/biz").getGuid()); - fService.removeNode("main:/a/b/c/foo"); - fService.createFile("main:/a/b/c", "Foo").close(); - ContentWriter writer = fService.getContentWriter("main:/a/b/c/Foo"); - writer.setEncoding("UTF-8"); - writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - writer.putContent("I am main:/a/b/c/foo"); - report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, false, null); - System.out.println(report); - assertEquals(DeploymentEvent.Type.UPDATED, report.iterator().next().getType()); - fService.removeNode("main:/a/b/c/foo"); - report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, true, false, null); - runQueriesForCreateAndDeploy("target"); - System.out.println(report); - assertNotNull(fService.lookup(-1, "target:/a/b/c/foo")); - report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, false, null); - System.out.println(report); - runQueriesForRemoveAndDelpoy("target"); - assertNull(fService.lookup(-1, "target:/a/b/c/foo")); - fService.removeNode("main:/a/b/c/bar"); - fService.createDirectory("main:/a/b/c", "bar"); - report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, false, null); - System.out.println(report); - runQueriesForRemoveFileAndCreateDirectoryAndDeploy("target"); - report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, false, null); - depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target2:/wiggly/diggly", matcher, true, false, false, null); - System.out.println(report); - fService.createStore("source"); - RetryingTransactionHelper.RetryingTransactionCallback cb = new RetryingTransactionHelper.RetryingTransactionCallback() - { - public Object execute() throws Exception - { - BulkLoader loader = new BulkLoader(); - loader.setAvmService(fService); - loader.recursiveLoad("source/java/org/alfresco/repo/avm", "source:/"); - return null; - } - }; - RetryingTransactionHelper helper = (RetryingTransactionHelper) fContext.getBean("retryingTransactionHelper"); - helper.doInTransaction(cb); - fService.createStore("dest"); - depService.deployDifference(-1, "source:/avm", "localhost", 50500, "admin", "admin", "dest:/avm", null, true, false, false, null); - Runnable runner = new Runnable() - { - public void run() - { - depService.deployDifference(-1, "source:/avm", "localhost", 50500, "admin", "admin", "dest:/avm", null, true, false, false, null); - } - }; - Thread thread = new Thread(runner); - thread.start(); - thread.join(); - report = depService.deployDifference(-1, "source:/avm", "localhost", 50500, "admin", "admin", "dest:/avm", null, true, false, false, null); - System.out.println(report); - assertEquals("", report.toString()); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - } -*/ - protected void runQueriesForCreateAndDeploy(String store) throws Exception - { - StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); - - // Text index - SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef(store), true); - ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); - assertEquals(2, results.length()); - results.close(); - - // Basic properties - - // Note "a" is a stop word and therefore not findable ... - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":biz"); - assertEquals(1, results.length()); - results.close(); - - // TODO: Fix auth in AVMDiskDriver and more?? - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); - assertEquals(7, results.length()); - results.close(); - - // Basic paths - - results = searchService.query(storeRef, "lucene", "PATH:\"/\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/biz\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); - assertEquals(0, results.length()); - results.close(); - } - - protected void runQueriesForRemoveAndDelpoy(String store) - { - StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); - - // Text index - SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef(store), true); - ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); - assertEquals(1, results.length()); - results.close(); - - // Basic properties - - // Note "a" is a stop word and therefore not findable ... - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":biz"); - assertEquals(1, results.length()); - results.close(); - - // TODO: Fix auth in AVMDiskDriver and more?? - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); - assertEquals(6, results.length()); - results.close(); - - // Basic paths - - results = searchService.query(storeRef, "lucene", "PATH:\"/\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/biz\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); - assertEquals(4, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); - assertEquals(0, results.length()); - results.close(); - } - - protected void runQueriesForRemoveFileAndCreateDirectoryAndDeploy(String store) - { - StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); - - // Text index - SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef(store), true); - ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); - assertEquals(0, results.length()); - results.close(); - - // Basic properties - - // Note "a" is a stop word and therefore not findable ... - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"bar\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":biz"); - assertEquals(1, results.length()); - results.close(); - - // TODO: Fix auth in AVMDiskDriver and more?? - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); - assertEquals(6, results.length()); - results.close(); - - // Basic paths - - results = searchService.query(storeRef, "lucene", "PATH:\"/\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/biz\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); - assertEquals(4, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); - assertEquals(0, results.length()); - results.close(); - } - - /** - * Test of GUIDs on AVM Nodes. - */ - public void testGuids() throws Exception - { - try - { - setupBasicTree(); - System.out.println(fService.lookup(-1, "main:/a/b/c/foo").getGuid()); - String guid = GUID.generate(); - fService.setGuid("main:/a/b/c/foo", guid); - assertEquals(guid, fService.lookup(-1, "main:/a/b/c/foo").getGuid()); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - } - - /** - * Test the revert to version action. - */ - public void testRevertToVersionAction() throws Exception - { - try - { - setupBasicTree(); - - ContentWriter writer = fService.getContentWriter("main:/a/b/c/foo"); - writer.setEncoding("UTF-8"); - writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - writer.putContent("I am main:/a/b/c/foo V1"); - fService.createSnapshot("main", "v1", null); - - writer = fService.getContentWriter("main:/a/b/c/foo"); - writer.setEncoding("UTF-8"); - writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - writer.putContent("I am main:/a/b/c/foo V2"); - fService.createSnapshot("main", "v2", null); - - writer = fService.getContentWriter("main:/a/b/c/foo"); - writer.setEncoding("UTF-8"); - writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - writer.putContent("I am main:/a/b/c/foo V3"); - fService.createSnapshot("main", "v3", null); - - writer = fService.getContentWriter("main:/a/b/c/foo"); - writer.setEncoding("UTF-8"); - writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - writer.putContent("I am main:/a/b/c/foo V4"); - fService.createSnapshot("main", "v4", null); - - writer = fService.getContentWriter("main:/a/b/c/foo"); - writer.setEncoding("UTF-8"); - writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - writer.putContent("I am main:/a/b/c/foo V5"); - fService.createSnapshot("main", "v5", null); - - writer = fService.getContentWriter("main:/a/b/c/foo"); - writer.setEncoding("UTF-8"); - writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - writer.putContent("I am main:/a/b/c/foo HEAD"); - - StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); - - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - - ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"HEAD\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "TEXT:\"V5\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "TEXT:\"V2\""); - assertEquals(0, results.length()); - results.close(); - - AVMNodeDescriptor desc = fService.lookup(-1, "main:/a/b/c/foo"); - List history = fService.getHistory(desc, 100); - AVMNodeDescriptor toRevert = history.get(3); - - final ActionImpl action = new ActionImpl(null, GUID.generate(), AVMRevertToVersionAction.NAME); - action.setParameterValue(AVMRevertToVersionAction.TOREVERT, toRevert); - final AVMRevertToVersionAction revert = (AVMRevertToVersionAction) fContext.getBean("avm-revert-to-version"); - class TxnWork implements RetryingTransactionCallback - { - public Object execute() throws Exception - { - // note: including implicit snapshot - revert.execute(action, AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/foo")); - return null; - } - }; - - TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); - transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); - - results = searchService.query(storeRef, "lucene", "TEXT:\"HEAD\""); - assertEquals(0, results.length()); - results.close(); - results = searchService.query(storeRef, "lucene", "TEXT:\"V5\""); - assertEquals(0, results.length()); - results.close(); - results = searchService.query(storeRef, "lucene", "TEXT:\"V2\""); - assertEquals(1, results.length()); - results.close(); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - } - - /** - * Test version numbering. - */ - public void testVersionNumbering() throws Exception - { - try - { - setupBasicTree(); - AVMNodeDescriptor desc = fService.lookup(-1, "main:/a/b/c/foo"); - assertEquals(1, desc.getVersionID()); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - desc = fService.lookup(-1, "main:/a/b/c/foo"); - assertEquals(2, desc.getVersionID()); - desc = fService.lookup(-1, "main:/a/b"); - assertEquals(2, desc.getVersionID()); - fService.createSnapshot("main", null, null); - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - fService.getFileOutputStream("main:/layer/b/c/bar").close(); - desc = fService.lookup(-1, "main:/layer/b/c/bar"); - assertEquals(2, desc.getVersionID()); - desc = fService.lookup(-1, "main:/layer/b/c"); - assertEquals(3, desc.getVersionID()); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - } - - /** - * Test relinking of nodes to history. - */ - public void testHistoryRelink() throws Exception - { - try - { - setupBasicTree(); - fService.createStore("branch"); - fService.createBranch(-1, "main:/a", "branch:/", "a"); - fService.removeNode("branch:/a/b/c/foo"); - List diffs = fSyncService.compare(-1, "branch:/a", -1, "main:/a", null); - assertEquals(1, diffs.size()); - assertEquals(AVMDifference.NEWER, diffs.get(0).getDifferenceCode()); - assertEquals("[branch:/a/b/c/foo[-1] > main:/a/b/c/foo[-1]]", diffs.toString()); - fService.createFile("branch:/a/b/c", "foo").close(); - diffs = fSyncService.compare(-1, "branch:/a", -1, "main:/a", null); - assertEquals(1, diffs.size()); - assertEquals(AVMDifference.NEWER, diffs.get(0).getDifferenceCode()); - assertEquals("[branch:/a/b/c/foo[-1] > main:/a/b/c/foo[-1]]", diffs.toString()); - fSyncService.update(diffs, null, false, false, false, false, null, null); - fService.removeNode("branch:/a/b/c/bar"); - fService.createFile("branch:/a/b/c", "pismo").close(); - fService.rename("branch:/a/b/c", "pismo", "branch:/a/b/c", "bar"); - diffs = fSyncService.compare(-1, "branch:/a", -1, "main:/a", null); - assertEquals(1, diffs.size()); - assertEquals(AVMDifference.NEWER, diffs.get(0).getDifferenceCode()); - assertEquals("[branch:/a/b/c/bar[-1] > main:/a/b/c/bar[-1]]", diffs.toString()); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - finally - { - fService.purgeStore("branch"); - } - } - - /** - * Test renaming a store. - */ - public void testRenameStore() throws Exception - { - try - { - setupBasicTree(); - assertNotNull(fService.lookup(-1, "main:/a/b")); - fService.renameStore("main", "foo"); - assertNotNull(fService.getStore("foo")); - assertNotNull(fService.lookup(-1, "foo:/a/b")); - runQueriesAgainstBasicTree("foo"); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - finally - { - fService.purgeStore("foo"); - } - } - - /** - * Test copy. - */ - public void testCopy() throws Exception - { - try - { - setupBasicTree(); - // Copy a file. - fService.copy(-1, "main:/a/b/c/foo", "main:/d", "fooCopy"); - AVMNodeDescriptor desc = fService.lookup(-1, "main:/d/fooCopy"); - assertTrue(desc.isFile()); - fService.createSnapshot("main", null, null); - runQueriesAgainstBasicTreePlusFileCopy("main"); - - // Copy a whole tree - fService.copy(-1, "main:/a", "main:/d/e", "aCopy"); - desc = fService.lookup(-1, "main:/d/e/aCopy"); - assertTrue(desc.isDirectory()); - desc = fService.lookup(-1, "main:/a/b/c/bar"); - AVMNodeDescriptor desc2 = fService.lookup(-1, "main:/d/e/aCopy/b/c/bar"); - assertTrue(desc2.isFile()); - assertEquals(desc.getLength(), desc2.getLength()); - fService.createSnapshot("main", null, null); - runQueriesAgainstBasicTreePlusFileCopyAndDirectoryCopy("main"); - - // Check that it rejects infinite copies. - try - { - fService.copy(-1, "main:/", "main://d/e", "illegal"); - fail(); - } - catch (AVMException ae) - { - // This is a success. - } - - StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - ResultSet results = searchService.query(storeRef, "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_NAME.toString()) + ":\"guest\""); - assertEquals(0, results.length()); - results.close(); - - CrossRepositoryCopyService copyService = (CrossRepositoryCopyService) fContext.getBean("CrossRepositoryCopyService"); - RepoRemote remoteService = (RepoRemote) fContext.getBean("RepoRemoteService"); - Pair toCopy = remoteService.lookup(remoteService.getRoot(), "Guest Home"); - copyService.copy(toCopy.getFirst(), AVMNodeConverter.ToNodeRef(-1, "main:/"), "Guest Home"); - desc = fService.lookup(-1, "main:/Guest Home"); - assertTrue(desc.isDirectory()); - System.out.println(this.recursiveList("main", -1, true)); - - fService.createSnapshot("main", null, null); - searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - results = searchService.query(storeRef, "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_NAME.toString()) + ":\"guest\""); - assertEquals(1, results.length()); - results.close(); - - StoreRef spacesStore = new StoreRef("workspace", "SpacesStore"); - - searchService = fIndexerAndSearcher.getSearcher(spacesStore, true); - results = searchService.query(spacesStore, "lucene", "PATH:\"//.\""); - int count = results.length(); - results.close(); - - copyService.copy(AVMNodeConverter.ToNodeRef(-1, "main:/a"), toCopy.getFirst(), "a"); - Pair theCopy = remoteService.lookup(toCopy.getFirst(), "a"); - assertTrue(theCopy.getSecond()); - - results = searchService.query(spacesStore, "lucene", "PATH:\"//.\""); - assertEquals(count + 5, results.length()); - results.close(); - - results = searchService.query(spacesStore, "lucene", "PATH:\"//.\""); - assertEquals(count + 5, results.length()); - results.close(); - - results = searchService.query(spacesStore, "lucene", "@cm\\:name:foo"); - assertEquals(1, results.length()); - results.close(); - - remoteService.removeNode(theCopy.getFirst()); - - results = searchService.query(spacesStore, "lucene", "PATH:\"//.\""); - assertEquals(count, results.length()); - results.close(); - - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - } - - protected void runQueriesAgainstBasicTreePlusFileCopy(String store) - { - StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); - - // Text index - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); - assertEquals(3, results.length()); - results.close(); - - // Basic properties - - // Note "a" is a stop word and therefore not findable ... - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"fooCopy\""); - assertEquals(1, results.length()); - results.close(); - - // TODO: Fix auth in AVMDiskDriver and more?? - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); - assertEquals(10, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); - assertEquals(10, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); - assertEquals(10, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); - assertEquals(10, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); - assertEquals(10, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); - assertEquals(10, results.length()); - results.close(); - - // Basic paths - - results = searchService.query(storeRef, "lucene", "PATH:\"/\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/fooCopy\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); - assertEquals(10, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); - assertEquals(9, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); - assertEquals(4, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); - assertEquals(3, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); - assertEquals(0, results.length()); - results.close(); - } - - protected void runQueriesAgainstBasicTreePlusFileCopyAndDirectoryCopy(String store) - { - StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); - - // Text index - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); - assertEquals(5, results.length()); - results.close(); - - // Basic properties - - // Note "a" is a stop word and therefore not findable ... - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"fooCopy\""); - assertEquals(1, results.length()); - results.close(); - - // TODO: Fix auth in AVMDiskDriver and more?? - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); - assertEquals(15, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); - assertEquals(15, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); - assertEquals(15, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); - assertEquals(15, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); - assertEquals(15, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); - assertEquals(15, results.length()); - results.close(); - - // Basic paths - - results = searchService.query(storeRef, "lucene", "PATH:\"/\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/fooCopy\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/aCopy\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/aCopy/b\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/aCopy/b/c\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/aCopy/b/c/foo\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/aCopy/b/c/bar\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); - assertEquals(15, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); - assertEquals(14, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); - assertEquals(4, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); - assertEquals(4, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); - assertEquals(3, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); - assertEquals(3, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); - assertEquals(3, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*/*/*\""); - assertEquals(0, results.length()); - results.close(); - } - - /** - * Test cyclic lookup behavior. - */ - public void testCyclicLookup() throws Exception - { - try - { - fService.createDirectory("main:/", "a"); - fService.createFile("main:/a", "foo").close(); - for (int i = 0; i < 1000; i++) - { - fService.lookup(-1, "main:/a/bar"); - } - fService.lookup(-1, "main:/a/foo"); - fService.createLayeredDirectory("main:/c", "main:/", "b"); - fService.createLayeredDirectory("main:/b", "main:/", "c"); - try - { - fService.lookup(-1, "main:/b/bar"); - fail(); - } - catch (AVMCycleException ce) - { - // Do nothing; this means success. - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test getting all paths for a node. - */ - public void testGetPaths() throws Exception - { - try - { - setupBasicTree(); - fService.createBranch(-1, "main:/a", "main:/", "abranch"); - fService.createSnapshot("main", null, null); - fService.createBranch(-1, "main:/a/b", "main:/", "bbranch"); - List> paths = fService.getPaths(fService.lookup(-1, "main:/a/b/c/foo")); - for (Pair path : paths) - { - System.out.println(path.getFirst() + " " + path.getSecond()); - } - paths = fService.getHeadPaths(fService.lookup(-1, "main:/a/b/c/foo")); - System.out.println("------------------------------"); - for (Pair path : paths) - { - System.out.println(path.getFirst() + " " + path.getSecond()); - } - paths = fService.getPathsInStoreHead(fService.lookup(-1, "main:/a/b/c/foo"), "main"); - System.out.println("------------------------------"); - for (Pair path : paths) - { - System.out.println(path.getFirst() + " " + path.getSecond()); - } - assertNotNull(fService.getAPath(fService.lookup(-1, "main:/a/b/c/foo"))); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test getIndirection. - */ - public void testGetIndirection() throws Exception - { - try - { - setupBasicTree(); - fService.createStore("layer"); - fService.createLayeredDirectory("main:/a", "layer:/", "layer"); - fService.createFile("layer:/layer/b", "figs").close(); - assertEquals("main:/a", fService.getIndirectionPath(-1, "layer:/layer")); - assertEquals("main:/a/b", fService.getIndirectionPath(-1, "layer:/layer/b")); - assertEquals("main:/a/b/c", fService.getIndirectionPath(-1, "layer:/layer/b/c")); - assertEquals("main:/a/b/c/foo", fService.getIndirectionPath(-1, "layer:/layer/b/c/foo")); - fService.createLayeredDirectory("main:/d", "layer:/layer/b", "dlayer"); - assertEquals("main:/d", fService.getIndirectionPath(-1, "layer:/layer/b/dlayer")); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - finally - { - fService.purgeStore("layer"); - } - } - - /** - * Test the revert list action. - * - * @deprecated - */ - public void testRevertListAction() throws Exception - { - try - { - setupBasicTree(); - fService.createStore("area"); - fService.createLayeredDirectory("main:/a", "area:/", "a"); - fService.getFileOutputStream("area:/a/b/c/foo").close(); - List diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); - assertEquals(1, diffs.size()); - assertEquals("[area:/a/b/c/foo[-1] > main:/a/b/c/foo[-1]]", diffs.toString()); - fSyncService.update(diffs, null, false, false, false, false, null, null); - fService.getFileOutputStream("area:/a/b/c/bar").close(); - diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); - assertEquals(1, diffs.size()); - assertEquals("[area:/a/b/c/bar[-1] > main:/a/b/c/bar[-1]]", diffs.toString()); - final ActionImpl action = new ActionImpl(null, GUID.generate(), AVMRevertListAction.NAME); - List paths = new ArrayList(); - paths.add("area:/a/b"); - action.setParameterValue(AVMRevertListAction.PARAM_VERSION, fService.getLatestSnapshotID("area")); - action.setParameterValue(AVMRevertListAction.PARAM_NODE_LIST, (Serializable) paths); - final AVMRevertListAction revert = (AVMRevertListAction) fContext.getBean("avm-revert-list"); - class TxnWork implements RetryingTransactionCallback - { - public Object execute() throws Exception - { - revert.execute(action, null); - return null; - } - } - ; - TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); - transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); - - diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); - assertEquals(0, diffs.size()); - System.out.println(recursiveList("area", -1, true)); - System.out.println(recursiveList("main", -1, true)); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - finally - { - fService.purgeStore("area"); - } - } - - /** - * Test the revert store action. - * - * @deprecated see org.alfresco.wcm.actions.WCMSandboxRevertSnapshotAction or org.alfresco.wcm.SandboxService.revertSnapshot - */ - public void testRevertStoreAction() throws Exception - { - try - { - setupBasicTree(); - - fService.createStore("area"); - fService.createLayeredDirectory("main:/a", "area:/", "a"); - - fService.getFileOutputStream("area:/a/b/c/foo").close(); - - List diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); - assertEquals(1, diffs.size()); - assertEquals("[area:/a/b/c/foo[-1] > main:/a/b/c/foo[-1]]", diffs.toString()); - - fSyncService.update(diffs, null, false, false, false, false, null, null); - - diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); - assertEquals(0, diffs.size()); - - fService.getFileOutputStream("area:/a/b/c/bar").close(); - - diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); - assertEquals(1, diffs.size()); - assertEquals("[area:/a/b/c/bar[-1] > main:/a/b/c/bar[-1]]", diffs.toString()); - - final ActionImpl action = new ActionImpl(null, GUID.generate(), AVMRevertStoreAction.NAME); - action.setParameterValue(AVMRevertStoreAction.PARAM_VERSION, fService.getLatestSnapshotID("area")); - - final AVMRevertStoreAction revert = (AVMRevertStoreAction)fContext.getBean("avm-revert-store"); - - class TxnWork implements RetryingTransactionCallback - { - public Object execute() throws Exception - { - revert.execute(action, AVMNodeConverter.ToNodeRef(-1, "area:/")); - return null; - } - }; - - TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); - transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); - - diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); - assertEquals(0, diffs.size()); - - System.out.println(recursiveList("area", -1, true)); - System.out.println(recursiveList("main", -1, true)); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - finally - { - fService.purgeStore("area"); - } - } - - /** - * Test the undo list action. - * - * @deprecated see org.alfresco.wcm.actions.WCMSandboxUndoAction or org.alfresco.wcm.SandboxService.revertList - */ - public void testUndoListAction() throws Exception - { - try - { - setupBasicTree(); - fService.createStore("area"); - fService.createLayeredDirectory("main:/a", "area:/", "a"); - fService.getFileOutputStream("area:/a/b/c/foo").close(); - List diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); - assertEquals(1, diffs.size()); - assertEquals("[area:/a/b/c/foo[-1] > main:/a/b/c/foo[-1]]", diffs.toString()); - fSyncService.update(diffs, null, false, false, false, false, null, null); - fService.getFileOutputStream("area:/a/b/c/bar").close(); - diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); - assertEquals(1, diffs.size()); - assertEquals("[area:/a/b/c/bar[-1] > main:/a/b/c/bar[-1]]", diffs.toString()); - final ActionImpl action = new ActionImpl(null, GUID.generate(), AVMUndoSandboxListAction.NAME); - List> versionPaths = new ArrayList>(); - versionPaths.add(new Pair(-1, "area:/a/b/c/bar")); - action.setParameterValue(AVMUndoSandboxListAction.PARAM_NODE_LIST, (Serializable) versionPaths); - final AVMUndoSandboxListAction revert = (AVMUndoSandboxListAction) fContext.getBean("avm-undo-list"); - class TxnWork implements RetryingTransactionCallback - { - public Object execute() throws Exception - { - revert.execute(action, null); - return null; - } - } - ; - TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); - transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); - - diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); - assertEquals(0, diffs.size()); - System.out.println(recursiveList("area", -1, true)); - System.out.println(recursiveList("main", -1, true)); - } - catch (Exception e) - { - e.printStackTrace(); - throw e; - } - finally - { - fService.purgeStore("area"); - } - } - - /** - * Test the promote action. - * - * @deprecated - */ - public void testPromoteAction() throws Exception - { - try - { - setupBasicTree(); - fService.createDirectory("main:/", JNDIConstants.DIR_DEFAULT_WWW); - fService.rename("main:/", "a", "main:/" + JNDIConstants.DIR_DEFAULT_WWW, "a"); - fService.rename("main:/", "d", "main:/" + JNDIConstants.DIR_DEFAULT_WWW, "d"); - fService.createSnapshot("main", null, null); - fService.createStore("source"); - fService.createLayeredDirectory("main:/" + JNDIConstants.DIR_DEFAULT_WWW, "source:/", JNDIConstants.DIR_DEFAULT_WWW); - fService.getFileOutputStream("source:/" + JNDIConstants.DIR_DEFAULT_WWW + "/a/b/c/foo").close(); - final ActionImpl action = new ActionImpl(AVMNodeConverter.ToNodeRef(-1, "source:/" + JNDIConstants.DIR_DEFAULT_WWW + "/a"), GUID.generate(), - SimpleAVMPromoteAction.NAME); - action.setParameterValue(SimpleAVMPromoteAction.PARAM_TARGET_STORE, "main"); - final SimpleAVMPromoteAction promote = (SimpleAVMPromoteAction) fContext.getBean("simple-avm-promote"); - class TxnWork implements RetryingTransactionCallback - { - public Object execute() throws Exception - { - promote.execute(action, AVMNodeConverter.ToNodeRef(-1, "source:/" + JNDIConstants.DIR_DEFAULT_WWW + "/a")); - return null; - } - } - ; - TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); - transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); - - assertEquals(0, fSyncService.compare(-1, "source:/" + JNDIConstants.DIR_DEFAULT_WWW, -1, "main:/" + JNDIConstants.DIR_DEFAULT_WWW, null).size()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - finally - { - fService.purgeStore("source"); - } - } - - /** - * Test the SimpleAVMSubmitAction. - * - * @deprecated see org.alfresco.wcm.actions.WCMSandboxSubmitAction or org.alfesco.wcm.SandboxService.submit - */ - public void testSubmitAction() throws Exception - { - // NOTE: it is implied that the sandboxes follow WCM naming conventions - final String STAGING = "foo"; - final String SANDBOX = "foo--sandbox"; - - try - { - fService.createStore(STAGING); - fService.createDirectory(STAGING+":/", JNDIConstants.DIR_DEFAULT_WWW); - fService.createDirectory(STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW, "a"); - fService.createDirectory(STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW + "/a", "b"); - fService.createDirectory(STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW + "/a/b", "c"); - fService.createFile(STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW + "/a/b/c", "foo").close(); - fService.createFile(STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW + "/a/b/c", "bar").close(); - - fService.createStore(SANDBOX); - fService.setStoreProperty(SANDBOX, SandboxConstants.PROP_WEBSITE_NAME, new PropertyValue(null, STAGING)); // note: it is implied that the website name is the same as staging name - fService.createLayeredDirectory(STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW, SANDBOX+":/", JNDIConstants.DIR_DEFAULT_WWW); - fService.createFile(SANDBOX+":/" + JNDIConstants.DIR_DEFAULT_WWW, "figs").close(); - fService.getFileOutputStream(SANDBOX+":/" + JNDIConstants.DIR_DEFAULT_WWW + "/a/b/c/foo").close(); - fService.removeNode(SANDBOX+":/" + JNDIConstants.DIR_DEFAULT_WWW + "/a/b/c/bar"); - - List diffs = fSyncService.compare(-1, SANDBOX+":/" + JNDIConstants.DIR_DEFAULT_WWW, -1, STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW, null); - assertEquals(3, diffs.size()); - assertEquals("["+SANDBOX+":/www/a/b/c/bar[-1] > "+STAGING+":/www/a/b/c/bar[-1], "+SANDBOX+":/www/a/b/c/foo[-1] > "+STAGING+":/www/a/b/c/foo[-1], "+SANDBOX+":/www/figs[-1] > "+STAGING+":/www/figs[-1]]", diffs.toString()); - - final SimpleAVMSubmitAction action = (SimpleAVMSubmitAction) fContext.getBean("simple-avm-submit"); - class TxnWork implements RetryingTransactionCallback - { - public Object execute() throws Exception - { - action.execute(null, AVMNodeConverter.ToNodeRef(-1, SANDBOX+":/" + JNDIConstants.DIR_DEFAULT_WWW)); - return null; - } - }; - - TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); - transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); - - diffs = fSyncService.compare(-1, SANDBOX+":/" + JNDIConstants.DIR_DEFAULT_WWW, -1, STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW, null); - - assertEquals(0, diffs.size()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - finally - { - fService.purgeStore(STAGING); - fService.purgeStore(SANDBOX); - } - } - - /** - * Test one argument remove. - */ - public void testOneArgRemove() throws Exception - { - try - { - setupBasicTree(); - fService.removeNode("main:/a/b/c/foo/"); - fService.removeNode("main://d"); - fService.createSnapshot("main", null, null); - - StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); - - // Text index - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); - assertEquals(1, results.length()); - results.close(); - - // Basic properties - - // Note "a" is a stop word and therefore not findable ... - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); - assertEquals(0, results.length()); - results.close(); - - // TODO: Fix auth in AVMDiskDriver and more?? - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); - if (results.length() == 6) - { - for (ResultSetRow row : results) - { - System.out.println(row.getNodeRef()); - } - } - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + "main"); - assertEquals(5, results.length()); - results.close(); - - // Basic paths - - results = searchService.query(storeRef, "lucene", "PATH:\"/\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); - assertEquals(4, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); - assertEquals(4, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); - assertEquals(3, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); - assertEquals(0, results.length()); - results.close(); - - try - { - fService.removeNode("main://"); - fail(); - } - catch (AVMException e) - { - // Do nothing. - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - } - } - - /** - * Test that non head version sources are update correctly. - */ - public void testVersionUpdate() throws Exception - { - try - { - BulkLoader loader = new BulkLoader(); - loader.setAvmService(fService); - fService.createStore("source"); - fService.createStore("dest"); - loader.recursiveLoad("config/alfresco/bootstrap", "source:/"); - int version1 = fService.createSnapshot("source", null, null).get("source"); - loader.recursiveLoad("config/alfresco/extension", "source:/"); - int version2 = fService.createSnapshot("source", null, null).get("source"); - List diffs = fSyncService.compare(version1, "source:/", -1, "dest:/", null); - fService.createSnapshot("dest", null, null); - assertEquals(1, diffs.size()); - assertEquals("[source:/bootstrap[1] > dest:/bootstrap[-1]]", diffs.toString()); - fSyncService.update(diffs, null, false, false, false, false, null, null); - diffs = fSyncService.compare(version1, "source:/", -1, "dest:/", null); - assertEquals(0, diffs.size()); - diffs = fSyncService.compare(version2, "source:/", -1, "dest:/", null); - assertEquals(1, diffs.size()); - assertEquals("[source:/extension[2] > dest:/extension[-1]]", diffs.toString()); - fSyncService.update(diffs, null, false, false, false, false, null, null); - fService.createSnapshot("dest", null, null); - diffs = fSyncService.compare(version2, "source:/", -1, "dest:/", null); - assertEquals(0, diffs.size()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - finally - { - fService.purgeStore("source"); - fService.purgeStore("dest"); - } - } - - /** - * Test that branching forces a snapshot on the source repository. - */ - public void testBranchSnapshot() throws Exception - { - try - { - setupBasicTree(); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - fService.createBranch(-1, "main:/a", "main:/", "abranch"); - assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getId(), fService.lookup(-1, "main:/abranch/b/c/foo").getId()); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - assertTrue(fService.lookup(-1, "main:/a/b/c/foo").getId() != fService.lookup(-1, "main:/abranch/b/c/foo").getId()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test of Descriptor indirection field. - */ - public void testDescriptorIndirection() throws Exception - { - try - { - setupBasicTree(); - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createFile("main:/layer/b/c", "bambino").close(); - AVMNodeDescriptor desc = fService.lookup(-1, "main:/layer"); - assertEquals("main:/a", desc.getIndirection()); - Map list = fService.getDirectoryListing(-1, "main:/"); - assertEquals("main:/a", list.get("layer").getIndirection()); - desc = fService.lookup(-1, "main:/layer/b"); - assertEquals("main:/a/b", desc.getIndirection()); - list = fService.getDirectoryListing(-1, "main:/layer"); - assertEquals("main:/a/b", list.get("b").getIndirection()); - list = fService.getDirectoryListingDirect(-1, "main:/layer"); - assertEquals("main:/a/b", list.get("b").getIndirection()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test link AVMService call. - */ - public void testLink() throws Exception - { - try - { - setupBasicTree(); - // Just try linking /a/b/c/foo into /a/b - fService.link("main:/a/b", "foo", fService.lookup(-1, "main:/a/b/c/foo")); - assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getId(), fService.lookup(-1, "main:/a/b/foo").getId()); - // Try linking /a/b/c/bar to /a/b/foo. It should fail. - System.out.println(recursiveList("main", -1, true)); - try - { - fService.link("main:/a/b", "foo", fService.lookup(-1, "main:/a/b/c/bar")); - fail(); - } - catch (AVMExistsException e) - { - // Do nothing. It's OK. - } - // Delete /a/b/foo, and link /a/b/c/foo into /a/b. This checks that - // a deleted node is no impediment. - fService.removeNode("main:/a/b", "foo"); - fService.link("main:/a/b", "foo", fService.lookup(-1, "main:/a/b/c/foo")); - assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getId(), fService.lookup(-1, "main:/a/b/foo").getId()); - // Delete /a/b/foo again in prep for layer tests. - fService.removeNode("main:/a/b", "foo"); - System.out.println(recursiveList("main", -1, true)); - fService.createSnapshot("main", null, null); - // Create a layer do a link from /layer/b/c/bar to /layer/b - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.link("main:/layer/b", "bar", fService.lookup(-1, "main:/layer/b/c/bar")); - assertEquals(fService.lookup(-1, "main:/layer/b/c/bar").getId(), fService.lookup(-1, "main:/layer/b/bar").getId()); - System.out.println(recursiveList("main", -1, true)); - // Now link /layer/b/c/foo into /layer/b. - fService.link("main:/layer/b", "foo", fService.lookup(-1, "main:/layer/b/c/foo")); - assertEquals(fService.lookup(-1, "main:/layer/b/c/foo").getId(), fService.lookup(-1, "main:/layer/b/foo").getId()); - // Make sure that the underlying layer is not mucked up. - assertTrue(fService.lookup(-1, "main:/a/b/foo", true).isDeleted()); - System.out.println(recursiveList("main", -1, true)); - // Try to link /layer/b/c/bar to /layer/b/c. It should fail. - try - { - fService.link("main:/layer/b", "bar", fService.lookup(-1, "main:/layer/b/c/bar")); - fail(); - } - catch (AVMExistsException e) - { - // Do nothing. - } - // Try to link /layer/b to /frinx. It should fail. - try - { - fService.link("main:/", "frinx", fService.lookup(-1, "main:/layer/b")); - fail(); - } - catch (AVMBadArgumentException ba) - { - // Do nothing. - } - // Delete /layer/b/bar and redo. It should work. - fService.removeNode("main:/layer/b", "bar"); - fService.link("main:/layer/b", "bar", fService.lookup(-1, "main:/layer/b/c/bar")); - assertEquals(fService.lookup(-1, "main:/layer/b/c/bar").getId(), fService.lookup(-1, "main:/layer/b/bar").getId()); - System.out.println(recursiveList("main", -1, true)); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test goofy paths. - */ - public void testGoofyPaths() throws Exception - { - try - { - setupBasicTree(); - fService.getFileInputStream(-1, "main://a/b/c/foo").close(); - fService.getDirectoryListing(-1, "main:/a/"); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test getting deleted names. - */ - public void testGetDeleted() throws Exception - { - try - { - setupBasicTree(); - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - List deleted = fService.getDeleted(-1, "main:/layer/b/c"); - assertEquals(0, deleted.size()); - fService.removeNode("main:/a/b/c", "foo"); - fService.createSnapshot("main", null, null); - deleted = fService.getDeleted(-1, "main:/a/b/c"); - assertEquals(0, deleted.size()); - fService.removeNode("main:/layer/b/c", "bar"); - fService.createSnapshot("main", null, null); - deleted = fService.getDeleted(-1, "main:/layer/b/c"); - assertEquals(1, deleted.size()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test directly contained listing. - */ - public void testListingDirect() throws Exception - { - try - { - setupBasicTree(); - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - Map listing = fService.getDirectoryListingDirect(-1, "main:/layer"); - assertEquals(0, listing.size()); - listing = fService.getDirectoryListingDirect(-1, "main:/layer/b"); - assertEquals(0, listing.size()); - fService.createFile("main:/layer/b/c", "sigmoid").close(); - fService.createSnapshot("main", null, null); - listing = fService.getDirectoryListingDirect(-1, "main:/layer"); - assertEquals(1, listing.size()); - fService.createFile("main:/layer", "lepton"); - fService.createSnapshot("main", null, null); - listing = fService.getDirectoryListingDirect(-1, "main:/layer"); - assertEquals(2, listing.size()); - listing = fService.getDirectoryListingDirect(-1, "main:/layer/b/c"); - assertEquals(1, listing.size()); - listing = fService.getDirectoryListingDirect(-1, "main:/a/b/c"); - assertEquals(2, listing.size()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test layering info. - */ - public void testLayeringInfo() throws Exception - { - try - { - setupBasicTree(); - fService.createStore("layer"); - fService.createLayeredDirectory("main:/a", "layer:/", "alayer"); - fService.createSnapshot("layer", null, null); - LayeringDescriptor info = fService.getLayeringInfo(-1, "layer:/alayer"); - assertFalse(info.isBackground()); - assertEquals("layer", info.getPathAVMStore().getName()); - assertEquals("layer", info.getNativeAVMStore().getName()); - info = fService.getLayeringInfo(-1, "layer:/alayer/b/c"); - assertTrue(info.isBackground()); - assertEquals("layer", info.getPathAVMStore().getName()); - assertEquals("main", info.getNativeAVMStore().getName()); - fService.createFile("layer:/alayer/b", "figs").close(); - fService.createSnapshot("layer", null, null); - info = fService.getLayeringInfo(-1, "layer:/alayer/b/figs"); - assertFalse(info.isBackground()); - assertEquals("layer", info.getPathAVMStore().getName()); - assertEquals("layer", info.getNativeAVMStore().getName()); - info = fService.getLayeringInfo(-1, "layer:/alayer/b/c"); - assertTrue(info.isBackground()); - assertEquals("layer", info.getPathAVMStore().getName()); - assertEquals("main", info.getNativeAVMStore().getName()); - fService.createLayeredDirectory("layer:/alayer/b", "layer:/", "blayer"); - fService.createSnapshot("layer", null, null); - System.err.println(recursiveList("main", -1, true)); - System.err.println(recursiveList("layer", -1, true)); - info = fService.getLayeringInfo(-1, "layer:/blayer/c"); - assertEquals("main", info.getNativeAVMStore().getName()); - info = fService.getLayeringInfo(-1, "layer:/blayer/figs"); - assertEquals("layer", info.getNativeAVMStore().getName()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - finally - { - fService.purgeStore("layer"); - } - } - - /** - * Another test of renaming in a layer. - */ - public void testRenameLayer2() throws Exception - { - try - { - TreeMap history = new TreeMap(); - // Set up a basic hierarchy. - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createDirectory("main:/a", "c"); - fService.createFile("main:/a/b", "foo", new ByteArrayInputStream("I am foo.".getBytes())); - fService.createFile("main:/a/c", "bar", new ByteArrayInputStream("I am bar.".getBytes())); - fService.createSnapshot("main", null, null); - // History is unchanged. - checkHistory(history, "main"); - // Make a layer to a. - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // History is unchanged. - checkHistory(history, "main"); - // /a and /layer should have identical contents. - assertEquals(recursiveContents("main:/a", -1, true), recursiveContents("main:/layer", -1, true)); - // Now rename /layer/c/bar to /layer/b/bar - fService.rename("main:/layer/c", "bar", "main:/layer/b", "bar"); - fService.createSnapshot("main", null, null); - // History is unchanged. - checkHistory(history, "main"); - // /layer/c should be empty. - Map listing = fService.getDirectoryListing(-1, "main:/layer/c"); - assertEquals(0, listing.size()); - // /layer/b should contain fao and bar - listing = fService.getDirectoryListing(-1, "main:/layer/b"); - assertEquals(2, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("bar", list.get(0)); - assertEquals("foo", list.get(1)); - // /a/b should contain foo. - listing = fService.getDirectoryListing(-1, "main:/a/b"); - assertEquals(1, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("foo", list.get(0)); - // /a/c should contain bar. - listing = fService.getDirectoryListing(-1, "main:/a/c"); - assertEquals(1, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("bar", list.get(0)); - // Now make a file in /a/b - fService.createFile("main:/a/b", "baz").close(); - fService.createSnapshot("main", null, null); - // History is unchanged. - checkHistory(history, "main"); - // /a/b should contain baz and foo. - listing = fService.getDirectoryListing(-1, "main:/a/b"); - assertEquals(2, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("baz", list.get(0)); - assertEquals("foo", list.get(1)); - // /layer/b should contain foo, bar, and baz. - listing = fService.getDirectoryListing(-1, "main:/layer/b"); - System.out.println(recursiveList("main", -1, true)); - assertEquals(3, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("bar", list.get(0)); - assertEquals("baz", list.get(1)); - assertEquals("foo", list.get(2)); - // Remove baz from /layer/b - fService.removeNode("main:/layer/b", "baz"); - fService.createSnapshot("main", null, null); - // History is unchanged. - checkHistory(history, "main"); - System.out.println(recursiveList("main", -1, true)); - // /layer/b should have bar and foo. - listing = fService.getDirectoryListing(-1, "main:/layer/b"); - assertEquals(2, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("bar", list.get(0)); - assertEquals("foo", list.get(1)); - // /a/b should contain baz and foo as before. - listing = fService.getDirectoryListing(-1, "main:/a/b"); - assertEquals(2, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("baz", list.get(0)); - assertEquals("foo", list.get(1)); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Yet another test around rename in layers. - */ - public void testRenameLayer3() throws Exception - { - try - { - TreeMap history = new TreeMap(); - // Set up a handy hierarchy. - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createFile("main:/a/b", "foo").close(); - fService.createFile("main:/a/b", "bar").close(); - fService.createDirectory("main:/", "c"); - fService.createDirectory("main:/c", "d"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make a layer over /a - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Move /c/d to /layer - fService.rename("main:/c", "d", "main:/layer", "d"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Now make a file in /layer/d - fService.createFile("main:/layer/d", "baz").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make /a/d/figs and see the wackiness. - fService.createDirectory("main:/a", "d"); - fService.createFile("main:/a/d", "figs").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer/d should no contain baz and figs. - Map listing = fService.getDirectoryListing(-1, "main:/layer/d"); - assertEquals(2, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("baz", list.get(0)); - assertEquals("figs", list.get(1)); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test the uncover operation. - */ - public void testUncover() throws Exception - { - try - { - TreeMap history = new TreeMap(); - // Set up a handy hierarchy. - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a/", "b"); - fService.createFile("main:/a/b", "foo").close(); - fService.createFile("main:/a/b", "bar").close(); - fService.createDirectory("main:/", "c"); - fService.createDirectory("main:/c", "d"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make a layer over /a - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Move /c/d to /layer - fService.rename("main:/c", "d", "main:/layer", "d"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make a file in /layer/d - fService.createFile("main:/layer/d", "baz").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make /a/d/figs and see the wackiness. - fService.createDirectory("main:/a", "d"); - fService.createFile("main:/a/d", "figs").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer/d should now contain baz and figs. - Map listing = fService.getDirectoryListing(-1, "main:/layer/d"); - assertEquals(2, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("baz", list.get(0)); - assertEquals("figs", list.get(1)); - // Rename /layer/d to /layer/e and uncover /layer/d - System.out.println(recursiveContents("main:/", -1, true)); - fService.rename("main:/layer", "d", "main:/layer", "e"); - fService.uncover("main:/layer", "d"); - fService.createSnapshot("main", null, null); - System.out.println(recursiveContents("main:/", -1, true)); - // History unchanged. - checkHistory(history, "main"); - // /layer/d contains figs. - listing = fService.getDirectoryListing(-1, "main:/layer/d"); - assertEquals(1, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("figs", list.get(0)); - // /layer/e contains baz and figs. - listing = fService.getDirectoryListing(-1, "main:/layer/e"); - assertEquals(2, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("baz", list.get(0)); - assertEquals("figs", list.get(1)); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Another test of renaming in a layer. - */ - public void testRenameLayer4() throws Exception - { - try - { - TreeMap history = new TreeMap(); - // Set up a handy hierarchy. - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createFile("main:/a/b", "foo").close(); - fService.createFile("main:/a/b", "bar").close(); - fService.createDirectory("main:/", "c"); - fService.createDirectory("main:/c", "d"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make a layer over /a - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Move /layer/b to /b - fService.rename("main:/layer", "b", "main:/", "b"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Add something to /a/b and it should show up in /b. - fService.createFile("main:/a/b", "baz").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /b should have foo and bar and baz. - Map listing = fService.getDirectoryListing(-1, "main:/b"); - assertEquals(3, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("bar", list.get(0)); - assertEquals("baz", list.get(1)); - assertEquals("foo", list.get(2)); - // Add something to /a and it will show up in /layer. - fService.createFile("main:/a", "figs").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer should have figs in it. - listing = fService.getDirectoryListing(-1, "main:/layer"); - assertEquals(1, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("figs", list.get(0)); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test branching within branches. - */ - public void testBranchesInBranches() throws Exception - { - try - { - TreeMap history = new TreeMap(); - // Set up a hierarchy. - setupBasicTree(); - // History unchanged. - checkHistory(history, "main"); - // Make a branch from /a - fService.createBranch(-1, "main:/a", "main:/", "abranch"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make a branch in something that has been branched. - fService.createBranch(-1, "main:/a/b", "main:/a", "bbranch"); - fService.createSnapshot("main", null, null); - // History unchanged - checkHistory(history, "main"); - // Everything under /abranch should be identical in this version - // and the previous. - int version = fService.getNextVersionID("main"); - assertEquals(recursiveContents("main:/abranch", version - 1, true), recursiveContents("main:/abranch", version - 2, true)); - // Make a branch within a branch. - fService.createBranch(-1, "main:/abranch/b/c", "main:/abranch/b", "cbranch"); - fService.createSnapshot("main", null, null); - // History unchanged - checkHistory(history, "main"); - // Everything under /a should be unchanged between this version and the last. - version = fService.getNextVersionID("main"); - assertEquals(recursiveContents("main:/a", version - 1, true), recursiveContents("main:/a", version - 2, true)); - // Make a branch to something outside of a branch inside a branch. - fService.createBranch(-1, "main:/d", "main:/abranch", "dbranch"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make something ind /abranch/dbranch. - fService.createFile("main:/abranch/dbranch/e/f", "baz").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // d should not have changed since the previous version. - version = fService.getNextVersionID("main"); - assertEquals(recursiveContents("main:/d", version - 1, true), recursiveContents("main:/d", version - 2, true)); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test layers inside of layers. - */ - public void testLayersInLayers() throws Exception - { - try - { - TreeMap history = new TreeMap(); - setupBasicTree(); - // History unchanged. - checkHistory(history, "main"); - // Create a layer to /a - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make a layer inside of a layer pointing to d. - fService.createLayeredDirectory("main:/d", "main:/layer", "under"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Create a file in /layer/under/e/f. - fService.createFile("main:/layer/under/e/f", "baz").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Create a file in /d/e. - fService.createFile("main:/d/e", "bow").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer/under/e should contain bow and f. - Map listing = fService.getDirectoryListing(-1, "main:/layer/under/e"); - assertEquals(2, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("bow", list.get(0)); - assertEquals("f", list.get(1)); - // Put a new set of dirs in to be made into a layering under d. - fService.createDirectory("main:/", "g"); - fService.createDirectory("main:/g", "h"); - fService.createDirectory("main:/g/h", "i"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make a layer in /d to /g. - fService.createLayeredDirectory("main:/g", "main:/d", "gover"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /d/gover should be identical to /layer/under/gover - assertEquals(recursiveContents("main:/d/gover", -1, true), recursiveContents("main:/layer/under/gover", -1, true)); - // Create a file in /layer/under/gover/h/i - fService.createFile("main:/layer/under/gover/h/i", "moo").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /d should be unchanged before this version and the last - // and /g should be unchanged between this version and the last. - int version = fService.getNextVersionID("main"); - // TODO Need an equivalent test that won't mind the version number change - // assertEquals(recursiveContents("main:/d", version - 1, true), - // recursiveContents("main:/d", version - 2, true)); - // assertEquals(recursiveContents("main:/g", version - 1, true), - // recursiveContents("main:/g", version - 2, true)); - // Add a file through /d/gover/h/i - fService.createFile("main:/d/gover/h/i", "cow").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /g should not have changed since its last version. - version = fService.getNextVersionID("main"); - assertEquals(recursiveContents("main:/g", version - 1, true), recursiveContents("main:/g", version - 2, true)); - // /layer/under/gover/h/i shows both moo and cow. - listing = fService.getDirectoryListing(-1, "main:/layer/under/gover/h/i"); - assertEquals(2, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("cow", list.get(0)); - assertEquals("moo", list.get(1)); - // Rename /layer/under/gover to /layer/b/gover and see what happens. - fService.rename("main:/layer/under", "gover", "main:/layer/b", "gover"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // moo should be in /layer/b/gover/h/i - listing = fService.getDirectoryListing(-1, "main:/layer/b/gover/h/i"); - assertEquals(1, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("moo", list.get(0)); - // Add a new file to /layer/b/gover/h/i - fService.createFile("main:/layer/b/gover/h/i", "oink").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer/b/gover/h/i should contain moo, oink. - listing = fService.getDirectoryListing(-1, "main:/layer/b/gover/h/i"); - assertEquals(2, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("moo", list.get(0)); - assertEquals("oink", list.get(1)); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test behavior when one branches a layer. - */ - public void testLayerAndBranch() throws Exception - { - try - { - TreeMap history = new TreeMap(); - // Create a basic tree. - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createDirectory("main:/a/b", "c"); - fService.createFile("main:/a/b/c", "foo").close(); - fService.createFile("main:/a/b/c", "bar").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Create a layer over /a - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /a and /layer should have identical contents. - assertEquals(recursiveContents("main:/a", -1, true), recursiveContents("main:/layer", -1, true)); - // Make a modification in /layer - fService.createFile("main:/layer/b", "baz").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Branch off layer. - fService.createBranch(-1, "main:/layer", "main:/", "branch"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer/b and /branch/b should have identical contents. - assertEquals(recursiveContents("main:/layer/b", -1, true), recursiveContents("main:/branch/b", -1, true)); - // Create /branch/b/c/foo - fService.createFile("main:/branch/b/c", "baz").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer should not have changed. - int version = fService.getNextVersionID("main"); - assertEquals(recursiveContents("main:/layer", version - 1, true), recursiveContents("main:/layer", version - 2, true)); - // Change something in /layer - fService.createFile("main:/layer/b/c", "fig").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /branch should not have changed. - version = fService.getNextVersionID("main"); - assertEquals(recursiveContents("main:/branch", version - 1, true), recursiveContents("main:/branch", version - 2, true)); - // Create another layer on /a - fService.createLayeredDirectory("main:/a", "main:/", "layer2"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Branch from /layer2/b. - fService.createBranch(-1, "main:/layer2/b", "main:/", "branch2"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Create something in the branch. - fService.createFile("main:/branch2", "goofy").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer2 should be unchanged. - version = fService.getNextVersionID("main"); - assertEquals(recursiveContents("main:/layer2", version - 1, true), recursiveContents("main:/layer2", version - 2, true)); - // Remove something from /layer2 - fService.removeNode("main:/layer2/b/c", "foo"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /branch2 is unchanged. - version = fService.getNextVersionID("main"); - assertEquals(recursiveContents("main:/branch2", version - 1, true), recursiveContents("main:/branch2", version - 2, true)); - // /a is unchanged. - assertEquals(recursiveContents("main:/a", version - 1, true), recursiveContents("main:/a", version - 2, true)); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test scenario in which something is renamed from inside one independent layer to another. - */ - public void testRenameLayerToLayer() throws Exception - { - try - { - TreeMap history = new TreeMap(); - // Set up two trees - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createDirectory("main:/a/b", "c"); - fService.createFile("main:/a/b/c", "foo").close(); - fService.createFile("main:/a/b/c", "bar").close(); - fService.createDirectory("main:/", "d"); - fService.createDirectory("main:/d", "e"); - fService.createDirectory("main:/d/e", "f"); - fService.createFile("main:/d/e/f", "moo").close(); - fService.createFile("main:/d/e/f", "cow").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make a layer to /a and a layer to /d - fService.createLayeredDirectory("main:/a", "main:/", "la"); - fService.createLayeredDirectory("main:/d", "main:/", "ld"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Move /la/b/c to /ld/e/c. - fService.rename("main:/la/b", "c", "main:/ld/e", "c"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Create file /ld/e/c/baz. - fService.createFile("main:/ld/e/c", "baz").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Here's the thing we'd like to assert. - assertEquals("main:/a/b/c", fService.lookup(-1, "main:/ld/e/c").getIndirection()); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test Nothing. Just make sure set up works. - */ - public void testNothing() throws Exception - { - } - - /** - * Test making a simple directory. - */ - public void testCreateDirectory() throws Exception - { - try - { - fService.createDirectory("main:/", "testdir"); - fService.createSnapshot("main", null, null); - assertEquals(AVMNodeType.PLAIN_DIRECTORY, fService.lookup(-1, "main:/").getType()); - - StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); - - // Text index - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - ResultSet results = searchService.query(storeRef, "lucene", "@cm\\:name:testdir"); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); - assertEquals(2, results.length()); - results.close(); - - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test creating a file. - */ - public void testCreateFile() throws Exception - { - try - { - testCreateDirectory(); - fService.createFile("main:/testdir", "testfile").close(); - fService.createFile("main:/", "testfile2").close(); - fService.createSnapshot("main", null, null); - - StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); - - // Text index - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - ResultSet results = searchService.query(storeRef, "lucene", "@cm\\:name:testfile"); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "@cm\\:name:testfile2"); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "TEXT:\"This is testdir/testfile\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "TEXT:\"This is testfile2\""); - assertEquals(0, results.length()); - results.close(); - - ContentWriter writer = fService.getContentWriter("main:/testdir/testfile"); - writer.setEncoding("UTF-8"); - writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - PrintStream out = new PrintStream(writer.getContentOutputStream()); - out.println("This is testdir/testfile"); - out.close(); - - out = new PrintStream(fService.getFileOutputStream("main:/testfile2")); - - writer = fService.getContentWriter("main:/testfile2"); - writer.setEncoding("UTF-8"); - writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); - out = new PrintStream(writer.getContentOutputStream()); - out.println("This is testfile2"); - out.close(); - fService.createSnapshot("main", null, null); - - results = searchService.query(storeRef, "lucene", "TEXT:\"This is testdir/testfile\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "TEXT:\"This is testfile2\""); - assertEquals(1, results.length()); - results.close(); - - List versions = fService.getStoreVersions("main"); - for (VersionDescriptor version : versions) - { - System.out.println("V:" + version.getVersionID()); - System.out.println(recursiveList("main", version.getVersionID(), true)); - } - BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/testdir/testfile"))); - String line = reader.readLine(); - assertEquals("This is testdir/testfile", line); - reader.close(); - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/testfile2"))); - line = reader.readLine(); - assertEquals("This is testfile2", line); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test creating a branch. - */ - public void testCreateBranch() throws Exception - { - try - { - setupBasicTree(); - fService.createBranch(-1, "main:/a", "main:/d/e", "abranch"); - fService.createSnapshot("main", null, null); - List versions = fService.getStoreVersions("main"); - for (VersionDescriptor version : versions) - { - System.out.println("V:" + version.getVersionID()); - System.out.println(recursiveList("main", version.getVersionID(), true)); - } - String original = recursiveList("main:/a", -1, 0, true); - original = original.substring(original.indexOf('\n')); - String branch = recursiveList("main:/d/e/abranch", -1, 0, true); - branch = branch.substring(branch.indexOf('\n')); - assertEquals(original, branch); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test creating a layer. - */ - public void testCreateLayer() throws Exception - { - try - { - setupBasicTree(); - fService.createLayeredDirectory("main:/a", "main:/d/e", "alayer"); - fService.createSnapshot("main", null, null); - System.out.println(recursiveList("main", -1, true)); - assertEquals("main:/a", fService.getIndirectionPath(-1, "main:/d/e/alayer")); - assertEquals(recursiveContents("main:/a", -1, true), recursiveContents("main:/d/e/alayer", -1, true)); - PrintStream out = new PrintStream(fService.getFileOutputStream("main:/d/e/alayer/b/c/foo")); - out.println("I am main:/d/e/alayer/b/c/foo"); - out.close(); - fService.createSnapshot("main", null, null); - BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/b/c/foo"))); - String line = reader.readLine(); - reader.close(); - assertEquals("I am main:/a/b/c/foo", line); - System.out.println(recursiveList("main", -1, true)); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test creating a layered file. - */ - public void testLayeredFile1() throws Exception - { - try - { - setupBasicTree(); - fService.createLayeredFile("main:/a/b/c/foo", "main:/d", "lfoo"); - assertTrue(fService.lookup(-1, "main:/d/lfoo").isLayeredFile()); - fService.createSnapshot("main", null, null); - System.out.println(recursiveList("main", -1, true)); - assertEquals("main:/a/b/c/foo", fService.lookup(-1, "main:/d/lfoo").getIndirection()); - assertTrue(fService.lookup(-1, "main:/d/lfoo").isLayeredFile()); - BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/d/lfoo"))); - String line = reader.readLine(); - reader.close(); - assertEquals("I am main:/a/b/c/foo", line); - PrintStream out = new PrintStream(fService.getFileOutputStream("main:/d/lfoo")); - out.println("I am main:/d/lfoo"); - out.close(); - assertFalse(fService.lookup(-1, "main:/d/lfoo").isLayeredFile()); - fService.createSnapshot("main", null, null); - System.out.println(recursiveList("main", -1, true)); - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/b/c/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/a/b/c/foo", line); - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/d/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/d/lfoo", line); - assertFalse(fService.lookup(-1, "main:/d/lfoo").isLayeredFile()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - public void testLayeredFile2() throws Exception - { - try - { - AVMNodeDescriptor desc = fService.lookup(-1, "main:/foo"); - assertNull(desc); - - try - { - fService.getFileOutputStream("main:/foo"); - fail("Unexpected"); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - try - { - fService.getFileInputStream(-1, "main:/foo"); - fail("Unexpected"); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - // create plain file - fService.createFile("main:/", "foo").close(); - - assertEquals(1, fService.lookup(-1, "main:/foo").getVersionID()); - - BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - String line = reader.readLine(); - reader.close(); - assertNull(line); - - PrintStream out = new PrintStream(fService.getFileOutputStream("main:/foo")); - out.println("I am main:/foo V1a"); - out.close(); - - // update plain file - - out = new PrintStream(fService.getFileOutputStream("main:/foo")); - out.println("I am main:/foo V1b"); - out.close(); - - out = new PrintStream(fService.getFileOutputStream("main:/foo")); - out.println("I am main:/foo V1c"); - out.close(); - - assertEquals(1, fService.lookup(-1, "main:/foo").getVersionID()); - - fService.createSnapshot("main", null, null); - - assertEquals(1, fService.lookup(-1, "main:/foo").getVersionID()); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V1c", line); - - // update plain file - - out = new PrintStream(fService.getFileOutputStream("main:/foo")); - out.println("I am main:/foo V2a"); - out.close(); - - assertEquals(2, fService.lookup(-1, "main:/foo").getVersionID()); - - out = new PrintStream(fService.getFileOutputStream("main:/foo")); - out.println("I am main:/foo V2b"); - out.close(); - - assertEquals(2, fService.lookup(-1, "main:/foo").getVersionID()); - - fService.createSnapshot("main", null, null); - - assertEquals(2, fService.lookup(-1, "main:/foo").getVersionID()); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V2b", line); - - // update plain file - out = new PrintStream(fService.getFileOutputStream("main:/foo")); - out.println("I am main:/foo V3"); - out.close(); - - assertEquals(3, fService.lookup(-1, "main:/foo").getVersionID()); - - fService.createSnapshot("main", null, null); - - assertEquals(3, fService.lookup(-1, "main:/foo").getVersionID()); - - try - { - fService.createLayeredFile("main:/foo", "main:/", "foo"); - fail("Unexpected"); - } - catch (AVMExistsException ee) - { - // expected - } - - // create layered file - fService.createLayeredFile("main:/foo", "main:/", "lfoo"); - - assertEquals(3, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(1, fService.lookup(-1, "main:/lfoo").getVersionID()); - assertTrue(fService.lookup(-1, "main:/lfoo").isLayeredFile()); - - assertEquals("main:/foo", fService.lookup(-1, "main:/lfoo").getIndirection()); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V3", line); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V3", line); - - fService.createSnapshot("main", null, null); - - assertEquals(3, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(1, fService.lookup(-1, "main:/lfoo").getVersionID()); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V3", line); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V3", line); - - // update plain file - out = new PrintStream(fService.getFileOutputStream("main:/foo")); - out.println("I am main:/foo V4"); - out.close(); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V4", line); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V4", line); - - assertEquals(4, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(1, fService.lookup(-1, "main:/lfoo").getVersionID()); - - fService.createSnapshot("main", null, null); - - assertEquals(4, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(2, fService.lookup(-1, "main:/lfoo").getVersionID()); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V4", line); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V4", line); - - // update plain file - - out = new PrintStream(fService.getFileOutputStream("main:/foo")); - out.println("I am main:/foo V5a"); - out.close(); - - out = new PrintStream(fService.getFileOutputStream("main:/foo")); - out.println("I am main:/foo V5b"); - out.close(); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V5b", line); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V5b", line); - - assertEquals(5, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(2, fService.lookup(-1, "main:/lfoo").getVersionID()); - - fService.createSnapshot("main", null, null); - - assertEquals(5, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(3, fService.lookup(-1, "main:/lfoo").getVersionID()); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V5b", line); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V5b", line); - - // update plain file - out = new PrintStream(fService.getFileOutputStream("main:/foo")); - out.println("I am main:/foo V6"); - out.close(); - - assertEquals(6, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(3, fService.lookup(-1, "main:/lfoo").getVersionID()); - - fService.createSnapshot("main", null, null); - - assertEquals(6, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(4, fService.lookup(-1, "main:/lfoo").getVersionID()); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V6", line); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V6", line); - - // update layered file - out = new PrintStream(fService.getFileOutputStream("main:/lfoo")); - out.println("I am main:/lfoo V1"); - out.close(); - - assertEquals(6, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(5, fService.lookup(-1, "main:/lfoo").getVersionID()); - assertFalse(fService.lookup(-1, "main:/lfoo").isLayeredFile()); - - fService.createSnapshot("main", null, null); - - assertEquals(6, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(5, fService.lookup(-1, "main:/lfoo").getVersionID()); - assertFalse(fService.lookup(-1, "main:/lfoo").isLayeredFile()); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V6", line); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/lfoo V1", line); - - // update layered file - out = new PrintStream(fService.getFileOutputStream("main:/lfoo")); - out.println("I am main:/lfoo V2"); - out.close(); - - assertEquals(6, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(6, fService.lookup(-1, "main:/lfoo").getVersionID()); - assertFalse(fService.lookup(-1, "main:/lfoo").isLayeredFile()); - - fService.createSnapshot("main", null, null); - - assertEquals(6, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(6, fService.lookup(-1, "main:/lfoo").getVersionID()); - assertFalse(fService.lookup(-1, "main:/lfoo").isLayeredFile()); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V6", line); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/lfoo V2", line); - - // remove plain file - fService.removeNode("main:/foo"); - - desc = fService.lookup(-1, "main:/foo"); - assertNull(desc); - - try - { - fService.getFileOutputStream("main:/foo"); - fail("Unexpected"); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - try - { - fService.getFileInputStream(-1, "main:/foo"); - fail("Unexpected"); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - fService.createSnapshot("main", null, null); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/lfoo V2", line); - - assertEquals(6, fService.lookup(-1, "main:/lfoo").getVersionID()); - - // remove layered file - fService.removeNode("main:/lfoo"); - - desc = fService.lookup(-1, "main:/lfoo"); - assertNull(desc); - - try - { - fService.getFileOutputStream("main:/lfoo"); - fail("Unexpected"); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - try - { - fService.getFileInputStream(-1, "main:/lfoo"); - fail("Unexpected"); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - fService.createSnapshot("main", null, null); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - public void testLayeredFile3() throws Exception - { - try - { - AVMNodeDescriptor desc = fService.lookup(-1, "main:/foo"); - assertNull(desc); - - try - { - fService.getFileOutputStream("main:/foo"); - fail("Unexpected"); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - try - { - fService.getFileInputStream(-1, "main:/foo"); - fail("Unexpected"); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - // create layered file (pointing nowhere) - fService.createLayeredFile("main:/foo", "main:/", "lfoo"); - - assertEquals(1, fService.lookup(-1, "main:/lfoo").getVersionID()); - - fService.createSnapshot("main", null, null); - - try - { - fService.getFileOutputStream("main:/lfoo"); - fail("Unexpected"); - } - catch (AVMException e) - { - // TODO - review - } - - try - { - fService.getFileInputStream(-1, "main:/lfoo"); - fail("Unexpected"); - } - catch (AVMException e) - { - // TODO - review - } - - // create plain file - fService.createFile("main:/", "foo").close(); - - assertEquals(1, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(1, fService.lookup(-1, "main:/lfoo").getVersionID()); - - BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - String line = reader.readLine(); - reader.close(); - assertNull(line); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertNull(line); - - // update plain file - PrintStream out = new PrintStream(fService.getFileOutputStream("main:/foo")); - out.println("I am main:/foo V1"); - out.close(); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V1", line); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V1", line); - - assertEquals(1, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(1, fService.lookup(-1, "main:/lfoo").getVersionID()); - - fService.createSnapshot("main", null, null); - - assertEquals(1, fService.lookup(-1, "main:/foo").getVersionID()); - assertEquals(2, fService.lookup(-1, "main:/lfoo").getVersionID()); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V1", line); - - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/foo V1", line); - - // remove plain file - fService.removeNode( "main:/foo"); - - desc = fService.lookup(-1, "main:/foo"); - assertNull(desc); - - try - { - fService.getFileOutputStream("main:/foo"); - fail("Unexpected"); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - try - { - fService.getFileInputStream(-1, "main:/foo"); - fail("Unexpected"); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - assertEquals(2, fService.lookup(-1, "main:/lfoo").getVersionID()); - - try - { - fService.getFileInputStream(-1, "main:/lfoo"); - fail("Unexpected"); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - fService.createSnapshot("main", null, null); - - assertEquals(3, fService.lookup(-1, "main:/lfoo").getVersionID()); - - try - { - fService.getFileInputStream(-1, "main:/lfoo"); - fail("Unexpected"); - } - catch (AVMNotFoundException nfe) - { - // expected - } - - assertTrue(fService.lookup(-1, "main:/lfoo").isLayeredFile()); - assertFalse(fService.lookup(-1, "main:/lfoo").isPlainFile()); - - try - { - fService.getFileOutputStream("main:/lfoo"); - fail(); - } - catch (AVMException e) - { - // TODO - review - } - - // remove layered file - fService.removeNode("main:/lfoo"); - - fService.createSnapshot("main", null, null); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test rename. - */ - public void testRename() throws Exception - { - try - { - setupBasicTree(); - fService.rename("main:/a", "b", "main:/d/e", "brenamed"); - fService.createSnapshot("main", null, null); - System.out.println(recursiveList("main", -1, true)); - assertEquals(recursiveContents("main:/a/b", 1, true), recursiveContents("main:/d/e/brenamed", 2, true)); - - // Test inedx update - - StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); - - // Text index - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); - assertEquals(2, results.length()); - results.close(); - - // Basic properties - - // Note "a" is a stop word and therefore not findable ... - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); - assertEquals(1, results.length()); - results.close(); - - // TODO: Fix auth in AVMDiskDriver and more?? - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); - - assertEquals(9, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); - assertEquals(9, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); - assertEquals(9, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); - assertEquals(9, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); - assertEquals(9, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":main"); - assertEquals(9, results.length()); - results.close(); - - // Basic paths - - results = searchService.query(storeRef, "lucene", "PATH:\"/\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/brenamed\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/brenamed/c\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/brenamed/c/foo\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/brenamed/c/bar\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); - assertEquals(9, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); - assertEquals(8, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*/*\""); - assertEquals(0, results.length()); - results.close(); - - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test remove. - */ - public void testRemove() throws Exception - { - try - { - setupBasicTree(); - TreeMap history = new TreeMap(); - checkHistory(history, "main"); - System.out.println(history.get(0)); - fService.removeNode("main:/a/b/c", "foo"); - fService.createSnapshot("main", null, null); - checkHistory(history, "main"); - System.out.println(history.get(1)); - Map l = fService.getDirectoryListing(-1, "main:/a/b/c"); - assertEquals(1, l.size()); - fService.removeNode("main:/d", "e"); - fService.createSnapshot("main", null, null); - checkHistory(history, "main"); - System.out.println(history.get(2)); - l = fService.getDirectoryListing(-1, "main:/d"); - assertEquals(0, l.size()); - - // Text index - StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); - assertEquals(1, results.length()); - results.close(); - - // Basic properties - - // Note "a" is a stop word and therefore not findable ... - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); - assertEquals(0, results.length()); - results.close(); - - // TODO: Fix auth in AVMDiskDriver and more?? - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + "main"); - assertEquals(6, results.length()); - results.close(); - - // Basic paths - - results = searchService.query(storeRef, "lucene", "PATH:\"/\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); - assertEquals(5, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); - assertEquals(4, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); - assertEquals(3, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); - assertEquals(0, results.length()); - results.close(); - - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test branching from one AVMStore to another. - */ - public void testBranchAcross() throws Exception - { - try - { - setupBasicTree(); - fService.createStore("second"); - List repos = fService.getStores(); - assertTrue(checkStoreExists("main", repos)); - assertTrue(checkStoreExists("second", repos)); - fService.createBranch(-1, "main:/", "second:/", "main"); - fService.createSnapshot("second", null, null); - System.out.println(recursiveList("second", -1, true)); - assertEquals(recursiveContents("main:/", -1, true), recursiveContents("second:/main", -1, true)); - // Now make sure nothing happens to the branched from place, - // if the branch is modified. - PrintStream out = new PrintStream(fService.getFileOutputStream("second:/main/a/b/c/foo")); - out.println("I am second:/main/a/b/c/foo"); - out.close(); - fService.createSnapshot("second", null, null); - System.out.println(recursiveList("second", -1, true)); - BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/b/c/foo"))); - String line = reader.readLine(); - reader.close(); - assertEquals("I am main:/a/b/c/foo", line); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - finally - { - fService.purgeStore("second"); - } - } - - private boolean checkStoreExists(String storeName, List stores) - { - for (AVMStoreDescriptor store : stores) - { - if (store.getName().equals(storeName)) - { - return true; - } - } - return false; - } - - /** - * Test creating a layer across AVMStores. - */ - public void testLayerAcross() throws Exception - { - try - { - setupBasicTree(); - fService.createStore("second"); - fService.createLayeredDirectory("main:/", "second:/", "main"); - fService.createSnapshot("second", null, null); - System.out.println(recursiveList("second", -1, true)); - assertEquals(recursiveContents("main:/", -1, true), recursiveContents("second:/main", -1, true)); - // Now make sure that a copy on write will occur and - // that the underlying stuff doesn't get changed. - PrintStream out = new PrintStream(fService.getFileOutputStream("second:/main/a/b/c/foo")); - out.println("I am second:/main/a/b/c/foo"); - out.close(); - fService.createSnapshot("second", null, null); - System.out.println(recursiveList("second", -1, true)); - BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "second:/main/a/b/c/foo"))); - String line = reader.readLine(); - reader.close(); - assertEquals("I am second:/main/a/b/c/foo", line); - reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/b/c/foo"))); - line = reader.readLine(); - reader.close(); - assertEquals("I am main:/a/b/c/foo", line); - fService.purgeStore("second"); - fService.purgeVersion(1, "main"); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test rename across AVMStores. - */ - public void testRenameAcross() throws Exception - { - try - { - setupBasicTree(); - fService.createStore("second"); - fService.rename("main:/a/b", "c", "second:/", "cmoved"); - ArrayList toSnapshot = new ArrayList(); - toSnapshot.add("main"); - toSnapshot.add("second"); - System.out.println(recursiveList("main", -1, true)); - System.out.println(recursiveList("second", -1, true)); - // Check that the moved thing has identical contents to the thing it - // was moved from. - assertEquals(recursiveContents("main:/a/b/c", 1, true), recursiveContents("second:/cmoved", -1, true)); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - finally - { - fService.purgeStore("second"); - } - } - - /** - * Test COW in various circumstances. - */ - public void testDeepCOW() throws Exception - { - try - { - // Makes a layer on top of a layer on top of a plain directory. - // Assures that the correct layers are copied when files - // are added in the two layers. - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createSnapshot("main", null, null); - Map listing = fService.getDirectoryListing(-1, "main:/a"); - assertEquals(1, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("b", list.get(0)); - fService.createLayeredDirectory("main:/a", "main:/", "c"); - fService.createLayeredDirectory("main:/c", "main:/", "d"); - fService.createFile("main:/d/b", "foo.txt").close(); - fService.createSnapshot("main", null, null); - System.out.println(recursiveList("main", -1, true)); - listing = fService.getDirectoryListing(-1, "main:/d/b"); - assertEquals(1, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("foo.txt", list.get(0)); - fService.createFile("main:/c/b", "bar.txt").close(); - fService.createSnapshot("main", null, null); - System.out.println(recursiveList("main", -1, true)); - listing = fService.getDirectoryListing(-1, "main:/c/b"); - assertEquals(1, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("bar.txt", list.get(0)); - listing = fService.getDirectoryListing(-1, "main:/d/b"); - assertEquals(2, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("bar.txt", list.get(0)); - assertEquals("foo.txt", list.get(1)); - AVMNodeDescriptor[] arrayListing = fService.getDirectoryListingArray(-1, "main:/d/b", false); - assertEquals("bar.txt", arrayListing[0].getName()); - assertEquals("foo.txt", arrayListing[1].getName()); - fService.rename("main:/", "c", "main:/", "e"); - fService.createSnapshot("main", null, null); - System.out.println(recursiveList("main", -1, true)); - listing = fService.getDirectoryListing(-1, "main:/d/b"); - assertEquals(1, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("foo.txt", list.get(0)); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test branching and layering interaction. - */ - public void testBranchAndLayer() throws Exception - { - try - { - // Create a simple directory hierarchy. - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createFile("main:/a/b", "c.txt").close(); - fService.createFile("main:/a/b", "d.txt").close(); - fService.createFile("main:/a", "e.txt").close(); - fService.createSnapshot("main", null, null); - // Make a branch off of a. - fService.createBranch(-1, "main:/a", "main:/", "branch"); - fService.createSnapshot("main", null, null); - // The branch should contain exactly the same things as the thing - // it branched from. - assertEquals(recursiveContents("main:/a", -1, true), recursiveContents("main:/branch", -1, true)); - // Make a layer pointing to /branch/b - fService.createLayeredDirectory("main:/branch/b", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // The new layer should contain exactly the same things as the thing it is layered to. - assertEquals(recursiveContents("main:/branch/b", -1, true), recursiveContents("main:/layer", -1, true)); - // Make a modification in /a/b, the original branch. - PrintStream out = new PrintStream(fService.getFileOutputStream("main:/a/b/c.txt")); - out.println("I am c, modified in main:/a/b."); - out.close(); - fService.createSnapshot("main", null, null); - // The layer should still have identical content to /branch/b. - assertEquals(recursiveContents("main:/branch/b", -1, true), recursiveContents("main:/layer", -1, true)); - // But the layer won't have contents identical to /a/b's - assertFalse(recursiveContents("main:/a/b", -1, true).equals(recursiveContents("main:/layer", -1, true))); - // Make a modification in /branch/b - out = new PrintStream(fService.getFileOutputStream("main:/branch/b/d.txt")); - out.println("I am d, modified in main:/branch/b"); - out.close(); - fService.createSnapshot("main", null, null); - // The layer contents should be identical to the latest contents of /branch/b. - assertEquals(recursiveContents("main:/branch/b", -1, true), recursiveContents("main:/layer", -1, true)); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test basic Layering. - */ - public void testLayering() throws Exception - { - try - { - // Make some directories; - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createDirectory("main:/a/b", "c"); - fService.createDirectory("main:/a/b/c", "d"); - fService.createSnapshot("main", null, null); - // Now make some layers. Three to be precise. - fService.createLayeredDirectory("main:/a", "main:/", "e"); - fService.createLayeredDirectory("main:/e", "main:/", "f"); - fService.createLayeredDirectory("main:/f", "main:/", "g"); - fService.createSnapshot("main", null, null); - // e, f, g should all have the same contents as a. - String a = recursiveContents("main:/a", -1, true); - String e = recursiveContents("main:/e", -1, true); - String f = recursiveContents("main:/f", -1, true); - String g = recursiveContents("main:/g", -1, true); - assertEquals(a, e); - assertEquals(a, f); - assertEquals(a, g); - // Now make a file in /g/b/c/d and /f/b/c/d - fService.createFile("main:/g/b/c/d", "foo").close(); - fService.createFile("main:/f/b/c/d", "bar").close(); - fService.createSnapshot("main", null, null); - // /g/b/c/d should contain foo and bar. - Map listing = fService.getDirectoryListing(-1, "main:/g/b/c/d"); - assertEquals(2, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("bar", list.get(0)); - assertEquals("foo", list.get(1)); - // /f/b/c/d should contain just bar. - listing = fService.getDirectoryListing(-1, "main:/f/b/c/d"); - assertEquals(1, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("bar", list.get(0)); - // Now do something in the bottom layer. - fService.createFile("main:/a/b/c", "baz").close(); - fService.createSnapshot("main", null, null); - // /e/b/c should contain baz and d - listing = fService.getDirectoryListing(-1, "main:/e/b/c"); - assertEquals(2, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("baz", list.get(0)); - assertEquals("d", list.get(1)); - // Now add something in the e layer. - fService.createFile("main:/e/b/c/d", "bing").close(); - fService.createSnapshot("main", null, null); - // /f/b/c/d should now contain bar and bing. - listing = fService.getDirectoryListing(-1, "main:/f/b/c/d"); - assertEquals(2, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("bar", list.get(0)); - assertEquals("bing", list.get(1)); - System.out.println(recursiveList("main", -1, true)); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test rename within a layer. - */ - public void testRenameInLayer() throws Exception - { - try - { - // Setup a base hierarchy. - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createDirectory("main:/a/b", "c"); - fService.createDirectory("main:/a", "d"); - fService.createSnapshot("main", null, null); - // Now make a layer to a. - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // /layer should have the same contents as /a at this point. - assertEquals(recursiveContents("main:/a", -1, true), recursiveContents("main:/layer", -1, true)); - // Now we will rename /layer/d to /layer/moved - fService.rename("main:/layer", "d", "main:/layer", "moved"); - fService.createSnapshot("main", null, null); - // /layer should contain b and moved - Map listing = fService.getDirectoryListing(-1, "main:/layer"); - assertEquals(2, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("b", list.get(0)); - assertEquals("moved", list.get(1)); - // Now rename moved back to d. - fService.rename("main:/layer", "moved", "main:/layer", "d"); - fService.createSnapshot("main", null, null); - // /layer should contain b and d. - listing = fService.getDirectoryListing(-1, "main:/layer"); - assertEquals(2, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("b", list.get(0)); - assertEquals("d", list.get(1)); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test behavior of multiply layers not in register. - */ - public void testMultiLayerUnregistered() throws Exception - { - try - { - TreeMap history = new TreeMap(); - setupBasicTree(); - // History unchanged. - checkHistory(history, "main"); - // Create layered directory /d/e/f/ to /a - fService.createLayeredDirectory("main:/a", "main:/d/e/f", "l0"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Create layered directory /d/l1 to /d/e/f. - fService.createLayeredDirectory("main:/d/e/f", "main:/d", "l1"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Create layered directory /l2 to /d - fService.createLayeredDirectory("main:/d", "main:/", "l2"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Create /l2/l1/l0/a/foo. - fService.createFile("main:/l2/l1/l0/b", "foo").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /l2/l1/l0 should now point at /d/l1/l0 - assertEquals("main:/d/l1/l0", fService.lookup(-1, "main:/l2/l1/l0").getIndirection()); - // /l2/l1/l0/b should now point at /d/l1/l0/b - assertEquals("main:/d/l1/l0/b", fService.lookup(-1, "main:/l2/l1/l0/b").getIndirection()); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test makePrimary. - */ - public void testMakePrimary() throws Exception - { - try - { - TreeMap history = new TreeMap(); - setupBasicTree(); - // History unchanged. - checkHistory(history, "main"); - // Make a layer to /a - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make /layer/b/c primary. - fService.makePrimary("main:/layer/b/c"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Rename /layer/b/c to /layer/c - fService.rename("main:/layer/b", "c", "main:/layer", "c"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /a/b/c should have identical contents to /layer/c - assertEquals(recursiveContents("main:/a/b/c", -1, true), recursiveContents("main:/layer/c", -1, true)); - // Create /layer2 to /a. - fService.createLayeredDirectory("main:/a", "main:/", "layer2"); - // Make a file down in /layer2/b/c - fService.createFile("main:/layer2/b/c", "baz").close(); - // make /layer2/b/c primary. - fService.makePrimary("main:/layer2/b/c"); - // Rename /layer2/b/c to /layer2/c - fService.rename("main:/layer2/b", "c", "main:/layer2", "c"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer2/c should contain foo bar and baz. - Map listing = fService.getDirectoryListing(-1, "main:/layer2/c"); - assertEquals(3, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("bar", list.get(0)); - assertEquals("baz", list.get(1)); - assertEquals("foo", list.get(2)); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test retargeting a directory. - */ - public void testRetarget() throws Exception - { - try - { - TreeMap history = new TreeMap(); - setupBasicTree(); - // History unchanged. - checkHistory(history, "main"); - // Make a layer to /a - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Retarget /layer/b/c to /d. - fService.retargetLayeredDirectory("main:/layer/b/c", "main:/d"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer/b/c should contain e. - Map listing = fService.getDirectoryListing(-1, "main:/layer/b/c"); - assertEquals(1, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("e", list.get(0)); - // Rename /layer/b/c to /layer/c - fService.rename("main:/layer/b", "c", "main:/layer", "c"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /d should have identical contents to /layer/c - assertEquals(recursiveContents("main:/d", -1, true), recursiveContents("main:/layer/c", -1, true)); - // Create /layer2 to /a. - fService.createLayeredDirectory("main:/a", "main:/", "layer2"); - // Make a file down in /layer2/b/c - fService.createFile("main:/layer2/b/c", "baz").close(); - // make /layer2/b/c primary. - fService.retargetLayeredDirectory("main:/layer2/b/c", "main:/d"); - // Rename /layer2/b/c to /layer2/c - fService.rename("main:/layer2/b", "c", "main:/layer2", "c"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer2/c should have baz and e in it. - listing = fService.getDirectoryListing(-1, "main:/layer2/c"); - assertEquals(2, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("baz", list.get(0)); - assertEquals("e", list.get(1)); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test rename between branches. - */ - public void testRenameBranchToBranch() throws Exception - { - try - { - TreeMap history = new TreeMap(); - // Set up two trees - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createDirectory("main:/a/b", "c"); - fService.createFile("main:/a/b/c", "foo").close(); - fService.createFile("main:/a/b/c", "bar").close(); - fService.createDirectory("main:/", "d"); - fService.createDirectory("main:/d", "e"); - fService.createDirectory("main:/d/e", "f"); - fService.createFile("main:/d/e/f", "moo").close(); - fService.createFile("main:/d/e/f", "cow").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make branches. - fService.createBranch(-1, "main:/a/b", "main:/", "abranch"); - fService.createBranch(-1, "main:/d/e", "main:/", "dbranch"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Move /abranch/c/foo /dbranch/foo - fService.rename("main:/abranch/c", "foo", "main:/dbranch", "foo"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Confirm that /a and /d are unchanged. - int version = fService.getNextVersionID("main"); - assertEquals(recursiveContents("main:/a", version - 1, true), recursiveContents("main:/a", version - 2, true)); - assertEquals(recursiveContents("main:/d", version - 1, true), recursiveContents("main:/d", version - 2, true)); - // Move /dbranch/f to /abranch/c/f - fService.rename("main:/dbranch", "f", "main:/abranch/c", "f"); - fService.createSnapshot("main", null, null); - // Confirm that /a and /d are unchanged. - version = fService.getNextVersionID("main"); - assertEquals(recursiveContents("main:/a", version - 1, true), recursiveContents("main:/a", version - 2, true)); - assertEquals(recursiveContents("main:/d", version - 1, true), recursiveContents("main:/d", version - 2, true)); - // History unchanged. - checkHistory(history, "main"); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test a branch being created in a layer. - */ - public void testBranchIntoLayer() throws Exception - { - try - { - TreeMap history = new TreeMap(); - // Set up two trees - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createDirectory("main:/a/b", "c"); - fService.createFile("main:/a/b/c", "foo").close(); - fService.createFile("main:/a/b/c", "bar").close(); - fService.createDirectory("main:/", "d"); - fService.createDirectory("main:/d", "e"); - fService.createDirectory("main:/d/e", "f"); - fService.createFile("main:/d/e/f", "moo").close(); - fService.createFile("main:/d/e/f", "cow").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Create a layer to /a - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Now create a branch from /d in /layer/a/b. - fService.createBranch(-1, "main:/d", "main:/layer/b", "branch"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Now modify /layer/b/branch/e/f/moo. - PrintStream out = new PrintStream(fService.getFileOutputStream("main:/layer/b/branch/e/f/moo")); - out.println("moo modified."); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer/b/branch/e/f should contain moo and cow. - Map listing = fService.getDirectoryListing(-1, "main:/layer/b/branch/e/f"); - assertEquals(2, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("cow", list.get(0)); - assertEquals("moo", list.get(1)); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test renaming into a layer. - */ - public void testRenameIntoLayer() throws Exception - { - try - { - TreeMap history = new TreeMap(); - // Set up two trees - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createDirectory("main:/a/b", "c"); - fService.createFile("main:/a/b/c", "foo").close(); - fService.createFile("main:/a/b/c", "bar").close(); - fService.createDirectory("main:/", "d"); - fService.createDirectory("main:/d", "e"); - fService.createDirectory("main:/d/e", "f"); - fService.createFile("main:/d/e/f", "moo").close(); - fService.createFile("main:/d/e/f", "cow").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Create a layer to /a - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Now rename /d into /layer/a/b. - fService.rename("main:/", "d", "main:/layer/b", "d"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Now modify /layer/b/branch/e/f/moo. - PrintStream out = new PrintStream(fService.getFileOutputStream("main:/layer/b/d/e/f/moo")); - out.println("moo modified."); - out.close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer/b/branch/e/f should contain moo and cow. - Map listing = fService.getDirectoryListing(-1, "main:/layer/b/d/e/f"); - assertEquals(2, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("cow", list.get(0)); - assertEquals("moo", list.get(1)); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test proper indirection behavior. - */ - public void testIndirectionBehavior() throws Exception - { - try - { - TreeMap history = new TreeMap(); - // Setup the stage. - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createDirectory("main:/a/b", "c"); - fService.createDirectory("main:/a/b/c", "d"); - fService.createDirectory("main:/a/b/c/d", "e"); - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - fService.createDirectory("main:/", "f"); - fService.createDirectory("main:/f", "g"); - fService.createDirectory("main:/f/g", "h"); - fService.createLayeredDirectory("main:/f", "main:/", "flayer"); - fService.createLayeredDirectory("main:/flayer", "main:/layer/b/c", "fover"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - fService.createDirectory("main:/", "i"); - fService.createDirectory("main:/i", "j"); - fService.createDirectory("main:/i/j", "k"); - fService.createLayeredDirectory("main:/i", "main:/f/g/h", "iover"); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - fService.createFile("main:/layer/b/c/fover/g/h/iover/j/k", "foo").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // Make a file in /i/j/k - fService.createFile("main:/i/j/k", "pismo").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer/b/c/fover/g/h/iover/j/k should contain pismo and foo. - Map listing = fService.getDirectoryListing(-1, "main:/layer/b/c/fover/g/h/iover/j/k"); - assertEquals(2, listing.size()); - List list = new ArrayList(listing.keySet()); - assertEquals("foo", list.get(0)); - assertEquals("pismo", list.get(1)); - // Make a file in /flayer/g/h/iover/j/k - fService.createFile("main:/flayer/g/h/iover/j/k", "zuma").close(); - fService.createSnapshot("main", null, null); - // History unchanged. - checkHistory(history, "main"); - // /layer/b/c/fover/g/h/iover/j/k should contain foo, pismo, and zuma. - listing = fService.getDirectoryListing(-1, "main:/layer/b/c/fover/g/h/iover/j/k"); - assertEquals(3, listing.size()); - list = new ArrayList(listing.keySet()); - assertEquals("foo", list.get(0)); - assertEquals("pismo", list.get(1)); - assertEquals("zuma", list.get(2)); - for (String val : history.values()) - { - System.out.println(val); - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test reading of versioned content via a layer. - */ - public void testVersionedRead() throws Exception - { - try - { - PrintStream out = new PrintStream(fService.createFile("main:/", "foo")); - out.print("version1"); - out.close(); - fService.createLayeredFile("main:/foo", "main:/", "afoo"); - fService.createSnapshot("main", null, null); - 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); - BufferedReader 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(-1, "main:/afoo"))); - assertEquals("version2", reader.readLine()); - reader.close(); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test rename of an overlayed directory contained in an overlayed directory. - */ - public void testRenameLayerInLayer() throws Exception - { - try - { - // Make some directories. - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createDirectory("main:/a/b", "c"); - fService.createSnapshot("main", null, null); - // Make a layer to /a. - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - // Force a copy on write in the layer. - fService.createFile("main:/layer/b/c", "foo").close(); - fService.createSnapshot("main", null, null); - assertEquals("main:/a/b/c", fService.lookup(-1, "main:/layer/b/c").getIndirection()); - // Now rename. - fService.rename("main:/layer/b", "c", "main:/layer/b", "d"); - fService.createSnapshot("main", null, null); - assertEquals("main:/a/b/d", fService.lookup(-1, "main:/layer/b/d").getIndirection()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Yet another rename from layer to layer test. - */ - public void testAnotherRename() throws Exception - { - try - { - // Make two directory trees. - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createDirectory("main:/a/b", "c"); - fService.createDirectory("main:/", "d"); - fService.createDirectory("main:/d", "e"); - fService.createDirectory("main:/d/e", "f"); - fService.createSnapshot("main", null, null); - runQueriesForInitialRenameStructure("main"); - // Make a layer over each. - fService.createLayeredDirectory("main:/a", "main:/", "la"); - fService.createLayeredDirectory("main:/d", "main:/", "ld"); - fService.createSnapshot("main", null, null); - // TODO: Sort out paths to layers .... - // runQueriesForInitialRenameStructureAndInitialLayers("main"); - // rename from down in one layer to another. - fService.rename("main:/ld/e", "f", "main:/la/b", "f"); - fService.createSnapshot("main", null, null); - AVMNodeDescriptor desc = fService.lookup(-1, "main:/la/b/f"); - assertTrue(desc.isPrimary()); - assertEquals("main:/d/e/f", desc.getIndirection()); - // Now rename in in the layer. - fService.rename("main:/la/b", "f", "main:/la/b/c", "f"); - fService.createSnapshot("main", null, null); - desc = fService.lookup(-1, "main:/la/b/c/f"); - assertTrue(desc.isPrimary()); - assertEquals("main:/d/e/f", desc.getIndirection()); - // Now create a directory in the layered f. - fService.createDirectory("main:/la/b/c/f", "dir"); - fService.createSnapshot("main", null, null); - desc = fService.lookup(-1, "main:/la/b/c/f/dir"); - assertFalse(desc.isPrimary()); - assertEquals("main:/d/e/f/dir", desc.getIndirection()); - // Now rename that and see where it points. - fService.rename("main:/la/b/c/f", "dir", "main:/la/b", "dir"); - fService.createSnapshot("main", null, null); - desc = fService.lookup(-1, "main:/la/b/dir"); - assertFalse(desc.isPrimary()); - assertEquals("main:/a/b/dir", desc.getIndirection()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - protected void runQueriesForInitialRenameStructure(String store) throws Exception - { - StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); - - SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef(store), true); - - // Note "a" is a stop word and therefore not findable ... - - ResultSet results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); - assertEquals(7, results.length()); - results.close(); - - // Basic paths - - results = searchService.query(storeRef, "lucene", "PATH:\"/\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); - assertEquals(3, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); - assertEquals(0, results.length()); - results.close(); - } - - protected void runQueriesForInitialRenameStructureAndInitialLayers(String store) - { - StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); - - SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef(store), true); - - // Note "a" is a stop word and therefore not findable ... - - ResultSet results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); - assertEquals(9, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); - assertEquals(7, results.length()); - results.close(); - - // Basic paths - - results = searchService.query(storeRef, "lucene", "PATH:\"/\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); - assertEquals(7, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); - assertEquals(6, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); - assertEquals(3, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); - assertEquals(1, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); - assertEquals(2, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); - assertEquals(0, results.length()); - results.close(); - - results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); - assertEquals(0, results.length()); - results.close(); - } - - /** - * Test rename behavior of an overlayed file withing a layer. - */ - public void testFileRenameLayer() throws Exception - { - try - { - // Make a set of directories. - fService.createDirectory("main:/", "a"); - fService.createDirectory("main:/a", "b"); - fService.createDirectory("main:/a/b", "c"); - fService.createFile("main:/", "foo").close(); - fService.createSnapshot("main", null, null); - // Make a layer. - fService.createLayeredDirectory("main:/a", "main:/", "la"); - fService.createSnapshot("main", null, null); - // Make a layered file. - fService.createLayeredFile("main:/foo", "main:/la/b", "foo"); - fService.createSnapshot("main", null, null); - AVMNodeDescriptor desc = fService.lookup(-1, "main:/la/b/foo"); - assertEquals("main:/foo", desc.getIndirection()); - // Now rename it. It should still point at the same place. - fService.rename("main:/la/b", "foo", "main:/la", "foo"); - fService.createSnapshot("main", null, null); - desc = fService.lookup(-1, "main:/la/foo"); - assertEquals("main:/foo", desc.getIndirection()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * The random access. - */ - /* - * public void testRandomAccess() { try { setupBasicTree(); RandomAccessFile file = fService.getRandomAccess(1, - * "main:/a/b/c/foo", "r"); byte [] buff = new byte[256]; assertTrue(file.read(buff) >= 20); file.close(); file = - * fService.getRandomAccess(-1, "main:/a/b/c/bar", "rw"); for (int i = 0; i < 256; i++) { buff[i] = (byte)i; } - * file.write(buff); file.close(); fService.createSnapshot("main", null, null); } catch (Exception e) { - * e.printStackTrace(System.err); throw e; } } - */ - - /** - * Test COW during long operations. - */ - public void testCOWLongOps() throws Exception - { - try - { - setupBasicTree(); - // Create a layer to a. - fService.createLayeredDirectory("main:/a", "main:/d/e/f", "layer"); - // Create a layer to /d - fService.createLayeredDirectory("main:/d", "main:/", "l2"); - // Force a copy on write on l2 - fService.createFile("main:/l2", "baz").close(); - // Force a copy on write on /d/e/f/layer/b/c - fService.createFile("main:/d/e/f/layer/b/c", "fink").close(); - // Create /l2/e/f/layer/b/c/nottle - fService.createFile("main:/l2/e/f/layer/b/c", "nottle").close(); - fService.createSnapshot("main", null, null); - System.out.println(recursiveList("main", -1, true)); - assertFalse(fService.lookup(-1, "main:/d/e/f/layer/b/c").getId() == fService.lookup(-1, "main:/l2/e/f/layer/b/c").getId()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test new lookup methods. - */ - public void testLookup() throws Exception - { - try - { - setupBasicTree(); - AVMNodeDescriptor desc = fService.getStoreRoot(-1, "main"); - assertNotNull(desc); - System.out.println(desc.toString()); - AVMNodeDescriptor child = fService.lookup(desc, "a"); - assertNotNull(child); - System.out.println(child.toString()); - child = fService.lookup(child, "b"); - assertNotNull(child); - System.out.println(child.toString()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test AVMStore functions. - */ - public void testAVMStore() throws Exception - { - try - { - // First check that we get the right error when we try to create an - // AVMStore that exists. - try - { - fService.createStore("main"); - fail(); - } - catch (AVMExistsException ae) - { - // Do nothing. - } - // Now make sure getRepository() works. - AVMStoreDescriptor desc = fService.getStore("main"); - assertNotNull(desc); - System.out.println(desc); - fService.purgeStore("main"); - assertNull(fService.getStore("main")); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test opacity and manipulations. - */ - public void testOpacity() throws Exception - { - try - { - setupBasicTree(); - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - fService.createSnapshot("main", null, null); - fService.createFile("main:/layer/b/c", "baz").close(); - fService.createFile("main:/layer/b/c", "fig").close(); - fService.createSnapshot("main", null, null); - Map listing = fService.getDirectoryListing(-1, "main:/layer/b/c"); - assertEquals(4, listing.size()); - System.out.println(recursiveList("main", -1, true)); - // Setting the opacity of layer to true will make no difference to what we see through - // main:/layer/b/c. - fService.setOpacity("main:/layer", true); - fService.createSnapshot("main", null, null); - assertTrue(fService.lookup(-1, "main:/layer").getOpacity()); - assertEquals(4, fService.getDirectoryListing(-1, "main:/layer/b/c").size()); - System.out.println(recursiveList("main", -1, true)); - // If main:/layer/b/c is opaque, however, we'll only see two items in it. - fService.setOpacity("main:/layer", false); - fService.setOpacity("main:/layer/b/c", true); - fService.createSnapshot("main", null, null); - assertFalse(fService.lookup(-1, "main:/layer").getOpacity()); - assertTrue(fService.lookup(-1, "main:/layer/b/c").getOpacity()); - assertEquals(2, fService.getDirectoryListing(-1, "main:/layer/b/c").size()); - System.out.println(recursiveList("main", -1, true)); - // Gratuitous test of retarget. - fService.retargetLayeredDirectory("main:/layer", "main:/d"); - fService.setOpacity("main:/layer/b/c", false); - fService.createSnapshot("main", null, null); - assertFalse(fService.lookup(-1, "main:/layer/b/c").getOpacity()); - assertEquals(2, fService.getDirectoryListing(-1, "main:/layer/b/c").size()); - // This is just testing that opacity setting works on latent - // layered directories. - fService.setOpacity("main:/layer/e/f", true); - System.out.println(recursiveList("main", -1, true)); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test common ancestor. - */ - public void testCommonAncestor() throws Exception - { - try - { - setupBasicTree(); - fService.createBranch(-1, "main:/a", "main:/", "branch"); - fService.createSnapshot("main", null, null); - AVMNodeDescriptor ancestor = fService.lookup(-1, "main:/a/b/c/foo"); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - fService.getFileOutputStream("main:/branch/b/c/foo").close(); - fService.createSnapshot("main", null, null); - AVMNodeDescriptor main = fService.lookup(-1, "main:/a/b/c/foo"); - AVMNodeDescriptor branch = fService.lookup(-1, "main:/branch/b/c/foo"); - AVMNodeDescriptor ca = fService.getCommonAncestor(main, branch); - assertEquals(ancestor, ca); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test properties on stores. - */ - public void testStoreProperties() throws Exception - { - try - { - Map props = fService.getStoreProperties("main"); - assertEquals(2, props.size()); - assertEquals(AuthenticationUtil.getAdminUserName(), props.get(ContentModel.PROP_CREATOR).getStringValue()); - assertNotNull(props.get(ContentModel.PROP_CREATED)); - System.out.println(props.toString()); - - QName name = QName.createQName("silly.uri", "SillyProperty"); - PropertyValue value = new PropertyValue(DataTypeDefinition.TEXT, "Silly Property Value"); - fService.setStoreProperty("main", name, value); - PropertyValue found = fService.getStoreProperty("main", name); - assertEquals(value.toString(), found.toString()); - props = fService.getStoreProperties("main"); - assertEquals(3, props.size()); - - props = new HashMap(5); - QName n1 = QName.createQName("silly.uri", "Prop1"); - PropertyValue p1 = new PropertyValue(null, new Date(System.currentTimeMillis())); - props.put(n1, p1); - QName n2 = QName.createQName("silly.uri", "Prop2"); - PropertyValue p2 = new PropertyValue(null, "A String Property."); - props.put(n2, p2); - QName n3 = QName.createQName("silly.uri", "Prop3"); - PropertyValue p3 = new PropertyValue(null, 42); - props.put(n3, p3); - QName n4 = QName.createQName("silly.uri", "Prop4"); - PropertyValue p4 = new PropertyValue(null, new Boolean(false)); - props.put(n4, p4); - QName n5 = QName.createQName("silly.uri", "Prop5"); - List strList = new ArrayList(2); - strList.add("hello"); - strList.add("world"); - PropertyValue p5 = new PropertyValue(DataTypeDefinition.TEXT, (Serializable)strList); - props.put(n5, p5); - fService.setStoreProperties("main", props); - - props = fService.getStoreProperties("main"); - System.out.println(props.toString()); - assertEquals(8, props.size()); - assertEquals(p1.toString(), props.get(n1).toString()); - assertEquals(p2.toString(), props.get(n2).toString()); - assertEquals(p3.toString(), props.get(n3).toString()); - assertEquals(p4.toString(), props.get(n4).toString()); - assertEquals(p5.toString(), props.get(n5).toString()); - - props = new HashMap(5); - n1 = QName.createQName("silly.uri", "Prop1"); - p1 = new PropertyValue(null, new Date(System.currentTimeMillis())); - props.put(n1, p1); - n2 = QName.createQName("silly.uri", "Prop2"); - p2 = new PropertyValue(null, "A String Property - updated."); - props.put(n2, p2); - n3 = QName.createQName("silly.uri", "Prop3"); - p3 = new PropertyValue(null, -42); - props.put(n3, p3); - n4 = QName.createQName("silly.uri", "Prop4"); - p4 = new PropertyValue(null, new Boolean(true)); - props.put(n4, p4); - n5 = QName.createQName("silly.uri", "Prop5"); - strList = new ArrayList(2); - strList.add("goodbye"); - strList.add("world"); - p5 = new PropertyValue(DataTypeDefinition.TEXT, (Serializable)strList); - props.put(n5, p5); - fService.setStoreProperties("main", props); - - props = fService.getStoreProperties("main"); - System.out.println(props.toString()); - assertEquals(8, props.size()); - assertEquals(p1.toString(), props.get(n1).toString()); - assertEquals(p2.toString(), props.get(n2).toString()); - assertEquals(p3.toString(), props.get(n3).toString()); - assertEquals(p4.toString(), props.get(n4).toString()); - assertEquals(p5.toString(), props.get(n5).toString()); - - fService.deleteStoreProperty("main", name); - props = fService.getStoreProperties("main"); - assertEquals(7, props.size()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test Aspect Name storage. - */ - public void testAspectNames() throws Exception - { - try - { - setupBasicTree(); - - StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); - SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); - ResultSet results = searchService.query(storeRef, "lucene", "ASPECT:\"" + ContentModel.ASPECT_TITLED.toString() + "\""); - assertEquals(0, results.length()); - results.close(); - results = searchService.query(storeRef, "lucene", "ASPECT:\"" + ContentModel.ASPECT_AUDITABLE.toString() + "\""); - assertEquals(0, results.length()); - results.close(); - - fService.addAspect("main:/a/b/c/foo", ContentModel.ASPECT_TITLED); - fService.addAspect("main:/a/b/c/foo", ContentModel.ASPECT_AUDITABLE); - Map properties = new HashMap(); - properties.put(ContentModel.PROP_ACCESSED, new PropertyValue(DataTypeDefinition.DATETIME, new Date(System.currentTimeMillis()))); - properties.put(ContentModel.PROP_CREATED, new PropertyValue(DataTypeDefinition.DATETIME, new Date(System.currentTimeMillis()))); - properties.put(ContentModel.PROP_MODIFIED, new PropertyValue(DataTypeDefinition.DATETIME, new Date(System.currentTimeMillis()))); - properties.put(ContentModel.PROP_CREATOR, new PropertyValue(DataTypeDefinition.TEXT, "Giles")); - properties.put(ContentModel.PROP_MODIFIER, new PropertyValue(DataTypeDefinition.TEXT, "Quentin")); - fService.setNodeProperties("main:/a/b/c/foo", properties); - fService.createSnapshot("main", null, null); - - results = searchService.query(storeRef, "lucene", "ASPECT:\"" + ContentModel.ASPECT_TITLED.toString() + "\""); - assertEquals(1, results.length()); - results.close(); - results = searchService.query(storeRef, "lucene", "ASPECT:\"" + ContentModel.ASPECT_AUDITABLE.toString() + "\""); - assertEquals(1, results.length()); - results.close(); - - fService.removeNode("main:/a/b/c/bar"); - fService.addAspect("main:/a/b/c/bar", ContentModel.ASPECT_TITLED); - Set names = fService.getAspects(-1, "main:/a/b/c/foo"); - assertEquals(2, names.size()); - assertTrue(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_TITLED)); - assertFalse(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_AUTHOR)); - assertTrue(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_TITLED)); - fService.removeAspect("main:/a/b/c/foo", ContentModel.ASPECT_TITLED); - fService.createSnapshot("main", null, null); - - results = searchService.query(storeRef, "lucene", "ASPECT:\"" + ContentModel.ASPECT_TITLED.toString() + "\""); - assertEquals(0, results.length()); - results.close(); - results = searchService.query(storeRef, "lucene", "ASPECT:\"" + ContentModel.ASPECT_AUDITABLE.toString() + "\""); - assertEquals(1, results.length()); - results.close(); - - fService.getFileOutputStream("main:/a/b/c/foo").close(); - assertFalse(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_TITLED)); - assertTrue(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_AUDITABLE)); - Map props = fService.getNodeProperties(-1, "main:/a/b/c/foo"); - assertEquals(5, props.size()); - fService.removeAspect("main:/a/b/c/foo", ContentModel.ASPECT_AUDITABLE); - props = fService.getNodeProperties(-1, "main:/a/b/c/foo"); - assertEquals(0, props.size()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test case insensitivity. - */ - public void testCaseInsensitive() throws Exception - { - try - { - setupBasicTree(); - try - { - fService.createFile("main:/a/b/c", "Foo").close(); - fail(); - } - catch (AVMExistsException e) - { - // Do nothing. - } - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test ACLs. - */ - public void testACLs() throws Exception - { - try - { - setupBasicTree(); - PermissionService perm = (PermissionService) fContext.getBean("PermissionService"); - // AuthenticationService ac = (AuthenticationService)fContext.getBean("AuthenticationService"); - // ac.authenticate("admin", "admin".toCharArray()); - perm.setPermission(AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/foo"), PermissionService.ADMINISTRATOR_AUTHORITY, PermissionService.ALL_PERMISSIONS, true); - fService.createSnapshot("main", null, null); - fService.getFileOutputStream("main:/a/b/c/foo").close(); - Set perms = perm.getPermissions(AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/foo")); - for (AccessPermission permission : perms) - { - System.out.println(permission); - } - assertTrue(perms.size() > 0); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test FileFolderService with AVM. - */ - public void testFileFolderService() throws Exception - { - try - { - setupBasicTree(); - FileFolderService ffs = (FileFolderService) fContext.getBean("FileFolderService"); - // AuthenticationComponent ac = (AuthenticationComponent)fContext.getBean("authenticationComponent"); - // ac.authenticate("admin", "admin".toCharArray()); - assertTrue(ffs.create(AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/"), "banana", WCMModel.TYPE_AVM_PLAIN_CONTENT) != null); - assertTrue(ffs.create(AVMNodeConverter.ToNodeRef(-1, "main://"), "banana", WCMModel.TYPE_AVM_PLAIN_CONTENT) != null); - assertTrue(ffs.create(AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c"), "apples", WCMModel.TYPE_AVM_PLAIN_FOLDER) != null); - NodeService ns = (NodeService) fContext.getBean("NodeService"); - Map properties = new HashMap(); - properties.put(WCMModel.PROP_AVM_DIR_INDIRECTION, AVMNodeConverter.ToNodeRef(-1, "main:/a")); - assertTrue(ns.createNode(AVMNodeConverter.ToNodeRef(-1, "main:/"), ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "layer"), - WCMModel.TYPE_AVM_LAYERED_FOLDER, properties) != null); - assertTrue(ns.getProperty(AVMNodeConverter.ToNodeRef(-1, "main:/layer"), WCMModel.PROP_AVM_DIR_INDIRECTION) != null); - properties.clear(); - properties.put(WCMModel.PROP_AVM_FILE_INDIRECTION, AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/foo")); - assertTrue(ns.createNode(AVMNodeConverter.ToNodeRef(-1, "main:/"), ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "foo"), - WCMModel.TYPE_AVM_LAYERED_CONTENT, properties) != null); - assertTrue(ns.getProperty(AVMNodeConverter.ToNodeRef(-1, "main:/foo"), WCMModel.PROP_AVM_FILE_INDIRECTION) != null); - fService.createSnapshot("main", null, null); - System.out.println(recursiveList("main", -1, true)); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test overwriting without snapshots in between. - */ - public void testOverwrite() throws Exception - { - try - { - setupBasicTree(); - class TxnCallback implements RetryingTransactionHelper.RetryingTransactionCallback - { - public Object execute() throws Exception - { - try - { - AVMService service = (AVMService) fContext.getBean("avmService"); - service.createLayeredDirectory("main:/a", "main:/", "layer"); - // Modify something in an ordinary directory 3 times. - service.getFileOutputStream("main:/a/b/c/foo").close(); - service.getFileOutputStream("main:/a/b/c/foo").close(); - service.getFileOutputStream("main:/a/b/c/foo").close(); - service.createFile("main:/a/b/c", "pint").close(); - service.createFile("main:/a/b/c", "quart").close(); - // Modify another file in the same directory. - service.getFileOutputStream("main:/a/b/c/bar").close(); - service.getFileOutputStream("main:/a/b/c/bar").close(); - service.lookup(-1, "main:/a/b/c"); - service.createFile("main:/a/b/c", "figment").close(); - // Repeat in a layer. - service.getFileOutputStream("main:/layer/b/c/foo").close(); - service.getFileOutputStream("main:/layer/b/c/foo").close(); - service.getFileOutputStream("main:/layer/b/c/foo").close(); - service.createFile("main:/layer/b/c", "gallon").close(); - service.createFile("main:/layer/b/c", "dram").close(); - service.getFileOutputStream("main:/layer/b/c/bar").close(); - service.getFileOutputStream("main:/layer/b/c/bar").close(); - try - { - service.lookup(-1, "main:/a/b/c/froo"); - } - catch (AVMException ae) - { - // Do nothing. - } - service.createDirectory("main:/a/b/c", "froo"); - service.createFile("main:/a/b/c/froo", "franistan").close(); - try - { - service.lookup(-1, "main:/layer/b/c/groo"); - } - catch (AVMException ae) - { - // Do nothing. - } - service.createDirectory("main:/layer/b/c", "groo"); - service.createFile("main:/layer/b/c/groo", "granistan").close(); - return null; - } - catch (IOException e) - { - e.printStackTrace(); - throw e; - } - } - } - TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); - RetryingTransactionHelper helper = transactionService.getRetryingTransactionHelper(); - helper.doInTransaction(new TxnCallback(), false); - assertNotNull(fService.lookup(-1, "main:/layer/b/c/groo")); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test creating a file over a ghost. - */ - public void testCreateOverDeleted() throws Exception - { - try - { - setupBasicTree(); - fService.removeNode("main:/a/b/c", "foo"); - fService.createFile("main:/a/b/c", "foo").close(); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - } - - /** - * Test lookup and listing of deleted files. - */ - public void testDeleted() throws Exception - { - try - { - setupBasicTree(); - fService.createLayeredDirectory("main:/a", "main:/", "layer"); - // Delete something in regular directory. - fService.removeNode("main:/a/b/c", "foo"); - AVMNodeDescriptor desc = fService.lookup(-1, "main:/a/b/c/foo", true); - assertTrue(desc.isDeleted()); - assertTrue(desc.isDeletedFile()); - Map listing = fService.getDirectoryListing(-1, "main:/a/b/c", true); - assertEquals(2, listing.size()); - assertTrue(listing.get("foo").isDeleted()); - AVMNodeDescriptor dir = fService.lookup(-1, "main:/a/b/c", true); - desc = fService.lookup(dir, "foo", true); - assertTrue(desc.isDeleted()); - listing = fService.getDirectoryListing(dir, true); - assertEquals(2, listing.size()); - assertTrue(listing.get("foo").isDeleted()); - desc = fService.lookup(-1, "main:/layer/b/c/foo", true); - assertTrue(desc.isDeleted()); - listing = fService.getDirectoryListing(-1, "main:/layer/b/c", true); - assertEquals(2, listing.size()); - assertTrue(listing.get("foo").isDeleted()); - dir = fService.lookup(-1, "main:/layer/b/c", true); - listing = fService.getDirectoryListing(dir, true); - assertEquals(2, listing.size()); - assertTrue(listing.get("foo").isDeleted()); - // Delete something in a layer. - fService.removeNode("main:/layer/b/c", "bar"); - desc = fService.lookup(-1, "main:/layer/b/c/bar", true); - assertTrue(desc.isDeleted()); - assertTrue(desc.isDeletedFile()); - listing = fService.getDirectoryListing(-1, "main:/layer/b/c", true); - assertEquals(2, listing.size()); - assertTrue(listing.get("foo").isDeleted()); - assertTrue(listing.get("bar").isDeleted()); - listing = fService.getDirectoryListingDirect(-1, "main:/layer/b/c", true); - assertEquals(1, listing.size()); - assertTrue(listing.get("bar").isDeleted()); - dir = fService.lookup(-1, "main:/layer/b/c", true); - desc = fService.lookup(dir, "bar", true); - assertTrue(desc.isDeleted()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - - } - } - - /** - * Test Store property querying. - */ - public void testStorePropertyQuerying() throws Exception - { - try - { - fService.setStoreProperty("main", QName.createQName(null, ".dns.alice--preview"), new PropertyValue(null, "alice-preview")); - fService.setStoreProperty("main", QName.createQName("", ".other.property"), new PropertyValue(null, "other value")); - Map result = fService.queryStorePropertyKey("main", QName.createQName("", ".dns.%")); - assertEquals(1, result.size()); - - fService.createStore("second"); - fService.setStoreProperty("second", QName.createQName("", ".dns.alice"), new PropertyValue(null, "alice-space")); - Map> matches = fService.queryStoresPropertyKeys(QName.createQName("", ".dns.%")); - assertEquals(1, matches.get("main").size()); - assertEquals(1, matches.get("second").size()); - assertEquals("alice-preview", matches.get("main").get(QName.createQName(null, ".dns.alice--preview")).getStringValue()); - assertEquals("alice-space", matches.get("second").get(QName.createQName(null, ".dns.alice")).getStringValue()); - - fService.createStore("third"); - fService.setStoreProperty("third", QName.createQName("", ".dns.someUPPERcase"), new PropertyValue(null, "someUPPERcase-space")); - matches = fService.queryStoresPropertyKeys(QName.createQName("", ".dns.someuppercase%")); - assertEquals(1, matches.get("third").size()); - assertEquals("someUPPERcase-space", matches.get("third").get(QName.createQName(null, ".dns.someUPPERcase")).getStringValue()); - } - catch (Exception e) - { - e.printStackTrace(System.err); - throw e; - } - finally - { - fService.purgeStore("second"); - fService.purgeStore("third"); - } - } - - -} +/* + * 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" */ + +package org.alfresco.repo.avm; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import org.alfresco.config.JNDIConstants; +import org.alfresco.model.ContentModel; +import org.alfresco.model.WCMModel; +import org.alfresco.repo.action.ActionImpl; +import org.alfresco.repo.avm.actions.AVMRevertListAction; +import org.alfresco.repo.avm.actions.AVMRevertStoreAction; +import org.alfresco.repo.avm.actions.AVMRevertToVersionAction; +import org.alfresco.repo.avm.actions.AVMUndoSandboxListAction; +import org.alfresco.repo.avm.actions.SimpleAVMPromoteAction; +import org.alfresco.repo.avm.actions.SimpleAVMSubmitAction; +import org.alfresco.repo.avm.util.BulkLoader; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.repo.search.impl.lucene.LuceneQueryParser; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.transaction.RetryingTransactionHelper; +import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; +import org.alfresco.service.cmr.avm.AVMBadArgumentException; +import org.alfresco.service.cmr.avm.AVMCycleException; +import org.alfresco.service.cmr.avm.AVMException; +import org.alfresco.service.cmr.avm.AVMExistsException; +import org.alfresco.service.cmr.avm.AVMNodeDescriptor; +import org.alfresco.service.cmr.avm.AVMNotFoundException; +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avm.AVMStoreDescriptor; +import org.alfresco.service.cmr.avm.LayeringDescriptor; +import org.alfresco.service.cmr.avm.VersionDescriptor; +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.ContentWriter; +import org.alfresco.service.cmr.repository.CrossRepositoryCopyService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.ResultSetRow; +import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.cmr.security.AccessPermission; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.service.transaction.TransactionService; +import org.alfresco.util.GUID; +import org.springframework.extensions.surf.util.Pair; +import org.alfresco.wcm.sandbox.SandboxConstants; + +/** + * Big test of AVM behavior. + * + * @author britt + */ +public class AVMServiceTest extends AVMServiceTestBase +{ + public void testSetup() throws Exception + { + super.testSetup(); + } + + public void testDiffOrder() + { + try + { + fService.createStore("Bottom"); + fService.createStore("Top"); + + fService.createDirectory("Bottom:/", "www"); + fService.createLayeredDirectory("Bottom:/www", "Top:/", "www"); + + fService.createFile("Bottom:/www", "newInBottom"); + fService.createSnapshot("Bottom", null, null); + fService.createFile("Top:/www", "newInTop"); + fService.createSnapshot("Top", null, null); + fService.createFile("Bottom:/www", "file"); + fService.createSnapshot("Bottom", null, null); + fService.forceCopy("Top:/www/file"); + fService.createSnapshot("Top", null, null); + fService.forceCopy("Bottom:/www/file"); + fService.createSnapshot("Bottom", null, null); + + + List diffs = fSyncService.compare(-1, "Top:/", -1, "Bottom:/", null); + assertEquals( + 2, diffs.size()); + Collections.sort(diffs); + AVMDifference last = null; + for(AVMDifference current : diffs) + { + if(last != null) + { + assert(last.getOrderValue() < current.getOrderValue()); + } + last = current; + } + + diffs.add(new AVMDifference(1, null, -1, null, 0)); + diffs.add(new AVMDifference(1, null, -1, null, 1)); + diffs.add(new AVMDifference(1, null, -1, null, 2)); + diffs.add(new AVMDifference(1, null, -1, null, 3)); + diffs.add(new AVMDifference(1, null, -1, null, 4)); + diffs.add(new AVMDifference(1, null, -1, null, 5)); + diffs.add(new AVMDifference(1, null, -1, null, 6)); + + Collections.sort(diffs); + last = null; + for(AVMDifference current : diffs) + { + if(last != null) + { + assert(last.getOrderValue() < current.getOrderValue()); + } + last = current; + } + } + finally + { + fService.purgeStore("Bottom"); + fService.purgeStore("Top"); + } + + } + + public void test_ETWOTWO_570() throws Exception + { + // Check that read-write methods are properly intercepted + RetryingTransactionCallback readOnlyCallback = new RetryingTransactionCallback() + { + public Object execute() throws Throwable + { + fService.createStore("StagingArea" + "-" + getName() + "-" + System.currentTimeMillis()); + return null; + } + }; + fTransactionService.getRetryingTransactionHelper().doInTransaction(readOnlyCallback, false, true); + } + + public void test_WCM_949() throws Exception + { + try + { + fService.createStore("StagingArea"); + fService.createStore("SandBox"); + + fService.createDirectory("StagingArea:/", "www"); + fService.createLayeredDirectory("StagingArea:/www", "SandBox:/", "www"); + + fService.createDirectory("SandBox:/www", "TestFolder"); + fService.createFile("SandBox:/www/TestFolder", "test1").close(); + + List diffs = fSyncService.compare(-1, "SandBox:/www", -1, "StagingArea:/www", null); + assertEquals(1, diffs.size()); + assertEquals("[SandBox:/www/TestFolder[-1] > StagingArea:/www/TestFolder[-1]]", diffs.toString()); + fSyncService.update(diffs, null, true, true, false, false, "one", "one"); + fSyncService.flatten("SandBox:/www", "StagingArea:/www"); + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("StagingArea"); + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + ResultSet results = searchService.query(storeRef, "lucene", "@cm\\:name:test1"); + assertEquals(1, results.length()); + results.close(); + + fService.removeNode("SandBox:/www/TestFolder"); + + diffs = fSyncService.compare(-1, "SandBox:/www", -1, "StagingArea:/www", null); + assertEquals(1, diffs.size()); + assertEquals("[SandBox:/www/TestFolder[-1] > StagingArea:/www/TestFolder[-1]]", diffs.toString()); + fSyncService.update(diffs, null, true, true, false, false, "one", "one"); + fSyncService.flatten("SandBox:/www", "StagingArea:/www"); + + results = searchService.query(storeRef, "lucene", "@cm\\:name:test1"); + assertEquals(0, results.length()); + results.close(); + + fService.createDirectory("SandBox:/www", "TestFolder"); + fService.createFile("SandBox:/www/TestFolder", "test1").close(); + + diffs = fSyncService.compare(-1, "SandBox:/www", -1, "StagingArea:/www", null); + assertEquals(1, diffs.size()); + assertEquals("[SandBox:/www/TestFolder[-1] > StagingArea:/www/TestFolder[-1]]", diffs.toString()); + fSyncService.update(diffs, null, true, true, false, false, "one", "one"); + fSyncService.flatten("SandBox:/www", "StagingArea:/www"); + + results = searchService.query(storeRef, "lucene", "@cm\\:name:test1"); + assertEquals(1, results.length()); + results.close(); + } + finally + { + fService.purgeStore("StagingArea"); + fService.purgeStore("SandBox"); + } + + } + + public void testPathEncoding() throws Throwable + { + try + { + setupBasicTree(); + fService.createFile("main:/", "2007").close(); + fService.createFile("main:/", "meep meep").close(); + fService.createDirectory("main:/", "my space"); + fService.createFile("main:/my space", "my file"); + fService.createDirectory("main:/", "2001"); + fService.createFile("main:/2001", "2002"); + fService.createSnapshot("main", null, null); + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + ResultSet results = searchService.query(storeRef, "lucene", "PATH:\"/meep_x0020_meep\""); + assertEquals(1, results.length()); + System.out.println(results.getNodeRef(0)); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/_x0032_007\""); + assertEquals(1, results.length()); + System.out.println(results.getNodeRef(0)); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/my_x0020_space/my_x0020_file\""); + assertEquals(1, results.length()); + System.out.println(results.getNodeRef(0)); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/_x0032_001/_x0032_002\""); + assertEquals(1, results.length()); + System.out.println(results.getNodeRef(0)); + results.close(); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + } + + public void testSpacesInStoreNames() throws Exception + { + try + { + fService.createStore("I have spaces"); + fService.createFile("I have spaces:/", "in my name.txt").close(); + assertNotNull(fService.lookup(-1, "I have spaces:/in my name.txt")); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + finally + { + fService.purgeStore("I have spaces"); + } + } + + public void testHeadPathsInLayers() throws Exception + { + try + { + setupBasicTree(); + fService.createStore("user"); + fService.createLayeredDirectory("main:/a", "user:/", "a"); + fService.createStore("sandbox"); + fService.createLayeredDirectory("main:/a", "sandbox:/", "a"); + fService.createDirectory("user:/a/b", "newdir"); + fService.createFile("user:/a/b/newdir", "bibble.txt").close(); + List diffs = fSyncService.compare(-1, "user:/a", -1, "sandbox:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[user:/a/b/newdir[-1] > sandbox:/a/b/newdir[-1]]", diffs.toString()); + fSyncService.update(diffs, null, false, false, false, false, null, null); + AVMNodeDescriptor dir = fService.lookup(-1, "user:/a/b/newdir"); + List> paths = fService.getHeadPaths(dir); + System.out.println(paths); + AVMNodeDescriptor file = fService.lookup(-1, "user:/a/b/newdir/bibble.txt"); + paths = fService.getHeadPaths(file); + System.out.println(paths); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + finally + { + fService.purgeStore("user"); + fService.purgeStore("sandbox"); + } + } + + + /** + * Test version by date lookup. + */ + public void testVersionByDate() throws Exception + { + try + { + ArrayList times = new ArrayList(); + BulkLoader loader = new BulkLoader(); + loader.setAvmService(fService); + loader.recursiveLoad("source/java/org/alfresco/repo/avm", "main:/"); + times.add(System.currentTimeMillis()); + assertEquals(1, fService.createSnapshot("main", null, null).get("main").intValue()); + loader.recursiveLoad("source/java/org/alfresco/repo/action", "main:/"); + times.add(System.currentTimeMillis()); + assertEquals(2, fService.createSnapshot("main", null, null).get("main").intValue()); + loader.recursiveLoad("source/java/org/alfresco/repo/audit", "main:/"); + times.add(System.currentTimeMillis()); + assertEquals(3, fService.createSnapshot("main", null, null).get("main").intValue()); + assertEquals(1, fService.getStoreVersions("main", null, new Date(times.get(0))).size()); + assertEquals(3, fService.getStoreVersions("main", new Date(times.get(0)), null).size()); + assertEquals(2, fService.getStoreVersions("main", new Date(times.get(1)), new Date(System.currentTimeMillis())).size()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test (node) properties. + */ + public void testProperties() throws Exception + { + try + { + setupBasicTree(); + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + ResultSet results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}SillyProperty") + ":\"Silly\""); + assertEquals(0, results.length()); + results.close(); + + QName name = QName.createQName("silly.uri", "SillyProperty"); + PropertyValue value = new PropertyValue(DataTypeDefinition.TEXT, "Silly Property Value"); + fService.setNodeProperty("main:/a/b/c/foo", name, value); + fService.createSnapshot("main", null, null); + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}SillyProperty") + ":\"Silly\""); + assertEquals(1, results.length()); + results.close(); + PropertyValue returned = fService.getNodeProperty(-1, "main:/a/b/c/foo", name); + assertEquals(value.toString(), returned.toString()); + Map props = fService.getNodeProperties(-1, "main:/a/b/c/foo"); + assertEquals(1, props.size()); + assertEquals(value.toString(), props.get(name).toString()); + + props = new HashMap(); + QName n1 = QName.createQName("silly.uri", "Prop1"); + PropertyValue p1 = new PropertyValue(DataTypeDefinition.DATETIME, new Date(System.currentTimeMillis())); + props.put(n1, p1); + QName n2 = QName.createQName("silly.uri", "Prop2"); + PropertyValue p2 = new PropertyValue(DataTypeDefinition.TEXT, "A String Property."); + props.put(n2, p2); + QName n3 = QName.createQName("silly.uri", "Prop3"); + PropertyValue p3 = new PropertyValue(DataTypeDefinition.INT, 42); + props.put(n3, p3); + QName n4 = QName.createQName("silly.uri", "Prop4"); + PropertyValue p4 = new PropertyValue(null, new Boolean(false)); + props.put(n4, p4); + QName n5 = QName.createQName("silly.uri", "Prop5"); + List strList = new ArrayList(2); + strList.add("hello"); + strList.add("world"); + PropertyValue p5 = new PropertyValue(DataTypeDefinition.TEXT, (Serializable)strList); + props.put(n5, p5); + fService.setNodeProperties("main:/a/b/c/bar", props); + fService.createSnapshot("main", null, null); + props = fService.getNodeProperties(-1, "main:/a/b/c/bar"); + assertEquals(5, props.size()); + assertEquals(p1.toString(), props.get(n1).toString()); + assertEquals(p2.toString(), props.get(n2).toString()); + assertEquals(p3.toString(), props.get(n3).toString()); + assertEquals(p4.toString(), props.get(n4).toString()); + assertEquals(p5.toString(), props.get(n5).toString()); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1") + ":\"" + props.get(n1).getStringValue() + "\""); + assertEquals(1, results.length()); + results.close(); + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2") + ":\"" + props.get(n2).getStringValue() + "\""); + assertEquals(1, results.length()); + results.close(); + + props = new HashMap(); + n1 = QName.createQName("silly.uri", "Prop1"); + p1 = new PropertyValue(DataTypeDefinition.DATETIME, new Date(System.currentTimeMillis())); + props.put(n1, p1); + n2 = QName.createQName("silly.uri", "Prop2"); + p2 = new PropertyValue(DataTypeDefinition.TEXT, "A String Property - updated."); + props.put(n2, p2); + n3 = QName.createQName("silly.uri", "Prop3"); + p3 = new PropertyValue(DataTypeDefinition.INT, -42); + props.put(n3, p3); + n4 = QName.createQName("silly.uri", "Prop4"); + p4 = new PropertyValue(null, new Boolean(true)); + props.put(n4, p4); + n5 = QName.createQName("silly.uri", "Prop5"); + strList = new ArrayList(2); + strList.add("goodbye"); + strList.add("world"); + p5 = new PropertyValue(DataTypeDefinition.TEXT, (Serializable)strList); + props.put(n5, p5); + fService.setNodeProperties("main:/a/b/c/bar", props); + fService.createSnapshot("main", null, null); + props = fService.getNodeProperties(-1, "main:/a/b/c/bar"); + assertEquals(5, props.size()); + assertEquals(p1.toString(), props.get(n1).toString()); + assertEquals(p2.toString(), props.get(n2).toString()); + assertEquals(p3.toString(), props.get(n3).toString()); + assertEquals(p4.toString(), props.get(n4).toString()); + assertEquals(p5.toString(), props.get(n5).toString()); + + fService.deleteNodeProperty("main:/a/b/c/bar", n1); + fService.createSnapshot("main", null, null); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1") + ":\"" + props.get(n1).getStringValue() + "\""); + assertEquals(0, results.length()); + results.close(); + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2") + ":\"" + props.get(n2).getStringValue() + "\""); + assertEquals(1, results.length()); + results.close(); + + props = fService.getNodeProperties(-1, "main:/a/b/c/bar"); + assertEquals(4, props.size()); + assertEquals(p2.toString(), props.get(n2).toString()); + assertEquals(p3.toString(), props.get(n3).toString()); + assertEquals(p4.toString(), props.get(n4).toString()); + assertEquals(p5.toString(), props.get(n5).toString()); + fService.deleteNodeProperties("main:/a/b/c/bar"); + fService.createSnapshot("main", null, null); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1") + ":\"" + p1.getStringValue() + "\""); + assertEquals(0, results.length()); + results.close(); + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2") + ":\"" + props.get(n2).getStringValue() + "\""); + assertEquals(0, results.length()); + results.close(); + + props = fService.getNodeProperties(-1, "main:/a/b/c/bar"); + assertEquals(0, props.size()); + + fService.removeNode("main:/a/b/c/foo"); + assertEquals(1, fService.getNodeProperties(-1, "main:/a/b/c/foo").size()); + fService.setNodeProperty("main:/a/b/c/foo", QName.createQName("silly.uri", "Prop1"), new PropertyValue(null, 42)); + assertEquals(2, fService.getNodeProperties(-1, "main:/a/b/c/foo").size()); + + fService.createSnapshot("main", null, null); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop1") + ":\"" + p1.getStringValue() + "\""); + assertEquals(0, results.length()); + results.close(); + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@{silly.uri}Prop2") + ":\"" + p2.getStringValue() + "\""); + assertEquals(0, results.length()); + results.close(); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test getStoreVersionRootPaths(). + */ + public void testGetStoreVersionRootPaths() throws Exception + { + try + { + setupBasicTree(); + AVMNodeDescriptor desc = fService.lookup(-1, "main:/a/b/c/foo"); + List paths = fService.getPathsInStoreVersion(desc, "main", 1); + assertEquals(1, paths.size()); + assertEquals("main:/a/b/c/foo", paths.get(0)); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + fService.createSnapshot("main", null, null); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + fService.createSnapshot("main", null, null); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + fService.createSnapshot("main", null, null); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + fService.createSnapshot("main", null, null); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + fService.createSnapshot("main", null, null); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + fService.createSnapshot("main", null, null); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + fService.createSnapshot("main", null, null); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + fService.createSnapshot("main", null, null); + paths = fService.getPathsInStoreVersion(desc, "main", 1); + assertEquals(1, paths.size()); + assertEquals("main:/a/b/c/foo", paths.get(0)); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + } + + public void testForceCopyDeleted() throws Exception + { + try + { + setupBasicTree(); + fService.removeNode("main:/a/b/c/foo"); + fService.createSnapshot("main", null, null); + AVMNodeDescriptor desc = fService.forceCopy("main:/a/b/c/foo"); + assertTrue(desc.isDeleted()); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + } + + public void testLayerSnapshots() throws Exception + { + try + { + // Layers are not yet indexed + setupBasicTree(); + assertEquals(1, fService.createSnapshot("main", null, null).get("main").intValue()); + runQueriesAgainstBasicTree("main"); + fService.createStore("layer"); + fService.createLayeredDirectory("main:/a", "layer:/", "a"); + fService.createSnapshot("layer", null, null); + runQueriesAgainstBasicTree("main"); + fService.createFile("main:/a", "Xander"); + fService.createSnapshot("layer", null, null); + + assertEquals(2, fService.lookup(2, "layer:/a").getIndirectionVersion()); + Map listing =fService.getDirectoryListing(2, "layer:/"); + assertEquals(1, listing.size()); + assertEquals(2, listing.values().iterator().next().getIndirectionVersion()); + assertEquals(fService.lookup(2, "main:/a/Xander").getId(), fService.lookup(2, "layer:/a/Xander").getId()); + + assertNull(fService.lookup(1, "layer:/a/Xander")); + listing = fService.getDirectoryListing(1, "layer:/"); + assertEquals(1, listing.size()); + assertEquals(1, listing.values().iterator().next().getIndirectionVersion()); + + assertEquals(-1, fService.lookup(-1, "layer:/a").getIndirectionVersion()); + listing = fService.getDirectoryListing(-1, "layer:/"); + assertEquals(1, listing.size()); + assertEquals(-1, listing.values().iterator().next().getIndirectionVersion()); + assertEquals(fService.lookup(-1, "main:/a/Xander").getId(), fService.lookup(-1, "layer:/a/Xander").getId()); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + finally + { + fService.purgeStore("layer"); + } + } + + public void testBranchLayerSnapshot() throws Exception + { + try + { + // layers are not yet indexed + setupBasicTree(); + fService.createStore("layer"); + fService.createDirectory("layer:/", "root"); + fService.createLayeredDirectory("main:/a", "layer:/root", "layer"); + fService.createSnapshot("layer", null, null); + fService.createFile("main:/a", "dummy").close(); + fService.createFile("layer:/root/layer", "pygmy"); + fService.createSnapshot("layer", null, null); + fService.createStore("branch"); + fService.createBranch(1, "layer:/root", "branch:/", "branch"); + fService.createSnapshot("branch", null, null); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + System.out.println("main 1"); + System.out.println(recursiveList("main", 1, true)); + System.out.println("branch 1"); + System.out.println(recursiveList("branch", 1, true)); + assertEquals(fService.lookup(1, "main:/a/b/c/foo").getId(), fService.lookup(1, "branch:/branch/layer/b/c/foo").getId()); + System.out.println("main -1"); + System.out.println(recursiveList("main", -1, true)); + System.out.println("branch -1"); + System.out.println(recursiveList("branch", -1, true)); + assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getId(), fService.lookup(-1, "branch:/branch/layer/b/c/foo").getId()); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + finally + { + fService.purgeStore("layer"); + fService.purgeStore("branch"); + } + } + + /** + * Test Deployment. + */ +/* + public void testDeployment() throws Exception + { + try + { + final DeploymentService depService = (DeploymentService) fContext.getBean("DeploymentService"); + NameMatcher matcher = (NameMatcher) fContext.getBean("globalPathExcluder"); + setupBasicTree(); + fService.addAspect("main:/a", ContentModel.ASPECT_REFERENCEABLE); + fService.addAspect("main:/a/b", ContentModel.ASPECT_REFERENCEABLE); + fService.addAspect("main:/a/b/c", ContentModel.ASPECT_REFERENCEABLE); + fService.addAspect("main:/a/b/c/foo", ContentModel.ASPECT_REFERENCEABLE); + fService.addAspect("main:/a/b/c/bar", ContentModel.ASPECT_REFERENCEABLE); + fService.createFile("main:/a/b", "snarl.bak").close(); + // TestDeploymentCallback callback = new TestDeploymentCallback(); + fService.createStore("target"); + DeploymentReport report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, false, null); + assertNull(fService.lookup(-1, "target:/a/b/snarl.bak")); + runQueriesAgainstBasicTreeWithAOnly("target"); + System.out.println(report); + ActionService actionService = depService.getRemoteActionService("localhost", 50500, "admin", "admin"); + Map params = new HashMap(); + params.put("property", ContentModel.PROP_ADDRESSEE); + params.put("value", "Santa Claus"); + assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getGuid(), fService.lookup(-1, "target:/a/b/c/foo").getGuid()); + assertEquals(fService.lookup(-1, "main:/a/b/c/bar").getGuid(), fService.lookup(-1, "target:/a/b/c/bar").getGuid()); + NodeRef nodeRef = AVMNodeConverter.ToNodeRef(-1, "target:/a/b/c/foo"); + Action action = new ActionImpl(nodeRef, "set-property-value", "set-property-value", params); + actionService.executeAction(action, nodeRef, false, false); + assertEquals("Santa Claus", fService.getNodeProperty(-1, "target:/a/b/c/foo", ContentModel.PROP_ADDRESSEE).getStringValue()); + ContentData srcCD = fService.getContentDataForRead(-1, "main:/a/b/c/bar"); + ContentData dstCD = fService.getContentDataForRead(-1, "target:/a/b/c/bar"); + assertEquals(srcCD.getMimetype(), dstCD.getMimetype()); + fService.createFile("main:/a/b", "biz").close(); + report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, true, null); + // Nothing was done + runQueriesAgainstBasicTreeWithAOnly("target"); + System.out.println(report); + System.out.println(recursiveList("target", -1, true)); + assertNull(fService.lookup(-1, "target:/a/b/biz")); + report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, false, null); + System.out.println(report); + runQueriesForCreateAndDeploy("target"); + assertEquals(fService.lookup(-1, "main:/a/b/biz").getGuid(), fService.lookup(-1, "target:/a/b/biz").getGuid()); + fService.removeNode("main:/a/b/c/foo"); + fService.createFile("main:/a/b/c", "Foo").close(); + ContentWriter writer = fService.getContentWriter("main:/a/b/c/Foo"); + writer.setEncoding("UTF-8"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.putContent("I am main:/a/b/c/foo"); + report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, false, null); + System.out.println(report); + assertEquals(DeploymentEvent.Type.UPDATED, report.iterator().next().getType()); + fService.removeNode("main:/a/b/c/foo"); + report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, true, false, null); + runQueriesForCreateAndDeploy("target"); + System.out.println(report); + assertNotNull(fService.lookup(-1, "target:/a/b/c/foo")); + report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, false, null); + System.out.println(report); + runQueriesForRemoveAndDelpoy("target"); + assertNull(fService.lookup(-1, "target:/a/b/c/foo")); + fService.removeNode("main:/a/b/c/bar"); + fService.createDirectory("main:/a/b/c", "bar"); + report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, false, null); + System.out.println(report); + runQueriesForRemoveFileAndCreateDirectoryAndDeploy("target"); + report = depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target:/a", matcher, false, false, false, null); + depService.deployDifference(-1, "main:/a", "localhost", 50500, "admin", "admin", "target2:/wiggly/diggly", matcher, true, false, false, null); + System.out.println(report); + fService.createStore("source"); + RetryingTransactionHelper.RetryingTransactionCallback cb = new RetryingTransactionHelper.RetryingTransactionCallback() + { + public Object execute() throws Exception + { + BulkLoader loader = new BulkLoader(); + loader.setAvmService(fService); + loader.recursiveLoad("source/java/org/alfresco/repo/avm", "source:/"); + return null; + } + }; + RetryingTransactionHelper helper = (RetryingTransactionHelper) fContext.getBean("retryingTransactionHelper"); + helper.doInTransaction(cb); + fService.createStore("dest"); + depService.deployDifference(-1, "source:/avm", "localhost", 50500, "admin", "admin", "dest:/avm", null, true, false, false, null); + Runnable runner = new Runnable() + { + public void run() + { + depService.deployDifference(-1, "source:/avm", "localhost", 50500, "admin", "admin", "dest:/avm", null, true, false, false, null); + } + }; + Thread thread = new Thread(runner); + thread.start(); + thread.join(); + report = depService.deployDifference(-1, "source:/avm", "localhost", 50500, "admin", "admin", "dest:/avm", null, true, false, false, null); + System.out.println(report); + assertEquals("", report.toString()); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + } +*/ + protected void runQueriesForCreateAndDeploy(String store) throws Exception + { + StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); + + // Text index + SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef(store), true); + ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); + assertEquals(2, results.length()); + results.close(); + + // Basic properties + + // Note "a" is a stop word and therefore not findable ... + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":biz"); + assertEquals(1, results.length()); + results.close(); + + // TODO: Fix auth in AVMDiskDriver and more?? + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); + assertEquals(7, results.length()); + results.close(); + + // Basic paths + + results = searchService.query(storeRef, "lucene", "PATH:\"/\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/biz\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); + assertEquals(0, results.length()); + results.close(); + } + + protected void runQueriesForRemoveAndDelpoy(String store) + { + StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); + + // Text index + SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef(store), true); + ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); + assertEquals(1, results.length()); + results.close(); + + // Basic properties + + // Note "a" is a stop word and therefore not findable ... + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":biz"); + assertEquals(1, results.length()); + results.close(); + + // TODO: Fix auth in AVMDiskDriver and more?? + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); + assertEquals(6, results.length()); + results.close(); + + // Basic paths + + results = searchService.query(storeRef, "lucene", "PATH:\"/\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/biz\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); + assertEquals(4, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); + assertEquals(0, results.length()); + results.close(); + } + + protected void runQueriesForRemoveFileAndCreateDirectoryAndDeploy(String store) + { + StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); + + // Text index + SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef(store), true); + ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); + assertEquals(0, results.length()); + results.close(); + + // Basic properties + + // Note "a" is a stop word and therefore not findable ... + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"bar\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":biz"); + assertEquals(1, results.length()); + results.close(); + + // TODO: Fix auth in AVMDiskDriver and more?? + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); + assertEquals(6, results.length()); + results.close(); + + // Basic paths + + results = searchService.query(storeRef, "lucene", "PATH:\"/\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/biz\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); + assertEquals(4, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); + assertEquals(0, results.length()); + results.close(); + } + + /** + * Test of GUIDs on AVM Nodes. + */ + public void testGuids() throws Exception + { + try + { + setupBasicTree(); + System.out.println(fService.lookup(-1, "main:/a/b/c/foo").getGuid()); + String guid = GUID.generate(); + fService.setGuid("main:/a/b/c/foo", guid); + assertEquals(guid, fService.lookup(-1, "main:/a/b/c/foo").getGuid()); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + } + + /** + * Test the revert to version action. + */ + public void testRevertToVersionAction() throws Exception + { + try + { + setupBasicTree(); + + ContentWriter writer = fService.getContentWriter("main:/a/b/c/foo"); + writer.setEncoding("UTF-8"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.putContent("I am main:/a/b/c/foo V1"); + fService.createSnapshot("main", "v1", null); + + writer = fService.getContentWriter("main:/a/b/c/foo"); + writer.setEncoding("UTF-8"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.putContent("I am main:/a/b/c/foo V2"); + fService.createSnapshot("main", "v2", null); + + writer = fService.getContentWriter("main:/a/b/c/foo"); + writer.setEncoding("UTF-8"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.putContent("I am main:/a/b/c/foo V3"); + fService.createSnapshot("main", "v3", null); + + writer = fService.getContentWriter("main:/a/b/c/foo"); + writer.setEncoding("UTF-8"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.putContent("I am main:/a/b/c/foo V4"); + fService.createSnapshot("main", "v4", null); + + writer = fService.getContentWriter("main:/a/b/c/foo"); + writer.setEncoding("UTF-8"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.putContent("I am main:/a/b/c/foo V5"); + fService.createSnapshot("main", "v5", null); + + writer = fService.getContentWriter("main:/a/b/c/foo"); + writer.setEncoding("UTF-8"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.putContent("I am main:/a/b/c/foo HEAD"); + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + + ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"HEAD\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "TEXT:\"V5\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "TEXT:\"V2\""); + assertEquals(0, results.length()); + results.close(); + + AVMNodeDescriptor desc = fService.lookup(-1, "main:/a/b/c/foo"); + List history = fService.getHistory(desc, 100); + AVMNodeDescriptor toRevert = history.get(3); + + final ActionImpl action = new ActionImpl(null, GUID.generate(), AVMRevertToVersionAction.NAME); + action.setParameterValue(AVMRevertToVersionAction.TOREVERT, toRevert); + final AVMRevertToVersionAction revert = (AVMRevertToVersionAction) fContext.getBean("avm-revert-to-version"); + class TxnWork implements RetryingTransactionCallback + { + public Object execute() throws Exception + { + // note: including implicit snapshot + revert.execute(action, AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/foo")); + return null; + } + }; + + TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); + transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); + + results = searchService.query(storeRef, "lucene", "TEXT:\"HEAD\""); + assertEquals(0, results.length()); + results.close(); + results = searchService.query(storeRef, "lucene", "TEXT:\"V5\""); + assertEquals(0, results.length()); + results.close(); + results = searchService.query(storeRef, "lucene", "TEXT:\"V2\""); + assertEquals(1, results.length()); + results.close(); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + } + + /** + * Test version numbering. + */ + public void testVersionNumbering() throws Exception + { + try + { + setupBasicTree(); + AVMNodeDescriptor desc = fService.lookup(-1, "main:/a/b/c/foo"); + assertEquals(1, desc.getVersionID()); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + desc = fService.lookup(-1, "main:/a/b/c/foo"); + assertEquals(2, desc.getVersionID()); + desc = fService.lookup(-1, "main:/a/b"); + assertEquals(2, desc.getVersionID()); + fService.createSnapshot("main", null, null); + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + fService.getFileOutputStream("main:/layer/b/c/bar").close(); + desc = fService.lookup(-1, "main:/layer/b/c/bar"); + assertEquals(2, desc.getVersionID()); + desc = fService.lookup(-1, "main:/layer/b/c"); + assertEquals(3, desc.getVersionID()); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + } + + /** + * Test relinking of nodes to history. + */ + public void testHistoryRelink() throws Exception + { + try + { + setupBasicTree(); + fService.createStore("branch"); + fService.createBranch(-1, "main:/a", "branch:/", "a"); + fService.removeNode("branch:/a/b/c/foo"); + List diffs = fSyncService.compare(-1, "branch:/a", -1, "main:/a", null); + assertEquals(1, diffs.size()); + assertEquals(AVMDifference.NEWER, diffs.get(0).getDifferenceCode()); + assertEquals("[branch:/a/b/c/foo[-1] > main:/a/b/c/foo[-1]]", diffs.toString()); + fService.createFile("branch:/a/b/c", "foo").close(); + diffs = fSyncService.compare(-1, "branch:/a", -1, "main:/a", null); + assertEquals(1, diffs.size()); + assertEquals(AVMDifference.NEWER, diffs.get(0).getDifferenceCode()); + assertEquals("[branch:/a/b/c/foo[-1] > main:/a/b/c/foo[-1]]", diffs.toString()); + fSyncService.update(diffs, null, false, false, false, false, null, null); + fService.removeNode("branch:/a/b/c/bar"); + fService.createFile("branch:/a/b/c", "pismo").close(); + fService.rename("branch:/a/b/c", "pismo", "branch:/a/b/c", "bar"); + diffs = fSyncService.compare(-1, "branch:/a", -1, "main:/a", null); + assertEquals(1, diffs.size()); + assertEquals(AVMDifference.NEWER, diffs.get(0).getDifferenceCode()); + assertEquals("[branch:/a/b/c/bar[-1] > main:/a/b/c/bar[-1]]", diffs.toString()); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + finally + { + fService.purgeStore("branch"); + } + } + + /** + * Test renaming a store. + */ + public void testRenameStore() throws Exception + { + try + { + setupBasicTree(); + assertNotNull(fService.lookup(-1, "main:/a/b")); + fService.renameStore("main", "foo"); + assertNotNull(fService.getStore("foo")); + assertNotNull(fService.lookup(-1, "foo:/a/b")); + runQueriesAgainstBasicTree("foo"); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + finally + { + fService.purgeStore("foo"); + } + } + + /** + * Test copy. + */ + public void testCopy() throws Exception + { + try + { + setupBasicTree(); + // Copy a file. + fService.copy(-1, "main:/a/b/c/foo", "main:/d", "fooCopy"); + AVMNodeDescriptor desc = fService.lookup(-1, "main:/d/fooCopy"); + assertTrue(desc.isFile()); + fService.createSnapshot("main", null, null); + runQueriesAgainstBasicTreePlusFileCopy("main"); + + // Copy a whole tree + fService.copy(-1, "main:/a", "main:/d/e", "aCopy"); + desc = fService.lookup(-1, "main:/d/e/aCopy"); + assertTrue(desc.isDirectory()); + desc = fService.lookup(-1, "main:/a/b/c/bar"); + AVMNodeDescriptor desc2 = fService.lookup(-1, "main:/d/e/aCopy/b/c/bar"); + assertTrue(desc2.isFile()); + assertEquals(desc.getLength(), desc2.getLength()); + fService.createSnapshot("main", null, null); + runQueriesAgainstBasicTreePlusFileCopyAndDirectoryCopy("main"); + + // Check that it rejects infinite copies. + try + { + fService.copy(-1, "main:/", "main://d/e", "illegal"); + fail(); + } + catch (AVMException ae) + { + // This is a success. + } + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + ResultSet results = searchService.query(storeRef, "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_NAME.toString()) + ":\"guest\""); + assertEquals(0, results.length()); + results.close(); + + CrossRepositoryCopyService copyService = (CrossRepositoryCopyService) fContext.getBean("CrossRepositoryCopyService"); + RepoRemote remoteService = (RepoRemote) fContext.getBean("RepoRemoteService"); + Pair toCopy = remoteService.lookup(remoteService.getRoot(), "Guest Home"); + copyService.copy(toCopy.getFirst(), AVMNodeConverter.ToNodeRef(-1, "main:/"), "Guest Home"); + desc = fService.lookup(-1, "main:/Guest Home"); + assertTrue(desc.isDirectory()); + System.out.println(this.recursiveList("main", -1, true)); + + fService.createSnapshot("main", null, null); + searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + results = searchService.query(storeRef, "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_NAME.toString()) + ":\"guest\""); + assertEquals(1, results.length()); + results.close(); + + StoreRef spacesStore = new StoreRef("workspace", "SpacesStore"); + + searchService = fIndexerAndSearcher.getSearcher(spacesStore, true); + results = searchService.query(spacesStore, "lucene", "PATH:\"//.\""); + int count = results.length(); + results.close(); + + copyService.copy(AVMNodeConverter.ToNodeRef(-1, "main:/a"), toCopy.getFirst(), "a"); + Pair theCopy = remoteService.lookup(toCopy.getFirst(), "a"); + assertTrue(theCopy.getSecond()); + + results = searchService.query(spacesStore, "lucene", "PATH:\"//.\""); + assertEquals(count + 5, results.length()); + results.close(); + + results = searchService.query(spacesStore, "lucene", "PATH:\"//.\""); + assertEquals(count + 5, results.length()); + results.close(); + + results = searchService.query(spacesStore, "lucene", "@cm\\:name:foo"); + assertEquals(1, results.length()); + results.close(); + + remoteService.removeNode(theCopy.getFirst()); + + results = searchService.query(spacesStore, "lucene", "PATH:\"//.\""); + assertEquals(count, results.length()); + results.close(); + + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + } + + protected void runQueriesAgainstBasicTreePlusFileCopy(String store) + { + StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); + + // Text index + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); + assertEquals(3, results.length()); + results.close(); + + // Basic properties + + // Note "a" is a stop word and therefore not findable ... + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"fooCopy\""); + assertEquals(1, results.length()); + results.close(); + + // TODO: Fix auth in AVMDiskDriver and more?? + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); + assertEquals(10, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); + assertEquals(10, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); + assertEquals(10, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); + assertEquals(10, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); + assertEquals(10, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); + assertEquals(10, results.length()); + results.close(); + + // Basic paths + + results = searchService.query(storeRef, "lucene", "PATH:\"/\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/fooCopy\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); + assertEquals(10, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); + assertEquals(9, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); + assertEquals(4, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); + assertEquals(3, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); + assertEquals(0, results.length()); + results.close(); + } + + protected void runQueriesAgainstBasicTreePlusFileCopyAndDirectoryCopy(String store) + { + StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); + + // Text index + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); + assertEquals(5, results.length()); + results.close(); + + // Basic properties + + // Note "a" is a stop word and therefore not findable ... + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"fooCopy\""); + assertEquals(1, results.length()); + results.close(); + + // TODO: Fix auth in AVMDiskDriver and more?? + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); + assertEquals(15, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); + assertEquals(15, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); + assertEquals(15, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); + assertEquals(15, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); + assertEquals(15, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); + assertEquals(15, results.length()); + results.close(); + + // Basic paths + + results = searchService.query(storeRef, "lucene", "PATH:\"/\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/fooCopy\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/aCopy\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/aCopy/b\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/aCopy/b/c\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/aCopy/b/c/foo\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/aCopy/b/c/bar\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); + assertEquals(15, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); + assertEquals(14, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); + assertEquals(4, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); + assertEquals(4, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); + assertEquals(3, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); + assertEquals(3, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); + assertEquals(3, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*/*/*\""); + assertEquals(0, results.length()); + results.close(); + } + + /** + * Test cyclic lookup behavior. + */ + public void testCyclicLookup() throws Exception + { + try + { + fService.createDirectory("main:/", "a"); + fService.createFile("main:/a", "foo").close(); + for (int i = 0; i < 1000; i++) + { + fService.lookup(-1, "main:/a/bar"); + } + fService.lookup(-1, "main:/a/foo"); + fService.createLayeredDirectory("main:/c", "main:/", "b"); + fService.createLayeredDirectory("main:/b", "main:/", "c"); + try + { + fService.lookup(-1, "main:/b/bar"); + fail(); + } + catch (AVMCycleException ce) + { + // Do nothing; this means success. + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test getting all paths for a node. + */ + public void testGetPaths() throws Exception + { + try + { + setupBasicTree(); + fService.createBranch(-1, "main:/a", "main:/", "abranch"); + fService.createSnapshot("main", null, null); + fService.createBranch(-1, "main:/a/b", "main:/", "bbranch"); + List> paths = fService.getPaths(fService.lookup(-1, "main:/a/b/c/foo")); + for (Pair path : paths) + { + System.out.println(path.getFirst() + " " + path.getSecond()); + } + paths = fService.getHeadPaths(fService.lookup(-1, "main:/a/b/c/foo")); + System.out.println("------------------------------"); + for (Pair path : paths) + { + System.out.println(path.getFirst() + " " + path.getSecond()); + } + paths = fService.getPathsInStoreHead(fService.lookup(-1, "main:/a/b/c/foo"), "main"); + System.out.println("------------------------------"); + for (Pair path : paths) + { + System.out.println(path.getFirst() + " " + path.getSecond()); + } + assertNotNull(fService.getAPath(fService.lookup(-1, "main:/a/b/c/foo"))); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test getIndirection. + */ + public void testGetIndirection() throws Exception + { + try + { + setupBasicTree(); + fService.createStore("layer"); + fService.createLayeredDirectory("main:/a", "layer:/", "layer"); + fService.createFile("layer:/layer/b", "figs").close(); + assertEquals("main:/a", fService.getIndirectionPath(-1, "layer:/layer")); + assertEquals("main:/a/b", fService.getIndirectionPath(-1, "layer:/layer/b")); + assertEquals("main:/a/b/c", fService.getIndirectionPath(-1, "layer:/layer/b/c")); + assertEquals("main:/a/b/c/foo", fService.getIndirectionPath(-1, "layer:/layer/b/c/foo")); + fService.createLayeredDirectory("main:/d", "layer:/layer/b", "dlayer"); + assertEquals("main:/d", fService.getIndirectionPath(-1, "layer:/layer/b/dlayer")); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + finally + { + fService.purgeStore("layer"); + } + } + + /** + * Test the revert list action. + * + * @deprecated + */ + public void testRevertListAction() throws Exception + { + try + { + setupBasicTree(); + fService.createStore("area"); + fService.createLayeredDirectory("main:/a", "area:/", "a"); + fService.getFileOutputStream("area:/a/b/c/foo").close(); + List diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[area:/a/b/c/foo[-1] > main:/a/b/c/foo[-1]]", diffs.toString()); + fSyncService.update(diffs, null, false, false, false, false, null, null); + fService.getFileOutputStream("area:/a/b/c/bar").close(); + diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[area:/a/b/c/bar[-1] > main:/a/b/c/bar[-1]]", diffs.toString()); + final ActionImpl action = new ActionImpl(null, GUID.generate(), AVMRevertListAction.NAME); + List paths = new ArrayList(); + paths.add("area:/a/b"); + action.setParameterValue(AVMRevertListAction.PARAM_VERSION, fService.getLatestSnapshotID("area")); + action.setParameterValue(AVMRevertListAction.PARAM_NODE_LIST, (Serializable) paths); + final AVMRevertListAction revert = (AVMRevertListAction) fContext.getBean("avm-revert-list"); + class TxnWork implements RetryingTransactionCallback + { + public Object execute() throws Exception + { + revert.execute(action, null); + return null; + } + } + ; + TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); + transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); + + diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); + assertEquals(0, diffs.size()); + System.out.println(recursiveList("area", -1, true)); + System.out.println(recursiveList("main", -1, true)); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + finally + { + fService.purgeStore("area"); + } + } + + /** + * Test the revert store action. + * + * @deprecated see org.alfresco.wcm.actions.WCMSandboxRevertSnapshotAction or org.alfresco.wcm.SandboxService.revertSnapshot + */ + public void testRevertStoreAction() throws Exception + { + try + { + setupBasicTree(); + + fService.createStore("area"); + fService.createLayeredDirectory("main:/a", "area:/", "a"); + + fService.getFileOutputStream("area:/a/b/c/foo").close(); + + List diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[area:/a/b/c/foo[-1] > main:/a/b/c/foo[-1]]", diffs.toString()); + + fSyncService.update(diffs, null, false, false, false, false, null, null); + + diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); + assertEquals(0, diffs.size()); + + fService.getFileOutputStream("area:/a/b/c/bar").close(); + + diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[area:/a/b/c/bar[-1] > main:/a/b/c/bar[-1]]", diffs.toString()); + + final ActionImpl action = new ActionImpl(null, GUID.generate(), AVMRevertStoreAction.NAME); + action.setParameterValue(AVMRevertStoreAction.PARAM_VERSION, fService.getLatestSnapshotID("area")); + + final AVMRevertStoreAction revert = (AVMRevertStoreAction)fContext.getBean("avm-revert-store"); + + class TxnWork implements RetryingTransactionCallback + { + public Object execute() throws Exception + { + revert.execute(action, AVMNodeConverter.ToNodeRef(-1, "area:/")); + return null; + } + }; + + TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); + transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); + + diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); + assertEquals(0, diffs.size()); + + System.out.println(recursiveList("area", -1, true)); + System.out.println(recursiveList("main", -1, true)); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + finally + { + fService.purgeStore("area"); + } + } + + /** + * Test the undo list action. + * + * @deprecated see org.alfresco.wcm.actions.WCMSandboxUndoAction or org.alfresco.wcm.SandboxService.revertList + */ + public void testUndoListAction() throws Exception + { + try + { + setupBasicTree(); + fService.createStore("area"); + fService.createLayeredDirectory("main:/a", "area:/", "a"); + fService.getFileOutputStream("area:/a/b/c/foo").close(); + List diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[area:/a/b/c/foo[-1] > main:/a/b/c/foo[-1]]", diffs.toString()); + fSyncService.update(diffs, null, false, false, false, false, null, null); + fService.getFileOutputStream("area:/a/b/c/bar").close(); + diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); + assertEquals(1, diffs.size()); + assertEquals("[area:/a/b/c/bar[-1] > main:/a/b/c/bar[-1]]", diffs.toString()); + final ActionImpl action = new ActionImpl(null, GUID.generate(), AVMUndoSandboxListAction.NAME); + List> versionPaths = new ArrayList>(); + versionPaths.add(new Pair(-1, "area:/a/b/c/bar")); + action.setParameterValue(AVMUndoSandboxListAction.PARAM_NODE_LIST, (Serializable) versionPaths); + final AVMUndoSandboxListAction revert = (AVMUndoSandboxListAction) fContext.getBean("avm-undo-list"); + class TxnWork implements RetryingTransactionCallback + { + public Object execute() throws Exception + { + revert.execute(action, null); + return null; + } + } + ; + TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); + transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); + + diffs = fSyncService.compare(-1, "area:/a", -1, "main:/a", null); + assertEquals(0, diffs.size()); + System.out.println(recursiveList("area", -1, true)); + System.out.println(recursiveList("main", -1, true)); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + finally + { + fService.purgeStore("area"); + } + } + + /** + * Test the promote action. + * + * @deprecated + */ + public void testPromoteAction() throws Exception + { + try + { + setupBasicTree(); + fService.createDirectory("main:/", JNDIConstants.DIR_DEFAULT_WWW); + fService.rename("main:/", "a", "main:/" + JNDIConstants.DIR_DEFAULT_WWW, "a"); + fService.rename("main:/", "d", "main:/" + JNDIConstants.DIR_DEFAULT_WWW, "d"); + fService.createSnapshot("main", null, null); + fService.createStore("source"); + fService.createLayeredDirectory("main:/" + JNDIConstants.DIR_DEFAULT_WWW, "source:/", JNDIConstants.DIR_DEFAULT_WWW); + fService.getFileOutputStream("source:/" + JNDIConstants.DIR_DEFAULT_WWW + "/a/b/c/foo").close(); + final ActionImpl action = new ActionImpl(AVMNodeConverter.ToNodeRef(-1, "source:/" + JNDIConstants.DIR_DEFAULT_WWW + "/a"), GUID.generate(), + SimpleAVMPromoteAction.NAME); + action.setParameterValue(SimpleAVMPromoteAction.PARAM_TARGET_STORE, "main"); + final SimpleAVMPromoteAction promote = (SimpleAVMPromoteAction) fContext.getBean("simple-avm-promote"); + class TxnWork implements RetryingTransactionCallback + { + public Object execute() throws Exception + { + promote.execute(action, AVMNodeConverter.ToNodeRef(-1, "source:/" + JNDIConstants.DIR_DEFAULT_WWW + "/a")); + return null; + } + } + ; + TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); + transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); + + assertEquals(0, fSyncService.compare(-1, "source:/" + JNDIConstants.DIR_DEFAULT_WWW, -1, "main:/" + JNDIConstants.DIR_DEFAULT_WWW, null).size()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + finally + { + fService.purgeStore("source"); + } + } + + /** + * Test the SimpleAVMSubmitAction. + * + * @deprecated see org.alfresco.wcm.actions.WCMSandboxSubmitAction or org.alfesco.wcm.SandboxService.submit + */ + public void testSubmitAction() throws Exception + { + // NOTE: it is implied that the sandboxes follow WCM naming conventions + final String STAGING = "foo"; + final String SANDBOX = "foo--sandbox"; + + try + { + fService.createStore(STAGING); + fService.createDirectory(STAGING+":/", JNDIConstants.DIR_DEFAULT_WWW); + fService.createDirectory(STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW, "a"); + fService.createDirectory(STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW + "/a", "b"); + fService.createDirectory(STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW + "/a/b", "c"); + fService.createFile(STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW + "/a/b/c", "foo").close(); + fService.createFile(STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW + "/a/b/c", "bar").close(); + + fService.createStore(SANDBOX); + fService.setStoreProperty(SANDBOX, SandboxConstants.PROP_WEBSITE_NAME, new PropertyValue(null, STAGING)); // note: it is implied that the website name is the same as staging name + fService.createLayeredDirectory(STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW, SANDBOX+":/", JNDIConstants.DIR_DEFAULT_WWW); + fService.createFile(SANDBOX+":/" + JNDIConstants.DIR_DEFAULT_WWW, "figs").close(); + fService.getFileOutputStream(SANDBOX+":/" + JNDIConstants.DIR_DEFAULT_WWW + "/a/b/c/foo").close(); + fService.removeNode(SANDBOX+":/" + JNDIConstants.DIR_DEFAULT_WWW + "/a/b/c/bar"); + + List diffs = fSyncService.compare(-1, SANDBOX+":/" + JNDIConstants.DIR_DEFAULT_WWW, -1, STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW, null); + assertEquals(3, diffs.size()); + assertEquals("["+SANDBOX+":/www/a/b/c/bar[-1] > "+STAGING+":/www/a/b/c/bar[-1], "+SANDBOX+":/www/a/b/c/foo[-1] > "+STAGING+":/www/a/b/c/foo[-1], "+SANDBOX+":/www/figs[-1] > "+STAGING+":/www/figs[-1]]", diffs.toString()); + + final SimpleAVMSubmitAction action = (SimpleAVMSubmitAction) fContext.getBean("simple-avm-submit"); + class TxnWork implements RetryingTransactionCallback + { + public Object execute() throws Exception + { + action.execute(null, AVMNodeConverter.ToNodeRef(-1, SANDBOX+":/" + JNDIConstants.DIR_DEFAULT_WWW)); + return null; + } + }; + + TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); + transactionService.getRetryingTransactionHelper().doInTransaction(new TxnWork()); + + diffs = fSyncService.compare(-1, SANDBOX+":/" + JNDIConstants.DIR_DEFAULT_WWW, -1, STAGING+":/" + JNDIConstants.DIR_DEFAULT_WWW, null); + + assertEquals(0, diffs.size()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + finally + { + fService.purgeStore(STAGING); + fService.purgeStore(SANDBOX); + } + } + + /** + * Test one argument remove. + */ + public void testOneArgRemove() throws Exception + { + try + { + setupBasicTree(); + fService.removeNode("main:/a/b/c/foo/"); + fService.removeNode("main://d"); + fService.createSnapshot("main", null, null); + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + + // Text index + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); + assertEquals(1, results.length()); + results.close(); + + // Basic properties + + // Note "a" is a stop word and therefore not findable ... + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); + assertEquals(0, results.length()); + results.close(); + + // TODO: Fix auth in AVMDiskDriver and more?? + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); + if (results.length() == 6) + { + for (ResultSetRow row : results) + { + System.out.println(row.getNodeRef()); + } + } + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + "main"); + assertEquals(5, results.length()); + results.close(); + + // Basic paths + + results = searchService.query(storeRef, "lucene", "PATH:\"/\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); + assertEquals(4, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); + assertEquals(4, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); + assertEquals(3, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); + assertEquals(0, results.length()); + results.close(); + + try + { + fService.removeNode("main://"); + fail(); + } + catch (AVMException e) + { + // Do nothing. + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + } + } + + /** + * Test that non head version sources are update correctly. + */ + public void testVersionUpdate() throws Exception + { + try + { + BulkLoader loader = new BulkLoader(); + loader.setAvmService(fService); + fService.createStore("source"); + fService.createStore("dest"); + loader.recursiveLoad("config/alfresco/bootstrap", "source:/"); + int version1 = fService.createSnapshot("source", null, null).get("source"); + loader.recursiveLoad("config/alfresco/extension", "source:/"); + int version2 = fService.createSnapshot("source", null, null).get("source"); + List diffs = fSyncService.compare(version1, "source:/", -1, "dest:/", null); + fService.createSnapshot("dest", null, null); + assertEquals(1, diffs.size()); + assertEquals("[source:/bootstrap[1] > dest:/bootstrap[-1]]", diffs.toString()); + fSyncService.update(diffs, null, false, false, false, false, null, null); + diffs = fSyncService.compare(version1, "source:/", -1, "dest:/", null); + assertEquals(0, diffs.size()); + diffs = fSyncService.compare(version2, "source:/", -1, "dest:/", null); + assertEquals(1, diffs.size()); + assertEquals("[source:/extension[2] > dest:/extension[-1]]", diffs.toString()); + fSyncService.update(diffs, null, false, false, false, false, null, null); + fService.createSnapshot("dest", null, null); + diffs = fSyncService.compare(version2, "source:/", -1, "dest:/", null); + assertEquals(0, diffs.size()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + finally + { + fService.purgeStore("source"); + fService.purgeStore("dest"); + } + } + + /** + * Test that branching forces a snapshot on the source repository. + */ + public void testBranchSnapshot() throws Exception + { + try + { + setupBasicTree(); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + fService.createBranch(-1, "main:/a", "main:/", "abranch"); + assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getId(), fService.lookup(-1, "main:/abranch/b/c/foo").getId()); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + assertTrue(fService.lookup(-1, "main:/a/b/c/foo").getId() != fService.lookup(-1, "main:/abranch/b/c/foo").getId()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test of Descriptor indirection field. + */ + public void testDescriptorIndirection() throws Exception + { + try + { + setupBasicTree(); + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createFile("main:/layer/b/c", "bambino").close(); + AVMNodeDescriptor desc = fService.lookup(-1, "main:/layer"); + assertEquals("main:/a", desc.getIndirection()); + Map list = fService.getDirectoryListing(-1, "main:/"); + assertEquals("main:/a", list.get("layer").getIndirection()); + desc = fService.lookup(-1, "main:/layer/b"); + assertEquals("main:/a/b", desc.getIndirection()); + list = fService.getDirectoryListing(-1, "main:/layer"); + assertEquals("main:/a/b", list.get("b").getIndirection()); + list = fService.getDirectoryListingDirect(-1, "main:/layer"); + assertEquals("main:/a/b", list.get("b").getIndirection()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test link AVMService call. + */ + public void testLink() throws Exception + { + try + { + setupBasicTree(); + // Just try linking /a/b/c/foo into /a/b + fService.link("main:/a/b", "foo", fService.lookup(-1, "main:/a/b/c/foo")); + assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getId(), fService.lookup(-1, "main:/a/b/foo").getId()); + // Try linking /a/b/c/bar to /a/b/foo. It should fail. + System.out.println(recursiveList("main", -1, true)); + try + { + fService.link("main:/a/b", "foo", fService.lookup(-1, "main:/a/b/c/bar")); + fail(); + } + catch (AVMExistsException e) + { + // Do nothing. It's OK. + } + // Delete /a/b/foo, and link /a/b/c/foo into /a/b. This checks that + // a deleted node is no impediment. + fService.removeNode("main:/a/b", "foo"); + fService.link("main:/a/b", "foo", fService.lookup(-1, "main:/a/b/c/foo")); + assertEquals(fService.lookup(-1, "main:/a/b/c/foo").getId(), fService.lookup(-1, "main:/a/b/foo").getId()); + // Delete /a/b/foo again in prep for layer tests. + fService.removeNode("main:/a/b", "foo"); + System.out.println(recursiveList("main", -1, true)); + fService.createSnapshot("main", null, null); + // Create a layer do a link from /layer/b/c/bar to /layer/b + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.link("main:/layer/b", "bar", fService.lookup(-1, "main:/layer/b/c/bar")); + assertEquals(fService.lookup(-1, "main:/layer/b/c/bar").getId(), fService.lookup(-1, "main:/layer/b/bar").getId()); + System.out.println(recursiveList("main", -1, true)); + // Now link /layer/b/c/foo into /layer/b. + fService.link("main:/layer/b", "foo", fService.lookup(-1, "main:/layer/b/c/foo")); + assertEquals(fService.lookup(-1, "main:/layer/b/c/foo").getId(), fService.lookup(-1, "main:/layer/b/foo").getId()); + // Make sure that the underlying layer is not mucked up. + assertTrue(fService.lookup(-1, "main:/a/b/foo", true).isDeleted()); + System.out.println(recursiveList("main", -1, true)); + // Try to link /layer/b/c/bar to /layer/b/c. It should fail. + try + { + fService.link("main:/layer/b", "bar", fService.lookup(-1, "main:/layer/b/c/bar")); + fail(); + } + catch (AVMExistsException e) + { + // Do nothing. + } + // Try to link /layer/b to /frinx. It should fail. + try + { + fService.link("main:/", "frinx", fService.lookup(-1, "main:/layer/b")); + fail(); + } + catch (AVMBadArgumentException ba) + { + // Do nothing. + } + // Delete /layer/b/bar and redo. It should work. + fService.removeNode("main:/layer/b", "bar"); + fService.link("main:/layer/b", "bar", fService.lookup(-1, "main:/layer/b/c/bar")); + assertEquals(fService.lookup(-1, "main:/layer/b/c/bar").getId(), fService.lookup(-1, "main:/layer/b/bar").getId()); + System.out.println(recursiveList("main", -1, true)); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test goofy paths. + */ + public void testGoofyPaths() throws Exception + { + try + { + setupBasicTree(); + fService.getFileInputStream(-1, "main://a/b/c/foo").close(); + fService.getDirectoryListing(-1, "main:/a/"); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test getting deleted names. + */ + public void testGetDeleted() throws Exception + { + try + { + setupBasicTree(); + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + List deleted = fService.getDeleted(-1, "main:/layer/b/c"); + assertEquals(0, deleted.size()); + fService.removeNode("main:/a/b/c", "foo"); + fService.createSnapshot("main", null, null); + deleted = fService.getDeleted(-1, "main:/a/b/c"); + assertEquals(0, deleted.size()); + fService.removeNode("main:/layer/b/c", "bar"); + fService.createSnapshot("main", null, null); + deleted = fService.getDeleted(-1, "main:/layer/b/c"); + assertEquals(1, deleted.size()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test directly contained listing. + */ + public void testListingDirect() throws Exception + { + try + { + setupBasicTree(); + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + Map listing = fService.getDirectoryListingDirect(-1, "main:/layer"); + assertEquals(0, listing.size()); + listing = fService.getDirectoryListingDirect(-1, "main:/layer/b"); + assertEquals(0, listing.size()); + fService.createFile("main:/layer/b/c", "sigmoid").close(); + fService.createSnapshot("main", null, null); + listing = fService.getDirectoryListingDirect(-1, "main:/layer"); + assertEquals(1, listing.size()); + fService.createFile("main:/layer", "lepton"); + fService.createSnapshot("main", null, null); + listing = fService.getDirectoryListingDirect(-1, "main:/layer"); + assertEquals(2, listing.size()); + listing = fService.getDirectoryListingDirect(-1, "main:/layer/b/c"); + assertEquals(1, listing.size()); + listing = fService.getDirectoryListingDirect(-1, "main:/a/b/c"); + assertEquals(2, listing.size()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test layering info. + */ + public void testLayeringInfo() throws Exception + { + try + { + setupBasicTree(); + fService.createStore("layer"); + fService.createLayeredDirectory("main:/a", "layer:/", "alayer"); + fService.createSnapshot("layer", null, null); + LayeringDescriptor info = fService.getLayeringInfo(-1, "layer:/alayer"); + assertFalse(info.isBackground()); + assertEquals("layer", info.getPathAVMStore().getName()); + assertEquals("layer", info.getNativeAVMStore().getName()); + info = fService.getLayeringInfo(-1, "layer:/alayer/b/c"); + assertTrue(info.isBackground()); + assertEquals("layer", info.getPathAVMStore().getName()); + assertEquals("main", info.getNativeAVMStore().getName()); + fService.createFile("layer:/alayer/b", "figs").close(); + fService.createSnapshot("layer", null, null); + info = fService.getLayeringInfo(-1, "layer:/alayer/b/figs"); + assertFalse(info.isBackground()); + assertEquals("layer", info.getPathAVMStore().getName()); + assertEquals("layer", info.getNativeAVMStore().getName()); + info = fService.getLayeringInfo(-1, "layer:/alayer/b/c"); + assertTrue(info.isBackground()); + assertEquals("layer", info.getPathAVMStore().getName()); + assertEquals("main", info.getNativeAVMStore().getName()); + fService.createLayeredDirectory("layer:/alayer/b", "layer:/", "blayer"); + fService.createSnapshot("layer", null, null); + System.err.println(recursiveList("main", -1, true)); + System.err.println(recursiveList("layer", -1, true)); + info = fService.getLayeringInfo(-1, "layer:/blayer/c"); + assertEquals("main", info.getNativeAVMStore().getName()); + info = fService.getLayeringInfo(-1, "layer:/blayer/figs"); + assertEquals("layer", info.getNativeAVMStore().getName()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + finally + { + fService.purgeStore("layer"); + } + } + + /** + * Another test of renaming in a layer. + */ + public void testRenameLayer2() throws Exception + { + try + { + TreeMap history = new TreeMap(); + // Set up a basic hierarchy. + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a", "c"); + fService.createFile("main:/a/b", "foo", new ByteArrayInputStream("I am foo.".getBytes())); + fService.createFile("main:/a/c", "bar", new ByteArrayInputStream("I am bar.".getBytes())); + fService.createSnapshot("main", null, null); + // History is unchanged. + checkHistory(history, "main"); + // Make a layer to a. + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // History is unchanged. + checkHistory(history, "main"); + // /a and /layer should have identical contents. + assertEquals(recursiveContents("main:/a", -1, true), recursiveContents("main:/layer", -1, true)); + // Now rename /layer/c/bar to /layer/b/bar + fService.rename("main:/layer/c", "bar", "main:/layer/b", "bar"); + fService.createSnapshot("main", null, null); + // History is unchanged. + checkHistory(history, "main"); + // /layer/c should be empty. + Map listing = fService.getDirectoryListing(-1, "main:/layer/c"); + assertEquals(0, listing.size()); + // /layer/b should contain fao and bar + listing = fService.getDirectoryListing(-1, "main:/layer/b"); + assertEquals(2, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("bar", list.get(0)); + assertEquals("foo", list.get(1)); + // /a/b should contain foo. + listing = fService.getDirectoryListing(-1, "main:/a/b"); + assertEquals(1, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("foo", list.get(0)); + // /a/c should contain bar. + listing = fService.getDirectoryListing(-1, "main:/a/c"); + assertEquals(1, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("bar", list.get(0)); + // Now make a file in /a/b + fService.createFile("main:/a/b", "baz").close(); + fService.createSnapshot("main", null, null); + // History is unchanged. + checkHistory(history, "main"); + // /a/b should contain baz and foo. + listing = fService.getDirectoryListing(-1, "main:/a/b"); + assertEquals(2, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("baz", list.get(0)); + assertEquals("foo", list.get(1)); + // /layer/b should contain foo, bar, and baz. + listing = fService.getDirectoryListing(-1, "main:/layer/b"); + System.out.println(recursiveList("main", -1, true)); + assertEquals(3, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("bar", list.get(0)); + assertEquals("baz", list.get(1)); + assertEquals("foo", list.get(2)); + // Remove baz from /layer/b + fService.removeNode("main:/layer/b", "baz"); + fService.createSnapshot("main", null, null); + // History is unchanged. + checkHistory(history, "main"); + System.out.println(recursiveList("main", -1, true)); + // /layer/b should have bar and foo. + listing = fService.getDirectoryListing(-1, "main:/layer/b"); + assertEquals(2, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("bar", list.get(0)); + assertEquals("foo", list.get(1)); + // /a/b should contain baz and foo as before. + listing = fService.getDirectoryListing(-1, "main:/a/b"); + assertEquals(2, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("baz", list.get(0)); + assertEquals("foo", list.get(1)); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Yet another test around rename in layers. + */ + public void testRenameLayer3() throws Exception + { + try + { + TreeMap history = new TreeMap(); + // Set up a handy hierarchy. + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createFile("main:/a/b", "foo").close(); + fService.createFile("main:/a/b", "bar").close(); + fService.createDirectory("main:/", "c"); + fService.createDirectory("main:/c", "d"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make a layer over /a + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Move /c/d to /layer + fService.rename("main:/c", "d", "main:/layer", "d"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Now make a file in /layer/d + fService.createFile("main:/layer/d", "baz").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make /a/d/figs and see the wackiness. + fService.createDirectory("main:/a", "d"); + fService.createFile("main:/a/d", "figs").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer/d should no contain baz and figs. + Map listing = fService.getDirectoryListing(-1, "main:/layer/d"); + assertEquals(2, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("baz", list.get(0)); + assertEquals("figs", list.get(1)); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test the uncover operation. + */ + public void testUncover() throws Exception + { + try + { + TreeMap history = new TreeMap(); + // Set up a handy hierarchy. + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a/", "b"); + fService.createFile("main:/a/b", "foo").close(); + fService.createFile("main:/a/b", "bar").close(); + fService.createDirectory("main:/", "c"); + fService.createDirectory("main:/c", "d"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make a layer over /a + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Move /c/d to /layer + fService.rename("main:/c", "d", "main:/layer", "d"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make a file in /layer/d + fService.createFile("main:/layer/d", "baz").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make /a/d/figs and see the wackiness. + fService.createDirectory("main:/a", "d"); + fService.createFile("main:/a/d", "figs").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer/d should now contain baz and figs. + Map listing = fService.getDirectoryListing(-1, "main:/layer/d"); + assertEquals(2, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("baz", list.get(0)); + assertEquals("figs", list.get(1)); + // Rename /layer/d to /layer/e and uncover /layer/d + System.out.println(recursiveContents("main:/", -1, true)); + fService.rename("main:/layer", "d", "main:/layer", "e"); + fService.uncover("main:/layer", "d"); + fService.createSnapshot("main", null, null); + System.out.println(recursiveContents("main:/", -1, true)); + // History unchanged. + checkHistory(history, "main"); + // /layer/d contains figs. + listing = fService.getDirectoryListing(-1, "main:/layer/d"); + assertEquals(1, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("figs", list.get(0)); + // /layer/e contains baz and figs. + listing = fService.getDirectoryListing(-1, "main:/layer/e"); + assertEquals(2, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("baz", list.get(0)); + assertEquals("figs", list.get(1)); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Another test of renaming in a layer. + */ + public void testRenameLayer4() throws Exception + { + try + { + TreeMap history = new TreeMap(); + // Set up a handy hierarchy. + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createFile("main:/a/b", "foo").close(); + fService.createFile("main:/a/b", "bar").close(); + fService.createDirectory("main:/", "c"); + fService.createDirectory("main:/c", "d"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make a layer over /a + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Move /layer/b to /b + fService.rename("main:/layer", "b", "main:/", "b"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Add something to /a/b and it should show up in /b. + fService.createFile("main:/a/b", "baz").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /b should have foo and bar and baz. + Map listing = fService.getDirectoryListing(-1, "main:/b"); + assertEquals(3, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("bar", list.get(0)); + assertEquals("baz", list.get(1)); + assertEquals("foo", list.get(2)); + // Add something to /a and it will show up in /layer. + fService.createFile("main:/a", "figs").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer should have figs in it. + listing = fService.getDirectoryListing(-1, "main:/layer"); + assertEquals(1, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("figs", list.get(0)); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test branching within branches. + */ + public void testBranchesInBranches() throws Exception + { + try + { + TreeMap history = new TreeMap(); + // Set up a hierarchy. + setupBasicTree(); + // History unchanged. + checkHistory(history, "main"); + // Make a branch from /a + fService.createBranch(-1, "main:/a", "main:/", "abranch"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make a branch in something that has been branched. + fService.createBranch(-1, "main:/a/b", "main:/a", "bbranch"); + fService.createSnapshot("main", null, null); + // History unchanged + checkHistory(history, "main"); + // Everything under /abranch should be identical in this version + // and the previous. + int version = fService.getNextVersionID("main"); + assertEquals(recursiveContents("main:/abranch", version - 1, true), recursiveContents("main:/abranch", version - 2, true)); + // Make a branch within a branch. + fService.createBranch(-1, "main:/abranch/b/c", "main:/abranch/b", "cbranch"); + fService.createSnapshot("main", null, null); + // History unchanged + checkHistory(history, "main"); + // Everything under /a should be unchanged between this version and the last. + version = fService.getNextVersionID("main"); + assertEquals(recursiveContents("main:/a", version - 1, true), recursiveContents("main:/a", version - 2, true)); + // Make a branch to something outside of a branch inside a branch. + fService.createBranch(-1, "main:/d", "main:/abranch", "dbranch"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make something ind /abranch/dbranch. + fService.createFile("main:/abranch/dbranch/e/f", "baz").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // d should not have changed since the previous version. + version = fService.getNextVersionID("main"); + assertEquals(recursiveContents("main:/d", version - 1, true), recursiveContents("main:/d", version - 2, true)); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test layers inside of layers. + */ + public void testLayersInLayers() throws Exception + { + try + { + TreeMap history = new TreeMap(); + setupBasicTree(); + // History unchanged. + checkHistory(history, "main"); + // Create a layer to /a + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make a layer inside of a layer pointing to d. + fService.createLayeredDirectory("main:/d", "main:/layer", "under"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Create a file in /layer/under/e/f. + fService.createFile("main:/layer/under/e/f", "baz").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Create a file in /d/e. + fService.createFile("main:/d/e", "bow").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer/under/e should contain bow and f. + Map listing = fService.getDirectoryListing(-1, "main:/layer/under/e"); + assertEquals(2, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("bow", list.get(0)); + assertEquals("f", list.get(1)); + // Put a new set of dirs in to be made into a layering under d. + fService.createDirectory("main:/", "g"); + fService.createDirectory("main:/g", "h"); + fService.createDirectory("main:/g/h", "i"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make a layer in /d to /g. + fService.createLayeredDirectory("main:/g", "main:/d", "gover"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /d/gover should be identical to /layer/under/gover + assertEquals(recursiveContents("main:/d/gover", -1, true), recursiveContents("main:/layer/under/gover", -1, true)); + // Create a file in /layer/under/gover/h/i + fService.createFile("main:/layer/under/gover/h/i", "moo").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /d should be unchanged before this version and the last + // and /g should be unchanged between this version and the last. + int version = fService.getNextVersionID("main"); + // TODO Need an equivalent test that won't mind the version number change + // assertEquals(recursiveContents("main:/d", version - 1, true), + // recursiveContents("main:/d", version - 2, true)); + // assertEquals(recursiveContents("main:/g", version - 1, true), + // recursiveContents("main:/g", version - 2, true)); + // Add a file through /d/gover/h/i + fService.createFile("main:/d/gover/h/i", "cow").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /g should not have changed since its last version. + version = fService.getNextVersionID("main"); + assertEquals(recursiveContents("main:/g", version - 1, true), recursiveContents("main:/g", version - 2, true)); + // /layer/under/gover/h/i shows both moo and cow. + listing = fService.getDirectoryListing(-1, "main:/layer/under/gover/h/i"); + assertEquals(2, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("cow", list.get(0)); + assertEquals("moo", list.get(1)); + // Rename /layer/under/gover to /layer/b/gover and see what happens. + fService.rename("main:/layer/under", "gover", "main:/layer/b", "gover"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // moo should be in /layer/b/gover/h/i + listing = fService.getDirectoryListing(-1, "main:/layer/b/gover/h/i"); + assertEquals(1, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("moo", list.get(0)); + // Add a new file to /layer/b/gover/h/i + fService.createFile("main:/layer/b/gover/h/i", "oink").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer/b/gover/h/i should contain moo, oink. + listing = fService.getDirectoryListing(-1, "main:/layer/b/gover/h/i"); + assertEquals(2, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("moo", list.get(0)); + assertEquals("oink", list.get(1)); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test behavior when one branches a layer. + */ + public void testLayerAndBranch() throws Exception + { + try + { + TreeMap history = new TreeMap(); + // Create a basic tree. + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a/b", "c"); + fService.createFile("main:/a/b/c", "foo").close(); + fService.createFile("main:/a/b/c", "bar").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Create a layer over /a + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /a and /layer should have identical contents. + assertEquals(recursiveContents("main:/a", -1, true), recursiveContents("main:/layer", -1, true)); + // Make a modification in /layer + fService.createFile("main:/layer/b", "baz").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Branch off layer. + fService.createBranch(-1, "main:/layer", "main:/", "branch"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer/b and /branch/b should have identical contents. + assertEquals(recursiveContents("main:/layer/b", -1, true), recursiveContents("main:/branch/b", -1, true)); + // Create /branch/b/c/foo + fService.createFile("main:/branch/b/c", "baz").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer should not have changed. + int version = fService.getNextVersionID("main"); + assertEquals(recursiveContents("main:/layer", version - 1, true), recursiveContents("main:/layer", version - 2, true)); + // Change something in /layer + fService.createFile("main:/layer/b/c", "fig").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /branch should not have changed. + version = fService.getNextVersionID("main"); + assertEquals(recursiveContents("main:/branch", version - 1, true), recursiveContents("main:/branch", version - 2, true)); + // Create another layer on /a + fService.createLayeredDirectory("main:/a", "main:/", "layer2"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Branch from /layer2/b. + fService.createBranch(-1, "main:/layer2/b", "main:/", "branch2"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Create something in the branch. + fService.createFile("main:/branch2", "goofy").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer2 should be unchanged. + version = fService.getNextVersionID("main"); + assertEquals(recursiveContents("main:/layer2", version - 1, true), recursiveContents("main:/layer2", version - 2, true)); + // Remove something from /layer2 + fService.removeNode("main:/layer2/b/c", "foo"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /branch2 is unchanged. + version = fService.getNextVersionID("main"); + assertEquals(recursiveContents("main:/branch2", version - 1, true), recursiveContents("main:/branch2", version - 2, true)); + // /a is unchanged. + assertEquals(recursiveContents("main:/a", version - 1, true), recursiveContents("main:/a", version - 2, true)); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test scenario in which something is renamed from inside one independent layer to another. + */ + public void testRenameLayerToLayer() throws Exception + { + try + { + TreeMap history = new TreeMap(); + // Set up two trees + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a/b", "c"); + fService.createFile("main:/a/b/c", "foo").close(); + fService.createFile("main:/a/b/c", "bar").close(); + fService.createDirectory("main:/", "d"); + fService.createDirectory("main:/d", "e"); + fService.createDirectory("main:/d/e", "f"); + fService.createFile("main:/d/e/f", "moo").close(); + fService.createFile("main:/d/e/f", "cow").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make a layer to /a and a layer to /d + fService.createLayeredDirectory("main:/a", "main:/", "la"); + fService.createLayeredDirectory("main:/d", "main:/", "ld"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Move /la/b/c to /ld/e/c. + fService.rename("main:/la/b", "c", "main:/ld/e", "c"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Create file /ld/e/c/baz. + fService.createFile("main:/ld/e/c", "baz").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Here's the thing we'd like to assert. + assertEquals("main:/a/b/c", fService.lookup(-1, "main:/ld/e/c").getIndirection()); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test Nothing. Just make sure set up works. + */ + public void testNothing() throws Exception + { + } + + /** + * Test making a simple directory. + */ + public void testCreateDirectory() throws Exception + { + try + { + fService.createDirectory("main:/", "testdir"); + fService.createSnapshot("main", null, null); + assertEquals(AVMNodeType.PLAIN_DIRECTORY, fService.lookup(-1, "main:/").getType()); + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + + // Text index + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + ResultSet results = searchService.query(storeRef, "lucene", "@cm\\:name:testdir"); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); + assertEquals(2, results.length()); + results.close(); + + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test creating a file. + */ + public void testCreateFile() throws Exception + { + try + { + testCreateDirectory(); + fService.createFile("main:/testdir", "testfile").close(); + fService.createFile("main:/", "testfile2").close(); + fService.createSnapshot("main", null, null); + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + + // Text index + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + ResultSet results = searchService.query(storeRef, "lucene", "@cm\\:name:testfile"); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "@cm\\:name:testfile2"); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "TEXT:\"This is testdir/testfile\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "TEXT:\"This is testfile2\""); + assertEquals(0, results.length()); + results.close(); + + ContentWriter writer = fService.getContentWriter("main:/testdir/testfile"); + writer.setEncoding("UTF-8"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + PrintStream out = new PrintStream(writer.getContentOutputStream()); + out.println("This is testdir/testfile"); + out.close(); + + out = new PrintStream(fService.getFileOutputStream("main:/testfile2")); + + writer = fService.getContentWriter("main:/testfile2"); + writer.setEncoding("UTF-8"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + out = new PrintStream(writer.getContentOutputStream()); + out.println("This is testfile2"); + out.close(); + fService.createSnapshot("main", null, null); + + results = searchService.query(storeRef, "lucene", "TEXT:\"This is testdir/testfile\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "TEXT:\"This is testfile2\""); + assertEquals(1, results.length()); + results.close(); + + List versions = fService.getStoreVersions("main"); + for (VersionDescriptor version : versions) + { + System.out.println("V:" + version.getVersionID()); + System.out.println(recursiveList("main", version.getVersionID(), true)); + } + BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/testdir/testfile"))); + String line = reader.readLine(); + assertEquals("This is testdir/testfile", line); + reader.close(); + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/testfile2"))); + line = reader.readLine(); + assertEquals("This is testfile2", line); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test creating a branch. + */ + public void testCreateBranch() throws Exception + { + try + { + setupBasicTree(); + fService.createBranch(-1, "main:/a", "main:/d/e", "abranch"); + fService.createSnapshot("main", null, null); + List versions = fService.getStoreVersions("main"); + for (VersionDescriptor version : versions) + { + System.out.println("V:" + version.getVersionID()); + System.out.println(recursiveList("main", version.getVersionID(), true)); + } + String original = recursiveList("main:/a", -1, 0, true); + original = original.substring(original.indexOf('\n')); + String branch = recursiveList("main:/d/e/abranch", -1, 0, true); + branch = branch.substring(branch.indexOf('\n')); + assertEquals(original, branch); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test creating a layer. + */ + public void testCreateLayer() throws Exception + { + try + { + setupBasicTree(); + fService.createLayeredDirectory("main:/a", "main:/d/e", "alayer"); + fService.createSnapshot("main", null, null); + System.out.println(recursiveList("main", -1, true)); + assertEquals("main:/a", fService.getIndirectionPath(-1, "main:/d/e/alayer")); + assertEquals(recursiveContents("main:/a", -1, true), recursiveContents("main:/d/e/alayer", -1, true)); + PrintStream out = new PrintStream(fService.getFileOutputStream("main:/d/e/alayer/b/c/foo")); + out.println("I am main:/d/e/alayer/b/c/foo"); + out.close(); + fService.createSnapshot("main", null, null); + BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/b/c/foo"))); + String line = reader.readLine(); + reader.close(); + assertEquals("I am main:/a/b/c/foo", line); + System.out.println(recursiveList("main", -1, true)); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test creating a layered file. + */ + public void testLayeredFile1() throws Exception + { + try + { + setupBasicTree(); + fService.createLayeredFile("main:/a/b/c/foo", "main:/d", "lfoo"); + assertTrue(fService.lookup(-1, "main:/d/lfoo").isLayeredFile()); + fService.createSnapshot("main", null, null); + System.out.println(recursiveList("main", -1, true)); + assertEquals("main:/a/b/c/foo", fService.lookup(-1, "main:/d/lfoo").getIndirection()); + assertTrue(fService.lookup(-1, "main:/d/lfoo").isLayeredFile()); + BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/d/lfoo"))); + String line = reader.readLine(); + reader.close(); + assertEquals("I am main:/a/b/c/foo", line); + PrintStream out = new PrintStream(fService.getFileOutputStream("main:/d/lfoo")); + out.println("I am main:/d/lfoo"); + out.close(); + assertFalse(fService.lookup(-1, "main:/d/lfoo").isLayeredFile()); + fService.createSnapshot("main", null, null); + System.out.println(recursiveList("main", -1, true)); + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/b/c/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/a/b/c/foo", line); + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/d/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/d/lfoo", line); + assertFalse(fService.lookup(-1, "main:/d/lfoo").isLayeredFile()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + public void testLayeredFile2() throws Exception + { + try + { + AVMNodeDescriptor desc = fService.lookup(-1, "main:/foo"); + assertNull(desc); + + try + { + fService.getFileOutputStream("main:/foo"); + fail("Unexpected"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + try + { + fService.getFileInputStream(-1, "main:/foo"); + fail("Unexpected"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + // create plain file + fService.createFile("main:/", "foo").close(); + + assertEquals(1, fService.lookup(-1, "main:/foo").getVersionID()); + + BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + String line = reader.readLine(); + reader.close(); + assertNull(line); + + PrintStream out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.println("I am main:/foo V1a"); + out.close(); + + // update plain file + + out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.println("I am main:/foo V1b"); + out.close(); + + out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.println("I am main:/foo V1c"); + out.close(); + + assertEquals(1, fService.lookup(-1, "main:/foo").getVersionID()); + + fService.createSnapshot("main", null, null); + + assertEquals(1, fService.lookup(-1, "main:/foo").getVersionID()); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V1c", line); + + // update plain file + + out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.println("I am main:/foo V2a"); + out.close(); + + assertEquals(2, fService.lookup(-1, "main:/foo").getVersionID()); + + out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.println("I am main:/foo V2b"); + out.close(); + + assertEquals(2, fService.lookup(-1, "main:/foo").getVersionID()); + + fService.createSnapshot("main", null, null); + + assertEquals(2, fService.lookup(-1, "main:/foo").getVersionID()); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V2b", line); + + // update plain file + out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.println("I am main:/foo V3"); + out.close(); + + assertEquals(3, fService.lookup(-1, "main:/foo").getVersionID()); + + fService.createSnapshot("main", null, null); + + assertEquals(3, fService.lookup(-1, "main:/foo").getVersionID()); + + try + { + fService.createLayeredFile("main:/foo", "main:/", "foo"); + fail("Unexpected"); + } + catch (AVMExistsException ee) + { + // expected + } + + // create layered file + fService.createLayeredFile("main:/foo", "main:/", "lfoo"); + + assertEquals(3, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(1, fService.lookup(-1, "main:/lfoo").getVersionID()); + assertTrue(fService.lookup(-1, "main:/lfoo").isLayeredFile()); + + assertEquals("main:/foo", fService.lookup(-1, "main:/lfoo").getIndirection()); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V3", line); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V3", line); + + fService.createSnapshot("main", null, null); + + assertEquals(3, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(1, fService.lookup(-1, "main:/lfoo").getVersionID()); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V3", line); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V3", line); + + // update plain file + out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.println("I am main:/foo V4"); + out.close(); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V4", line); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V4", line); + + assertEquals(4, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(1, fService.lookup(-1, "main:/lfoo").getVersionID()); + + fService.createSnapshot("main", null, null); + + assertEquals(4, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(2, fService.lookup(-1, "main:/lfoo").getVersionID()); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V4", line); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V4", line); + + // update plain file + + out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.println("I am main:/foo V5a"); + out.close(); + + out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.println("I am main:/foo V5b"); + out.close(); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V5b", line); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V5b", line); + + assertEquals(5, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(2, fService.lookup(-1, "main:/lfoo").getVersionID()); + + fService.createSnapshot("main", null, null); + + assertEquals(5, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(3, fService.lookup(-1, "main:/lfoo").getVersionID()); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V5b", line); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V5b", line); + + // update plain file + out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.println("I am main:/foo V6"); + out.close(); + + assertEquals(6, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(3, fService.lookup(-1, "main:/lfoo").getVersionID()); + + fService.createSnapshot("main", null, null); + + assertEquals(6, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(4, fService.lookup(-1, "main:/lfoo").getVersionID()); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V6", line); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V6", line); + + // update layered file + out = new PrintStream(fService.getFileOutputStream("main:/lfoo")); + out.println("I am main:/lfoo V1"); + out.close(); + + assertEquals(6, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(5, fService.lookup(-1, "main:/lfoo").getVersionID()); + assertFalse(fService.lookup(-1, "main:/lfoo").isLayeredFile()); + + fService.createSnapshot("main", null, null); + + assertEquals(6, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(5, fService.lookup(-1, "main:/lfoo").getVersionID()); + assertFalse(fService.lookup(-1, "main:/lfoo").isLayeredFile()); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V6", line); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/lfoo V1", line); + + // update layered file + out = new PrintStream(fService.getFileOutputStream("main:/lfoo")); + out.println("I am main:/lfoo V2"); + out.close(); + + assertEquals(6, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(6, fService.lookup(-1, "main:/lfoo").getVersionID()); + assertFalse(fService.lookup(-1, "main:/lfoo").isLayeredFile()); + + fService.createSnapshot("main", null, null); + + assertEquals(6, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(6, fService.lookup(-1, "main:/lfoo").getVersionID()); + assertFalse(fService.lookup(-1, "main:/lfoo").isLayeredFile()); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V6", line); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/lfoo V2", line); + + // remove plain file + fService.removeNode("main:/foo"); + + desc = fService.lookup(-1, "main:/foo"); + assertNull(desc); + + try + { + fService.getFileOutputStream("main:/foo"); + fail("Unexpected"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + try + { + fService.getFileInputStream(-1, "main:/foo"); + fail("Unexpected"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + fService.createSnapshot("main", null, null); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/lfoo V2", line); + + assertEquals(6, fService.lookup(-1, "main:/lfoo").getVersionID()); + + // remove layered file + fService.removeNode("main:/lfoo"); + + desc = fService.lookup(-1, "main:/lfoo"); + assertNull(desc); + + try + { + fService.getFileOutputStream("main:/lfoo"); + fail("Unexpected"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + try + { + fService.getFileInputStream(-1, "main:/lfoo"); + fail("Unexpected"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + fService.createSnapshot("main", null, null); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + public void testLayeredFile3() throws Exception + { + try + { + AVMNodeDescriptor desc = fService.lookup(-1, "main:/foo"); + assertNull(desc); + + try + { + fService.getFileOutputStream("main:/foo"); + fail("Unexpected"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + try + { + fService.getFileInputStream(-1, "main:/foo"); + fail("Unexpected"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + // create layered file (pointing nowhere) + fService.createLayeredFile("main:/foo", "main:/", "lfoo"); + + assertEquals(1, fService.lookup(-1, "main:/lfoo").getVersionID()); + + fService.createSnapshot("main", null, null); + + try + { + fService.getFileOutputStream("main:/lfoo"); + fail("Unexpected"); + } + catch (AVMException e) + { + // TODO - review + } + + try + { + fService.getFileInputStream(-1, "main:/lfoo"); + fail("Unexpected"); + } + catch (AVMException e) + { + // TODO - review + } + + // create plain file + fService.createFile("main:/", "foo").close(); + + assertEquals(1, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(1, fService.lookup(-1, "main:/lfoo").getVersionID()); + + BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + String line = reader.readLine(); + reader.close(); + assertNull(line); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertNull(line); + + // update plain file + PrintStream out = new PrintStream(fService.getFileOutputStream("main:/foo")); + out.println("I am main:/foo V1"); + out.close(); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V1", line); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V1", line); + + assertEquals(1, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(1, fService.lookup(-1, "main:/lfoo").getVersionID()); + + fService.createSnapshot("main", null, null); + + assertEquals(1, fService.lookup(-1, "main:/foo").getVersionID()); + assertEquals(2, fService.lookup(-1, "main:/lfoo").getVersionID()); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V1", line); + + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/lfoo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/foo V1", line); + + // remove plain file + fService.removeNode( "main:/foo"); + + desc = fService.lookup(-1, "main:/foo"); + assertNull(desc); + + try + { + fService.getFileOutputStream("main:/foo"); + fail("Unexpected"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + try + { + fService.getFileInputStream(-1, "main:/foo"); + fail("Unexpected"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + assertEquals(2, fService.lookup(-1, "main:/lfoo").getVersionID()); + + try + { + fService.getFileInputStream(-1, "main:/lfoo"); + fail("Unexpected"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + fService.createSnapshot("main", null, null); + + assertEquals(3, fService.lookup(-1, "main:/lfoo").getVersionID()); + + try + { + fService.getFileInputStream(-1, "main:/lfoo"); + fail("Unexpected"); + } + catch (AVMNotFoundException nfe) + { + // expected + } + + assertTrue(fService.lookup(-1, "main:/lfoo").isLayeredFile()); + assertFalse(fService.lookup(-1, "main:/lfoo").isPlainFile()); + + try + { + fService.getFileOutputStream("main:/lfoo"); + fail(); + } + catch (AVMException e) + { + // TODO - review + } + + // remove layered file + fService.removeNode("main:/lfoo"); + + fService.createSnapshot("main", null, null); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test rename. + */ + public void testRename() throws Exception + { + try + { + setupBasicTree(); + fService.rename("main:/a", "b", "main:/d/e", "brenamed"); + fService.createSnapshot("main", null, null); + System.out.println(recursiveList("main", -1, true)); + assertEquals(recursiveContents("main:/a/b", 1, true), recursiveContents("main:/d/e/brenamed", 2, true)); + + // Test inedx update + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + + // Text index + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); + assertEquals(2, results.length()); + results.close(); + + // Basic properties + + // Note "a" is a stop word and therefore not findable ... + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); + assertEquals(1, results.length()); + results.close(); + + // TODO: Fix auth in AVMDiskDriver and more?? + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); + + assertEquals(9, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); + assertEquals(9, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); + assertEquals(9, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); + assertEquals(9, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); + assertEquals(9, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":main"); + assertEquals(9, results.length()); + results.close(); + + // Basic paths + + results = searchService.query(storeRef, "lucene", "PATH:\"/\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/brenamed\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/brenamed/c\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/brenamed/c/foo\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/brenamed/c/bar\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); + assertEquals(9, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); + assertEquals(8, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*/*\""); + assertEquals(0, results.length()); + results.close(); + + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test remove. + */ + public void testRemove() throws Exception + { + try + { + setupBasicTree(); + TreeMap history = new TreeMap(); + checkHistory(history, "main"); + System.out.println(history.get(0)); + fService.removeNode("main:/a/b/c", "foo"); + fService.createSnapshot("main", null, null); + checkHistory(history, "main"); + System.out.println(history.get(1)); + Map l = fService.getDirectoryListing(-1, "main:/a/b/c"); + assertEquals(1, l.size()); + fService.removeNode("main:/d", "e"); + fService.createSnapshot("main", null, null); + checkHistory(history, "main"); + System.out.println(history.get(2)); + l = fService.getDirectoryListing(-1, "main:/d"); + assertEquals(0, l.size()); + + // Text index + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + ResultSet results = searchService.query(storeRef, "lucene", "TEXT:\"I am main\""); + assertEquals(1, results.length()); + results.close(); + + // Basic properties + + // Note "a" is a stop word and therefore not findable ... + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":\"foo\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NAME) + ":foo"); + assertEquals(0, results.length()); + results.close(); + + // TODO: Fix auth in AVMDiskDriver and more?? + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + "main"); + assertEquals(6, results.length()); + results.close(); + + // Basic paths + + results = searchService.query(storeRef, "lucene", "PATH:\"/\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/foo\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c/bar\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); + assertEquals(5, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); + assertEquals(4, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); + assertEquals(3, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); + assertEquals(0, results.length()); + results.close(); + + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test branching from one AVMStore to another. + */ + public void testBranchAcross() throws Exception + { + try + { + setupBasicTree(); + fService.createStore("second"); + List repos = fService.getStores(); + assertTrue(checkStoreExists("main", repos)); + assertTrue(checkStoreExists("second", repos)); + fService.createBranch(-1, "main:/", "second:/", "main"); + fService.createSnapshot("second", null, null); + System.out.println(recursiveList("second", -1, true)); + assertEquals(recursiveContents("main:/", -1, true), recursiveContents("second:/main", -1, true)); + // Now make sure nothing happens to the branched from place, + // if the branch is modified. + PrintStream out = new PrintStream(fService.getFileOutputStream("second:/main/a/b/c/foo")); + out.println("I am second:/main/a/b/c/foo"); + out.close(); + fService.createSnapshot("second", null, null); + System.out.println(recursiveList("second", -1, true)); + BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/b/c/foo"))); + String line = reader.readLine(); + reader.close(); + assertEquals("I am main:/a/b/c/foo", line); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + finally + { + fService.purgeStore("second"); + } + } + + private boolean checkStoreExists(String storeName, List stores) + { + for (AVMStoreDescriptor store : stores) + { + if (store.getName().equals(storeName)) + { + return true; + } + } + return false; + } + + /** + * Test creating a layer across AVMStores. + */ + public void testLayerAcross() throws Exception + { + try + { + setupBasicTree(); + fService.createStore("second"); + fService.createLayeredDirectory("main:/", "second:/", "main"); + fService.createSnapshot("second", null, null); + System.out.println(recursiveList("second", -1, true)); + assertEquals(recursiveContents("main:/", -1, true), recursiveContents("second:/main", -1, true)); + // Now make sure that a copy on write will occur and + // that the underlying stuff doesn't get changed. + PrintStream out = new PrintStream(fService.getFileOutputStream("second:/main/a/b/c/foo")); + out.println("I am second:/main/a/b/c/foo"); + out.close(); + fService.createSnapshot("second", null, null); + System.out.println(recursiveList("second", -1, true)); + BufferedReader reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "second:/main/a/b/c/foo"))); + String line = reader.readLine(); + reader.close(); + assertEquals("I am second:/main/a/b/c/foo", line); + reader = new BufferedReader(new InputStreamReader(fService.getFileInputStream(-1, "main:/a/b/c/foo"))); + line = reader.readLine(); + reader.close(); + assertEquals("I am main:/a/b/c/foo", line); + fService.purgeStore("second"); + fService.purgeVersion(1, "main"); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test rename across AVMStores. + */ + public void testRenameAcross() throws Exception + { + try + { + setupBasicTree(); + fService.createStore("second"); + fService.rename("main:/a/b", "c", "second:/", "cmoved"); + ArrayList toSnapshot = new ArrayList(); + toSnapshot.add("main"); + toSnapshot.add("second"); + System.out.println(recursiveList("main", -1, true)); + System.out.println(recursiveList("second", -1, true)); + // Check that the moved thing has identical contents to the thing it + // was moved from. + assertEquals(recursiveContents("main:/a/b/c", 1, true), recursiveContents("second:/cmoved", -1, true)); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + finally + { + fService.purgeStore("second"); + } + } + + /** + * Test COW in various circumstances. + */ + public void testDeepCOW() throws Exception + { + try + { + // Makes a layer on top of a layer on top of a plain directory. + // Assures that the correct layers are copied when files + // are added in the two layers. + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createSnapshot("main", null, null); + Map listing = fService.getDirectoryListing(-1, "main:/a"); + assertEquals(1, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("b", list.get(0)); + fService.createLayeredDirectory("main:/a", "main:/", "c"); + fService.createLayeredDirectory("main:/c", "main:/", "d"); + fService.createFile("main:/d/b", "foo.txt").close(); + fService.createSnapshot("main", null, null); + System.out.println(recursiveList("main", -1, true)); + listing = fService.getDirectoryListing(-1, "main:/d/b"); + assertEquals(1, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("foo.txt", list.get(0)); + fService.createFile("main:/c/b", "bar.txt").close(); + fService.createSnapshot("main", null, null); + System.out.println(recursiveList("main", -1, true)); + listing = fService.getDirectoryListing(-1, "main:/c/b"); + assertEquals(1, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("bar.txt", list.get(0)); + listing = fService.getDirectoryListing(-1, "main:/d/b"); + assertEquals(2, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("bar.txt", list.get(0)); + assertEquals("foo.txt", list.get(1)); + AVMNodeDescriptor[] arrayListing = fService.getDirectoryListingArray(-1, "main:/d/b", false); + assertEquals("bar.txt", arrayListing[0].getName()); + assertEquals("foo.txt", arrayListing[1].getName()); + fService.rename("main:/", "c", "main:/", "e"); + fService.createSnapshot("main", null, null); + System.out.println(recursiveList("main", -1, true)); + listing = fService.getDirectoryListing(-1, "main:/d/b"); + assertEquals(1, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("foo.txt", list.get(0)); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test branching and layering interaction. + */ + public void testBranchAndLayer() throws Exception + { + try + { + // Create a simple directory hierarchy. + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createFile("main:/a/b", "c.txt").close(); + fService.createFile("main:/a/b", "d.txt").close(); + fService.createFile("main:/a", "e.txt").close(); + fService.createSnapshot("main", null, null); + // Make a branch off of a. + fService.createBranch(-1, "main:/a", "main:/", "branch"); + fService.createSnapshot("main", null, null); + // The branch should contain exactly the same things as the thing + // it branched from. + assertEquals(recursiveContents("main:/a", -1, true), recursiveContents("main:/branch", -1, true)); + // Make a layer pointing to /branch/b + fService.createLayeredDirectory("main:/branch/b", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // The new layer should contain exactly the same things as the thing it is layered to. + assertEquals(recursiveContents("main:/branch/b", -1, true), recursiveContents("main:/layer", -1, true)); + // Make a modification in /a/b, the original branch. + PrintStream out = new PrintStream(fService.getFileOutputStream("main:/a/b/c.txt")); + out.println("I am c, modified in main:/a/b."); + out.close(); + fService.createSnapshot("main", null, null); + // The layer should still have identical content to /branch/b. + assertEquals(recursiveContents("main:/branch/b", -1, true), recursiveContents("main:/layer", -1, true)); + // But the layer won't have contents identical to /a/b's + assertFalse(recursiveContents("main:/a/b", -1, true).equals(recursiveContents("main:/layer", -1, true))); + // Make a modification in /branch/b + out = new PrintStream(fService.getFileOutputStream("main:/branch/b/d.txt")); + out.println("I am d, modified in main:/branch/b"); + out.close(); + fService.createSnapshot("main", null, null); + // The layer contents should be identical to the latest contents of /branch/b. + assertEquals(recursiveContents("main:/branch/b", -1, true), recursiveContents("main:/layer", -1, true)); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test basic Layering. + */ + public void testLayering() throws Exception + { + try + { + // Make some directories; + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a/b", "c"); + fService.createDirectory("main:/a/b/c", "d"); + fService.createSnapshot("main", null, null); + // Now make some layers. Three to be precise. + fService.createLayeredDirectory("main:/a", "main:/", "e"); + fService.createLayeredDirectory("main:/e", "main:/", "f"); + fService.createLayeredDirectory("main:/f", "main:/", "g"); + fService.createSnapshot("main", null, null); + // e, f, g should all have the same contents as a. + String a = recursiveContents("main:/a", -1, true); + String e = recursiveContents("main:/e", -1, true); + String f = recursiveContents("main:/f", -1, true); + String g = recursiveContents("main:/g", -1, true); + assertEquals(a, e); + assertEquals(a, f); + assertEquals(a, g); + // Now make a file in /g/b/c/d and /f/b/c/d + fService.createFile("main:/g/b/c/d", "foo").close(); + fService.createFile("main:/f/b/c/d", "bar").close(); + fService.createSnapshot("main", null, null); + // /g/b/c/d should contain foo and bar. + Map listing = fService.getDirectoryListing(-1, "main:/g/b/c/d"); + assertEquals(2, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("bar", list.get(0)); + assertEquals("foo", list.get(1)); + // /f/b/c/d should contain just bar. + listing = fService.getDirectoryListing(-1, "main:/f/b/c/d"); + assertEquals(1, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("bar", list.get(0)); + // Now do something in the bottom layer. + fService.createFile("main:/a/b/c", "baz").close(); + fService.createSnapshot("main", null, null); + // /e/b/c should contain baz and d + listing = fService.getDirectoryListing(-1, "main:/e/b/c"); + assertEquals(2, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("baz", list.get(0)); + assertEquals("d", list.get(1)); + // Now add something in the e layer. + fService.createFile("main:/e/b/c/d", "bing").close(); + fService.createSnapshot("main", null, null); + // /f/b/c/d should now contain bar and bing. + listing = fService.getDirectoryListing(-1, "main:/f/b/c/d"); + assertEquals(2, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("bar", list.get(0)); + assertEquals("bing", list.get(1)); + System.out.println(recursiveList("main", -1, true)); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test rename within a layer. + */ + public void testRenameInLayer() throws Exception + { + try + { + // Setup a base hierarchy. + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a/b", "c"); + fService.createDirectory("main:/a", "d"); + fService.createSnapshot("main", null, null); + // Now make a layer to a. + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // /layer should have the same contents as /a at this point. + assertEquals(recursiveContents("main:/a", -1, true), recursiveContents("main:/layer", -1, true)); + // Now we will rename /layer/d to /layer/moved + fService.rename("main:/layer", "d", "main:/layer", "moved"); + fService.createSnapshot("main", null, null); + // /layer should contain b and moved + Map listing = fService.getDirectoryListing(-1, "main:/layer"); + assertEquals(2, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("b", list.get(0)); + assertEquals("moved", list.get(1)); + // Now rename moved back to d. + fService.rename("main:/layer", "moved", "main:/layer", "d"); + fService.createSnapshot("main", null, null); + // /layer should contain b and d. + listing = fService.getDirectoryListing(-1, "main:/layer"); + assertEquals(2, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("b", list.get(0)); + assertEquals("d", list.get(1)); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test behavior of multiply layers not in register. + */ + public void testMultiLayerUnregistered() throws Exception + { + try + { + TreeMap history = new TreeMap(); + setupBasicTree(); + // History unchanged. + checkHistory(history, "main"); + // Create layered directory /d/e/f/ to /a + fService.createLayeredDirectory("main:/a", "main:/d/e/f", "l0"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Create layered directory /d/l1 to /d/e/f. + fService.createLayeredDirectory("main:/d/e/f", "main:/d", "l1"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Create layered directory /l2 to /d + fService.createLayeredDirectory("main:/d", "main:/", "l2"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Create /l2/l1/l0/a/foo. + fService.createFile("main:/l2/l1/l0/b", "foo").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /l2/l1/l0 should now point at /d/l1/l0 + assertEquals("main:/d/l1/l0", fService.lookup(-1, "main:/l2/l1/l0").getIndirection()); + // /l2/l1/l0/b should now point at /d/l1/l0/b + assertEquals("main:/d/l1/l0/b", fService.lookup(-1, "main:/l2/l1/l0/b").getIndirection()); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test makePrimary. + */ + public void testMakePrimary() throws Exception + { + try + { + TreeMap history = new TreeMap(); + setupBasicTree(); + // History unchanged. + checkHistory(history, "main"); + // Make a layer to /a + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make /layer/b/c primary. + fService.makePrimary("main:/layer/b/c"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Rename /layer/b/c to /layer/c + fService.rename("main:/layer/b", "c", "main:/layer", "c"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /a/b/c should have identical contents to /layer/c + assertEquals(recursiveContents("main:/a/b/c", -1, true), recursiveContents("main:/layer/c", -1, true)); + // Create /layer2 to /a. + fService.createLayeredDirectory("main:/a", "main:/", "layer2"); + // Make a file down in /layer2/b/c + fService.createFile("main:/layer2/b/c", "baz").close(); + // make /layer2/b/c primary. + fService.makePrimary("main:/layer2/b/c"); + // Rename /layer2/b/c to /layer2/c + fService.rename("main:/layer2/b", "c", "main:/layer2", "c"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer2/c should contain foo bar and baz. + Map listing = fService.getDirectoryListing(-1, "main:/layer2/c"); + assertEquals(3, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("bar", list.get(0)); + assertEquals("baz", list.get(1)); + assertEquals("foo", list.get(2)); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test retargeting a directory. + */ + public void testRetarget() throws Exception + { + try + { + TreeMap history = new TreeMap(); + setupBasicTree(); + // History unchanged. + checkHistory(history, "main"); + // Make a layer to /a + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Retarget /layer/b/c to /d. + fService.retargetLayeredDirectory("main:/layer/b/c", "main:/d"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer/b/c should contain e. + Map listing = fService.getDirectoryListing(-1, "main:/layer/b/c"); + assertEquals(1, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("e", list.get(0)); + // Rename /layer/b/c to /layer/c + fService.rename("main:/layer/b", "c", "main:/layer", "c"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /d should have identical contents to /layer/c + assertEquals(recursiveContents("main:/d", -1, true), recursiveContents("main:/layer/c", -1, true)); + // Create /layer2 to /a. + fService.createLayeredDirectory("main:/a", "main:/", "layer2"); + // Make a file down in /layer2/b/c + fService.createFile("main:/layer2/b/c", "baz").close(); + // make /layer2/b/c primary. + fService.retargetLayeredDirectory("main:/layer2/b/c", "main:/d"); + // Rename /layer2/b/c to /layer2/c + fService.rename("main:/layer2/b", "c", "main:/layer2", "c"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer2/c should have baz and e in it. + listing = fService.getDirectoryListing(-1, "main:/layer2/c"); + assertEquals(2, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("baz", list.get(0)); + assertEquals("e", list.get(1)); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test rename between branches. + */ + public void testRenameBranchToBranch() throws Exception + { + try + { + TreeMap history = new TreeMap(); + // Set up two trees + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a/b", "c"); + fService.createFile("main:/a/b/c", "foo").close(); + fService.createFile("main:/a/b/c", "bar").close(); + fService.createDirectory("main:/", "d"); + fService.createDirectory("main:/d", "e"); + fService.createDirectory("main:/d/e", "f"); + fService.createFile("main:/d/e/f", "moo").close(); + fService.createFile("main:/d/e/f", "cow").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make branches. + fService.createBranch(-1, "main:/a/b", "main:/", "abranch"); + fService.createBranch(-1, "main:/d/e", "main:/", "dbranch"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Move /abranch/c/foo /dbranch/foo + fService.rename("main:/abranch/c", "foo", "main:/dbranch", "foo"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Confirm that /a and /d are unchanged. + int version = fService.getNextVersionID("main"); + assertEquals(recursiveContents("main:/a", version - 1, true), recursiveContents("main:/a", version - 2, true)); + assertEquals(recursiveContents("main:/d", version - 1, true), recursiveContents("main:/d", version - 2, true)); + // Move /dbranch/f to /abranch/c/f + fService.rename("main:/dbranch", "f", "main:/abranch/c", "f"); + fService.createSnapshot("main", null, null); + // Confirm that /a and /d are unchanged. + version = fService.getNextVersionID("main"); + assertEquals(recursiveContents("main:/a", version - 1, true), recursiveContents("main:/a", version - 2, true)); + assertEquals(recursiveContents("main:/d", version - 1, true), recursiveContents("main:/d", version - 2, true)); + // History unchanged. + checkHistory(history, "main"); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test a branch being created in a layer. + */ + public void testBranchIntoLayer() throws Exception + { + try + { + TreeMap history = new TreeMap(); + // Set up two trees + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a/b", "c"); + fService.createFile("main:/a/b/c", "foo").close(); + fService.createFile("main:/a/b/c", "bar").close(); + fService.createDirectory("main:/", "d"); + fService.createDirectory("main:/d", "e"); + fService.createDirectory("main:/d/e", "f"); + fService.createFile("main:/d/e/f", "moo").close(); + fService.createFile("main:/d/e/f", "cow").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Create a layer to /a + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Now create a branch from /d in /layer/a/b. + fService.createBranch(-1, "main:/d", "main:/layer/b", "branch"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Now modify /layer/b/branch/e/f/moo. + PrintStream out = new PrintStream(fService.getFileOutputStream("main:/layer/b/branch/e/f/moo")); + out.println("moo modified."); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer/b/branch/e/f should contain moo and cow. + Map listing = fService.getDirectoryListing(-1, "main:/layer/b/branch/e/f"); + assertEquals(2, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("cow", list.get(0)); + assertEquals("moo", list.get(1)); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test renaming into a layer. + */ + public void testRenameIntoLayer() throws Exception + { + try + { + TreeMap history = new TreeMap(); + // Set up two trees + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a/b", "c"); + fService.createFile("main:/a/b/c", "foo").close(); + fService.createFile("main:/a/b/c", "bar").close(); + fService.createDirectory("main:/", "d"); + fService.createDirectory("main:/d", "e"); + fService.createDirectory("main:/d/e", "f"); + fService.createFile("main:/d/e/f", "moo").close(); + fService.createFile("main:/d/e/f", "cow").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Create a layer to /a + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Now rename /d into /layer/a/b. + fService.rename("main:/", "d", "main:/layer/b", "d"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Now modify /layer/b/branch/e/f/moo. + PrintStream out = new PrintStream(fService.getFileOutputStream("main:/layer/b/d/e/f/moo")); + out.println("moo modified."); + out.close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer/b/branch/e/f should contain moo and cow. + Map listing = fService.getDirectoryListing(-1, "main:/layer/b/d/e/f"); + assertEquals(2, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("cow", list.get(0)); + assertEquals("moo", list.get(1)); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test proper indirection behavior. + */ + public void testIndirectionBehavior() throws Exception + { + try + { + TreeMap history = new TreeMap(); + // Setup the stage. + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a/b", "c"); + fService.createDirectory("main:/a/b/c", "d"); + fService.createDirectory("main:/a/b/c/d", "e"); + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + fService.createDirectory("main:/", "f"); + fService.createDirectory("main:/f", "g"); + fService.createDirectory("main:/f/g", "h"); + fService.createLayeredDirectory("main:/f", "main:/", "flayer"); + fService.createLayeredDirectory("main:/flayer", "main:/layer/b/c", "fover"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + fService.createDirectory("main:/", "i"); + fService.createDirectory("main:/i", "j"); + fService.createDirectory("main:/i/j", "k"); + fService.createLayeredDirectory("main:/i", "main:/f/g/h", "iover"); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + fService.createFile("main:/layer/b/c/fover/g/h/iover/j/k", "foo").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // Make a file in /i/j/k + fService.createFile("main:/i/j/k", "pismo").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer/b/c/fover/g/h/iover/j/k should contain pismo and foo. + Map listing = fService.getDirectoryListing(-1, "main:/layer/b/c/fover/g/h/iover/j/k"); + assertEquals(2, listing.size()); + List list = new ArrayList(listing.keySet()); + assertEquals("foo", list.get(0)); + assertEquals("pismo", list.get(1)); + // Make a file in /flayer/g/h/iover/j/k + fService.createFile("main:/flayer/g/h/iover/j/k", "zuma").close(); + fService.createSnapshot("main", null, null); + // History unchanged. + checkHistory(history, "main"); + // /layer/b/c/fover/g/h/iover/j/k should contain foo, pismo, and zuma. + listing = fService.getDirectoryListing(-1, "main:/layer/b/c/fover/g/h/iover/j/k"); + assertEquals(3, listing.size()); + list = new ArrayList(listing.keySet()); + assertEquals("foo", list.get(0)); + assertEquals("pismo", list.get(1)); + assertEquals("zuma", list.get(2)); + for (String val : history.values()) + { + System.out.println(val); + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test reading of versioned content via a layer. + */ + public void testVersionedRead() throws Exception + { + try + { + PrintStream out = new PrintStream(fService.createFile("main:/", "foo")); + out.print("version1"); + out.close(); + fService.createLayeredFile("main:/foo", "main:/", "afoo"); + fService.createSnapshot("main", null, null); + 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); + BufferedReader 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(-1, "main:/afoo"))); + assertEquals("version2", reader.readLine()); + reader.close(); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test rename of an overlayed directory contained in an overlayed directory. + */ + public void testRenameLayerInLayer() throws Exception + { + try + { + // Make some directories. + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a/b", "c"); + fService.createSnapshot("main", null, null); + // Make a layer to /a. + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + // Force a copy on write in the layer. + fService.createFile("main:/layer/b/c", "foo").close(); + fService.createSnapshot("main", null, null); + assertEquals("main:/a/b/c", fService.lookup(-1, "main:/layer/b/c").getIndirection()); + // Now rename. + fService.rename("main:/layer/b", "c", "main:/layer/b", "d"); + fService.createSnapshot("main", null, null); + assertEquals("main:/a/b/d", fService.lookup(-1, "main:/layer/b/d").getIndirection()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Yet another rename from layer to layer test. + */ + public void testAnotherRename() throws Exception + { + try + { + // Make two directory trees. + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a/b", "c"); + fService.createDirectory("main:/", "d"); + fService.createDirectory("main:/d", "e"); + fService.createDirectory("main:/d/e", "f"); + fService.createSnapshot("main", null, null); + runQueriesForInitialRenameStructure("main"); + // Make a layer over each. + fService.createLayeredDirectory("main:/a", "main:/", "la"); + fService.createLayeredDirectory("main:/d", "main:/", "ld"); + fService.createSnapshot("main", null, null); + // TODO: Sort out paths to layers .... + // runQueriesForInitialRenameStructureAndInitialLayers("main"); + // rename from down in one layer to another. + fService.rename("main:/ld/e", "f", "main:/la/b", "f"); + fService.createSnapshot("main", null, null); + AVMNodeDescriptor desc = fService.lookup(-1, "main:/la/b/f"); + assertTrue(desc.isPrimary()); + assertEquals("main:/d/e/f", desc.getIndirection()); + // Now rename in in the layer. + fService.rename("main:/la/b", "f", "main:/la/b/c", "f"); + fService.createSnapshot("main", null, null); + desc = fService.lookup(-1, "main:/la/b/c/f"); + assertTrue(desc.isPrimary()); + assertEquals("main:/d/e/f", desc.getIndirection()); + // Now create a directory in the layered f. + fService.createDirectory("main:/la/b/c/f", "dir"); + fService.createSnapshot("main", null, null); + desc = fService.lookup(-1, "main:/la/b/c/f/dir"); + assertFalse(desc.isPrimary()); + assertEquals("main:/d/e/f/dir", desc.getIndirection()); + // Now rename that and see where it points. + fService.rename("main:/la/b/c/f", "dir", "main:/la/b", "dir"); + fService.createSnapshot("main", null, null); + desc = fService.lookup(-1, "main:/la/b/dir"); + assertFalse(desc.isPrimary()); + assertEquals("main:/a/b/dir", desc.getIndirection()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + protected void runQueriesForInitialRenameStructure(String store) throws Exception + { + StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); + + SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef(store), true); + + // Note "a" is a stop word and therefore not findable ... + + ResultSet results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); + assertEquals(7, results.length()); + results.close(); + + // Basic paths + + results = searchService.query(storeRef, "lucene", "PATH:\"/\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); + assertEquals(3, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); + assertEquals(0, results.length()); + results.close(); + } + + protected void runQueriesForInitialRenameStructureAndInitialLayers(String store) + { + StoreRef storeRef = AVMNodeConverter.ToStoreRef(store); + + SearchService searchService = fIndexerAndSearcher.getSearcher(AVMNodeConverter.ToStoreRef(store), true); + + // Note "a" is a stop word and therefore not findable ... + + ResultSet results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_CREATOR) + ":admin"); + assertEquals(9, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_MODIFIER) + ":admin"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_OWNER) + ":admin"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_NODE_UUID) + ":unknown"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_PROTOCOL) + ":avm"); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", LuceneQueryParser.escape("@" + ContentModel.PROP_STORE_IDENTIFIER) + ":" + store); + assertEquals(7, results.length()); + results.close(); + + // Basic paths + + results = searchService.query(storeRef, "lucene", "PATH:\"/\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/b/c\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/d/e/f\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//.\""); + assertEquals(7, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//*\""); + assertEquals(6, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//.\""); + assertEquals(3, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a//*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/a/*\""); + assertEquals(1, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"//c/*\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*\""); + assertEquals(2, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*\""); + assertEquals(0, results.length()); + results.close(); + + results = searchService.query(storeRef, "lucene", "PATH:\"/*/*/*/*/*\""); + assertEquals(0, results.length()); + results.close(); + } + + /** + * Test rename behavior of an overlayed file withing a layer. + */ + public void testFileRenameLayer() throws Exception + { + try + { + // Make a set of directories. + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a/b", "c"); + fService.createFile("main:/", "foo").close(); + fService.createSnapshot("main", null, null); + // Make a layer. + fService.createLayeredDirectory("main:/a", "main:/", "la"); + fService.createSnapshot("main", null, null); + // Make a layered file. + fService.createLayeredFile("main:/foo", "main:/la/b", "foo"); + fService.createSnapshot("main", null, null); + AVMNodeDescriptor desc = fService.lookup(-1, "main:/la/b/foo"); + assertEquals("main:/foo", desc.getIndirection()); + // Now rename it. It should still point at the same place. + fService.rename("main:/la/b", "foo", "main:/la", "foo"); + fService.createSnapshot("main", null, null); + desc = fService.lookup(-1, "main:/la/foo"); + assertEquals("main:/foo", desc.getIndirection()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * The random access. + */ + /* + * public void testRandomAccess() { try { setupBasicTree(); RandomAccessFile file = fService.getRandomAccess(1, + * "main:/a/b/c/foo", "r"); byte [] buff = new byte[256]; assertTrue(file.read(buff) >= 20); file.close(); file = + * fService.getRandomAccess(-1, "main:/a/b/c/bar", "rw"); for (int i = 0; i < 256; i++) { buff[i] = (byte)i; } + * file.write(buff); file.close(); fService.createSnapshot("main", null, null); } catch (Exception e) { + * e.printStackTrace(System.err); throw e; } } + */ + + /** + * Test COW during long operations. + */ + public void testCOWLongOps() throws Exception + { + try + { + setupBasicTree(); + // Create a layer to a. + fService.createLayeredDirectory("main:/a", "main:/d/e/f", "layer"); + // Create a layer to /d + fService.createLayeredDirectory("main:/d", "main:/", "l2"); + // Force a copy on write on l2 + fService.createFile("main:/l2", "baz").close(); + // Force a copy on write on /d/e/f/layer/b/c + fService.createFile("main:/d/e/f/layer/b/c", "fink").close(); + // Create /l2/e/f/layer/b/c/nottle + fService.createFile("main:/l2/e/f/layer/b/c", "nottle").close(); + fService.createSnapshot("main", null, null); + System.out.println(recursiveList("main", -1, true)); + assertFalse(fService.lookup(-1, "main:/d/e/f/layer/b/c").getId() == fService.lookup(-1, "main:/l2/e/f/layer/b/c").getId()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test new lookup methods. + */ + public void testLookup() throws Exception + { + try + { + setupBasicTree(); + AVMNodeDescriptor desc = fService.getStoreRoot(-1, "main"); + assertNotNull(desc); + System.out.println(desc.toString()); + AVMNodeDescriptor child = fService.lookup(desc, "a"); + assertNotNull(child); + System.out.println(child.toString()); + child = fService.lookup(child, "b"); + assertNotNull(child); + System.out.println(child.toString()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test AVMStore functions. + */ + public void testAVMStore() throws Exception + { + try + { + // First check that we get the right error when we try to create an + // AVMStore that exists. + try + { + fService.createStore("main"); + fail(); + } + catch (AVMExistsException ae) + { + // Do nothing. + } + // Now make sure getRepository() works. + AVMStoreDescriptor desc = fService.getStore("main"); + assertNotNull(desc); + System.out.println(desc); + fService.purgeStore("main"); + assertNull(fService.getStore("main")); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test opacity and manipulations. + */ + public void testOpacity() throws Exception + { + try + { + setupBasicTree(); + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + fService.createSnapshot("main", null, null); + fService.createFile("main:/layer/b/c", "baz").close(); + fService.createFile("main:/layer/b/c", "fig").close(); + fService.createSnapshot("main", null, null); + Map listing = fService.getDirectoryListing(-1, "main:/layer/b/c"); + assertEquals(4, listing.size()); + System.out.println(recursiveList("main", -1, true)); + // Setting the opacity of layer to true will make no difference to what we see through + // main:/layer/b/c. + fService.setOpacity("main:/layer", true); + fService.createSnapshot("main", null, null); + assertTrue(fService.lookup(-1, "main:/layer").getOpacity()); + assertEquals(4, fService.getDirectoryListing(-1, "main:/layer/b/c").size()); + System.out.println(recursiveList("main", -1, true)); + // If main:/layer/b/c is opaque, however, we'll only see two items in it. + fService.setOpacity("main:/layer", false); + fService.setOpacity("main:/layer/b/c", true); + fService.createSnapshot("main", null, null); + assertFalse(fService.lookup(-1, "main:/layer").getOpacity()); + assertTrue(fService.lookup(-1, "main:/layer/b/c").getOpacity()); + assertEquals(2, fService.getDirectoryListing(-1, "main:/layer/b/c").size()); + System.out.println(recursiveList("main", -1, true)); + // Gratuitous test of retarget. + fService.retargetLayeredDirectory("main:/layer", "main:/d"); + fService.setOpacity("main:/layer/b/c", false); + fService.createSnapshot("main", null, null); + assertFalse(fService.lookup(-1, "main:/layer/b/c").getOpacity()); + assertEquals(2, fService.getDirectoryListing(-1, "main:/layer/b/c").size()); + // This is just testing that opacity setting works on latent + // layered directories. + fService.setOpacity("main:/layer/e/f", true); + System.out.println(recursiveList("main", -1, true)); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test common ancestor. + */ + public void testCommonAncestor() throws Exception + { + try + { + setupBasicTree(); + fService.createBranch(-1, "main:/a", "main:/", "branch"); + fService.createSnapshot("main", null, null); + AVMNodeDescriptor ancestor = fService.lookup(-1, "main:/a/b/c/foo"); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + fService.getFileOutputStream("main:/branch/b/c/foo").close(); + fService.createSnapshot("main", null, null); + AVMNodeDescriptor main = fService.lookup(-1, "main:/a/b/c/foo"); + AVMNodeDescriptor branch = fService.lookup(-1, "main:/branch/b/c/foo"); + AVMNodeDescriptor ca = fService.getCommonAncestor(main, branch); + assertEquals(ancestor, ca); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test properties on stores. + */ + public void testStoreProperties() throws Exception + { + try + { + Map props = fService.getStoreProperties("main"); + assertEquals(2, props.size()); + assertEquals(AuthenticationUtil.getAdminUserName(), props.get(ContentModel.PROP_CREATOR).getStringValue()); + assertNotNull(props.get(ContentModel.PROP_CREATED)); + System.out.println(props.toString()); + + QName name = QName.createQName("silly.uri", "SillyProperty"); + PropertyValue value = new PropertyValue(DataTypeDefinition.TEXT, "Silly Property Value"); + fService.setStoreProperty("main", name, value); + PropertyValue found = fService.getStoreProperty("main", name); + assertEquals(value.toString(), found.toString()); + props = fService.getStoreProperties("main"); + assertEquals(3, props.size()); + + props = new HashMap(5); + QName n1 = QName.createQName("silly.uri", "Prop1"); + PropertyValue p1 = new PropertyValue(null, new Date(System.currentTimeMillis())); + props.put(n1, p1); + QName n2 = QName.createQName("silly.uri", "Prop2"); + PropertyValue p2 = new PropertyValue(null, "A String Property."); + props.put(n2, p2); + QName n3 = QName.createQName("silly.uri", "Prop3"); + PropertyValue p3 = new PropertyValue(null, 42); + props.put(n3, p3); + QName n4 = QName.createQName("silly.uri", "Prop4"); + PropertyValue p4 = new PropertyValue(null, new Boolean(false)); + props.put(n4, p4); + QName n5 = QName.createQName("silly.uri", "Prop5"); + List strList = new ArrayList(2); + strList.add("hello"); + strList.add("world"); + PropertyValue p5 = new PropertyValue(DataTypeDefinition.TEXT, (Serializable)strList); + props.put(n5, p5); + fService.setStoreProperties("main", props); + + props = fService.getStoreProperties("main"); + System.out.println(props.toString()); + assertEquals(8, props.size()); + assertEquals(p1.toString(), props.get(n1).toString()); + assertEquals(p2.toString(), props.get(n2).toString()); + assertEquals(p3.toString(), props.get(n3).toString()); + assertEquals(p4.toString(), props.get(n4).toString()); + assertEquals(p5.toString(), props.get(n5).toString()); + + props = new HashMap(5); + n1 = QName.createQName("silly.uri", "Prop1"); + p1 = new PropertyValue(null, new Date(System.currentTimeMillis())); + props.put(n1, p1); + n2 = QName.createQName("silly.uri", "Prop2"); + p2 = new PropertyValue(null, "A String Property - updated."); + props.put(n2, p2); + n3 = QName.createQName("silly.uri", "Prop3"); + p3 = new PropertyValue(null, -42); + props.put(n3, p3); + n4 = QName.createQName("silly.uri", "Prop4"); + p4 = new PropertyValue(null, new Boolean(true)); + props.put(n4, p4); + n5 = QName.createQName("silly.uri", "Prop5"); + strList = new ArrayList(2); + strList.add("goodbye"); + strList.add("world"); + p5 = new PropertyValue(DataTypeDefinition.TEXT, (Serializable)strList); + props.put(n5, p5); + fService.setStoreProperties("main", props); + + props = fService.getStoreProperties("main"); + System.out.println(props.toString()); + assertEquals(8, props.size()); + assertEquals(p1.toString(), props.get(n1).toString()); + assertEquals(p2.toString(), props.get(n2).toString()); + assertEquals(p3.toString(), props.get(n3).toString()); + assertEquals(p4.toString(), props.get(n4).toString()); + assertEquals(p5.toString(), props.get(n5).toString()); + + fService.deleteStoreProperty("main", name); + props = fService.getStoreProperties("main"); + assertEquals(7, props.size()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test Aspect Name storage. + */ + public void testAspectNames() throws Exception + { + try + { + setupBasicTree(); + + StoreRef storeRef = AVMNodeConverter.ToStoreRef("main"); + SearchService searchService = fIndexerAndSearcher.getSearcher(storeRef, true); + ResultSet results = searchService.query(storeRef, "lucene", "ASPECT:\"" + ContentModel.ASPECT_TITLED.toString() + "\""); + assertEquals(0, results.length()); + results.close(); + results = searchService.query(storeRef, "lucene", "ASPECT:\"" + ContentModel.ASPECT_AUDITABLE.toString() + "\""); + assertEquals(0, results.length()); + results.close(); + + fService.addAspect("main:/a/b/c/foo", ContentModel.ASPECT_TITLED); + fService.addAspect("main:/a/b/c/foo", ContentModel.ASPECT_AUDITABLE); + Map properties = new HashMap(); + properties.put(ContentModel.PROP_ACCESSED, new PropertyValue(DataTypeDefinition.DATETIME, new Date(System.currentTimeMillis()))); + properties.put(ContentModel.PROP_CREATED, new PropertyValue(DataTypeDefinition.DATETIME, new Date(System.currentTimeMillis()))); + properties.put(ContentModel.PROP_MODIFIED, new PropertyValue(DataTypeDefinition.DATETIME, new Date(System.currentTimeMillis()))); + properties.put(ContentModel.PROP_CREATOR, new PropertyValue(DataTypeDefinition.TEXT, "Giles")); + properties.put(ContentModel.PROP_MODIFIER, new PropertyValue(DataTypeDefinition.TEXT, "Quentin")); + fService.setNodeProperties("main:/a/b/c/foo", properties); + fService.createSnapshot("main", null, null); + + results = searchService.query(storeRef, "lucene", "ASPECT:\"" + ContentModel.ASPECT_TITLED.toString() + "\""); + assertEquals(1, results.length()); + results.close(); + results = searchService.query(storeRef, "lucene", "ASPECT:\"" + ContentModel.ASPECT_AUDITABLE.toString() + "\""); + assertEquals(1, results.length()); + results.close(); + + fService.removeNode("main:/a/b/c/bar"); + fService.addAspect("main:/a/b/c/bar", ContentModel.ASPECT_TITLED); + Set names = fService.getAspects(-1, "main:/a/b/c/foo"); + assertEquals(2, names.size()); + assertTrue(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_TITLED)); + assertFalse(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_AUTHOR)); + assertTrue(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_TITLED)); + fService.removeAspect("main:/a/b/c/foo", ContentModel.ASPECT_TITLED); + fService.createSnapshot("main", null, null); + + results = searchService.query(storeRef, "lucene", "ASPECT:\"" + ContentModel.ASPECT_TITLED.toString() + "\""); + assertEquals(0, results.length()); + results.close(); + results = searchService.query(storeRef, "lucene", "ASPECT:\"" + ContentModel.ASPECT_AUDITABLE.toString() + "\""); + assertEquals(1, results.length()); + results.close(); + + fService.getFileOutputStream("main:/a/b/c/foo").close(); + assertFalse(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_TITLED)); + assertTrue(fService.hasAspect(-1, "main:/a/b/c/foo", ContentModel.ASPECT_AUDITABLE)); + Map props = fService.getNodeProperties(-1, "main:/a/b/c/foo"); + assertEquals(5, props.size()); + fService.removeAspect("main:/a/b/c/foo", ContentModel.ASPECT_AUDITABLE); + props = fService.getNodeProperties(-1, "main:/a/b/c/foo"); + assertEquals(0, props.size()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test case insensitivity. + */ + public void testCaseInsensitive() throws Exception + { + try + { + setupBasicTree(); + try + { + fService.createFile("main:/a/b/c", "Foo").close(); + fail(); + } + catch (AVMExistsException e) + { + // Do nothing. + } + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test ACLs. + */ + public void testACLs() throws Exception + { + try + { + setupBasicTree(); + PermissionService perm = (PermissionService) fContext.getBean("PermissionService"); + // AuthenticationService ac = (AuthenticationService)fContext.getBean("AuthenticationService"); + // ac.authenticate("admin", "admin".toCharArray()); + perm.setPermission(AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/foo"), PermissionService.ADMINISTRATOR_AUTHORITY, PermissionService.ALL_PERMISSIONS, true); + fService.createSnapshot("main", null, null); + fService.getFileOutputStream("main:/a/b/c/foo").close(); + Set perms = perm.getPermissions(AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/foo")); + for (AccessPermission permission : perms) + { + System.out.println(permission); + } + assertTrue(perms.size() > 0); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test FileFolderService with AVM. + */ + public void testFileFolderService() throws Exception + { + try + { + setupBasicTree(); + FileFolderService ffs = (FileFolderService) fContext.getBean("FileFolderService"); + // AuthenticationComponent ac = (AuthenticationComponent)fContext.getBean("authenticationComponent"); + // ac.authenticate("admin", "admin".toCharArray()); + assertTrue(ffs.create(AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/"), "banana", WCMModel.TYPE_AVM_PLAIN_CONTENT) != null); + assertTrue(ffs.create(AVMNodeConverter.ToNodeRef(-1, "main://"), "banana", WCMModel.TYPE_AVM_PLAIN_CONTENT) != null); + assertTrue(ffs.create(AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c"), "apples", WCMModel.TYPE_AVM_PLAIN_FOLDER) != null); + NodeService ns = (NodeService) fContext.getBean("NodeService"); + Map properties = new HashMap(); + properties.put(WCMModel.PROP_AVM_DIR_INDIRECTION, AVMNodeConverter.ToNodeRef(-1, "main:/a")); + assertTrue(ns.createNode(AVMNodeConverter.ToNodeRef(-1, "main:/"), ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "layer"), + WCMModel.TYPE_AVM_LAYERED_FOLDER, properties) != null); + assertTrue(ns.getProperty(AVMNodeConverter.ToNodeRef(-1, "main:/layer"), WCMModel.PROP_AVM_DIR_INDIRECTION) != null); + properties.clear(); + properties.put(WCMModel.PROP_AVM_FILE_INDIRECTION, AVMNodeConverter.ToNodeRef(-1, "main:/a/b/c/foo")); + assertTrue(ns.createNode(AVMNodeConverter.ToNodeRef(-1, "main:/"), ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "foo"), + WCMModel.TYPE_AVM_LAYERED_CONTENT, properties) != null); + assertTrue(ns.getProperty(AVMNodeConverter.ToNodeRef(-1, "main:/foo"), WCMModel.PROP_AVM_FILE_INDIRECTION) != null); + fService.createSnapshot("main", null, null); + System.out.println(recursiveList("main", -1, true)); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test overwriting without snapshots in between. + */ + public void testOverwrite() throws Exception + { + try + { + setupBasicTree(); + class TxnCallback implements RetryingTransactionHelper.RetryingTransactionCallback + { + public Object execute() throws Exception + { + try + { + AVMService service = (AVMService) fContext.getBean("avmService"); + service.createLayeredDirectory("main:/a", "main:/", "layer"); + // Modify something in an ordinary directory 3 times. + service.getFileOutputStream("main:/a/b/c/foo").close(); + service.getFileOutputStream("main:/a/b/c/foo").close(); + service.getFileOutputStream("main:/a/b/c/foo").close(); + service.createFile("main:/a/b/c", "pint").close(); + service.createFile("main:/a/b/c", "quart").close(); + // Modify another file in the same directory. + service.getFileOutputStream("main:/a/b/c/bar").close(); + service.getFileOutputStream("main:/a/b/c/bar").close(); + service.lookup(-1, "main:/a/b/c"); + service.createFile("main:/a/b/c", "figment").close(); + // Repeat in a layer. + service.getFileOutputStream("main:/layer/b/c/foo").close(); + service.getFileOutputStream("main:/layer/b/c/foo").close(); + service.getFileOutputStream("main:/layer/b/c/foo").close(); + service.createFile("main:/layer/b/c", "gallon").close(); + service.createFile("main:/layer/b/c", "dram").close(); + service.getFileOutputStream("main:/layer/b/c/bar").close(); + service.getFileOutputStream("main:/layer/b/c/bar").close(); + try + { + service.lookup(-1, "main:/a/b/c/froo"); + } + catch (AVMException ae) + { + // Do nothing. + } + service.createDirectory("main:/a/b/c", "froo"); + service.createFile("main:/a/b/c/froo", "franistan").close(); + try + { + service.lookup(-1, "main:/layer/b/c/groo"); + } + catch (AVMException ae) + { + // Do nothing. + } + service.createDirectory("main:/layer/b/c", "groo"); + service.createFile("main:/layer/b/c/groo", "granistan").close(); + return null; + } + catch (IOException e) + { + e.printStackTrace(); + throw e; + } + } + } + TransactionService transactionService = (TransactionService) fContext.getBean("transactionService"); + RetryingTransactionHelper helper = transactionService.getRetryingTransactionHelper(); + helper.doInTransaction(new TxnCallback(), false); + assertNotNull(fService.lookup(-1, "main:/layer/b/c/groo")); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test creating a file over a ghost. + */ + public void testCreateOverDeleted() throws Exception + { + try + { + setupBasicTree(); + fService.removeNode("main:/a/b/c", "foo"); + fService.createFile("main:/a/b/c", "foo").close(); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + } + + /** + * Test lookup and listing of deleted files. + */ + public void testDeleted() throws Exception + { + try + { + setupBasicTree(); + fService.createLayeredDirectory("main:/a", "main:/", "layer"); + // Delete something in regular directory. + fService.removeNode("main:/a/b/c", "foo"); + AVMNodeDescriptor desc = fService.lookup(-1, "main:/a/b/c/foo", true); + assertTrue(desc.isDeleted()); + assertTrue(desc.isDeletedFile()); + Map listing = fService.getDirectoryListing(-1, "main:/a/b/c", true); + assertEquals(2, listing.size()); + assertTrue(listing.get("foo").isDeleted()); + AVMNodeDescriptor dir = fService.lookup(-1, "main:/a/b/c", true); + desc = fService.lookup(dir, "foo", true); + assertTrue(desc.isDeleted()); + listing = fService.getDirectoryListing(dir, true); + assertEquals(2, listing.size()); + assertTrue(listing.get("foo").isDeleted()); + desc = fService.lookup(-1, "main:/layer/b/c/foo", true); + assertTrue(desc.isDeleted()); + listing = fService.getDirectoryListing(-1, "main:/layer/b/c", true); + assertEquals(2, listing.size()); + assertTrue(listing.get("foo").isDeleted()); + dir = fService.lookup(-1, "main:/layer/b/c", true); + listing = fService.getDirectoryListing(dir, true); + assertEquals(2, listing.size()); + assertTrue(listing.get("foo").isDeleted()); + // Delete something in a layer. + fService.removeNode("main:/layer/b/c", "bar"); + desc = fService.lookup(-1, "main:/layer/b/c/bar", true); + assertTrue(desc.isDeleted()); + assertTrue(desc.isDeletedFile()); + listing = fService.getDirectoryListing(-1, "main:/layer/b/c", true); + assertEquals(2, listing.size()); + assertTrue(listing.get("foo").isDeleted()); + assertTrue(listing.get("bar").isDeleted()); + listing = fService.getDirectoryListingDirect(-1, "main:/layer/b/c", true); + assertEquals(1, listing.size()); + assertTrue(listing.get("bar").isDeleted()); + dir = fService.lookup(-1, "main:/layer/b/c", true); + desc = fService.lookup(dir, "bar", true); + assertTrue(desc.isDeleted()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + + } + } + + /** + * Test Store property querying. + */ + public void testStorePropertyQuerying() throws Exception + { + try + { + fService.setStoreProperty("main", QName.createQName(null, ".dns.alice--preview"), new PropertyValue(null, "alice-preview")); + fService.setStoreProperty("main", QName.createQName("", ".other.property"), new PropertyValue(null, "other value")); + Map result = fService.queryStorePropertyKey("main", QName.createQName("", ".dns.%")); + assertEquals(1, result.size()); + + fService.createStore("second"); + fService.setStoreProperty("second", QName.createQName("", ".dns.alice"), new PropertyValue(null, "alice-space")); + Map> matches = fService.queryStoresPropertyKeys(QName.createQName("", ".dns.%")); + assertEquals(1, matches.get("main").size()); + assertEquals(1, matches.get("second").size()); + assertEquals("alice-preview", matches.get("main").get(QName.createQName(null, ".dns.alice--preview")).getStringValue()); + assertEquals("alice-space", matches.get("second").get(QName.createQName(null, ".dns.alice")).getStringValue()); + + fService.createStore("third"); + fService.setStoreProperty("third", QName.createQName("", ".dns.someUPPERcase"), new PropertyValue(null, "someUPPERcase-space")); + matches = fService.queryStoresPropertyKeys(QName.createQName("", ".dns.someuppercase%")); + assertEquals(1, matches.get("third").size()); + assertEquals("someUPPERcase-space", matches.get("third").get(QName.createQName(null, ".dns.someUPPERcase")).getStringValue()); + } + catch (Exception e) + { + e.printStackTrace(System.err); + throw e; + } + finally + { + fService.purgeStore("second"); + fService.purgeStore("third"); + } + } + + +} diff --git a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java index 1f68a181ab..27f004a34b 100644 --- a/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/LayeredDirectoryNodeImpl.java @@ -77,14 +77,14 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer * The indirection version. */ private int fIndirectionVersion; - + /** - * Default constructor. + * Default constructor. */ public LayeredDirectoryNodeImpl() { } - + /** * Make a new one from a specified indirection path. * @@ -96,24 +96,24 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer public LayeredDirectoryNodeImpl(String indirection, AVMStore store, AVMNode toCopy, Long parentAcl, ACLCopyMode mode) { super(store); - - setLayerID(-1); - setIndirection(indirection); - setIndirectionVersion(-1); - setPrimaryIndirection(true); - setOpacity(false); - + + setLayerID(-1); + setIndirection(indirection); + setIndirectionVersion(-1); + setPrimaryIndirection(true); + setOpacity(false); + if (toCopy != null) { setVersionID(toCopy.getVersionID() + 1); - + copyACLs(toCopy, parentAcl, mode); - copyCreationAndOwnerBasicAttributes(toCopy); + copyCreationAndOwnerBasicAttributes(toCopy); } else { - setVersionID(1); - + setVersionID(1); + if (indirection != null) { Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, indirection); @@ -126,7 +126,7 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer } else { - // TODO: Will not pick up changes if we start with no permission on the target node - may need + // TODO: Will not pick up changes if we start with no permission on the target node - may need // to add setAcl(DbAccessControlListImpl.createLayeredAcl(null)); } @@ -142,13 +142,13 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer } } - AVMDAOs.Instance().fAVMNodeDAO.save(this); - - if (toCopy != null) - { - copyProperties(toCopy); - copyAspects(toCopy); - } + AVMDAOs.Instance().fAVMNodeDAO.save(this); + + if (toCopy != null) + { + copyProperties(toCopy); + copyAspects(toCopy); + } } /** @@ -162,23 +162,23 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer public LayeredDirectoryNodeImpl(LayeredDirectoryNode other, AVMStore repos, Lookup lookup, boolean copyAll, Long parentAcl, ACLCopyMode mode) { super(repos); - - setLayerID(-1); - setIndirection(other.getIndirection()); - setIndirectionVersion(-1); - setPrimaryIndirection(other.getPrimaryIndirection()); - setOpacity(other.getOpacity()); - - setVersionID(other.getVersionID() + 1); - - copyACLs(other, parentAcl, mode); - copyCreationAndOwnerBasicAttributes(other); + + setLayerID(-1); + setIndirection(other.getIndirection()); + setIndirectionVersion(-1); + setPrimaryIndirection(other.getPrimaryIndirection()); + setOpacity(other.getOpacity()); + + setVersionID(other.getVersionID() + 1); + + copyACLs(other, parentAcl, mode); + copyCreationAndOwnerBasicAttributes(other); AVMDAOs.Instance().fAVMNodeDAO.save(this); - - copyProperties(other); - copyAspects(other); - + + copyProperties(other); + copyAspects(other); + Map children = null; if (copyAll) { @@ -209,23 +209,23 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer public LayeredDirectoryNodeImpl(PlainDirectoryNode other, AVMStore store, Lookup lPath, boolean copyContents, Long parentAcl, ACLCopyMode mode) { super(store); - - setLayerID(-1); - setIndirection(null); - setIndirectionVersion(-1); - setPrimaryIndirection(false); - setOpacity(false); - - setVersionID(other.getVersionID() + 1); - - copyACLs(other, parentAcl, mode); - copyCreationAndOwnerBasicAttributes(other); - + + setLayerID(-1); + setIndirection(null); + setIndirectionVersion(-1); + setPrimaryIndirection(false); + setOpacity(false); + + setVersionID(other.getVersionID() + 1); + + copyACLs(other, parentAcl, mode); + copyCreationAndOwnerBasicAttributes(other); + AVMDAOs.Instance().fAVMNodeDAO.save(this); - - copyProperties(other); - copyAspects(other); - + + copyProperties(other); + copyAspects(other); + if (copyContents) { for (ChildEntry child : AVMDAOs.Instance().fChildEntryDAO.getByParent(other, null)) @@ -253,23 +253,23 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer public LayeredDirectoryNodeImpl(DirectoryNode dir, AVMStore store, Lookup srcLookup, String name, Long inheritedAcl, ACLCopyMode mode) { super(store); - - setLayerID(-1); - setIndirection(srcLookup.getIndirectionPath() + "/" + name); - setIndirectionVersion(-1); - setPrimaryIndirection(true); - setOpacity(false); - + + setLayerID(-1); + setIndirection(srcLookup.getIndirectionPath() + "/" + name); + setIndirectionVersion(-1); + setPrimaryIndirection(true); + setOpacity(false); + setVersionID(dir.getVersionID() + 1); - - copyACLs(dir, inheritedAcl, mode); - copyCreationAndOwnerBasicAttributes(dir); - + + copyACLs(dir, inheritedAcl, mode); + copyCreationAndOwnerBasicAttributes(dir); + AVMDAOs.Instance().fAVMNodeDAO.save(this); - - copyProperties(dir); - copyAspects(dir); - + + copyProperties(dir); + copyAspects(dir); + Map children = dir.getListing(srcLookup, true); for (Map.Entry child : children.entrySet()) { @@ -319,9 +319,9 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer */ public String getUnderlying(Lookup lPath) { - if (getPrimaryIndirection()) + if (getPrimaryIndirection()) { - return getIndirection(); + return getIndirection(); } return lPath.getCurrentIndirection(); } @@ -339,9 +339,9 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer { return -1; } - if (getPrimaryIndirection()) + if (getPrimaryIndirection()) { - return getIndirectionVersion(); + return getIndirectionVersion(); } return lPath.getCurrentIndirectionVersion(); } @@ -427,7 +427,7 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer ChildEntry entry = new ChildEntryImpl(key, node); AVMDAOs.Instance().fChildEntryDAO.save(entry); } - + /** * Get a listing of the virtual contents of this directory. * @@ -451,7 +451,7 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer { // Get the base listing from the thing we indirect to. Map listing = new HashMap(); - if (!getOpacity()) + if (!getOpacity()) { Lookup lookup = AVMRepository.GetInstance().lookupDirectory(getUnderlyingVersion(lPath), getUnderlying(lPath)); if (lookup != null) @@ -463,7 +463,7 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer if (entry.getValue().getType() == AVMNodeType.LAYERED_DIRECTORY || entry.getValue().getType() == AVMNodeType.PLAIN_DIRECTORY) { - if (!AVMRepository.GetInstance().can(lookup.getAVMStore(), entry.getValue(), PermissionService.READ_CHILDREN, false)) + if (!AVMRepository.GetInstance().can(lookup.getAVMStore(), entry.getValue(), PermissionService.READ_CHILDREN, false)) { continue; } @@ -477,7 +477,7 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer if (entry.getChild().getType() == AVMNodeType.LAYERED_DIRECTORY || entry.getChild().getType() == AVMNodeType.PLAIN_DIRECTORY) { - if (!AVMRepository.GetInstance().can(lPath.getAVMStore(), entry.getChild(), PermissionService.READ_CHILDREN, lPath.getDirectlyContained())) + if (!AVMRepository.GetInstance().can(lPath.getAVMStore(), entry.getChild(), PermissionService.READ_CHILDREN, lPath.getDirectlyContained())) { continue; } @@ -509,9 +509,9 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer if (entry.getChild().getType() == AVMNodeType.LAYERED_DIRECTORY || entry.getChild().getType() == AVMNodeType.PLAIN_DIRECTORY) { - if (!AVMRepository.GetInstance().can(lPath != null ? lPath.getAVMStore() : null, - entry.getChild(), PermissionService.READ_CHILDREN, - lPath != null ? lPath.getDirectlyContained() : false)) + if (!AVMRepository.GetInstance().can(lPath != null ? lPath.getAVMStore() : null, + entry.getChild(), PermissionService.READ_CHILDREN, + lPath != null ? lPath.getDirectlyContained() : false)) { continue; } @@ -536,14 +536,14 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer public SortedMap getListingDirect(AVMNodeDescriptor dir, boolean includeDeleted) { List children = AVMDAOs.Instance().fChildEntryDAO.getByParent(this, null); - SortedMap listing = new TreeMap(String.CASE_INSENSITIVE_ORDER); + SortedMap listing = new TreeMap(String.CASE_INSENSITIVE_ORDER); for (ChildEntry child : children) { AVMNode childNode = child.getChild(); if (childNode.getType() == AVMNodeType.LAYERED_DIRECTORY || childNode.getType() == AVMNodeType.PLAIN_DIRECTORY) { - if (!AVMRepository.GetInstance().can(null, childNode, PermissionService.READ_CHILDREN, false)) + if (!AVMRepository.GetInstance().can(null, childNode, PermissionService.READ_CHILDREN, false)) { continue; } @@ -589,9 +589,9 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer { throw new AVMBadArgumentException("Illegal null argument."); } - SortedMap baseListing = new TreeMap(String.CASE_INSENSITIVE_ORDER); + SortedMap baseListing = new TreeMap(String.CASE_INSENSITIVE_ORDER); // If we are not opaque, get the underlying base listing. - if (!getOpacity()) + if (!getOpacity()) { Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, dir.getIndirection()); if (lookup != null) @@ -603,7 +603,7 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer if (entry.getValue().getType() == AVMNodeType.LAYERED_DIRECTORY || entry.getValue().getType() == AVMNodeType.PLAIN_DIRECTORY) { - if (!AVMRepository.GetInstance().can(null, entry.getValue(), PermissionService.READ_CHILDREN, false)) + if (!AVMRepository.GetInstance().can(null, entry.getValue(), PermissionService.READ_CHILDREN, false)) { continue; } @@ -621,7 +621,7 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer if (child.getChild().getType() == AVMNodeType.LAYERED_DIRECTORY || child.getChild().getType() == AVMNodeType.PLAIN_DIRECTORY) { - if (!AVMRepository.GetInstance().can(null, child.getChild(), PermissionService.READ_CHILDREN, false)) + if (!AVMRepository.GetInstance().can(null, child.getChild(), PermissionService.READ_CHILDREN, false)) { continue; } @@ -685,7 +685,7 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer return result; } // Don't check our underlying directory if we are opaque. - if (getOpacity()) + if (getOpacity()) { return null; } @@ -735,7 +735,7 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer return desc; } // If we are opaque don't check underneath. - if (getOpacity()) + if (getOpacity()) { return null; } @@ -804,10 +804,12 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer ghost.setAncestor(child); ghost.setDeletedType(child.getType()); - ghost.copyCreationAndOwnerBasicAttributes(child); + ghost.copyCreationAndOwnerBasicAttributes(child); + ghost.copyAspects(child); + ghost.copyProperties(child); AVMDAOs.Instance().fAVMNodeDAO.update(ghost); - + this.putChild(name, ghost); } } @@ -847,16 +849,16 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer checkReadOnly(); } - setIndirection(path); - setPrimaryIndirection(true); - + setIndirection(path); + setPrimaryIndirection(true); + // Need to change the permission we point to .... - if (getIndirection() != null) + if (getIndirection() != null) { if ((getAcl() == null) || (getAcl().getAclType() == ACLType.LAYERED)) { DbAccessControlList acl = null; - Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getIndirection()); + Lookup lookup = AVMRepository.GetInstance().lookupDirectory(-1, getIndirection()); if (lookup != null) { DirectoryNode dir = (DirectoryNode) lookup.getCurrentNode(); @@ -905,7 +907,7 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer } } - public void setAclAndInherit(LayeredDirectoryNode layeredDirectory, DbAccessControlList acl, String name) + public void setAclAndInherit(LayeredDirectoryNode layeredDirectory, DbAccessControlList acl, String name) { // Note ACLS may COW on next ACL change layeredDirectory.setAcl(acl); @@ -917,9 +919,9 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer { AVMNode node = directChildren.get(key); - if (node instanceof LayeredDirectoryNode) + if (node instanceof LayeredDirectoryNode) { - LayeredDirectoryNode childNode = (LayeredDirectoryNode) node; + LayeredDirectoryNode childNode = (LayeredDirectoryNode) node; DbAccessControlList currentAcl = node.getAcl(); if (currentAcl == null) { @@ -944,9 +946,9 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer } } } - else if (node instanceof PlainFileNode) + else if (node instanceof PlainFileNode) { - PlainFileNode childNode = (PlainFileNode) node; + PlainFileNode childNode = (PlainFileNode) node; DbAccessControlList currentAcl = node.getAcl(); if (currentAcl == null) { @@ -1045,10 +1047,10 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer BasicAttributes attrs = getBasicAttributes(); String path = lPath.getRepresentedPath(); path = AVMNodeConverter.ExtendAVMPath(path, name); - - int indirectionVersion = getUnderlyingVersion(lPath); + + int indirectionVersion = getUnderlyingVersion(lPath); String indirect = null; - if (getPrimaryIndirection()) + if (getPrimaryIndirection()) { indirect = getIndirection(); } @@ -1056,9 +1058,9 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer { indirect = AVMNodeConverter.ExtendAVMPath(lPath.getCurrentIndirection(), name); } - + return new AVMNodeDescriptor(path, name, AVMNodeType.LAYERED_DIRECTORY, attrs.getCreator(), attrs.getOwner(), attrs.getLastModifier(), attrs.getCreateDate(), attrs - .getModDate(), attrs.getAccessDate(), getId(), getGuid(), getVersionID(), indirect, indirectionVersion, getPrimaryIndirection(), getLayerID(), getOpacity(), -1, -1); + .getModDate(), attrs.getAccessDate(), getId(), getGuid(), getVersionID(), indirect, indirectionVersion, getPrimaryIndirection(), getLayerID(), getOpacity(), -1, -1); } /** @@ -1074,8 +1076,8 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer String path = lPath.getRepresentedPath(); String name = path.substring(path.lastIndexOf("/") + 1); return new AVMNodeDescriptor(path, name, AVMNodeType.LAYERED_DIRECTORY, attrs.getCreator(), attrs.getOwner(), attrs.getLastModifier(), attrs.getCreateDate(), attrs - .getModDate(), attrs.getAccessDate(), getId(), getGuid(), getVersionID(), getUnderlying(lPath), getUnderlyingVersion(lPath), getPrimaryIndirection(), getLayerID(), - getOpacity(), -1, -1); + .getModDate(), attrs.getAccessDate(), getId(), getGuid(), getVersionID(), getUnderlying(lPath), getUnderlyingVersion(lPath), getPrimaryIndirection(), getLayerID(), + getOpacity(), -1, -1); } /** @@ -1095,10 +1097,10 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer String path = parentPath.endsWith("/") ? parentPath + name : parentPath + "/" + name; String indirection = null; int indirectionVersion = -1; - if (getPrimaryIndirection()) + if (getPrimaryIndirection()) { - indirection = getIndirection(); - indirectionVersion = getIndirectionVersion(); + indirection = getIndirection(); + indirectionVersion = getIndirectionVersion(); } else { @@ -1106,7 +1108,7 @@ public class LayeredDirectoryNodeImpl extends DirectoryNodeImpl implements Layer indirectionVersion = parentIndirectionVersion; } return new AVMNodeDescriptor(path, name, AVMNodeType.LAYERED_DIRECTORY, attrs.getCreator(), attrs.getOwner(), attrs.getLastModifier(), attrs.getCreateDate(), attrs - .getModDate(), attrs.getAccessDate(), getId(), getGuid(), getVersionID(), indirection, indirectionVersion, getPrimaryIndirection(), getLayerID(), getOpacity(), -1, -1); + .getModDate(), attrs.getAccessDate(), getId(), getGuid(), getVersionID(), indirection, indirectionVersion, getPrimaryIndirection(), getLayerID(), getOpacity(), -1, -1); } /** diff --git a/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java b/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java index ec1110f805..f64eddd9e9 100644 --- a/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java +++ b/source/java/org/alfresco/repo/avm/PlainDirectoryNodeImpl.java @@ -42,7 +42,7 @@ import org.springframework.extensions.surf.util.Pair; * A plain directory. No monkey tricks except for possiblyCopy. * @author britt */ -public class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectoryNode +public class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDirectoryNode { static final long serialVersionUID = 9423813734583003L; @@ -55,14 +55,14 @@ public class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDi super(store); setVersionID(1); } - + /** - * Default constructor. + * Default constructor. */ - public PlainDirectoryNodeImpl() + public PlainDirectoryNodeImpl() { } - + /** * Copy like constructor. * @param other The other directory. @@ -72,12 +72,12 @@ public class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDi AVMStore store, Long parentAcl, ACLCopyMode mode) { super(store); - - setVersionID(other.getVersionID() + 1); - - copyACLs(other, parentAcl, mode); - copyCreationAndOwnerBasicAttributes(other); - + + setVersionID(other.getVersionID() + 1); + + copyACLs(other, parentAcl, mode); + copyCreationAndOwnerBasicAttributes(other); + AVMDAOs.Instance().fAVMNodeDAO.save(this); for (ChildEntry child : AVMDAOs.Instance().fChildEntryDAO.getByParent(other, null)) { @@ -86,11 +86,11 @@ public class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDi child.getChild()); AVMDAOs.Instance().fChildEntryDAO.save(newChild); } - + copyProperties(other); copyAspects(other); } - + /** * Get a directory listing. * @param lPath The lookup path. @@ -117,7 +117,7 @@ public class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDi if (child.getChild().getType() == AVMNodeType.LAYERED_DIRECTORY || child.getChild().getType() == AVMNodeType.PLAIN_DIRECTORY) { - if (!AVMRepository.GetInstance().can(lPath.getAVMStore(), child.getChild(), PermissionService.READ_CHILDREN, lPath.getDirectlyContained())) + if (!AVMRepository.GetInstance().can(lPath.getAVMStore(), child.getChild(), PermissionService.READ_CHILDREN, lPath.getDirectlyContained())) { continue; } @@ -126,7 +126,7 @@ public class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDi { continue; } - result.put(child.getKey().getName(), child.getChild()); + result.put(child.getKey().getName(), child.getChild()); } return result; } @@ -175,14 +175,14 @@ public class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDi { throw new AVMBadArgumentException("Path is null."); } - SortedMap result = new TreeMap(String.CASE_INSENSITIVE_ORDER); + SortedMap result = new TreeMap(String.CASE_INSENSITIVE_ORDER); List children = AVMDAOs.Instance().fChildEntryDAO.getByParent(this, childNamePattern); for (ChildEntry child : children) { if (child.getChild().getType() == AVMNodeType.LAYERED_DIRECTORY || child.getChild().getType() == AVMNodeType.PLAIN_DIRECTORY) { - if (!AVMRepository.GetInstance().can(null, child.getChild(), PermissionService.READ_CHILDREN, false)) + if (!AVMRepository.GetInstance().can(null, child.getChild(), PermissionService.READ_CHILDREN, false)) { continue; } @@ -228,7 +228,7 @@ public class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDi { return null; } - Pair result = new Pair(entry.getChild(), true); + Pair result = new Pair(entry.getChild(), true); return result; } @@ -280,13 +280,15 @@ public class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDi { DeletedNodeImpl ghost = new DeletedNodeImpl(lPath.getAVMStore(), child.getAcl()); AVMDAOs.Instance().fAVMNodeDAO.save(ghost); - + ghost.setAncestor(child); ghost.setDeletedType(child.getType()); - ghost.copyCreationAndOwnerBasicAttributes(child); - - AVMDAOs.Instance().fAVMNodeDAO.update(ghost); - + ghost.copyCreationAndOwnerBasicAttributes(child); + ghost.copyAspects(child); + ghost.copyProperties(child); + + AVMDAOs.Instance().fAVMNodeDAO.update(ghost); + putChild(name, ghost); } } @@ -338,8 +340,8 @@ public class PlainDirectoryNodeImpl extends DirectoryNodeImpl implements PlainDi newMe = new LayeredDirectoryNodeImpl(this, lPath.getAVMStore(), lPath, lPath.isInThisLayer(), parentAclId, ACLCopyMode.COPY); ((LayeredDirectoryNodeImpl)newMe).setLayerID(lPath.getTopLayer().getLayerID()); - - AVMDAOs.Instance().fAVMNodeDAO.update(newMe); + + AVMDAOs.Instance().fAVMNodeDAO.update(newMe); } else { diff --git a/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceTest.java b/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceTest.java index ef9c536899..0c27d39327 100644 --- a/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceTest.java +++ b/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceTest.java @@ -1,342 +1,533 @@ -/* - * 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 - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - * As a special exception to the terms and conditions of version 2.0 of - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: - * http://www.alfresco.com/legal/licensing - */ - -package org.alfresco.repo.avm.locking; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import junit.framework.TestCase; - -import org.alfresco.model.ContentModel; -import org.alfresco.model.WCMAppModel; -import org.alfresco.repo.security.authentication.AuthenticationComponent; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.service.cmr.attributes.AttributeService; -import org.alfresco.service.cmr.avm.locking.AVMLock; -import org.alfresco.service.cmr.avm.locking.AVMLockingService; -import org.alfresco.service.cmr.remote.RepoRemote; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.security.AuthenticationService; -import org.alfresco.service.cmr.security.AuthorityService; -import org.alfresco.service.cmr.security.AuthorityType; -import org.alfresco.service.cmr.security.MutableAuthenticationService; -import org.alfresco.service.cmr.security.PersonService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.ApplicationContextHelper; -import org.springframework.context.ApplicationContext; - -/** - * Tests for AVM locking service. - * @author britt - */ -public class AVMLockingServiceTest extends TestCase -{ - private static ApplicationContext fContext = null; - - private static AVMLockingService fService; - - private static AttributeService fAttributeService; - - private static PersonService fPersonService; - - private static AuthorityService fAuthorityService; - - private static MutableAuthenticationService fAuthenticationService; - - private static AuthenticationComponent fAuthenticationComponent; - - private static NodeService fNodeService; - - private static RepoRemote fRepoRemote; - - private static NodeRef fWebProject; - - private final static String WP = "alfresco-"+System.currentTimeMillis(); - - /* (non-Javadoc) - * @see junit.framework.TestCase#setUp() - */ - @Override - protected void setUp() throws Exception - { - if (fContext == null) - { - fContext = ApplicationContextHelper.getApplicationContext(); - fService = (AVMLockingService)fContext.getBean("AVMLockingService"); - fAttributeService = (AttributeService)fContext.getBean("AttributeService"); - fPersonService = (PersonService)fContext.getBean("PersonService"); - fAuthorityService = (AuthorityService)fContext.getBean("AuthorityService"); - fAuthenticationService = (MutableAuthenticationService)fContext.getBean("AuthenticationService"); - fAuthenticationComponent = (AuthenticationComponent)fContext.getBean("AuthenticationComponent"); - fAuthenticationComponent.setSystemUserAsCurrentUser(); - fNodeService = (NodeService)fContext.getBean("NodeService"); - fRepoRemote = (RepoRemote)fContext.getBean("RepoRemoteService"); - } - // Set up a fake web project. - NodeRef root = fRepoRemote.getRoot(); - Map properties = new HashMap(); - properties.put(WCMAppModel.PROP_AVMSTORE, WP); - fWebProject = fNodeService.createNode(root, ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, WP), - WCMAppModel.TYPE_AVMWEBFOLDER, properties).getChildRef(); - // Set up sample users groups and roles. - fAuthenticationService.createAuthentication("Buffy", "Buffy".toCharArray()); - fPersonService.getPerson("Buffy"); - fAuthorityService.createAuthority(AuthorityType.GROUP, "Scoobies"); - fAuthorityService.addAuthority("GROUP_Scoobies", "Buffy"); - fAuthorityService.createAuthority(AuthorityType.ROLE, "SUPER_POWERED"); - fAuthorityService.addAuthority("ROLE_SUPER_POWERED", "Buffy"); - fAuthenticationService.createAuthentication("Willow", "Willow".toCharArray()); - fPersonService.getPerson("Willow"); - fAuthorityService.addAuthority("GROUP_Scoobies", "Willow"); - fAuthenticationService.createAuthentication("Xander", "Xander".toCharArray()); - fPersonService.getPerson("Xander"); - fAuthorityService.addAuthority("GROUP_Scoobies", "Xander"); - fAuthenticationService.createAuthentication("Tara", "Tara".toCharArray()); - fPersonService.getPerson("Tara"); - fAuthenticationService.createAuthentication("Spike", "Spike".toCharArray()); - fPersonService.getPerson("Spike"); - fAuthorityService.addAuthority("ROLE_SUPER_POWERED", "Spike"); - fAuthorityService.createAuthority(AuthorityType.GROUP, "vampires"); - fAuthorityService.addAuthority("GROUP_vampires", "Spike"); - } - - /* (non-Javadoc) - * @see junit.framework.TestCase#tearDown() - */ - @Override - protected void tearDown() throws Exception - { - List webProjects = fService.getWebProjects(); - for (String webProject : webProjects) - { - if (webProject.equals(WP)) - { - fService.removeWebProject(WP); - } - } - fAuthenticationService.deleteAuthentication("Buffy"); - fAuthenticationService.deleteAuthentication("Willow"); - fAuthenticationService.deleteAuthentication("Xander"); - fAuthenticationService.deleteAuthentication("Tara"); - fAuthenticationService.deleteAuthentication("Spike"); - fPersonService.deletePerson("Buffy"); - fPersonService.deletePerson("Willow"); - fPersonService.deletePerson("Tara"); - fPersonService.deletePerson("Xander"); - fPersonService.deletePerson("Spike"); - fAuthorityService.deleteAuthority("GROUP_Scoobies"); - fAuthorityService.deleteAuthority("ROLE_SUPER_POWERED"); - fAuthorityService.deleteAuthority("GROUP_vampires"); - fNodeService.deleteNode(fWebProject); - } - - public void testAll() - { - try - { - fService.addWebProject(WP); - System.out.println(fAttributeService.getAttribute(".avm_lock_table")); - List owners = new ArrayList(); - owners.add("Buffy"); - owners.add("Spike"); - AVMLock lock = new AVMLock(WP, - "Sunnydale", - "Revello Drive/1630", - AVMLockingService.Type.DISCRETIONARY, - owners); - fService.lockPath(lock); - System.out.println(fAttributeService.getAttribute(".avm_lock_table")); - assertNotNull(fService.getLock(WP, "Revello Drive/1630")); - // assertEquals(1, fService.getUsersLocks("Buffy").size()); - assertEquals(1, fService.getWebProjectLocks(WP).size()); - List owners2 = new ArrayList(); - owners2.add("Buffy"); - owners2.add("Willow"); - AVMLock lock2 = new AVMLock(WP, - "Sunnydale", - "UC Sunnydale/Stevenson Hall", - AVMLockingService.Type.DISCRETIONARY, - owners2); - fService.lockPath(lock2); - System.out.println(fAttributeService.getAttribute(".avm_lock_table")); - // assertEquals(2, fService.getUsersLocks("Buffy").size()); - assertEquals(2, fService.getWebProjectLocks(WP).size()); - System.out.println("Before----------------------------"); - fService.removeLock(WP, "Revello Drive/1630"); - System.out.println("After----------------------------"); - System.out.println(fAttributeService.getAttribute(".avm_lock_table")); - // assertEquals(1, fService.getUsersLocks("Buffy").size()); - assertEquals(1, fService.getWebProjectLocks(WP).size()); - fService.removeWebProject(WP); - System.out.println(fAttributeService.getAttribute(".avm_lock_table")); - // assertEquals(0, fService.getUsersLocks("Spike").size()); - // assertEquals(0, fService.getUsersLocks("Buffy").size()); - // assertEquals(0, fService.getUsersLocks("Willow").size()); - // assertEquals(0, fService.getUsersLocks("Tara").size()); - } - catch (Exception e) - { - e.printStackTrace(); - fail(); - } - } - - public void testRoleBasedLocking() - { - try - { - fService.addWebProject(WP); - List owners = new ArrayList(); - owners.add("ROLE_SUPER_POWERED"); - owners.add("Tara"); - AVMLock lock = new AVMLock(WP, - "Sunnydale", - "TheInitiative/Adam/plans.txt", - AVMLockingService.Type.DISCRETIONARY, - owners); - fService.lockPath(lock); - assertTrue(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Buffy")); - assertTrue(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Spike")); - assertFalse(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Willow")); - assertTrue(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Tara")); - assertFalse(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Xander")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Buffy")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Spike")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Willow")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Tara")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Xander")); - } - catch (Exception e) - { - e.printStackTrace(); - fail(); - } - } - - public void testGroupBasedLocking() - { - try - { - fService.addWebProject(WP); - List owners = new ArrayList(); - owners.add("GROUP_Scoobies"); - owners.add("Tara"); - AVMLock lock = new AVMLock(WP, - "Sunnydale", - "TheInitiative/Adam/plans.txt", - AVMLockingService.Type.DISCRETIONARY, - owners); - fService.lockPath(lock); - assertTrue(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Buffy")); - assertFalse(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Spike")); - assertTrue(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Willow")); - assertTrue(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Tara")); - assertTrue(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Xander")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Buffy")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Spike")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Willow")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Tara")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Xander")); - } - catch (Exception e) - { - e.printStackTrace(); - fail(); - } - } - - public void testLockModification() - { - try - { - fService.addWebProject(WP); - List owners = new ArrayList(); - owners.add("GROUP_Scoobies"); - owners.add("Tara"); - AVMLock lock = new AVMLock(WP, - "Sunnydale", - "TheInitiative/Adam/plans.txt", - AVMLockingService.Type.DISCRETIONARY, - owners); - fService.lockPath(lock); - assertTrue(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Buffy")); - assertFalse(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Spike")); - assertTrue(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Willow")); - assertTrue(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Tara")); - assertTrue(fService.hasAccess(WP, "Sunnydale:/TheInitiative/Adam/plans.txt", "Xander")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Buffy")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Spike")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Willow")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Tara")); - assertFalse(fService.hasAccess(WP, "LA:/TheInitiative/Adam/plans.txt", "Xander")); - fService.modifyLock(WP, "TheInitiative/Adam/plans.txt", "ScrapHeap/Adam/plans.txt", null, null, null); - assertTrue(fService.hasAccess(WP, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Buffy")); - assertFalse(fService.hasAccess(WP, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Spike")); - assertTrue(fService.hasAccess(WP, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Willow")); - assertTrue(fService.hasAccess(WP, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Tara")); - assertTrue(fService.hasAccess(WP, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Xander")); - fService.modifyLock(WP, "ScrapHeap/Adam/plans.txt", null, "LA", null, null); - assertTrue(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Buffy")); - assertFalse(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Spike")); - assertTrue(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Willow")); - assertTrue(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Tara")); - assertTrue(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Xander")); - assertFalse(fService.hasAccess(WP, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Buffy")); - assertFalse(fService.hasAccess(WP, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Spike")); - assertFalse(fService.hasAccess(WP, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Willow")); - assertFalse(fService.hasAccess(WP, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Tara")); - assertFalse(fService.hasAccess(WP, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Xander")); - List usersToAdd = new ArrayList(); - usersToAdd.add("Spike"); - fService.modifyLock(WP, "ScrapHeap/Adam/plans.txt", null, null, null, usersToAdd); - assertTrue(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Buffy")); - assertTrue(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Spike")); - assertTrue(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Willow")); - assertTrue(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Tara")); - assertTrue(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Xander")); - List usersToRemove = new ArrayList(); - usersToRemove.add("GROUP_Scoobies"); - fService.modifyLock(WP, "ScrapHeap/Adam/plans.txt", null, null, usersToRemove, null); - assertFalse(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Buffy")); - assertTrue(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Spike")); - assertFalse(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Willow")); - assertTrue(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Tara")); - assertFalse(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", "Xander")); - assertTrue(fService.hasAccess(WP, "LA:/ScrapHeap/Adam/plans.txt", AuthenticationUtil.getAdminUserName())); - } - catch (Exception e) - { - e.printStackTrace(); - fail(); - } - } -} +/* + * 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ + +package org.alfresco.repo.avm.locking; + +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.alfresco.model.ContentModel; +import org.alfresco.model.WCMAppModel; +import org.alfresco.repo.avm.util.BulkLoader; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.transaction.RetryingTransactionHelper; +import org.alfresco.service.cmr.attributes.AttributeService; +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avm.locking.AVMLock; +import org.alfresco.service.cmr.avm.locking.AVMLockingService; +import org.alfresco.service.cmr.avmsync.AVMDifference; +import org.alfresco.service.cmr.avmsync.AVMSyncService; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.remote.RepoRemote; +import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.service.cmr.security.AuthorityType; +import org.alfresco.service.cmr.security.MutableAuthenticationService; +import org.alfresco.service.cmr.security.PersonService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.ApplicationContextHelper; +import org.alfresco.wcm.sandbox.SandboxConstants; +import org.springframework.context.ApplicationContext; + +/** + * Tests for WCM (web project) locking - AVMLockingService & AVMLockingAwareService + * + * @author britt + */ +public class AVMLockingServiceTest extends TestCase +{ + private static ApplicationContext fContext = null; + + private static AVMLockingService fLockingService; + + private static AVMService fService; + + private static AVMSyncService fSyncService; + + private static AttributeService fAttributeService; + + private static PersonService fPersonService; + + private static AuthorityService fAuthorityService; + + private static MutableAuthenticationService fAuthenticationService; + + private static NodeService fNodeService; + + private static RepoRemote fRepoRemote; + + private static NodeRef fWebProject; + + private static String[] testUsers = {"Buffy", "Willow", "Xander", "Tara", "Spike"}; + + private static String[] testAuthorities = {"GROUP_Scoobies", "ROLE_SUPER_POWERED", "GROUP_vampires"}; + + private static final String testWP1 = "alfresco-"+System.currentTimeMillis(); + + /* (non-Javadoc) + * @see junit.framework.TestCase#setUp() + */ + @Override + protected void setUp() throws Exception + { + if (fContext == null) + { + fContext = ApplicationContextHelper.getApplicationContext(); + fLockingService = (AVMLockingService)fContext.getBean("AVMLockingService"); + fService = (AVMService) fContext.getBean("AVMLockingAwareService"); + fSyncService = (AVMSyncService)fContext.getBean("AVMSyncService"); + fAttributeService = (AttributeService)fContext.getBean("AttributeService"); + fPersonService = (PersonService)fContext.getBean("PersonService"); + fAuthorityService = (AuthorityService)fContext.getBean("AuthorityService"); + fAuthenticationService = (MutableAuthenticationService)fContext.getBean("AuthenticationService"); + fNodeService = (NodeService)fContext.getBean("NodeService"); + fRepoRemote = (RepoRemote)fContext.getBean("RepoRemoteService"); + } + + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName()); + + // Set up a fake web project. + NodeRef root = fRepoRemote.getRoot(); + Map properties = new HashMap(); + properties.put(WCMAppModel.PROP_AVMSTORE, testWP1); + fWebProject = fNodeService.createNode(root, ContentModel.ASSOC_CONTAINS, + QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, testWP1), + WCMAppModel.TYPE_AVMWEBFOLDER, properties).getChildRef(); + + // Set up sample users groups and roles. + + cleanUsersAndGroups(); + + fAuthenticationService.createAuthentication("Buffy", "Buffy".toCharArray()); + fPersonService.getPerson("Buffy"); + fAuthorityService.createAuthority(AuthorityType.GROUP, "Scoobies"); + fAuthorityService.addAuthority("GROUP_Scoobies", "Buffy"); + fAuthorityService.createAuthority(AuthorityType.ROLE, "SUPER_POWERED"); + fAuthorityService.addAuthority("ROLE_SUPER_POWERED", "Buffy"); + + fAuthenticationService.createAuthentication("Willow", "Willow".toCharArray()); + fPersonService.getPerson("Willow"); + fAuthorityService.addAuthority("GROUP_Scoobies", "Willow"); + + fAuthenticationService.createAuthentication("Xander", "Xander".toCharArray()); + fPersonService.getPerson("Xander"); + fAuthorityService.addAuthority("GROUP_Scoobies", "Xander"); + + fAuthenticationService.createAuthentication("Tara", "Tara".toCharArray()); + fPersonService.getPerson("Tara"); + + fAuthenticationService.createAuthentication("Spike", "Spike".toCharArray()); + fPersonService.getPerson("Spike"); + fAuthorityService.addAuthority("ROLE_SUPER_POWERED", "Spike"); + fAuthorityService.createAuthority(AuthorityType.GROUP, "vampires"); + fAuthorityService.addAuthority("GROUP_vampires", "Spike"); + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#tearDown() + */ + @Override + protected void tearDown() throws Exception + { + List webProjects = fLockingService.getWebProjects(); + for (String webProject : webProjects) + { + if (webProject.equals(testWP1)) + { + fLockingService.removeStoreLocks(webProject); + fLockingService.removeWebProject(webProject); + } + } + cleanUsersAndGroups(); + fNodeService.deleteNode(fWebProject); + } + + private void cleanUsersAndGroups() + { + for (String testUser : testUsers) + { + if (fAuthenticationService.authenticationExists(testUser)) + { + fAuthenticationService.deleteAuthentication(testUser); + } + + if (fPersonService.personExists(testUser)) + { + fPersonService.deletePerson(testUser); + } + } + + for (String testAuthority : testAuthorities) + { + if (fAuthorityService.authorityExists(testAuthority)) + { + fAuthorityService.deleteAuthority(testAuthority); + } + } + } + + public void testAll() + { + try + { + fLockingService.addWebProject(testWP1); + System.out.println(fAttributeService.getAttribute(".avm_lock_table")); + List owners = new ArrayList(); + owners.add("Buffy"); + owners.add("Spike"); + AVMLock lock = new AVMLock(testWP1, + "Sunnydale", + "Revello Drive/1630", + AVMLockingService.Type.DISCRETIONARY, + owners); + fLockingService.lockPath(lock); + System.out.println(fAttributeService.getAttribute(".avm_lock_table")); + assertNotNull(fLockingService.getLock(testWP1, "Revello Drive/1630")); + // assertEquals(1, fLockingService.getUsersLocks("Buffy").size()); + assertEquals(1, fLockingService.getWebProjectLocks(testWP1).size()); + List owners2 = new ArrayList(); + owners2.add("Buffy"); + owners2.add("Willow"); + AVMLock lock2 = new AVMLock(testWP1, + "Sunnydale", + "UC Sunnydale/Stevenson Hall", + AVMLockingService.Type.DISCRETIONARY, + owners2); + fLockingService.lockPath(lock2); + System.out.println(fAttributeService.getAttribute(".avm_lock_table")); + // assertEquals(2, fLockingService.getUsersLocks("Buffy").size()); + assertEquals(2, fLockingService.getWebProjectLocks(testWP1).size()); + System.out.println("Before----------------------------"); + fLockingService.removeLock(testWP1, "Revello Drive/1630"); + System.out.println("After----------------------------"); + System.out.println(fAttributeService.getAttribute(".avm_lock_table")); + // assertEquals(1, fLockingService.getUsersLocks("Buffy").size()); + assertEquals(1, fLockingService.getWebProjectLocks(testWP1).size()); + fLockingService.removeWebProject(testWP1); + System.out.println(fAttributeService.getAttribute(".avm_lock_table")); + // assertEquals(0, fLockingService.getUsersLocks("Spike").size()); + // assertEquals(0, fLockingService.getUsersLocks("Buffy").size()); + // assertEquals(0, fLockingService.getUsersLocks("Willow").size()); + // assertEquals(0, fLockingService.getUsersLocks("Tara").size()); + } + catch (Exception e) + { + e.printStackTrace(); + fail(); + } + } + + public void testRoleBasedLocking() + { + try + { + fLockingService.addWebProject(testWP1); + List owners = new ArrayList(); + owners.add("ROLE_SUPER_POWERED"); + owners.add("Tara"); + AVMLock lock = new AVMLock(testWP1, + "Sunnydale", + "TheInitiative/Adam/plans.txt", + AVMLockingService.Type.DISCRETIONARY, + owners); + fLockingService.lockPath(lock); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Buffy")); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Spike")); + assertFalse(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Willow")); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Tara")); + assertFalse(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Xander")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Buffy")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Spike")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Willow")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Tara")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Xander")); + } + catch (Exception e) + { + e.printStackTrace(); + fail(); + } + } + + public void testGroupBasedLocking() + { + try + { + fLockingService.addWebProject(testWP1); + List owners = new ArrayList(); + owners.add("GROUP_Scoobies"); + owners.add("Tara"); + AVMLock lock = new AVMLock(testWP1, + "Sunnydale", + "TheInitiative/Adam/plans.txt", + AVMLockingService.Type.DISCRETIONARY, + owners); + fLockingService.lockPath(lock); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Buffy")); + assertFalse(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Spike")); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Willow")); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Tara")); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Xander")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Buffy")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Spike")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Willow")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Tara")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Xander")); + } + catch (Exception e) + { + e.printStackTrace(); + fail(); + } + } + + public void testLockModification() + { + try + { + fLockingService.addWebProject(testWP1); + List owners = new ArrayList(); + owners.add("GROUP_Scoobies"); + owners.add("Tara"); + AVMLock lock = new AVMLock(testWP1, + "Sunnydale", + "TheInitiative/Adam/plans.txt", + AVMLockingService.Type.DISCRETIONARY, + owners); + fLockingService.lockPath(lock); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Buffy")); + assertFalse(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Spike")); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Willow")); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Tara")); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/TheInitiative/Adam/plans.txt", "Xander")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Buffy")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Spike")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Willow")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Tara")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/TheInitiative/Adam/plans.txt", "Xander")); + fLockingService.modifyLock(testWP1, "TheInitiative/Adam/plans.txt", "ScrapHeap/Adam/plans.txt", null, null, null); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Buffy")); + assertFalse(fLockingService.hasAccess(testWP1, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Spike")); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Willow")); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Tara")); + assertTrue(fLockingService.hasAccess(testWP1, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Xander")); + fLockingService.modifyLock(testWP1, "ScrapHeap/Adam/plans.txt", null, "LA", null, null); + assertTrue(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Buffy")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Spike")); + assertTrue(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Willow")); + assertTrue(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Tara")); + assertTrue(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Xander")); + assertFalse(fLockingService.hasAccess(testWP1, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Buffy")); + assertFalse(fLockingService.hasAccess(testWP1, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Spike")); + assertFalse(fLockingService.hasAccess(testWP1, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Willow")); + assertFalse(fLockingService.hasAccess(testWP1, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Tara")); + assertFalse(fLockingService.hasAccess(testWP1, "Sunnydale:/ScrapHeap/Adam/plans.txt", "Xander")); + List usersToAdd = new ArrayList(); + usersToAdd.add("Spike"); + fLockingService.modifyLock(testWP1, "ScrapHeap/Adam/plans.txt", null, null, null, usersToAdd); + assertTrue(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Buffy")); + assertTrue(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Spike")); + assertTrue(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Willow")); + assertTrue(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Tara")); + assertTrue(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Xander")); + List usersToRemove = new ArrayList(); + usersToRemove.add("GROUP_Scoobies"); + fLockingService.modifyLock(testWP1, "ScrapHeap/Adam/plans.txt", null, null, usersToRemove, null); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Buffy")); + assertTrue(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Spike")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Willow")); + assertTrue(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Tara")); + assertFalse(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", "Xander")); + assertTrue(fLockingService.hasAccess(testWP1, "LA:/ScrapHeap/Adam/plans.txt", AuthenticationUtil.getAdminUserName())); + } + catch (Exception e) + { + e.printStackTrace(); + fail(); + } + } + + /** + * Minimal testing of Locking Aware service. + */ + public void testLockingAwareService() throws Exception + { + try + { + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); + + fService.createStore("main"); + + fLockingService.addWebProject("main"); + + // note: locking applies to WCM web projects, hence relies on WCM sandbox conventions (naming and properties) + fService.setStoreProperty("main", SandboxConstants.PROP_WEB_PROJECT_NODE_REF, new PropertyValue(DataTypeDefinition.NODE_REF, new NodeRef("workspace://SpacesStore/dummy"))); + + fService.createStore("main--admin"); + + setupBasicTree0(); + + List diffs = fSyncService.compare(-1, "main:/", -1, "main--admin:/", null); + assertEquals(2, diffs.size()); + assertEquals("[main:/a[-1] > main--admin:/a[-1], main:/d[-1] > main--admin:/d[-1]]", diffs.toString()); + + fSyncService.update(diffs, null, false, false, false, false, null, null); + + RetryingTransactionHelper.RetryingTransactionCallback cb = new RetryingTransactionHelper.RetryingTransactionCallback() + { + public Object execute() throws Exception + { + BulkLoader loader = new BulkLoader(); + loader.setAvmService(fService); + loader.recursiveLoad("source/java/org/alfresco/repo/avm", "main--admin:/"); + return null; + } + }; + RetryingTransactionHelper helper = (RetryingTransactionHelper) fContext.getBean("retryingTransactionHelper"); + helper.doInTransaction(cb); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + finally + { + fLockingService.removeStoreLocks("main"); + fLockingService.removeWebProject("main"); + + fService.purgeStore("main--admin"); + fService.purgeStore("main"); + + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName()); + } + } + + // Minimal test of locking with file 'rename' across web projects + public void testLockingAwareServiceFileRename() throws Exception + { + try + { + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getAdminUserName()); + + fService.createStore("wpA"); + fLockingService.addWebProject("wpA"); + + fService.createStore("wpA--admin"); + + fService.createStore("wpB"); + fLockingService.addWebProject("wpB"); + + fService.createStore("wpB--admin"); + + // note: locking applies to WCM web projects, hence relies on WCM sandbox conventions (naming and properties) + fService.setStoreProperty("wpA", SandboxConstants.PROP_WEB_PROJECT_NODE_REF, new PropertyValue(DataTypeDefinition.NODE_REF, new NodeRef("workspace://SpacesStore/dummyA"))); + fService.setStoreProperty("wpB", SandboxConstants.PROP_WEB_PROJECT_NODE_REF, new PropertyValue(DataTypeDefinition.NODE_REF, new NodeRef("workspace://SpacesStore/dummyB"))); + + assertNull(fLockingService.getLock("wpA", "/file1.txt")); + assertTrue(fLockingService.hasAccess("wpA", "wpA--admin:/file1.txt", "admin")); + + fService.createFile("wpA--admin:/", "file1.txt").close(); + + assertNotNull(fLockingService.getLock("wpA", "/file1.txt")); + assertEquals("admin", fLockingService.getLock("wpA", "/file1.txt").getOwners().get(0)); + assertTrue(fLockingService.hasAccess("wpA", "wpA--admin:/file1.txt", "admin")); + + assertNull(fLockingService.getLock("wpB", "/file1.txt")); + assertTrue(fLockingService.hasAccess("wpB", "wpB--admin:/file1.txt", "admin")); + + // ETHREEOH-1544 + fService.rename("wpA--admin:/", "file1.txt", "wpB--admin:/", "file1.txt"); + + assertNull(fLockingService.getLock("wpA", "/file1.txt")); + assertTrue(fLockingService.hasAccess("wpA", "wpA--admin:/file1.txt", "admin")); + + assertNotNull(fLockingService.getLock("wpB", "/file1.txt")); + assertEquals("admin", fLockingService.getLock("wpB", "/file1.txt").getOwners().get(0)); + assertTrue(fLockingService.hasAccess("wpB", "wpB--admin:/file1.txt", "admin")); + } + catch (Exception e) + { + e.printStackTrace(); + throw e; + } + finally + { + try { fLockingService.removeStoreLocks("wpA"); } catch (Exception e) {} + try { fLockingService.removeWebProject("wpA"); } catch (Exception e) {} + + if (fService.getStore("wpA--admin") != null) { fService.purgeStore("wpA--admin"); } + if (fService.getStore("wpA") != null) { fService.purgeStore("wpA"); } + + try { fLockingService.removeStoreLocks("wpB"); } catch (Exception e) {} + try { fLockingService.removeWebProject("wpB"); } catch (Exception e) {} + + if (fService.getStore("wpB--admin") != null) { fService.purgeStore("wpB--admin"); } + if (fService.getStore("wpB") != null) { fService.purgeStore("wpB"); } + + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName()); + } + } + + /** + * Setup a basic tree. + */ + protected void setupBasicTree0() + throws IOException + { + fService.createDirectory("main:/", "a"); + fService.createDirectory("main:/a", "b"); + fService.createDirectory("main:/a/b", "c"); + fService.createDirectory("main:/", "d"); + fService.createDirectory("main:/d", "e"); + fService.createDirectory("main:/d/e", "f"); + + fService.createFile("main:/a/b/c", "foo").close(); + ContentWriter writer = fService.getContentWriter("main:/a/b/c/foo"); + writer.setEncoding("UTF-8"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.putContent("I am main:/a/b/c/foo"); + + fService.createFile("main:/a/b/c", "bar").close(); + writer = fService.getContentWriter("main:/a/b/c/bar"); + // Force a conversion + writer.setEncoding("UTF-16"); + writer.setMimetype(MimetypeMap.MIMETYPE_TEXT_PLAIN); + writer.putContent("I am main:/a/b/c/bar"); + + fService.createSnapshot("main", null, null); + } +} diff --git a/source/java/org/alfresco/repo/deploy/DeploymentServiceImpl.java b/source/java/org/alfresco/repo/deploy/DeploymentServiceImpl.java index 7c979ed2c1..dde432e977 100644 --- a/source/java/org/alfresco/repo/deploy/DeploymentServiceImpl.java +++ b/source/java/org/alfresco/repo/deploy/DeploymentServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2009 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -425,12 +425,12 @@ public class DeploymentServiceImpl implements DeploymentService String name = entry.getKey(); AVMNodeDescriptor srcNode = entry.getValue(); - if (isStale(srcNode)) + if (isStale(srcNode)) { - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Stale child found: " + srcNode); - } + if (fgLogger.isDebugEnabled()) + { + fgLogger.debug("Stale child found: " + srcNode); + } srcList.remove(name); } } @@ -646,12 +646,12 @@ public class DeploymentServiceImpl implements DeploymentService /** * Temporary work around for staleness. */ - if (isStale(child)) + if (isStale(child)) { - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Stale child found: " + child); - } + if (fgLogger.isDebugEnabled()) + { + fgLogger.debug("Stale child found: " + child); + } continue; } @@ -1252,11 +1252,11 @@ public class DeploymentServiceImpl implements DeploymentService * Correct fix would be to remove stale files from the snapshot. * Code becomes obsolete once stale files are not part of the snapshot. */ - if (isStale(src)) + if (isStale(src)) { if (fgLogger.isDebugEnabled()) { - fgLogger.debug("Stale child found: " + src); + fgLogger.debug("Stale child found: " + src); } src = null; continue; @@ -1440,14 +1440,14 @@ public class DeploymentServiceImpl implements DeploymentService { if (!excluded(matcher, child.getPath(), null)) { - if (isStale(child)) - { - if (fgLogger.isDebugEnabled()) - { - fgLogger.debug("Stale child found: " + child); - } - continue; - } + if (isStale(child)) + { + if (fgLogger.isDebugEnabled()) + { + fgLogger.debug("Stale child found: " + child); + } + continue; + } createOnFSR(service, ticket, version, child, dstPath, matcher, sendQueue); } } @@ -1867,25 +1867,36 @@ public class DeploymentServiceImpl implements DeploymentService } } } - - private boolean isStale(AVMNodeDescriptor avmRef) - { - // note: currently specific to WCM use-cases, eg. ETHREEOH-2758 - if ((avmRef.isLayeredDirectory() && avmRef.isPrimary()) || avmRef.isLayeredFile()) - { - AVMNodeDescriptor parentNode = avmRef; - - while((parentNode.isLayeredDirectory() && parentNode.isPrimary()) || parentNode.isLayeredFile()) - { - AVMNodeDescriptor childNode = fAVMService.lookup(avmRef.getIndirectionVersion(), avmRef.getIndirection()); - if(childNode == null) - { - // The child node is missing - return true; - } - parentNode = childNode; - } - } - return false; - } + + private boolean isStale(AVMNodeDescriptor avmRef) + { + // note: currently specific to WCM use-cases, eg. ETHREEOH-2758 + if ((avmRef.isLayeredDirectory() && avmRef.isPrimary()) || avmRef.isLayeredFile()) + { + AVMNodeDescriptor srcNode = avmRef; + + while ((srcNode.isLayeredDirectory() && srcNode.isPrimary()) || srcNode.isLayeredFile()) + { + AVMNodeDescriptor targetNode = fAVMService.lookup(srcNode.getIndirectionVersion(), srcNode.getIndirection()); + if (targetNode == null) + { + if (srcNode.isLayeredFile() || + (srcNode.isLayeredDirectory() && + (! srcNode.getOpacity()) && + fAVMService.getDirectoryListingDirect(srcNode, false).isEmpty())) + { + // The target node is missing + return true; + } + else + { + // unbacked layered dir - however opaque or not directly empty + return false; + } + } + srcNode = targetNode; + } + } + return false; + } } diff --git a/source/java/org/alfresco/repo/domain/hibernate/AbstractPermissionsDaoComponentImpl.java b/source/java/org/alfresco/repo/domain/hibernate/AbstractPermissionsDaoComponentImpl.java index 9e52ddc576..d94671c4f5 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/AbstractPermissionsDaoComponentImpl.java +++ b/source/java/org/alfresco/repo/domain/hibernate/AbstractPermissionsDaoComponentImpl.java @@ -522,6 +522,7 @@ public abstract class AbstractPermissionsDaoComponentImpl implements Permissions public void setInheritParentPermissions(NodeRef nodeRef, boolean inheritParentPermissions) { + DbAccessControlList acl = getAccessControlList(nodeRef); if ((acl == null) && (inheritParentPermissions == INHERIT_PERMISSIONS_DEFAULT)) { @@ -541,9 +542,8 @@ public abstract class AbstractPermissionsDaoComponentImpl implements Permissions } else { - // TODO: Find inheritance - // ATM this should wire up any previous inheritance that existed - changes = aclDaoComponent.enableInheritance(report.getCreated().getId(), null); + Long parentAcl = getACLDAO(nodeRef).getInheritedAcl(nodeRef); + changes = aclDaoComponent.enableInheritance(report.getCreated().getId(), parentAcl); } List all = new ArrayList(changes.size() + report.getChanges().size()); all.addAll(report.getChanges()); diff --git a/source/java/org/alfresco/repo/domain/hibernate/AclDaoComponentImpl.java b/source/java/org/alfresco/repo/domain/hibernate/AclDaoComponentImpl.java index 57003d9507..2120c92128 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/AclDaoComponentImpl.java +++ b/source/java/org/alfresco/repo/domain/hibernate/AclDaoComponentImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2009 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -45,9 +45,9 @@ import org.alfresco.repo.domain.DbAuthority; import org.alfresco.repo.domain.DbPermission; import org.alfresco.repo.domain.Node; import org.alfresco.repo.domain.QNameDAO; -import org.alfresco.repo.domain.avm.AVMNodeDAO; -import org.alfresco.repo.domain.avm.AVMNodeEntity; -import org.alfresco.repo.domain.patch.PatchDAO; +import org.alfresco.repo.domain.avm.AVMNodeDAO; +import org.alfresco.repo.domain.avm.AVMNodeEntity; +import org.alfresco.repo.domain.patch.PatchDAO; import org.alfresco.repo.security.permissions.ACEType; import org.alfresco.repo.security.permissions.ACLCopyMode; import org.alfresco.repo.security.permissions.ACLType; @@ -113,12 +113,12 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo /** Access to QName entities */ private QNameDAO qnameDAO; - - /** Access to AVMNode queries */ - private AVMNodeDAO avmNodeDAO; - - /** Access to additional Patch queries */ - private PatchDAO patchDAO; + + /** Access to AVMNode queries */ + private AVMNodeDAO avmNodeDAO; + + /** Access to additional Patch queries */ + private PatchDAO patchDAO; /** a transactionally-safe cache to be injected */ private SimpleCache aclCache; @@ -174,17 +174,17 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo { this.qnameDAO = qnameDAO; } - - public void setPatchDAO(PatchDAO patchDAO) - { - this.patchDAO = patchDAO; - } - - public void setAvmNodeDAO(AVMNodeDAO avmNodeDAO) - { - this.avmNodeDAO = avmNodeDAO; - } - + + public void setPatchDAO(PatchDAO patchDAO) + { + this.patchDAO = patchDAO; + } + + public void setAvmNodeDAO(AVMNodeDAO avmNodeDAO) + { + this.avmNodeDAO = avmNodeDAO; + } + /** * Set the ACL cache * @@ -1277,7 +1277,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo { throw new UnsupportedOperationException(); } - + public AccessControlList getAccessControlList(Long id) { AccessControlList acl = aclCache.get(id); @@ -1434,7 +1434,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo } else { - // Assuem we are just resetting it to inherit as before + // Assume we are just resetting it to inherit as before if (targetAcl.getInheritsFrom() != null) { inheritedAcl = (DbAccessControlList) getHibernateTemplate().get(DbAccessControlListImpl.class, targetAcl.getInheritsFrom()); @@ -1786,14 +1786,14 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo DbAccessControlList acl = (DbAccessControlList) getHibernateTemplate().get(DbAccessControlListImpl.class, id); return acl; } - + public List getAvmNodesByACL(final Long id) { List avmNodeIds = avmNodeDAO.getAVMNodesByAclId(id); return avmNodeIds; } - + @SuppressWarnings("unchecked") private List disableInheritanceImpl(Long id, boolean setInheritedOnAcl, DbAccessControlList acl) { @@ -2224,7 +2224,7 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo /** * How many nodes are noew in store (approximate) * - * @return - the number of new nodes - approximate + * @return - the number of new nodes - approximate */ public Long getNewInStore() { @@ -2233,22 +2233,22 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo } /** - * Find layered directories Used to improve performance during patching and cascading the effect of permission + * Find layered directories Used to improve performance during patching and cascading the effect of permission * changes between layers * * @return - layered directories */ public List getLayeredDirectories() { - List ldNodeEntities = avmNodeDAO.getAllLayeredDirectories(); - - ArrayList indirections = new ArrayList(ldNodeEntities.size()); - - for (AVMNodeEntity ldNodeEntity : ldNodeEntities) + List ldNodeEntities = avmNodeDAO.getAllLayeredDirectories(); + + ArrayList indirections = new ArrayList(ldNodeEntities.size()); + + for (AVMNodeEntity ldNodeEntity : ldNodeEntities) { - Long from = ldNodeEntity.getId(); - String to = ldNodeEntity.getIndirection(); + Long from = ldNodeEntity.getId(); + String to = ldNodeEntity.getIndirection(); Integer version = ldNodeEntity.getIndirectionVersion(); indirections.add(new Indirection(from, to, version)); } @@ -2256,21 +2256,21 @@ public class AclDaoComponentImpl extends HibernateDaoSupport implements AclDaoCo } /** - * Find layered files Used to improve performance during patching and cascading the effect of permission changes + * Find layered files Used to improve performance during patching and cascading the effect of permission changes * between layers * - * @return - layered files + * @return - layered files */ public List getLayeredFiles() { - List lfNodeEntities = avmNodeDAO.getAllLayeredFiles(); - - ArrayList indirections = new ArrayList(lfNodeEntities.size()); - - for (AVMNodeEntity lfNodeEntity : lfNodeEntities) + List lfNodeEntities = avmNodeDAO.getAllLayeredFiles(); + + ArrayList indirections = new ArrayList(lfNodeEntities.size()); + + for (AVMNodeEntity lfNodeEntity : lfNodeEntities) { - Long from = lfNodeEntity.getId(); - String to = lfNodeEntity.getIndirection(); + Long from = lfNodeEntity.getId(); + String to = lfNodeEntity.getIndirection(); Integer version = lfNodeEntity.getIndirectionVersion(); indirections.add(new Indirection(from, to, version)); } diff --git a/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java b/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java index 4289bd2a65..54cd462db5 100644 --- a/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java +++ b/source/java/org/alfresco/repo/model/filefolder/FileFolderServiceImplTest.java @@ -51,6 +51,7 @@ import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.model.FileNotFoundException; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentWriter; +import org.alfresco.service.cmr.repository.CyclicChildRelationshipException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; @@ -685,4 +686,20 @@ public class FileFolderServiceImplTest extends TestCase FileFolderServiceType type = fileFolderService.getType(ContentModel.TYPE_FOLDER); assertEquals("Type incorrect for folder", FileFolderServiceType.FOLDER, type); } + + public void testETHREEOH_3088_MoveIntoSelf() throws Exception + { + FileInfo folderInfo = fileFolderService.create(workingRootNodeRef, "NotGood.txt", ContentModel.TYPE_FOLDER); + NodeRef folderNodeRef = folderInfo.getNodeRef(); + // Move into self + try + { + fileFolderService.move(folderNodeRef, folderNodeRef, null); + fail("Failed to detect cyclic relationship"); + } + catch (CyclicChildRelationshipException e) + { + // Expected + } + } } diff --git a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java index b50b7313ee..ebde7878e8 100644 --- a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java @@ -134,6 +134,7 @@ import org.hibernate.Session; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.exception.ConstraintViolationException; +import org.hibernate.exception.SQLGrammarException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; @@ -194,7 +195,8 @@ public class HibernateNodeDaoServiceImpl { DUPLICATE_CHILD_NAME_EXCEPTIONS = new Class[] { ConstraintViolationException.class, - DataIntegrityViolationException.class + DataIntegrityViolationException.class, + SQLGrammarException.class // Hibernate misinterprets a MS SQL Server exception }; } @@ -1992,7 +1994,6 @@ public class HibernateNodeDaoServiceImpl * @param childAssocChangingCallback the callback in which the child assoc is modified * @return Returns the callback's result */ - @SuppressWarnings("unchecked") private Object writeChildAssocChanges( HibernateCallback childAssocChangingCallback, NodeRef parentNodeRef, @@ -2022,18 +2023,31 @@ public class HibernateNodeDaoServiceImpl e, "Exception while flushing child assoc to database"); throw ee; } - else + else if (constraintViolation instanceof SQLGrammarException) { - if (isDebugEnabled) + SQLGrammarException sqlge = (SQLGrammarException) constraintViolation; + if (sqlge.getMessage().contains("isolation") || sqlge.getCause().getMessage().contains("isolation")) { - logger.debug( - "Duplicate child association detected: \n" + - " Parent node: " + parentNodeRef + "\n" + - " Child node name: " + childName, - e); + // This will do to cover ETHREEOH-3170 + } + else + { + // It was something else + RuntimeException ee = AlfrescoRuntimeException.makeRuntimeException( + e, "Exception while flushing child assoc to database"); + throw ee; } - throw new DuplicateChildNodeNameException(parentNodeRef, assocTypeQName, childName); } + // We caught an exception that indicates a duplicate child + if (isDebugEnabled) + { + logger.debug( + "Duplicate child association detected: \n" + + " Parent node: " + parentNodeRef + "\n" + + " Child node name: " + childName, + e); + } + throw new DuplicateChildNodeNameException(parentNodeRef, assocTypeQName, childName); } } @@ -2275,7 +2289,7 @@ public class HibernateNodeDaoServiceImpl } else if (aclProperties.getAclType() == ACLType.SHARED) { - setFixedAcls(childNodeId, inheritedAclId, true); + setFixedAcls(childNodeId, inheritedAclId, true, null); } } else @@ -2301,7 +2315,7 @@ public class HibernateNodeDaoServiceImpl { Long parentAcl = newParentNode.getAccessControlList().getId(); Long inheritedAcl = aclDaoComponent.getInheritedAccessControlList(parentAcl); - setFixedAcls(childNodeId, inheritedAcl, true); + setFixedAcls(childNodeId, inheritedAcl, true, null); } } } @@ -2317,16 +2331,26 @@ public class HibernateNodeDaoServiceImpl * This code is here, and not in another DAO, in order to avoid unnecessary circular callbacks * and cyclical dependencies. It would be nice if the ACL code could be separated (or combined) * but the node tree walking code is best done right here. - * - * @param nodeRef - * @param mergeFromAclId - * @param set */ private void setFixedAcls( final Long nodeId, final Long mergeFromAclId, - final boolean set) + final boolean set, + Set processedNodes) { + // ETHREEOH-3088: Cut/Paste into same hierarchy + if (processedNodes == null) + { + processedNodes = new HashSet(3); + } + if (!processedNodes.add(nodeId)) + { + logger.error( + "Cyclic parent-child relationship detected: \n" + + " current node: " + nodeId); + throw new CyclicChildRelationshipException("Node has been pasted into its own tree.", null); + } + Node mergeFromNode = getNodeNotNull(nodeId); if (set) @@ -2366,7 +2390,7 @@ public class HibernateNodeDaoServiceImpl if (acl == null) { - setFixedAcls(childNodeId, mergeFromAclId, true); + setFixedAcls(childNodeId, mergeFromAclId, true, processedNodes); } else if (acl.getAclType() == ACLType.LAYERED) { @@ -2380,7 +2404,7 @@ public class HibernateNodeDaoServiceImpl } else { - setFixedAcls(childNodeId, mergeFromAclId, true); + setFixedAcls(childNodeId, mergeFromAclId, true, processedNodes); } } } @@ -3125,12 +3149,17 @@ public class HibernateNodeDaoServiceImpl criteria.setFlushMode(FlushMode.MANUAL); List nodeList = criteria.list(); - List nodeIds = new ArrayList(nodeList.size()); + Set nodeIds = new HashSet(nodeList.size()*2); for (Node node : nodeList) { + // We have duplicate nodes, so make sure we only process each node once Long nodeId = node.getId(); + if (!nodeIds.add(nodeId)) + { + // Already processed + continue; + } storeAndNodeIdCache.put(node.getNodeRef(), nodeId); - nodeIds.add(nodeId); } if (nodeIds.size() == 0) @@ -3646,12 +3675,12 @@ public class HibernateNodeDaoServiceImpl if (assocIdStack.contains(assocId)) { // the association was present already - throw new CyclicChildRelationshipException( + logger.error( "Cyclic parent-child relationship detected: \n" + " current node: " + currentNodeId + "\n" + " current path: " + currentPath + "\n" + - " next assoc: " + assocId, - assocRef); + " next assoc: " + assocId); + throw new CyclicChildRelationshipException("Node has been pasted into its own tree.", assocRef); } // push the assoc stack, recurse and pop diff --git a/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java b/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java index fdd845898e..ef09ed02bd 100644 --- a/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java +++ b/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceImpl.java @@ -1,423 +1,423 @@ -/* +/* * 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 - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - * As a special exception to the terms and conditions of version 2.0 of - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: - * http://www.alfresco.com/legal/licensing - */ -package org.alfresco.repo.security.permissions.impl; - -import java.io.Serializable; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import net.sf.acegisecurity.Authentication; -import net.sf.acegisecurity.GrantedAuthority; -import net.sf.acegisecurity.providers.dao.User; - -import org.alfresco.model.ContentModel; -import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.avm.AVMRepository; -import org.alfresco.repo.cache.SimpleCache; -import org.alfresco.repo.policy.JavaBehaviour; -import org.alfresco.repo.policy.PolicyComponent; -import org.alfresco.repo.security.authentication.AuthenticationUtil; -import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; -import org.alfresco.repo.security.permissions.ACLType; -import org.alfresco.repo.security.permissions.AccessControlEntry; -import org.alfresco.repo.security.permissions.AccessControlList; -import org.alfresco.repo.security.permissions.AccessControlListProperties; -import org.alfresco.repo.security.permissions.DynamicAuthority; -import org.alfresco.repo.security.permissions.NodePermissionEntry; -import org.alfresco.repo.security.permissions.PermissionEntry; -import org.alfresco.repo.security.permissions.PermissionReference; -import org.alfresco.repo.security.permissions.PermissionServiceSPI; -import org.alfresco.repo.tenant.TenantService; + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ +package org.alfresco.repo.security.permissions.impl; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import net.sf.acegisecurity.Authentication; +import net.sf.acegisecurity.GrantedAuthority; +import net.sf.acegisecurity.providers.dao.User; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.avm.AVMNodeConverter; +import org.alfresco.repo.avm.AVMRepository; +import org.alfresco.repo.cache.SimpleCache; +import org.alfresco.repo.policy.JavaBehaviour; +import org.alfresco.repo.policy.PolicyComponent; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.repo.security.permissions.ACLType; +import org.alfresco.repo.security.permissions.AccessControlEntry; +import org.alfresco.repo.security.permissions.AccessControlList; +import org.alfresco.repo.security.permissions.AccessControlListProperties; +import org.alfresco.repo.security.permissions.DynamicAuthority; +import org.alfresco.repo.security.permissions.NodePermissionEntry; +import org.alfresco.repo.security.permissions.PermissionEntry; +import org.alfresco.repo.security.permissions.PermissionReference; +import org.alfresco.repo.security.permissions.PermissionServiceSPI; +import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.version.Version2Model; -import org.alfresco.repo.version.VersionModel; -import org.alfresco.repo.version.common.VersionUtil; -import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.service.cmr.security.AccessPermission; -import org.alfresco.service.cmr.security.AccessStatus; -import org.alfresco.service.cmr.security.AuthorityService; -import org.alfresco.service.cmr.security.PermissionContext; -import org.alfresco.service.cmr.security.PermissionService; -import org.alfresco.service.namespace.NamespaceService; -import org.alfresco.service.namespace.QName; -import org.alfresco.util.EqualsHelper; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.InitializingBean; - -/** - * The Alfresco implementation of a permissions service against our APIs for the permissions model and permissions - * persistence. - * - * @author andyh - */ -public class PermissionServiceImpl implements PermissionServiceSPI, InitializingBean -{ - - static SimplePermissionReference OLD_ALL_PERMISSIONS_REFERENCE = new SimplePermissionReference(QName.createQName("", PermissionService.ALL_PERMISSIONS), - PermissionService.ALL_PERMISSIONS); - - private static Log log = LogFactory.getLog(PermissionServiceImpl.class); - - /** a transactionally-safe cache to be injected */ - private SimpleCache accessCache; - - /* - * Access to the model - */ - private ModelDAO modelDAO; - - /* - * Access to permissions - */ - private PermissionsDaoComponent permissionsDaoComponent; - - /* - * Access to the node service - */ - private NodeService nodeService; - - /* - * Access to the tenant service - */ - private TenantService tenantService; - - /* - * Access to the data dictionary - */ - private DictionaryService dictionaryService; - - /* - * Access to the authority component - */ - private AuthorityService authorityService; - - /* - * Dynamic authorities providers - */ - private List dynamicAuthorities; - - private PolicyComponent policyComponent; - - private AclDaoComponent aclDaoComponent; - - private PermissionReference allPermissionReference; - - /** - * Standard spring construction. - */ - public PermissionServiceImpl() - { - super(); - } - - // - // Inversion of control - // - - /** - * Set the dictionary service - * @param dictionaryService - */ - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } - - /** - * Set the permissions model dao - * - * @param modelDAO - */ - public void setModelDAO(ModelDAO modelDAO) - { - this.modelDAO = modelDAO; - } - - /** - * Set the node service. - * - * @param nodeService - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - - /** - * Set the tenant service. - * @param tenantService - */ - public void setTenantService(TenantService tenantService) - { - this.tenantService = tenantService; - } - - /** - * Set the permissions dao component - * - * @param permissionsDaoComponent - */ - public void setPermissionsDaoComponent(PermissionsDaoComponent permissionsDaoComponent) - { - this.permissionsDaoComponent = permissionsDaoComponent; - } - - /** - * Set the authority service. - * - * @param authorityService - */ - public void setAuthorityService(AuthorityService authorityService) - { - this.authorityService = authorityService; - } - - /** - * Set the dynamic authorities - * - * @param dynamicAuthorities - */ - public void setDynamicAuthorities(List dynamicAuthorities) - { - this.dynamicAuthorities = dynamicAuthorities; - } - - /** - * Set the ACL DAO component. - * - * @param aclDaoComponent - */ - public void setAclDaoComponent(AclDaoComponent aclDaoComponent) - { - this.aclDaoComponent = aclDaoComponent; - } - - /** - * Set the permissions access cache. - * - * @param accessCache - * a transactionally safe cache - */ - public void setAccessCache(SimpleCache accessCache) - { - this.accessCache = accessCache; - } - - /** - * Set the policy component - * - * @param policyComponent - */ - public void setPolicyComponent(PolicyComponent policyComponent) - { - this.policyComponent = policyComponent; - } - - /** - * Cache clear on move node - * - * @param oldChildAssocRef - * @param newChildAssocRef - */ - public void onMoveNode(ChildAssociationRef oldChildAssocRef, ChildAssociationRef newChildAssocRef) - { - accessCache.clear(); - } - - public void afterPropertiesSet() throws Exception - { - if (dictionaryService == null) - { - throw new IllegalArgumentException("Property 'dictionaryService' has not been set"); - } - if (modelDAO == null) - { - throw new IllegalArgumentException("Property 'modelDAO' has not been set"); - } - if (nodeService == null) - { - throw new IllegalArgumentException("Property 'nodeService' has not been set"); - } - if (permissionsDaoComponent == null) - { - throw new IllegalArgumentException("Property 'permissionsDAO' has not been set"); - } - if (authorityService == null) - { - throw new IllegalArgumentException("Property 'authorityService' has not been set"); - } - if (accessCache == null) - { - throw new IllegalArgumentException("Property 'accessCache' has not been set"); - } - if (policyComponent == null) - { - throw new IllegalArgumentException("Property 'policyComponent' has not been set"); - } - if (aclDaoComponent == null) - { - throw new IllegalArgumentException("Property 'aclDaoComponent' has not been set"); - } - - allPermissionReference = getPermissionReference(ALL_PERMISSIONS); - - } - - public void init() - { - policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"), ContentModel.TYPE_BASE, new JavaBehaviour(this, "onMoveNode")); - - } - - // - // Permissions Service - // - - public String getOwnerAuthority() - { - return OWNER_AUTHORITY; - } - - public String getAllAuthorities() - { - return ALL_AUTHORITIES; - } - - public String getAllPermission() - { - return ALL_PERMISSIONS; - } - - public Set getPermissions(NodeRef nodeRef) - { - return getAllPermissionsImpl(nodeRef, true, true); - } - - public Set getAllSetPermissions(NodeRef nodeRef) - { - HashSet accessPermissions = new HashSet(); - NodePermissionEntry nodePremissionEntry = getSetPermissions(nodeRef); - for (PermissionEntry pe : nodePremissionEntry.getPermissionEntries()) - { - accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority(), pe.getPosition())); - } - return accessPermissions; - } - - public Set getAllSetPermissions(StoreRef storeRef) - { - HashSet accessPermissions = new HashSet(); - NodePermissionEntry nodePremissionEntry = getSetPermissions(storeRef); - for (PermissionEntry pe : nodePremissionEntry.getPermissionEntries()) - { - accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority(), pe.getPosition())); - } - return accessPermissions; - } - - private Set getAllPermissionsImpl(NodeRef nodeRef, boolean includeTrue, boolean includeFalse) - { - String userName = AuthenticationUtil.getRunAsUser(); - HashSet accessPermissions = new HashSet(); - for (PermissionReference pr : getSettablePermissionReferences(nodeRef)) - { - if (hasPermission(nodeRef, pr) == AccessStatus.ALLOWED) - { - accessPermissions.add(new AccessPermissionImpl(getPermission(pr), AccessStatus.ALLOWED, userName, -1)); - } - else - { - if (includeFalse) - { - accessPermissions.add(new AccessPermissionImpl(getPermission(pr), AccessStatus.DENIED, userName, -1)); - } - } - } - return accessPermissions; - } - - public Set getSettablePermissions(NodeRef nodeRef) - { - Set settable = getSettablePermissionReferences(nodeRef); - Set strings = new HashSet(settable.size()); - for (PermissionReference pr : settable) - { - strings.add(getPermission(pr)); - } - return strings; - } - - public Set getSettablePermissions(QName type) - { - Set settable = getSettablePermissionReferences(type); - Set strings = new LinkedHashSet(settable.size()); - for (PermissionReference pr : settable) - { - strings.add(getPermission(pr)); - } - return strings; - } - - public NodePermissionEntry getSetPermissions(NodeRef nodeRef) - { - return permissionsDaoComponent.getPermissions(tenantService.getName(nodeRef)); - } - - public NodePermissionEntry getSetPermissions(StoreRef storeRef) - { - return permissionsDaoComponent.getPermissions(storeRef); - } - - public AccessStatus hasPermission(NodeRef passedNodeRef, final PermissionReference permIn) - { - // If the node ref is null there is no sensible test to do - and there - // must be no permissions - // - so we allow it - if (passedNodeRef == null) - { - return AccessStatus.ALLOWED; - } - - // If the permission is null we deny - if (permIn == null) - { - return AccessStatus.DENIED; - } - - // AVM nodes - test for existence underneath - if (passedNodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM)) - { - return doAvmCan(passedNodeRef, permIn); - } +import org.alfresco.repo.version.VersionModel; +import org.alfresco.repo.version.common.VersionUtil; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.security.AccessPermission; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.AuthorityService; +import org.alfresco.service.cmr.security.PermissionContext; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.alfresco.util.EqualsHelper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.InitializingBean; + +/** + * The Alfresco implementation of a permissions service against our APIs for the permissions model and permissions + * persistence. + * + * @author andyh + */ +public class PermissionServiceImpl implements PermissionServiceSPI, InitializingBean +{ + + static SimplePermissionReference OLD_ALL_PERMISSIONS_REFERENCE = new SimplePermissionReference(QName.createQName("", PermissionService.ALL_PERMISSIONS), + PermissionService.ALL_PERMISSIONS); + + private static Log log = LogFactory.getLog(PermissionServiceImpl.class); + + /** a transactionally-safe cache to be injected */ + private SimpleCache accessCache; + + /* + * Access to the model + */ + private ModelDAO modelDAO; + + /* + * Access to permissions + */ + private PermissionsDaoComponent permissionsDaoComponent; + + /* + * Access to the node service + */ + private NodeService nodeService; + + /* + * Access to the tenant service + */ + private TenantService tenantService; + + /* + * Access to the data dictionary + */ + private DictionaryService dictionaryService; + + /* + * Access to the authority component + */ + private AuthorityService authorityService; + + /* + * Dynamic authorities providers + */ + private List dynamicAuthorities; + + private PolicyComponent policyComponent; + + private AclDaoComponent aclDaoComponent; + + private PermissionReference allPermissionReference; + + /** + * Standard spring construction. + */ + public PermissionServiceImpl() + { + super(); + } + + // + // Inversion of control + // + + /** + * Set the dictionary service + * @param dictionaryService + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * Set the permissions model dao + * + * @param modelDAO + */ + public void setModelDAO(ModelDAO modelDAO) + { + this.modelDAO = modelDAO; + } + + /** + * Set the node service. + * + * @param nodeService + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + /** + * Set the tenant service. + * @param tenantService + */ + public void setTenantService(TenantService tenantService) + { + this.tenantService = tenantService; + } + + /** + * Set the permissions dao component + * + * @param permissionsDaoComponent + */ + public void setPermissionsDaoComponent(PermissionsDaoComponent permissionsDaoComponent) + { + this.permissionsDaoComponent = permissionsDaoComponent; + } + + /** + * Set the authority service. + * + * @param authorityService + */ + public void setAuthorityService(AuthorityService authorityService) + { + this.authorityService = authorityService; + } + + /** + * Set the dynamic authorities + * + * @param dynamicAuthorities + */ + public void setDynamicAuthorities(List dynamicAuthorities) + { + this.dynamicAuthorities = dynamicAuthorities; + } + + /** + * Set the ACL DAO component. + * + * @param aclDaoComponent + */ + public void setAclDaoComponent(AclDaoComponent aclDaoComponent) + { + this.aclDaoComponent = aclDaoComponent; + } + + /** + * Set the permissions access cache. + * + * @param accessCache + * a transactionally safe cache + */ + public void setAccessCache(SimpleCache accessCache) + { + this.accessCache = accessCache; + } + + /** + * Set the policy component + * + * @param policyComponent + */ + public void setPolicyComponent(PolicyComponent policyComponent) + { + this.policyComponent = policyComponent; + } + + /** + * Cache clear on move node + * + * @param oldChildAssocRef + * @param newChildAssocRef + */ + public void onMoveNode(ChildAssociationRef oldChildAssocRef, ChildAssociationRef newChildAssocRef) + { + accessCache.clear(); + } + + public void afterPropertiesSet() throws Exception + { + if (dictionaryService == null) + { + throw new IllegalArgumentException("Property 'dictionaryService' has not been set"); + } + if (modelDAO == null) + { + throw new IllegalArgumentException("Property 'modelDAO' has not been set"); + } + if (nodeService == null) + { + throw new IllegalArgumentException("Property 'nodeService' has not been set"); + } + if (permissionsDaoComponent == null) + { + throw new IllegalArgumentException("Property 'permissionsDAO' has not been set"); + } + if (authorityService == null) + { + throw new IllegalArgumentException("Property 'authorityService' has not been set"); + } + if (accessCache == null) + { + throw new IllegalArgumentException("Property 'accessCache' has not been set"); + } + if (policyComponent == null) + { + throw new IllegalArgumentException("Property 'policyComponent' has not been set"); + } + if (aclDaoComponent == null) + { + throw new IllegalArgumentException("Property 'aclDaoComponent' has not been set"); + } + + allPermissionReference = getPermissionReference(ALL_PERMISSIONS); + + } + + public void init() + { + policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"), ContentModel.TYPE_BASE, new JavaBehaviour(this, "onMoveNode")); + + } + + // + // Permissions Service + // + + public String getOwnerAuthority() + { + return OWNER_AUTHORITY; + } + + public String getAllAuthorities() + { + return ALL_AUTHORITIES; + } + + public String getAllPermission() + { + return ALL_PERMISSIONS; + } + + public Set getPermissions(NodeRef nodeRef) + { + return getAllPermissionsImpl(nodeRef, true, true); + } + + public Set getAllSetPermissions(NodeRef nodeRef) + { + HashSet accessPermissions = new HashSet(); + NodePermissionEntry nodePremissionEntry = getSetPermissions(nodeRef); + for (PermissionEntry pe : nodePremissionEntry.getPermissionEntries()) + { + accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority(), pe.getPosition())); + } + return accessPermissions; + } + + public Set getAllSetPermissions(StoreRef storeRef) + { + HashSet accessPermissions = new HashSet(); + NodePermissionEntry nodePremissionEntry = getSetPermissions(storeRef); + for (PermissionEntry pe : nodePremissionEntry.getPermissionEntries()) + { + accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority(), pe.getPosition())); + } + return accessPermissions; + } + + private Set getAllPermissionsImpl(NodeRef nodeRef, boolean includeTrue, boolean includeFalse) + { + String userName = AuthenticationUtil.getRunAsUser(); + HashSet accessPermissions = new HashSet(); + for (PermissionReference pr : getSettablePermissionReferences(nodeRef)) + { + if (hasPermission(nodeRef, pr) == AccessStatus.ALLOWED) + { + accessPermissions.add(new AccessPermissionImpl(getPermission(pr), AccessStatus.ALLOWED, userName, -1)); + } + else + { + if (includeFalse) + { + accessPermissions.add(new AccessPermissionImpl(getPermission(pr), AccessStatus.DENIED, userName, -1)); + } + } + } + return accessPermissions; + } + + public Set getSettablePermissions(NodeRef nodeRef) + { + Set settable = getSettablePermissionReferences(nodeRef); + Set strings = new HashSet(settable.size()); + for (PermissionReference pr : settable) + { + strings.add(getPermission(pr)); + } + return strings; + } + + public Set getSettablePermissions(QName type) + { + Set settable = getSettablePermissionReferences(type); + Set strings = new LinkedHashSet(settable.size()); + for (PermissionReference pr : settable) + { + strings.add(getPermission(pr)); + } + return strings; + } + + public NodePermissionEntry getSetPermissions(NodeRef nodeRef) + { + return permissionsDaoComponent.getPermissions(tenantService.getName(nodeRef)); + } + + public NodePermissionEntry getSetPermissions(StoreRef storeRef) + { + return permissionsDaoComponent.getPermissions(storeRef); + } + + public AccessStatus hasPermission(NodeRef passedNodeRef, final PermissionReference permIn) + { + // If the node ref is null there is no sensible test to do - and there + // must be no permissions + // - so we allow it + if (passedNodeRef == null) + { + return AccessStatus.ALLOWED; + } + + // If the permission is null we deny + if (permIn == null) + { + return AccessStatus.DENIED; + } + + // AVM nodes - test for existence underneath + if (passedNodeRef.getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM)) + { + return doAvmCan(passedNodeRef, permIn); + } // Note: if we're directly accessing a frozen state (version) node (ie. in the 'version' store) we need to check permissions for the versioned node (ie. in the 'live' store) if (isVersionNodeRef(passedNodeRef)) @@ -425,1504 +425,1505 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing passedNodeRef = convertVersionNodeRefToVersionedNodeRef(VersionUtil.convertNodeRef(passedNodeRef)); } - // Allow permissions for nodes that do not exist - if (!nodeService.exists(passedNodeRef)) - { - return AccessStatus.ALLOWED; - } - - final NodeRef nodeRef = tenantService.getName(passedNodeRef); - - final PermissionReference perm; - if (permIn.equals(OLD_ALL_PERMISSIONS_REFERENCE)) - { - perm = getAllPermissionReference(); - } - else - { - perm = permIn; - } - - if (AuthenticationUtil.getRunAsUser() == null) - { - return AccessStatus.DENIED; - } - - if (AuthenticationUtil.isRunAsUserTheSystemUser()) - { - return AccessStatus.ALLOWED; - } - - // New ACLs - - AccessControlListProperties properties = permissionsDaoComponent.getAccessControlListProperties(nodeRef); - if ((properties != null) && (properties.getAclType() != null) && (properties.getAclType() != ACLType.OLD)) - { - QName typeQname = nodeService.getType(nodeRef); - Set aspectQNames = nodeService.getAspects(nodeRef); - PermissionContext context = new PermissionContext(typeQname); - context.getAspects().addAll(aspectQNames); - Authentication auth = AuthenticationUtil.getRunAsAuthentication(); - String user = AuthenticationUtil.getRunAsUser(); - for (String dynamicAuthority : getDynamicAuthorities(auth, nodeRef, perm)) - { - context.addDynamicAuthorityAssignment(user, dynamicAuthority); - } - return hasPermission(properties.getId(), context, perm); - } - - // Get the current authentications - // Use the smart authentication cache to improve permissions performance - Authentication auth = AuthenticationUtil.getRunAsAuthentication(); - final Set authorisations = getAuthorisations(auth, nodeRef, perm); - - // If the node does not support the given permission there is no point - // doing the test - Set available = AuthenticationUtil.runAs(new RunAsWork>() - { - public Set doWork() throws Exception - { - return modelDAO.getAllPermissions(nodeRef); - } - - }, AuthenticationUtil.getSystemUserName()); - - available.add(getAllPermissionReference()); - available.add(OLD_ALL_PERMISSIONS_REFERENCE); - - final Serializable key = generateKey(authorisations, nodeRef, perm, CacheType.HAS_PERMISSION); - if (!(available.contains(perm))) - { - accessCache.put(key, AccessStatus.DENIED); - return AccessStatus.DENIED; - } - - if (AuthenticationUtil.isRunAsUserTheSystemUser()) - { - return AccessStatus.ALLOWED; - } - - return AuthenticationUtil.runAs(new RunAsWork() - { - - public AccessStatus doWork() throws Exception - { - - AccessStatus status = accessCache.get(key); - if (status != null) - { - return status; - } - - // - // TODO: Dynamic permissions via evaluators - // - - /* - * Does the current authentication have the supplied permission on the given node. - */ - - QName typeQname = nodeService.getType(nodeRef); - Set aspectQNames = nodeService.getAspects(nodeRef); - - NodeTest nt = new NodeTest(perm, typeQname, aspectQNames); - boolean result = nt.evaluate(authorisations, nodeRef); - if (log.isDebugEnabled()) - { - log.debug("Permission <" - + perm + "> is " + (result ? "allowed" : "denied") + " for " + AuthenticationUtil.getRunAsUser() + " on node " - + nodeService.getPath(nodeRef)); - } - - status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; - accessCache.put(key, status); - return status; - } - }, AuthenticationUtil.getSystemUserName()); - - } - - private AccessStatus doAvmCan(NodeRef nodeRef, PermissionReference permission) - { - org.springframework.extensions.surf.util.Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); - int version = avmVersionPath.getFirst(); - String path = avmVersionPath.getSecond(); - boolean result = AVMRepository.GetInstance().can(nodeRef.getStoreRef().getIdentifier(), version, path, permission.getName()); - AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; - return status; - } - - /* - * (non-Javadoc) - * - * @see org.alfresco.service.cmr.security.PermissionService#hasPermission(java.lang.Long, java.lang.String, - * java.lang.String) - */ - public AccessStatus hasPermission(Long aclID, PermissionContext context, String permission) - { - return hasPermission(aclID, context, getPermissionReference(permission)); - } - - - private AccessStatus hasPermission(Long aclId, PermissionContext context, PermissionReference permission) - { - if (aclId == null) - { - // Enforce store ACLs if set - the AVM default was to "allow" if there are no permissions set ... - if (context.getStoreAcl() == null) - { - return AccessStatus.ALLOWED; - } - else - { - if (AuthenticationUtil.isRunAsUserTheSystemUser()) - { - return AccessStatus.ALLOWED; - } - - Authentication auth = AuthenticationUtil.getRunAsAuthentication(); - if (auth == null) - { - throw new IllegalStateException("Unauthenticated"); - } - Set storeAuthorisations = getAuthorisations(auth, (PermissionContext) null); - QName typeQname = context.getType(); - Set aspectQNames = context.getAspects(); - AclTest aclTest = new AclTest(permission, typeQname, aspectQNames); - boolean result = aclTest.evaluate(storeAuthorisations, context.getStoreAcl(), context); - AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; - return status; - } - } - - if (permission == null) - { - return AccessStatus.DENIED; - } - - if (AuthenticationUtil.getRunAsUser() == null) - { - return AccessStatus.DENIED; - } - - if (AuthenticationUtil.getRunAsUser().equals(AuthenticationUtil.getSystemUserName())) - { - return AccessStatus.ALLOWED; - } - - // Get the current authentications - // Use the smart authentication cache to improve permissions performance - Authentication auth = AuthenticationUtil.getRunAsAuthentication(); - if (auth == null) - { - throw new IllegalStateException("Unauthenticated"); - } - - Set authorisations = getAuthorisations(auth, context); - - // If the node does not support the given permission there is no point - // doing the test - - final QName typeQname = context.getType(); - final Set aspectQNames = context.getAspects(); - - Set available = AuthenticationUtil.runAs(new RunAsWork>() - { - public Set doWork() throws Exception - { - return modelDAO.getAllPermissions(typeQname, aspectQNames); - } - - }, AuthenticationUtil.getSystemUserName()); - available.add(getAllPermissionReference()); - available.add(OLD_ALL_PERMISSIONS_REFERENCE); - - if (!(available.contains(permission))) - { - return AccessStatus.DENIED; - } - - if (AuthenticationUtil.isRunAsUserTheSystemUser()) - { - return AccessStatus.ALLOWED; - } - - if (permission.equals(OLD_ALL_PERMISSIONS_REFERENCE)) - { - permission = getAllPermissionReference(); - } - - boolean result; - if (context.getStoreAcl() == null) - { - AclTest aclTest = new AclTest(permission, typeQname, aspectQNames); - result = aclTest.evaluate(authorisations, aclId, context); - } - else - { - Set storeAuthorisations = getAuthorisations(auth, (PermissionContext) null); - AclTest aclTest = new AclTest(permission, typeQname, aspectQNames); - result = aclTest.evaluate(authorisations, aclId, context) && aclTest.evaluate(storeAuthorisations, context.getStoreAcl(), context); - } - AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; - return status; - - } - - /** - * Control permissions cache - only used when we do old style permission evaluations - * - which should only be in DM stores where no permissions have been set - * - * @author andyh - * - */ - enum CacheType - { - /** - * cache full check - */ - HAS_PERMISSION, - /** - * Cache single permission check - */ - SINGLE_PERMISSION, - /** - * Cache single permission check for global permission checks - */ - SINGLE_PERMISSION_GLOBAL; - } - - /** - * Key for a cache object is built from all the known Authorities (which can change dynamically so they must all be - * used) the NodeRef ID and the permission reference itself. This gives a unique key for each permission test. - */ - static Serializable generateKey(Set auths, NodeRef nodeRef, PermissionReference perm, CacheType type) - { - LinkedHashSet key = new LinkedHashSet(); - key.add(perm.toString()); - key.addAll(auths); - key.add(nodeRef); - key.add(type); - return key; - } - - /** - * Get the authorisations for the currently authenticated user - * - * @param auth - * @return the set of authorisations - */ - private Set getAuthorisations(Authentication auth, NodeRef nodeRef, PermissionReference required) - { - - HashSet auths = new HashSet(); - // No authenticated user then no permissions - if (auth == null) - { - return auths; - } - // TODO: Refactor and use the authentication service for this. - User user = (User) auth.getPrincipal(); - - String username = user.getUsername(); - auths.add(username); - + // Allow permissions for nodes that do not exist + if (!nodeService.exists(passedNodeRef)) + { + return AccessStatus.ALLOWED; + } + + final NodeRef nodeRef = tenantService.getName(passedNodeRef); + + final PermissionReference perm; + if (permIn.equals(OLD_ALL_PERMISSIONS_REFERENCE)) + { + perm = getAllPermissionReference(); + } + else + { + perm = permIn; + } + + if (AuthenticationUtil.getRunAsUser() == null) + { + return AccessStatus.DENIED; + } + + if (AuthenticationUtil.isRunAsUserTheSystemUser()) + { + return AccessStatus.ALLOWED; + } + + // New ACLs + + AccessControlListProperties properties = permissionsDaoComponent.getAccessControlListProperties(nodeRef); + if ((properties != null) && (properties.getAclType() != null) && (properties.getAclType() != ACLType.OLD)) + { + QName typeQname = nodeService.getType(nodeRef); + Set aspectQNames = nodeService.getAspects(nodeRef); + PermissionContext context = new PermissionContext(typeQname); + context.getAspects().addAll(aspectQNames); + Authentication auth = AuthenticationUtil.getRunAsAuthentication(); + String user = AuthenticationUtil.getRunAsUser(); + for (String dynamicAuthority : getDynamicAuthorities(auth, nodeRef, perm)) + { + context.addDynamicAuthorityAssignment(user, dynamicAuthority); + } + return hasPermission(properties.getId(), context, perm); + } + + // Get the current authentications + // Use the smart authentication cache to improve permissions performance + Authentication auth = AuthenticationUtil.getRunAsAuthentication(); + final Set authorisations = getAuthorisations(auth, nodeRef, perm); + + // If the node does not support the given permission there is no point + // doing the test + Set available = AuthenticationUtil.runAs(new RunAsWork>() + { + public Set doWork() throws Exception + { + return modelDAO.getAllPermissions(nodeRef); + } + + }, AuthenticationUtil.getSystemUserName()); + + available.add(getAllPermissionReference()); + available.add(OLD_ALL_PERMISSIONS_REFERENCE); + + final Serializable key = generateKey(authorisations, nodeRef, perm, CacheType.HAS_PERMISSION); + if (!(available.contains(perm))) + { + accessCache.put(key, AccessStatus.DENIED); + return AccessStatus.DENIED; + } + + if (AuthenticationUtil.isRunAsUserTheSystemUser()) + { + return AccessStatus.ALLOWED; + } + + return AuthenticationUtil.runAs(new RunAsWork() + { + + public AccessStatus doWork() throws Exception + { + + AccessStatus status = accessCache.get(key); + if (status != null) + { + return status; + } + + // + // TODO: Dynamic permissions via evaluators + // + + /* + * Does the current authentication have the supplied permission on the given node. + */ + + QName typeQname = nodeService.getType(nodeRef); + Set aspectQNames = nodeService.getAspects(nodeRef); + + NodeTest nt = new NodeTest(perm, typeQname, aspectQNames); + boolean result = nt.evaluate(authorisations, nodeRef); + if (log.isDebugEnabled()) + { + log.debug("Permission <" + + perm + "> is " + (result ? "allowed" : "denied") + " for " + AuthenticationUtil.getRunAsUser() + " on node " + + nodeService.getPath(nodeRef)); + } + + status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; + accessCache.put(key, status); + return status; + } + }, AuthenticationUtil.getSystemUserName()); + + } + + private AccessStatus doAvmCan(NodeRef nodeRef, PermissionReference permission) + { + org.springframework.extensions.surf.util.Pair avmVersionPath = AVMNodeConverter.ToAVMVersionPath(nodeRef); + int version = avmVersionPath.getFirst(); + String path = avmVersionPath.getSecond(); + boolean result = AVMRepository.GetInstance().can(nodeRef.getStoreRef().getIdentifier(), version, path, permission.getName()); + AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; + return status; + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.service.cmr.security.PermissionService#hasPermission(java.lang.Long, java.lang.String, + * java.lang.String) + */ + public AccessStatus hasPermission(Long aclID, PermissionContext context, String permission) + { + return hasPermission(aclID, context, getPermissionReference(permission)); + } + + + private AccessStatus hasPermission(Long aclId, PermissionContext context, PermissionReference permission) + { + if (aclId == null) + { + // Enforce store ACLs if set - the AVM default was to "allow" if there are no permissions set ... + if (context.getStoreAcl() == null) + { + return AccessStatus.ALLOWED; + } + else + { + if (AuthenticationUtil.isRunAsUserTheSystemUser()) + { + return AccessStatus.ALLOWED; + } + + Authentication auth = AuthenticationUtil.getRunAsAuthentication(); + if (auth == null) + { + throw new IllegalStateException("Unauthenticated"); + } + Set storeAuthorisations = getAuthorisations(auth, (PermissionContext) null); + QName typeQname = context.getType(); + Set aspectQNames = context.getAspects(); + AclTest aclTest = new AclTest(permission, typeQname, aspectQNames); + boolean result = aclTest.evaluate(storeAuthorisations, context.getStoreAcl(), context); + AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; + return status; + } + } + + if (permission == null) + { + return AccessStatus.DENIED; + } + + if (AuthenticationUtil.getRunAsUser() == null) + { + return AccessStatus.DENIED; + } + + if (AuthenticationUtil.getRunAsUser().equals(AuthenticationUtil.getSystemUserName())) + { + return AccessStatus.ALLOWED; + } + + // Get the current authentications + // Use the smart authentication cache to improve permissions performance + Authentication auth = AuthenticationUtil.getRunAsAuthentication(); + if (auth == null) + { + throw new IllegalStateException("Unauthenticated"); + } + + Set authorisations = getAuthorisations(auth, context); + + // If the node does not support the given permission there is no point + // doing the test + + final QName typeQname = context.getType(); + final Set aspectQNames = context.getAspects(); + + Set available = AuthenticationUtil.runAs(new RunAsWork>() + { + public Set doWork() throws Exception + { + return modelDAO.getAllPermissions(typeQname, aspectQNames); + } + + }, AuthenticationUtil.getSystemUserName()); + available.add(getAllPermissionReference()); + available.add(OLD_ALL_PERMISSIONS_REFERENCE); + + if (!(available.contains(permission))) + { + return AccessStatus.DENIED; + } + + if (AuthenticationUtil.isRunAsUserTheSystemUser()) + { + return AccessStatus.ALLOWED; + } + + if (permission.equals(OLD_ALL_PERMISSIONS_REFERENCE)) + { + permission = getAllPermissionReference(); + } + + boolean result; + if (context.getStoreAcl() == null) + { + AclTest aclTest = new AclTest(permission, typeQname, aspectQNames); + result = aclTest.evaluate(authorisations, aclId, context); + } + else + { + Set storeAuthorisations = getAuthorisations(auth, (PermissionContext) null); + AclTest aclTest = new AclTest(permission, typeQname, aspectQNames); + result = aclTest.evaluate(authorisations, aclId, context) && aclTest.evaluate(storeAuthorisations, context.getStoreAcl(), context); + } + AccessStatus status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED; + return status; + + } + + /** + * Control permissions cache - only used when we do old style permission evaluations + * - which should only be in DM stores where no permissions have been set + * + * @author andyh + * + */ + enum CacheType + { + /** + * cache full check + */ + HAS_PERMISSION, + /** + * Cache single permission check + */ + SINGLE_PERMISSION, + /** + * Cache single permission check for global permission checks + */ + SINGLE_PERMISSION_GLOBAL; + } + + /** + * Key for a cache object is built from all the known Authorities (which can change dynamically so they must all be + * used) the NodeRef ID and the permission reference itself. This gives a unique key for each permission test. + */ + static Serializable generateKey(Set auths, NodeRef nodeRef, PermissionReference perm, CacheType type) + { + LinkedHashSet key = new LinkedHashSet(); + key.add(perm.toString()); + key.addAll(auths); + key.add(nodeRef); + key.add(type); + return key; + } + + /** + * Get the authorisations for the currently authenticated user + * + * @param auth + * @return the set of authorisations + */ + private Set getAuthorisations(Authentication auth, NodeRef nodeRef, PermissionReference required) + { + + HashSet auths = new HashSet(); + // No authenticated user then no permissions + if (auth == null) + { + return auths; + } + // TODO: Refactor and use the authentication service for this. + User user = (User) auth.getPrincipal(); + + String username = user.getUsername(); + auths.add(username); + if (tenantService.getBaseNameUser(username).equalsIgnoreCase(AuthenticationUtil.getGuestUserName())) - { - auths.add(PermissionService.GUEST_AUTHORITY); - } - - for (GrantedAuthority authority : auth.getAuthorities()) - { - auths.add(authority.getAuthority()); - } - auths.addAll(getDynamicAuthorities(auth, nodeRef, required)); - auths.addAll(authorityService.getAuthoritiesForUser(username)); - return auths; - } - - private Set getDynamicAuthorities(Authentication auth, NodeRef nodeRef, PermissionReference required) - { - HashSet auths = new HashSet(64); - - if (auth == null) - { - return auths; - } - User user = (User) auth.getPrincipal(); - String username = user.getUsername(); - - nodeRef = tenantService.getName(nodeRef); - if (nodeRef != null) - { - if (dynamicAuthorities != null) - { - for (DynamicAuthority da : dynamicAuthorities) - { - Set requiredFor = da.requiredFor(); - if ((requiredFor == null) || (requiredFor.contains(required))) - { - if (da.hasAuthority(nodeRef, username)) - { - auths.add(da.getAuthority()); - } - } - } - } - } - auths.addAll(authorityService.getAuthoritiesForUser(user.getUsername())); - return auths; - } - - private Set getAuthorisations(Authentication auth, PermissionContext context) - { - HashSet auths = new HashSet(); - // No authenticated user then no permissions - if (auth == null) - { - return auths; - } - // TODO: Refactor and use the authentication service for this. - User user = (User) auth.getPrincipal(); - auths.add(user.getUsername()); - for (GrantedAuthority authority : auth.getAuthorities()) - { - auths.add(authority.getAuthority()); - } - auths.addAll(authorityService.getAuthoritiesForUser(user.getUsername())); - - if (context != null) - { - Map> dynamicAuthorityAssignments = context.getDynamicAuthorityAssignment(); - HashSet dynAuths = new HashSet(); - for (String current : auths) - { - Set dynos = dynamicAuthorityAssignments.get(current); - if (dynos != null) - { - dynAuths.addAll(dynos); - } - } - auths.addAll(dynAuths); - } - - return auths; - } - - public NodePermissionEntry explainPermission(NodeRef nodeRef, PermissionReference perm) - { - // TODO Auto-generated method stub - return null; - } - - public void clearPermission(StoreRef storeRef, String authority) - { - permissionsDaoComponent.deletePermissions(storeRef, authority); - accessCache.clear(); - } - - public void deletePermission(StoreRef storeRef, String authority, String perm) - { - deletePermission(storeRef, authority, getPermissionReference(perm)); - } - - private void deletePermission(StoreRef storeRef, String authority, PermissionReference perm) - { - permissionsDaoComponent.deletePermission(storeRef, authority, perm); - accessCache.clear(); - } - - public void deletePermissions(StoreRef storeRef) - { - permissionsDaoComponent.deletePermissions(storeRef); - accessCache.clear(); - } - - public void setPermission(StoreRef storeRef, String authority, String perm, boolean allow) - { - setPermission(storeRef, authority, getPermissionReference(perm), allow); - } - - private void setPermission(StoreRef storeRef, String authority, PermissionReference permission, boolean allow) - { - permissionsDaoComponent.setPermission(storeRef, authority, permission, allow); - accessCache.clear(); - - } - - public void deletePermissions(NodeRef nodeRef) - { - permissionsDaoComponent.deletePermissions(tenantService.getName(nodeRef)); - accessCache.clear(); - } - - public void deletePermissions(NodePermissionEntry nodePermissionEntry) - { - permissionsDaoComponent.deletePermissions(tenantService.getName(nodePermissionEntry.getNodeRef())); - accessCache.clear(); - } - - /** - * @see #deletePermission(NodeRef, String, PermissionReference) - */ - public void deletePermission(PermissionEntry permissionEntry) - { - NodeRef nodeRef = permissionEntry.getNodeRef(); - String authority = permissionEntry.getAuthority(); - PermissionReference permission = permissionEntry.getPermissionReference(); - deletePermission(nodeRef, authority, permission); - } - - private void deletePermission(NodeRef nodeRef, String authority, PermissionReference perm) - { - permissionsDaoComponent.deletePermission(tenantService.getName(nodeRef), authority, perm); - accessCache.clear(); - } - - public void clearPermission(NodeRef nodeRef, String authority) - { - permissionsDaoComponent.deletePermissions(tenantService.getName(nodeRef), authority); - accessCache.clear(); - } - - private void setPermission(NodeRef nodeRef, String authority, PermissionReference perm, boolean allow) - { - permissionsDaoComponent.setPermission(tenantService.getName(nodeRef), authority, perm, allow); - accessCache.clear(); - } - - public void setPermission(PermissionEntry permissionEntry) - { - // TODO - not MT-enabled nodeRef - currently only used by tests - permissionsDaoComponent.setPermission(permissionEntry); - accessCache.clear(); - } - - public void setPermission(NodePermissionEntry nodePermissionEntry) - { - // TODO - not MT-enabled nodeRef- currently only used by tests - permissionsDaoComponent.setPermission(nodePermissionEntry); - accessCache.clear(); - } - - public void setInheritParentPermissions(NodeRef nodeRef, boolean inheritParentPermissions) - { - permissionsDaoComponent.setInheritParentPermissions(tenantService.getName(nodeRef), inheritParentPermissions); - accessCache.clear(); - } - - /** - * @see org.alfresco.service.cmr.security.PermissionService#getInheritParentPermissions(org.alfresco.service.cmr.repository.NodeRef) - */ - public boolean getInheritParentPermissions(NodeRef nodeRef) - { - return permissionsDaoComponent.getInheritParentPermissions(tenantService.getName(nodeRef)); - } - - public PermissionReference getPermissionReference(QName qname, String permissionName) - { - return modelDAO.getPermissionReference(qname, permissionName); - } - - public PermissionReference getAllPermissionReference() - { - return allPermissionReference; - } - - public String getPermission(PermissionReference permissionReference) - { - if (modelDAO.isUnique(permissionReference)) - { - return permissionReference.getName(); - } - else - { - return permissionReference.toString(); - } - } - - public PermissionReference getPermissionReference(String permissionName) - { - return modelDAO.getPermissionReference(null, permissionName); - } - - public Set getSettablePermissionReferences(QName type) - { - return modelDAO.getExposedPermissions(type); - } - - public Set getSettablePermissionReferences(NodeRef nodeRef) - { - return modelDAO.getExposedPermissions(tenantService.getName(nodeRef)); - } - - public void deletePermission(NodeRef nodeRef, String authority, String perm) - { - deletePermission(nodeRef, authority, getPermissionReference(perm)); - } - - public AccessStatus hasPermission(NodeRef nodeRef, String perm) - { - return hasPermission(nodeRef, getPermissionReference(perm)); - } - - public void setPermission(NodeRef nodeRef, String authority, String perm, boolean allow) - { - setPermission(nodeRef, authority, getPermissionReference(perm), allow); - } - - public void deletePermissions(String recipient) - { - permissionsDaoComponent.deletePermissions(recipient); - accessCache.clear(); - } - - // - // SUPPORT CLASSES - // - - /** - * Support class to test the permission on a node. - * - * @author Andy Hind - */ - private class NodeTest - { - /* - * The required permission. - */ - PermissionReference required; - - /* - * Granters of the permission - */ - Set granters; - - /* - * The additional permissions required at the node level. - */ - Set nodeRequirements = new HashSet(); - - /* - * The additional permissions required on the parent. - */ - Set parentRequirements = new HashSet(); - - /* - * The permissions required on all children . - */ - Set childrenRequirements = new HashSet(); - - /* - * The type name of the node. - */ - QName typeQName; - - /* - * The aspects set on the node. - */ - Set aspectQNames; - - /* - * Constructor just gets the additional requirements - */ - NodeTest(PermissionReference required, QName typeQName, Set aspectQNames) - { - this.required = required; - this.typeQName = typeQName; - this.aspectQNames = aspectQNames; - - // Set the required node permissions - if (required.equals(getPermissionReference(ALL_PERMISSIONS))) - { - nodeRequirements = modelDAO.getRequiredPermissions(getPermissionReference(PermissionService.FULL_CONTROL), typeQName, aspectQNames, RequiredPermission.On.NODE); - } - else - { - nodeRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.NODE); - } - - parentRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.PARENT); - - childrenRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.CHILDREN); - - // Find all the permissions that grant the allowed permission - // All permissions are treated specially. - granters = new LinkedHashSet(128, 1.0f); - granters.addAll(modelDAO.getGrantingPermissions(required)); - granters.add(getAllPermissionReference()); - granters.add(OLD_ALL_PERMISSIONS_REFERENCE); - } - - /** - * External hook point - * - * @param authorisations - * @param nodeRef - * @return true if allowed - */ - boolean evaluate(Set authorisations, NodeRef nodeRef) - { - Set> denied = new HashSet>(); - return evaluate(authorisations, nodeRef, denied, null); - } - - /** - * Internal hook point for recursion - * - * @param authorisations - * @param nodeRef - * @param denied - * @param recursiveIn - * @return true if allowed - */ - boolean evaluate(Set authorisations, NodeRef nodeRef, Set> denied, MutableBoolean recursiveIn) - { - // Do we defer our required test to a parent (yes if not null) - MutableBoolean recursiveOut = null; - - Set> locallyDenied = new HashSet>(); - locallyDenied.addAll(denied); - locallyDenied.addAll(getDenied(nodeRef)); - - // Start out true and "and" all other results - boolean success = true; - - // Check the required permissions but not for sets they rely on - // their underlying permissions - if (modelDAO.checkPermission(required)) - { - if (parentRequirements.contains(required)) - { - if (checkGlobalPermissions(authorisations) || checkRequired(authorisations, nodeRef, locallyDenied)) - { - // No need to do the recursive test as it has been found - if (recursiveIn != null) - { - recursiveIn.setValue(true); - } - } - else - { - // Much cheaper to do this as we go then check all the - // stack values for each parent - recursiveOut = new MutableBoolean(false); - } - } - else - { - // We have to do the test as no parent will help us out - success &= hasSinglePermission(authorisations, nodeRef); - } - if (!success) - { - return false; - } - } - - // Check the other permissions required on the node - for (PermissionReference pr : nodeRequirements) - { - // Build a new test - NodeTest nt = new NodeTest(pr, typeQName, aspectQNames); - success &= nt.evaluate(authorisations, nodeRef, locallyDenied, null); - if (!success) - { - return false; - } - } - - // Check the permission required of the parent - - if (success) - { - ChildAssociationRef car = nodeService.getPrimaryParent(nodeRef); - if (car.getParentRef() != null) - { - - NodePermissionEntry nodePermissions = permissionsDaoComponent.getPermissions(car.getChildRef()); - if ((nodePermissions == null) || (nodePermissions.inheritPermissions())) - { - - locallyDenied.addAll(getDenied(car.getParentRef())); - for (PermissionReference pr : parentRequirements) - { - if (pr.equals(required)) - { - // Recursive permission - success &= this.evaluate(authorisations, car.getParentRef(), locallyDenied, recursiveOut); - if ((recursiveOut != null) && recursiveOut.getValue()) - { - if (recursiveIn != null) - { - recursiveIn.setValue(true); - } - } - } - else - { - NodeTest nt = new NodeTest(pr, typeQName, aspectQNames); - success &= nt.evaluate(authorisations, car.getParentRef(), locallyDenied, null); - } - - if (!success) - { - return false; - } - } - } - } - } - - if ((recursiveOut != null) && (!recursiveOut.getValue())) - { - // The required authentication was not resolved in recursion - return false; - } - - // Check permissions required of children - if (childrenRequirements.size() > 0) - { - List childAssocRefs = nodeService.getChildAssocs(nodeRef); - for (PermissionReference pr : childrenRequirements) - { - for (ChildAssociationRef child : childAssocRefs) - { - success &= (hasPermission(child.getChildRef(), pr) == AccessStatus.ALLOWED); - if (!success) - { - return false; - } - } - } - } - - return success; - } - - boolean hasSinglePermission(Set authorisations, NodeRef nodeRef) - { - nodeRef = tenantService.getName(nodeRef); - - Serializable key = generateKey(authorisations, nodeRef, this.required, CacheType.SINGLE_PERMISSION_GLOBAL); - - AccessStatus status = accessCache.get(key); - if (status != null) - { - return status == AccessStatus.ALLOWED; - } - - // Check global permission - - if (checkGlobalPermissions(authorisations)) - { - accessCache.put(key, AccessStatus.ALLOWED); - return true; - } - - Set> denied = new HashSet>(); - - return hasSinglePermission(authorisations, nodeRef, denied); - - } - - boolean hasSinglePermission(Set authorisations, NodeRef nodeRef, Set> denied) - { - nodeRef = tenantService.getName(nodeRef); - - // Add any denied permission to the denied list - these can not - // then - // be used to given authentication. - // A -> B -> C - // If B denies all permissions to any - allowing all permissions - // to - // andy at node A has no effect - - denied.addAll(getDenied(nodeRef)); - - // Cache non denied - Serializable key = null; - if (denied.size() == 0) - { - key = generateKey(authorisations, nodeRef, this.required, CacheType.SINGLE_PERMISSION); - } - if (key != null) - { - AccessStatus status = accessCache.get(key); - if (status != null) - { - return status == AccessStatus.ALLOWED; - } - } - - // If the current node allows the permission we are done - // The test includes any parent or ancestor requirements - if (checkRequired(authorisations, nodeRef, denied)) - { - if (key != null) - { - accessCache.put(key, AccessStatus.ALLOWED); - } - return true; - } - - // Permissions are only evaluated up the primary parent chain - // TODO: Do not ignore non primary permissions - ChildAssociationRef car = nodeService.getPrimaryParent(nodeRef); - - // Build the next element of the evaluation chain - if (car.getParentRef() != null) - { - NodePermissionEntry nodePermissions = permissionsDaoComponent.getPermissions(nodeRef); - if ((nodePermissions == null) || (nodePermissions.inheritPermissions())) - { - if (hasSinglePermission(authorisations, car.getParentRef(), denied)) - { - if (key != null) - { - accessCache.put(key, AccessStatus.ALLOWED); - } - return true; - } - else - { - if (key != null) - { - accessCache.put(key, AccessStatus.DENIED); - } - return false; - } - } - else - { - if (key != null) - { - accessCache.put(key, AccessStatus.DENIED); - } - return false; - } - } - else - { - if (key != null) - { - accessCache.put(key, AccessStatus.DENIED); - } - return false; - } - } - - /** - * Check if we have a global permission - * - * @param authorisations - * @return true if allowed - */ - private boolean checkGlobalPermissions(Set authorisations) - { - for (PermissionEntry pe : modelDAO.getGlobalPermissionEntries()) - { - if (isGranted(pe, authorisations, null)) - { - return true; - } - } - return false; - } - - /** - * Get the list of permissions denied for this node. - * - * @param nodeRef - * @return the list of denied permissions - */ - Set> getDenied(NodeRef nodeRef) - { - Set> deniedSet = new HashSet>(); - - // Loop over all denied permissions - NodePermissionEntry nodeEntry = permissionsDaoComponent.getPermissions(nodeRef); - if (nodeEntry != null) - { - for (PermissionEntry pe : nodeEntry.getPermissionEntries()) - { - if (pe.isDenied()) - { - // All the sets that grant this permission must be - // denied - // Note that granters includes the orginal permission - Set granters = modelDAO.getGrantingPermissions(pe.getPermissionReference()); - for (PermissionReference granter : granters) - { - deniedSet.add(new Pair(pe.getAuthority(), granter)); - } - - // All the things granted by this permission must be - // denied - Set grantees = modelDAO.getGranteePermissions(pe.getPermissionReference()); - for (PermissionReference grantee : grantees) - { - deniedSet.add(new Pair(pe.getAuthority(), grantee)); - } - - // All permission excludes all permissions available for - // the node. - if (pe.getPermissionReference().equals(getAllPermissionReference()) || pe.getPermissionReference().equals(OLD_ALL_PERMISSIONS_REFERENCE)) - { - for (PermissionReference deny : modelDAO.getAllPermissions(nodeRef)) - { - deniedSet.add(new Pair(pe.getAuthority(), deny)); - } - } - } - } - } - return deniedSet; - } - - /** - * Check that a given authentication is available on a node - * - * @param authorisations - * @param nodeRef - * @param denied - * @return true if the check is required - */ - boolean checkRequired(Set authorisations, NodeRef nodeRef, Set> denied) - { - NodePermissionEntry nodeEntry = permissionsDaoComponent.getPermissions(nodeRef); - - // No permissions set - short cut to deny - if (nodeEntry == null) - { - return false; - } - - // Check if each permission allows - the first wins. - // We could have other voting style mechanisms here - for (PermissionEntry pe : nodeEntry.getPermissionEntries()) - { - if (isGranted(pe, authorisations, denied)) - { - return true; - } - } - return false; - } - - /** - * Is a permission granted - * - * @param pe - - * the permissions entry to consider - * @param granters - - * the set of granters - * @param authorisations - - * the set of authorities - * @param denied - - * the set of denied permissions/authority pais - * @return true if granted - */ - private boolean isGranted(PermissionEntry pe, Set authorisations, Set> denied) - { - // If the permission entry denies then we just deny - if (pe.isDenied()) - { - return false; - } - - // The permission is allowed but we deny it as it is in the denied - // set - - if (denied != null) - { - Pair specific = new Pair(pe.getAuthority(), required); - if (denied.contains(specific)) - { - return false; - } - } - - // any deny denies - - if (false) - { - if (denied != null) - { - for (String auth : authorisations) - { - Pair specific = new Pair(auth, required); - if (denied.contains(specific)) - { - return false; - } - for (PermissionReference perm : granters) - { - specific = new Pair(auth, perm); - if (denied.contains(specific)) - { - return false; - } - } - } - } - } - - // If the permission has a match in both the authorities and - // granters list it is allowed - // It applies to the current user and it is granted - if (authorisations.contains(pe.getAuthority()) && granters.contains(pe.getPermissionReference())) - { - { - return true; - } - } - - // Default deny - return false; - } - - } - - /** - * Test a permission in the context of the new ACL implementation. All components of the ACL are in the object - - * there is no need to walk up the parent chain. Parent conditions cna not be applied as there is no context to do - * this. Child conditions can not be applied as there is no context to do this - * - * @author andyh - */ - - private class AclTest - { - /* - * The required permission. - */ - PermissionReference required; - - /* - * Granters of the permission - */ - Set granters; - - /* - * The additional permissions required at the node level. - */ - Set nodeRequirements = new HashSet(); - - /* - * The type name of the node. - */ - QName typeQName; - - /* - * The aspects set on the node. - */ - Set aspectQNames; - - /* - * Constructor just gets the additional requirements - */ - AclTest(PermissionReference required, QName typeQName, Set aspectQNames) - { - this.required = required; - this.typeQName = typeQName; - this.aspectQNames = aspectQNames; - - // Set the required node permissions - if (required.equals(getPermissionReference(ALL_PERMISSIONS))) - { - nodeRequirements = modelDAO.getRequiredPermissions(getPermissionReference(PermissionService.FULL_CONTROL), typeQName, aspectQNames, RequiredPermission.On.NODE); - } - else - { - nodeRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.NODE); - } - - if (modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.PARENT).size() > 0) - { - throw new IllegalStateException("Parent permissions can not be checked for an acl"); - } - - if (modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.CHILDREN).size() > 0) - { - throw new IllegalStateException("Child permissions can not be checked for an acl"); - } - - // Find all the permissions that grant the allowed permission - // All permissions are treated specially. - granters = new LinkedHashSet(128, 1.0f); - granters.addAll(modelDAO.getGrantingPermissions(required)); - granters.add(getAllPermissionReference()); - granters.add(OLD_ALL_PERMISSIONS_REFERENCE); - } - - /** - * Internal hook point for recursion - * - * @param authorisations - * @param nodeRef - * @param denied - * @param recursiveIn - * @return true if granted - */ - boolean evaluate(Set authorisations, Long aclId, PermissionContext context) - { - // Start out true and "and" all other results - boolean success = true; - - // Check the required permissions but not for sets they rely on - // their underlying permissions - if (modelDAO.checkPermission(required)) - { - - // We have to do the test as no parent will help us out - success &= hasSinglePermission(authorisations, aclId, context); - - if (!success) - { - return false; - } - } - - // Check the other permissions required on the node - for (PermissionReference pr : nodeRequirements) - { - // Build a new test - AclTest nt = new AclTest(pr, typeQName, aspectQNames); - success &= nt.evaluate(authorisations, aclId, context); - if (!success) - { - return false; - } - } - - return success; - } - - boolean hasSinglePermission(Set authorisations, Long aclId, PermissionContext context) - { - // Check global permission - - if (checkGlobalPermissions(authorisations)) - { - return true; - } - - return checkRequired(authorisations, aclId, context); - - } - - /** - * Check if we have a global permission - * - * @param authorisations - * @return true if granted - */ - private boolean checkGlobalPermissions(Set authorisations) - { - for (PermissionEntry pe : modelDAO.getGlobalPermissionEntries()) - { - if (isGranted(pe, authorisations)) - { - return true; - } - } - return false; - } - - /** - * Check that a given authentication is available on a node - * - * @param authorisations - * @param nodeRef - * @param denied - * @return true if a check is required - */ - boolean checkRequired(Set authorisations, Long aclId, PermissionContext context) - { - AccessControlList acl = aclDaoComponent.getAccessControlList(aclId); - - if (acl == null) - { - return false; - } - - Set> denied = new HashSet>(); - - // Check if each permission allows - the first wins. - // We could have other voting style mechanisms here - for (AccessControlEntry ace : acl.getEntries()) - { - if (isGranted(ace, authorisations, denied, context)) - { - return true; - } - } - return false; - } - - /** - * Is a permission granted - * - * @param pe - - * the permissions entry to consider - * @param granters - - * the set of granters - * @param authorisations - - * the set of authorities - * @param denied - - * the set of denied permissions/authority pais - * @return true if granted - */ - private boolean isGranted(AccessControlEntry ace, Set authorisations, Set> denied, PermissionContext context) - { - // If the permission entry denies then we just deny - if (ace.getAccessStatus() == AccessStatus.DENIED) - { - denied.add(new Pair(ace.getAuthority(), ace.getPermission())); - - Set granters = modelDAO.getGrantingPermissions(ace.getPermission()); - for (PermissionReference granter : granters) - { - denied.add(new Pair(ace.getAuthority(), granter)); - } - - // All the things granted by this permission must be - // denied - Set grantees = modelDAO.getGranteePermissions(ace.getPermission()); - for (PermissionReference grantee : grantees) - { - denied.add(new Pair(ace.getAuthority(), grantee)); - } - - // All permission excludes all permissions available for - // the node. - if (ace.getPermission().equals(getAllPermissionReference()) || ace.getPermission().equals(OLD_ALL_PERMISSIONS_REFERENCE)) - { - for (PermissionReference deny : modelDAO.getAllPermissions(context.getType(), context.getAspects())) - { - denied.add(new Pair(ace.getAuthority(), deny)); - } - } - - return false; - } - - // The permission is allowed but we deny it as it is in the denied - // set - - if (denied != null) - { - Pair specific = new Pair(ace.getAuthority(), required); - if (denied.contains(specific)) - { - return false; - } - } - - // any deny denies - - if (false) - { - if (denied != null) - { - for (String auth : authorisations) - { - Pair specific = new Pair(auth, required); - if (denied.contains(specific)) - { - return false; - } - for (PermissionReference perm : granters) - { - specific = new Pair(auth, perm); - if (denied.contains(specific)) - { - return false; - } - } - } - } - } - - // If the permission has a match in both the authorities and - // granters list it is allowed - // It applies to the current user and it is granted - if (authorisations.contains(ace.getAuthority()) && granters.contains(ace.getPermission())) - { - { - return true; - } - } - - // Default deny - return false; - } - - private boolean isGranted(PermissionEntry pe, Set authorisations) - { - // If the permission entry denies then we just deny - if (pe.isDenied()) - { - return false; - } - - // If the permission has a match in both the authorities and - // granters list it is allowed - // It applies to the current user and it is granted - if (granters.contains(pe.getPermissionReference()) && authorisations.contains(pe.getAuthority())) - { - { - return true; - } - } - - // Default deny - return false; - } - - } - - /** - * Helper class to store a pair of objects which may be null - * - * @author Andy Hind - */ - private static class Pair - { - A a; - - B b; - - Pair(A a, B b) - { - this.a = a; - this.b = b; - } - - A getA() - { - return a; - } - - B getB() - { - return b; - } - - @SuppressWarnings("unchecked") - @Override - public boolean equals(Object o) - { - if (this == o) - { - return true; - } - if (!(this instanceof Pair)) - { - return false; - } - Pair other = (Pair) o; - return EqualsHelper.nullSafeEquals(this.getA(), other.getA()) && EqualsHelper.nullSafeEquals(this.getB(), other.getB()); - } - - @Override - public int hashCode() - { - return (((a == null) ? 0 : a.hashCode()) * 37) + ((b == null) ? 0 : b.hashCode()); - } - - } - - private static class MutableBoolean - { - private boolean value; - - MutableBoolean(boolean value) - { - this.value = value; - } - - void setValue(boolean value) - { - this.value = value; - } - - boolean getValue() - { - return value; - } - } - - public Map> getAllSetPermissionsForCurrentUser() - { - String currentUser = AuthenticationUtil.getRunAsUser(); - return getAllSetPermissionsForAuthority(currentUser); - } - - public Map> getAllSetPermissionsForAuthority(String authority) - { - return permissionsDaoComponent.getAllSetPermissions(authority); - } - - public Set findNodesByAssignedPermissionForCurrentUser(String permission, boolean allow, boolean includeContainingAuthorities, boolean exactPermissionMatch) - { - String currentUser = AuthenticationUtil.getRunAsUser(); - return findNodesByAssignedPermission(currentUser, permission, allow, includeContainingAuthorities, exactPermissionMatch); - } - - public Set findNodesByAssignedPermission(String authority, String permission, boolean allow, boolean includeContainingAuthorities, boolean includeContainingPermissions) - { - // TODO: owned nodes and add owner rights ?? - // Does not include dynamic permissions (they would have to be done by query - e.g. owership and OWNER rights) - // Does not include ACEGI auth object authorities - Set authorities = new HashSet(); - authorities.add(authority); - if (includeContainingAuthorities) - { - authorities.addAll(authorityService.getAuthoritiesForUser(authority)); - } - - HashSet answer = new HashSet(); - - PermissionReference pr = getPermissionReference(permission); - Set permissions = new HashSet(); - permissions.add(pr); - - if (includeContainingPermissions) - { - permissions.addAll(modelDAO.getGrantingPermissions(pr)); - } - - for (PermissionReference perm : permissions) - { - for (String auth : authorities) - { - answer.addAll(permissionsDaoComponent.findNodeByPermission(auth, perm, allow)); - } - } - return answer; - } - - /** + { + auths.add(PermissionService.GUEST_AUTHORITY); + } + + for (GrantedAuthority authority : auth.getAuthorities()) + { + auths.add(authority.getAuthority()); + } + auths.addAll(getDynamicAuthorities(auth, nodeRef, required)); + auths.addAll(authorityService.getAuthoritiesForUser(username)); + return auths; + } + + private Set getDynamicAuthorities(Authentication auth, NodeRef nodeRef, PermissionReference required) + { + HashSet auths = new HashSet(64); + + if (auth == null) + { + return auths; + } + User user = (User) auth.getPrincipal(); + String username = user.getUsername(); + + nodeRef = tenantService.getName(nodeRef); + if (nodeRef != null) + { + if (dynamicAuthorities != null) + { + for (DynamicAuthority da : dynamicAuthorities) + { + Set requiredFor = da.requiredFor(); + if ((requiredFor == null) || (requiredFor.contains(required))) + { + if (da.hasAuthority(nodeRef, username)) + { + auths.add(da.getAuthority()); + } + } + } + } + } + auths.addAll(authorityService.getAuthoritiesForUser(user.getUsername())); + return auths; + } + + private Set getAuthorisations(Authentication auth, PermissionContext context) + { + HashSet auths = new HashSet(); + // No authenticated user then no permissions + if (auth == null) + { + return auths; + } + // TODO: Refactor and use the authentication service for this. + User user = (User) auth.getPrincipal(); + auths.add(user.getUsername()); + for (GrantedAuthority authority : auth.getAuthorities()) + { + auths.add(authority.getAuthority()); + } + auths.addAll(authorityService.getAuthoritiesForUser(user.getUsername())); + + if (context != null) + { + Map> dynamicAuthorityAssignments = context.getDynamicAuthorityAssignment(); + HashSet dynAuths = new HashSet(); + for (String current : auths) + { + Set dynos = dynamicAuthorityAssignments.get(current); + if (dynos != null) + { + dynAuths.addAll(dynos); + } + } + auths.addAll(dynAuths); + } + + return auths; + } + + public NodePermissionEntry explainPermission(NodeRef nodeRef, PermissionReference perm) + { + // TODO Auto-generated method stub + return null; + } + + public void clearPermission(StoreRef storeRef, String authority) + { + permissionsDaoComponent.deletePermissions(storeRef, authority); + accessCache.clear(); + } + + public void deletePermission(StoreRef storeRef, String authority, String perm) + { + deletePermission(storeRef, authority, getPermissionReference(perm)); + } + + private void deletePermission(StoreRef storeRef, String authority, PermissionReference perm) + { + permissionsDaoComponent.deletePermission(storeRef, authority, perm); + accessCache.clear(); + } + + public void deletePermissions(StoreRef storeRef) + { + permissionsDaoComponent.deletePermissions(storeRef); + accessCache.clear(); + } + + public void setPermission(StoreRef storeRef, String authority, String perm, boolean allow) + { + setPermission(storeRef, authority, getPermissionReference(perm), allow); + } + + private void setPermission(StoreRef storeRef, String authority, PermissionReference permission, boolean allow) + { + permissionsDaoComponent.setPermission(storeRef, authority, permission, allow); + accessCache.clear(); + + } + + public void deletePermissions(NodeRef nodeRef) + { + permissionsDaoComponent.deletePermissions(tenantService.getName(nodeRef)); + accessCache.clear(); + } + + public void deletePermissions(NodePermissionEntry nodePermissionEntry) + { + permissionsDaoComponent.deletePermissions(tenantService.getName(nodePermissionEntry.getNodeRef())); + accessCache.clear(); + } + + /** + * @see #deletePermission(NodeRef, String, PermissionReference) + */ + public void deletePermission(PermissionEntry permissionEntry) + { + NodeRef nodeRef = permissionEntry.getNodeRef(); + String authority = permissionEntry.getAuthority(); + PermissionReference permission = permissionEntry.getPermissionReference(); + deletePermission(nodeRef, authority, permission); + } + + private void deletePermission(NodeRef nodeRef, String authority, PermissionReference perm) + { + permissionsDaoComponent.deletePermission(tenantService.getName(nodeRef), authority, perm); + accessCache.clear(); + } + + public void clearPermission(NodeRef nodeRef, String authority) + { + permissionsDaoComponent.deletePermissions(tenantService.getName(nodeRef), authority); + accessCache.clear(); + } + + private void setPermission(NodeRef nodeRef, String authority, PermissionReference perm, boolean allow) + { + permissionsDaoComponent.setPermission(tenantService.getName(nodeRef), authority, perm, allow); + accessCache.clear(); + } + + public void setPermission(PermissionEntry permissionEntry) + { + // TODO - not MT-enabled nodeRef - currently only used by tests + permissionsDaoComponent.setPermission(permissionEntry); + accessCache.clear(); + } + + public void setPermission(NodePermissionEntry nodePermissionEntry) + { + // TODO - not MT-enabled nodeRef- currently only used by tests + permissionsDaoComponent.setPermission(nodePermissionEntry); + accessCache.clear(); + } + + public void setInheritParentPermissions(NodeRef nodeRef, boolean inheritParentPermissions) + { + NodeRef actualRef = tenantService.getName(nodeRef); + permissionsDaoComponent.setInheritParentPermissions(actualRef, inheritParentPermissions); + accessCache.clear(); + } + + /** + * @see org.alfresco.service.cmr.security.PermissionService#getInheritParentPermissions(org.alfresco.service.cmr.repository.NodeRef) + */ + public boolean getInheritParentPermissions(NodeRef nodeRef) + { + return permissionsDaoComponent.getInheritParentPermissions(tenantService.getName(nodeRef)); + } + + public PermissionReference getPermissionReference(QName qname, String permissionName) + { + return modelDAO.getPermissionReference(qname, permissionName); + } + + public PermissionReference getAllPermissionReference() + { + return allPermissionReference; + } + + public String getPermission(PermissionReference permissionReference) + { + if (modelDAO.isUnique(permissionReference)) + { + return permissionReference.getName(); + } + else + { + return permissionReference.toString(); + } + } + + public PermissionReference getPermissionReference(String permissionName) + { + return modelDAO.getPermissionReference(null, permissionName); + } + + public Set getSettablePermissionReferences(QName type) + { + return modelDAO.getExposedPermissions(type); + } + + public Set getSettablePermissionReferences(NodeRef nodeRef) + { + return modelDAO.getExposedPermissions(tenantService.getName(nodeRef)); + } + + public void deletePermission(NodeRef nodeRef, String authority, String perm) + { + deletePermission(nodeRef, authority, getPermissionReference(perm)); + } + + public AccessStatus hasPermission(NodeRef nodeRef, String perm) + { + return hasPermission(nodeRef, getPermissionReference(perm)); + } + + public void setPermission(NodeRef nodeRef, String authority, String perm, boolean allow) + { + setPermission(nodeRef, authority, getPermissionReference(perm), allow); + } + + public void deletePermissions(String recipient) + { + permissionsDaoComponent.deletePermissions(recipient); + accessCache.clear(); + } + + // + // SUPPORT CLASSES + // + + /** + * Support class to test the permission on a node. + * + * @author Andy Hind + */ + private class NodeTest + { + /* + * The required permission. + */ + PermissionReference required; + + /* + * Granters of the permission + */ + Set granters; + + /* + * The additional permissions required at the node level. + */ + Set nodeRequirements = new HashSet(); + + /* + * The additional permissions required on the parent. + */ + Set parentRequirements = new HashSet(); + + /* + * The permissions required on all children . + */ + Set childrenRequirements = new HashSet(); + + /* + * The type name of the node. + */ + QName typeQName; + + /* + * The aspects set on the node. + */ + Set aspectQNames; + + /* + * Constructor just gets the additional requirements + */ + NodeTest(PermissionReference required, QName typeQName, Set aspectQNames) + { + this.required = required; + this.typeQName = typeQName; + this.aspectQNames = aspectQNames; + + // Set the required node permissions + if (required.equals(getPermissionReference(ALL_PERMISSIONS))) + { + nodeRequirements = modelDAO.getRequiredPermissions(getPermissionReference(PermissionService.FULL_CONTROL), typeQName, aspectQNames, RequiredPermission.On.NODE); + } + else + { + nodeRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.NODE); + } + + parentRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.PARENT); + + childrenRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.CHILDREN); + + // Find all the permissions that grant the allowed permission + // All permissions are treated specially. + granters = new LinkedHashSet(128, 1.0f); + granters.addAll(modelDAO.getGrantingPermissions(required)); + granters.add(getAllPermissionReference()); + granters.add(OLD_ALL_PERMISSIONS_REFERENCE); + } + + /** + * External hook point + * + * @param authorisations + * @param nodeRef + * @return true if allowed + */ + boolean evaluate(Set authorisations, NodeRef nodeRef) + { + Set> denied = new HashSet>(); + return evaluate(authorisations, nodeRef, denied, null); + } + + /** + * Internal hook point for recursion + * + * @param authorisations + * @param nodeRef + * @param denied + * @param recursiveIn + * @return true if allowed + */ + boolean evaluate(Set authorisations, NodeRef nodeRef, Set> denied, MutableBoolean recursiveIn) + { + // Do we defer our required test to a parent (yes if not null) + MutableBoolean recursiveOut = null; + + Set> locallyDenied = new HashSet>(); + locallyDenied.addAll(denied); + locallyDenied.addAll(getDenied(nodeRef)); + + // Start out true and "and" all other results + boolean success = true; + + // Check the required permissions but not for sets they rely on + // their underlying permissions + if (modelDAO.checkPermission(required)) + { + if (parentRequirements.contains(required)) + { + if (checkGlobalPermissions(authorisations) || checkRequired(authorisations, nodeRef, locallyDenied)) + { + // No need to do the recursive test as it has been found + if (recursiveIn != null) + { + recursiveIn.setValue(true); + } + } + else + { + // Much cheaper to do this as we go then check all the + // stack values for each parent + recursiveOut = new MutableBoolean(false); + } + } + else + { + // We have to do the test as no parent will help us out + success &= hasSinglePermission(authorisations, nodeRef); + } + if (!success) + { + return false; + } + } + + // Check the other permissions required on the node + for (PermissionReference pr : nodeRequirements) + { + // Build a new test + NodeTest nt = new NodeTest(pr, typeQName, aspectQNames); + success &= nt.evaluate(authorisations, nodeRef, locallyDenied, null); + if (!success) + { + return false; + } + } + + // Check the permission required of the parent + + if (success) + { + ChildAssociationRef car = nodeService.getPrimaryParent(nodeRef); + if (car.getParentRef() != null) + { + + NodePermissionEntry nodePermissions = permissionsDaoComponent.getPermissions(car.getChildRef()); + if ((nodePermissions == null) || (nodePermissions.inheritPermissions())) + { + + locallyDenied.addAll(getDenied(car.getParentRef())); + for (PermissionReference pr : parentRequirements) + { + if (pr.equals(required)) + { + // Recursive permission + success &= this.evaluate(authorisations, car.getParentRef(), locallyDenied, recursiveOut); + if ((recursiveOut != null) && recursiveOut.getValue()) + { + if (recursiveIn != null) + { + recursiveIn.setValue(true); + } + } + } + else + { + NodeTest nt = new NodeTest(pr, typeQName, aspectQNames); + success &= nt.evaluate(authorisations, car.getParentRef(), locallyDenied, null); + } + + if (!success) + { + return false; + } + } + } + } + } + + if ((recursiveOut != null) && (!recursiveOut.getValue())) + { + // The required authentication was not resolved in recursion + return false; + } + + // Check permissions required of children + if (childrenRequirements.size() > 0) + { + List childAssocRefs = nodeService.getChildAssocs(nodeRef); + for (PermissionReference pr : childrenRequirements) + { + for (ChildAssociationRef child : childAssocRefs) + { + success &= (hasPermission(child.getChildRef(), pr) == AccessStatus.ALLOWED); + if (!success) + { + return false; + } + } + } + } + + return success; + } + + boolean hasSinglePermission(Set authorisations, NodeRef nodeRef) + { + nodeRef = tenantService.getName(nodeRef); + + Serializable key = generateKey(authorisations, nodeRef, this.required, CacheType.SINGLE_PERMISSION_GLOBAL); + + AccessStatus status = accessCache.get(key); + if (status != null) + { + return status == AccessStatus.ALLOWED; + } + + // Check global permission + + if (checkGlobalPermissions(authorisations)) + { + accessCache.put(key, AccessStatus.ALLOWED); + return true; + } + + Set> denied = new HashSet>(); + + return hasSinglePermission(authorisations, nodeRef, denied); + + } + + boolean hasSinglePermission(Set authorisations, NodeRef nodeRef, Set> denied) + { + nodeRef = tenantService.getName(nodeRef); + + // Add any denied permission to the denied list - these can not + // then + // be used to given authentication. + // A -> B -> C + // If B denies all permissions to any - allowing all permissions + // to + // andy at node A has no effect + + denied.addAll(getDenied(nodeRef)); + + // Cache non denied + Serializable key = null; + if (denied.size() == 0) + { + key = generateKey(authorisations, nodeRef, this.required, CacheType.SINGLE_PERMISSION); + } + if (key != null) + { + AccessStatus status = accessCache.get(key); + if (status != null) + { + return status == AccessStatus.ALLOWED; + } + } + + // If the current node allows the permission we are done + // The test includes any parent or ancestor requirements + if (checkRequired(authorisations, nodeRef, denied)) + { + if (key != null) + { + accessCache.put(key, AccessStatus.ALLOWED); + } + return true; + } + + // Permissions are only evaluated up the primary parent chain + // TODO: Do not ignore non primary permissions + ChildAssociationRef car = nodeService.getPrimaryParent(nodeRef); + + // Build the next element of the evaluation chain + if (car.getParentRef() != null) + { + NodePermissionEntry nodePermissions = permissionsDaoComponent.getPermissions(nodeRef); + if ((nodePermissions == null) || (nodePermissions.inheritPermissions())) + { + if (hasSinglePermission(authorisations, car.getParentRef(), denied)) + { + if (key != null) + { + accessCache.put(key, AccessStatus.ALLOWED); + } + return true; + } + else + { + if (key != null) + { + accessCache.put(key, AccessStatus.DENIED); + } + return false; + } + } + else + { + if (key != null) + { + accessCache.put(key, AccessStatus.DENIED); + } + return false; + } + } + else + { + if (key != null) + { + accessCache.put(key, AccessStatus.DENIED); + } + return false; + } + } + + /** + * Check if we have a global permission + * + * @param authorisations + * @return true if allowed + */ + private boolean checkGlobalPermissions(Set authorisations) + { + for (PermissionEntry pe : modelDAO.getGlobalPermissionEntries()) + { + if (isGranted(pe, authorisations, null)) + { + return true; + } + } + return false; + } + + /** + * Get the list of permissions denied for this node. + * + * @param nodeRef + * @return the list of denied permissions + */ + Set> getDenied(NodeRef nodeRef) + { + Set> deniedSet = new HashSet>(); + + // Loop over all denied permissions + NodePermissionEntry nodeEntry = permissionsDaoComponent.getPermissions(nodeRef); + if (nodeEntry != null) + { + for (PermissionEntry pe : nodeEntry.getPermissionEntries()) + { + if (pe.isDenied()) + { + // All the sets that grant this permission must be + // denied + // Note that granters includes the orginal permission + Set granters = modelDAO.getGrantingPermissions(pe.getPermissionReference()); + for (PermissionReference granter : granters) + { + deniedSet.add(new Pair(pe.getAuthority(), granter)); + } + + // All the things granted by this permission must be + // denied + Set grantees = modelDAO.getGranteePermissions(pe.getPermissionReference()); + for (PermissionReference grantee : grantees) + { + deniedSet.add(new Pair(pe.getAuthority(), grantee)); + } + + // All permission excludes all permissions available for + // the node. + if (pe.getPermissionReference().equals(getAllPermissionReference()) || pe.getPermissionReference().equals(OLD_ALL_PERMISSIONS_REFERENCE)) + { + for (PermissionReference deny : modelDAO.getAllPermissions(nodeRef)) + { + deniedSet.add(new Pair(pe.getAuthority(), deny)); + } + } + } + } + } + return deniedSet; + } + + /** + * Check that a given authentication is available on a node + * + * @param authorisations + * @param nodeRef + * @param denied + * @return true if the check is required + */ + boolean checkRequired(Set authorisations, NodeRef nodeRef, Set> denied) + { + NodePermissionEntry nodeEntry = permissionsDaoComponent.getPermissions(nodeRef); + + // No permissions set - short cut to deny + if (nodeEntry == null) + { + return false; + } + + // Check if each permission allows - the first wins. + // We could have other voting style mechanisms here + for (PermissionEntry pe : nodeEntry.getPermissionEntries()) + { + if (isGranted(pe, authorisations, denied)) + { + return true; + } + } + return false; + } + + /** + * Is a permission granted + * + * @param pe - + * the permissions entry to consider + * @param granters - + * the set of granters + * @param authorisations - + * the set of authorities + * @param denied - + * the set of denied permissions/authority pais + * @return true if granted + */ + private boolean isGranted(PermissionEntry pe, Set authorisations, Set> denied) + { + // If the permission entry denies then we just deny + if (pe.isDenied()) + { + return false; + } + + // The permission is allowed but we deny it as it is in the denied + // set + + if (denied != null) + { + Pair specific = new Pair(pe.getAuthority(), required); + if (denied.contains(specific)) + { + return false; + } + } + + // any deny denies + + if (false) + { + if (denied != null) + { + for (String auth : authorisations) + { + Pair specific = new Pair(auth, required); + if (denied.contains(specific)) + { + return false; + } + for (PermissionReference perm : granters) + { + specific = new Pair(auth, perm); + if (denied.contains(specific)) + { + return false; + } + } + } + } + } + + // If the permission has a match in both the authorities and + // granters list it is allowed + // It applies to the current user and it is granted + if (authorisations.contains(pe.getAuthority()) && granters.contains(pe.getPermissionReference())) + { + { + return true; + } + } + + // Default deny + return false; + } + + } + + /** + * Test a permission in the context of the new ACL implementation. All components of the ACL are in the object - + * there is no need to walk up the parent chain. Parent conditions cna not be applied as there is no context to do + * this. Child conditions can not be applied as there is no context to do this + * + * @author andyh + */ + + private class AclTest + { + /* + * The required permission. + */ + PermissionReference required; + + /* + * Granters of the permission + */ + Set granters; + + /* + * The additional permissions required at the node level. + */ + Set nodeRequirements = new HashSet(); + + /* + * The type name of the node. + */ + QName typeQName; + + /* + * The aspects set on the node. + */ + Set aspectQNames; + + /* + * Constructor just gets the additional requirements + */ + AclTest(PermissionReference required, QName typeQName, Set aspectQNames) + { + this.required = required; + this.typeQName = typeQName; + this.aspectQNames = aspectQNames; + + // Set the required node permissions + if (required.equals(getPermissionReference(ALL_PERMISSIONS))) + { + nodeRequirements = modelDAO.getRequiredPermissions(getPermissionReference(PermissionService.FULL_CONTROL), typeQName, aspectQNames, RequiredPermission.On.NODE); + } + else + { + nodeRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.NODE); + } + + if (modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.PARENT).size() > 0) + { + throw new IllegalStateException("Parent permissions can not be checked for an acl"); + } + + if (modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.CHILDREN).size() > 0) + { + throw new IllegalStateException("Child permissions can not be checked for an acl"); + } + + // Find all the permissions that grant the allowed permission + // All permissions are treated specially. + granters = new LinkedHashSet(128, 1.0f); + granters.addAll(modelDAO.getGrantingPermissions(required)); + granters.add(getAllPermissionReference()); + granters.add(OLD_ALL_PERMISSIONS_REFERENCE); + } + + /** + * Internal hook point for recursion + * + * @param authorisations + * @param nodeRef + * @param denied + * @param recursiveIn + * @return true if granted + */ + boolean evaluate(Set authorisations, Long aclId, PermissionContext context) + { + // Start out true and "and" all other results + boolean success = true; + + // Check the required permissions but not for sets they rely on + // their underlying permissions + if (modelDAO.checkPermission(required)) + { + + // We have to do the test as no parent will help us out + success &= hasSinglePermission(authorisations, aclId, context); + + if (!success) + { + return false; + } + } + + // Check the other permissions required on the node + for (PermissionReference pr : nodeRequirements) + { + // Build a new test + AclTest nt = new AclTest(pr, typeQName, aspectQNames); + success &= nt.evaluate(authorisations, aclId, context); + if (!success) + { + return false; + } + } + + return success; + } + + boolean hasSinglePermission(Set authorisations, Long aclId, PermissionContext context) + { + // Check global permission + + if (checkGlobalPermissions(authorisations)) + { + return true; + } + + return checkRequired(authorisations, aclId, context); + + } + + /** + * Check if we have a global permission + * + * @param authorisations + * @return true if granted + */ + private boolean checkGlobalPermissions(Set authorisations) + { + for (PermissionEntry pe : modelDAO.getGlobalPermissionEntries()) + { + if (isGranted(pe, authorisations)) + { + return true; + } + } + return false; + } + + /** + * Check that a given authentication is available on a node + * + * @param authorisations + * @param nodeRef + * @param denied + * @return true if a check is required + */ + boolean checkRequired(Set authorisations, Long aclId, PermissionContext context) + { + AccessControlList acl = aclDaoComponent.getAccessControlList(aclId); + + if (acl == null) + { + return false; + } + + Set> denied = new HashSet>(); + + // Check if each permission allows - the first wins. + // We could have other voting style mechanisms here + for (AccessControlEntry ace : acl.getEntries()) + { + if (isGranted(ace, authorisations, denied, context)) + { + return true; + } + } + return false; + } + + /** + * Is a permission granted + * + * @param pe - + * the permissions entry to consider + * @param granters - + * the set of granters + * @param authorisations - + * the set of authorities + * @param denied - + * the set of denied permissions/authority pais + * @return true if granted + */ + private boolean isGranted(AccessControlEntry ace, Set authorisations, Set> denied, PermissionContext context) + { + // If the permission entry denies then we just deny + if (ace.getAccessStatus() == AccessStatus.DENIED) + { + denied.add(new Pair(ace.getAuthority(), ace.getPermission())); + + Set granters = modelDAO.getGrantingPermissions(ace.getPermission()); + for (PermissionReference granter : granters) + { + denied.add(new Pair(ace.getAuthority(), granter)); + } + + // All the things granted by this permission must be + // denied + Set grantees = modelDAO.getGranteePermissions(ace.getPermission()); + for (PermissionReference grantee : grantees) + { + denied.add(new Pair(ace.getAuthority(), grantee)); + } + + // All permission excludes all permissions available for + // the node. + if (ace.getPermission().equals(getAllPermissionReference()) || ace.getPermission().equals(OLD_ALL_PERMISSIONS_REFERENCE)) + { + for (PermissionReference deny : modelDAO.getAllPermissions(context.getType(), context.getAspects())) + { + denied.add(new Pair(ace.getAuthority(), deny)); + } + } + + return false; + } + + // The permission is allowed but we deny it as it is in the denied + // set + + if (denied != null) + { + Pair specific = new Pair(ace.getAuthority(), required); + if (denied.contains(specific)) + { + return false; + } + } + + // any deny denies + + if (false) + { + if (denied != null) + { + for (String auth : authorisations) + { + Pair specific = new Pair(auth, required); + if (denied.contains(specific)) + { + return false; + } + for (PermissionReference perm : granters) + { + specific = new Pair(auth, perm); + if (denied.contains(specific)) + { + return false; + } + } + } + } + } + + // If the permission has a match in both the authorities and + // granters list it is allowed + // It applies to the current user and it is granted + if (authorisations.contains(ace.getAuthority()) && granters.contains(ace.getPermission())) + { + { + return true; + } + } + + // Default deny + return false; + } + + private boolean isGranted(PermissionEntry pe, Set authorisations) + { + // If the permission entry denies then we just deny + if (pe.isDenied()) + { + return false; + } + + // If the permission has a match in both the authorities and + // granters list it is allowed + // It applies to the current user and it is granted + if (granters.contains(pe.getPermissionReference()) && authorisations.contains(pe.getAuthority())) + { + { + return true; + } + } + + // Default deny + return false; + } + + } + + /** + * Helper class to store a pair of objects which may be null + * + * @author Andy Hind + */ + private static class Pair + { + A a; + + B b; + + Pair(A a, B b) + { + this.a = a; + this.b = b; + } + + A getA() + { + return a; + } + + B getB() + { + return b; + } + + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object o) + { + if (this == o) + { + return true; + } + if (!(this instanceof Pair)) + { + return false; + } + Pair other = (Pair) o; + return EqualsHelper.nullSafeEquals(this.getA(), other.getA()) && EqualsHelper.nullSafeEquals(this.getB(), other.getB()); + } + + @Override + public int hashCode() + { + return (((a == null) ? 0 : a.hashCode()) * 37) + ((b == null) ? 0 : b.hashCode()); + } + + } + + private static class MutableBoolean + { + private boolean value; + + MutableBoolean(boolean value) + { + this.value = value; + } + + void setValue(boolean value) + { + this.value = value; + } + + boolean getValue() + { + return value; + } + } + + public Map> getAllSetPermissionsForCurrentUser() + { + String currentUser = AuthenticationUtil.getRunAsUser(); + return getAllSetPermissionsForAuthority(currentUser); + } + + public Map> getAllSetPermissionsForAuthority(String authority) + { + return permissionsDaoComponent.getAllSetPermissions(authority); + } + + public Set findNodesByAssignedPermissionForCurrentUser(String permission, boolean allow, boolean includeContainingAuthorities, boolean exactPermissionMatch) + { + String currentUser = AuthenticationUtil.getRunAsUser(); + return findNodesByAssignedPermission(currentUser, permission, allow, includeContainingAuthorities, exactPermissionMatch); + } + + public Set findNodesByAssignedPermission(String authority, String permission, boolean allow, boolean includeContainingAuthorities, boolean includeContainingPermissions) + { + // TODO: owned nodes and add owner rights ?? + // Does not include dynamic permissions (they would have to be done by query - e.g. owership and OWNER rights) + // Does not include ACEGI auth object authorities + Set authorities = new HashSet(); + authorities.add(authority); + if (includeContainingAuthorities) + { + authorities.addAll(authorityService.getAuthoritiesForUser(authority)); + } + + HashSet answer = new HashSet(); + + PermissionReference pr = getPermissionReference(permission); + Set permissions = new HashSet(); + permissions.add(pr); + + if (includeContainingPermissions) + { + permissions.addAll(modelDAO.getGrantingPermissions(pr)); + } + + for (PermissionReference perm : permissions) + { + for (String auth : authorities) + { + answer.addAll(permissionsDaoComponent.findNodeByPermission(auth, perm, allow)); + } + } + return answer; + } + + /** * This methods checks whether the specified nodeRef instance is a version nodeRef (ie. in the 'version' store) - * + * * @param nodeRef - version nodeRef * @return true if version nodeRef false otherwise - */ + */ private boolean isVersionNodeRef(NodeRef nodeRef) - { - return nodeRef.getStoreRef().getProtocol().equals(VersionModel.STORE_PROTOCOL); - } - - /** + { + return nodeRef.getStoreRef().getProtocol().equals(VersionModel.STORE_PROTOCOL); + } + + /** * Converts specified version nodeRef (eg. versionStore://...) to versioned nodeRef (eg. workspace://SpacesStore/...) - * + * * @param nodeRef - always version nodeRef (ie. in the 'version' store) * @return versioned nodeRef (ie.in the 'live' store) - */ + */ private NodeRef convertVersionNodeRefToVersionedNodeRef(NodeRef versionNodeRef) - { + { Map properties = nodeService.getProperties(versionNodeRef); NodeRef nodeRef = null; @@ -1942,5 +1943,5 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing } return nodeRef; - } -} + } +} diff --git a/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceTest.java b/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceTest.java index 7320265809..f2d80dd8c5 100644 --- a/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceTest.java +++ b/source/java/org/alfresco/repo/security/permissions/impl/PermissionServiceTest.java @@ -67,6 +67,41 @@ public class PermissionServiceTest extends AbstractPermissionTest super(); // TODO Auto-generated constructor stub } + + public void testMove() + { + runAs("admin"); + NodeRef one = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef(); + permissionService.setPermission(one, "andy", PermissionService.CONTRIBUTOR, true); + NodeRef two = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}two"), ContentModel.TYPE_FOLDER).getChildRef(); + NodeRef test = nodeService.createNode(one, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}test"), ContentModel.TYPE_FOLDER).getChildRef(); + + runAs("andy"); + assertEquals("andy", authenticationComponent.getCurrentUserName()); + assertTrue(permissionService.hasPermission(test, PermissionService.CONTRIBUTOR) == AccessStatus.ALLOWED); + + runAs("admin"); + permissionService.setInheritParentPermissions(test, false); + + runAs("andy"); + assertEquals("andy", authenticationComponent.getCurrentUserName()); + assertTrue(permissionService.hasPermission(test, PermissionService.CONTRIBUTOR) == AccessStatus.DENIED); + + runAs("admin"); + nodeService.moveNode(test, two, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}test")); + assertEquals(two, nodeService.getPrimaryParent(test).getParentRef()); + + runAs("andy"); + assertEquals("andy", authenticationComponent.getCurrentUserName()); + assertTrue(permissionService.hasPermission(test, PermissionService.CONTRIBUTOR) == AccessStatus.DENIED); + + runAs("admin"); + permissionService.setInheritParentPermissions(test, true); + + runAs("andy"); + assertEquals("andy", authenticationComponent.getCurrentUserName()); + assertTrue(permissionService.hasPermission(test, PermissionService.CONTRIBUTOR) == AccessStatus.DENIED); + } public void testChangePersonUid() { diff --git a/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java b/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java index 27c5bee1d7..001ac8d5f3 100644 --- a/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java +++ b/source/java/org/alfresco/repo/security/person/PersonServiceImpl.java @@ -42,6 +42,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.repo.cache.SimpleCache; +import org.alfresco.repo.domain.hibernate.DirtySessionMethodInterceptor; import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.PolicyComponent; @@ -629,7 +630,9 @@ public class PersonServiceImpl extends TransactionListenerAdapter implements Per homeFolderManager.makeHomeFolder(ref); return null; } - }, transactionService.isReadOnly(), false); + }, transactionService.isReadOnly(), transactionService.isReadOnly() ? false : AlfrescoTransactionSupport.getTransactionReadState() == TxnReadState.TXN_READ_ONLY); + //homeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER)); + //assert(homeFolder != null); } } } diff --git a/source/java/org/alfresco/repo/security/person/PersonServiceLoader.java b/source/java/org/alfresco/repo/security/person/PersonServiceLoader.java index 318c750923..e28eeae668 100644 --- a/source/java/org/alfresco/repo/security/person/PersonServiceLoader.java +++ b/source/java/org/alfresco/repo/security/person/PersonServiceLoader.java @@ -26,6 +26,9 @@ package org.alfresco.repo.security.person; import org.alfresco.model.ContentModel; import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.transaction.AlfrescoTransactionSupport; +import org.alfresco.repo.transaction.RetryingTransactionHelper; +import org.alfresco.repo.transaction.AlfrescoTransactionSupport.TxnReadState; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.NodeRef; @@ -93,7 +96,8 @@ public class PersonServiceLoader public static void main(String[] args) { StringBuilder sb = new StringBuilder(); - sb.append("\n").append("Usage\n").append(" PersonServiceLoader --user= --pwd= --batch-count= --batch-size= --threads=\n"); + sb.append("\n").append("Usage\n").append( + " PersonServiceLoader --user= --pwd= --batch-count= --batch-size= --threads=\n"); String usage = sb.toString(); ArgumentHelper argHelper = new ArgumentHelper(usage, args); try @@ -110,20 +114,19 @@ public class PersonServiceLoader PersonServiceLoader loader = new PersonServiceLoader(ctx, batchSize, batchCount); loader.run(user, pwd, threads); - // check the lazy creation - + AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getSystemUserName()); - + final ServiceRegistry serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY); final AuthenticationService authenticationService = serviceRegistry.getAuthenticationService(); final PersonService personService = serviceRegistry.getPersonService(); final TransactionService transactionService = serviceRegistry.getTransactionService(); final NodeService nodeService = serviceRegistry.getNodeService(); - + String firstName = "" + System.currentTimeMillis(); String lastName = String.format("%05d", -1); - String username = GUID.generate(); + final String username = GUID.generate(); String emailAddress = String.format("%s.%s@xyz.com", firstName, lastName); PropertyMap properties = new PropertyMap(7); properties.put(ContentModel.PROP_USERNAME, username); @@ -131,30 +134,36 @@ public class PersonServiceLoader properties.put(ContentModel.PROP_LASTNAME, lastName); properties.put(ContentModel.PROP_EMAIL, emailAddress); NodeRef madePerson = personService.createPerson(properties); - + NodeRef homeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(madePerson, ContentModel.PROP_HOMEFOLDER)); - if(homeFolder != null) + if (homeFolder != null) { - throw new IllegalStateException("Home folder created eagerly"); + throw new IllegalStateException("Home folder created eagerly"); } - - NodeRef person = personService.getPerson(username); - homeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER)); - if(homeFolder == null) + + RetryingTransactionHelper helper = transactionService.getRetryingTransactionHelper(); + helper.doInTransaction(new RetryingTransactionCallback() { - throw new IllegalStateException("Home folder not created lazily"); - } - + public Void execute() throws Throwable + { + NodeRef person = personService.getPerson(username); + NodeRef homeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(person, ContentModel.PROP_HOMEFOLDER)); + if (homeFolder == null) + { + throw new IllegalStateException("Home folder not created lazily"); + } + return null; + } + }, true, true); + NodeRef autoPerson = personService.getPerson(GUID.generate()); NodeRef autoHomeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(autoPerson, ContentModel.PROP_HOMEFOLDER)); - if(autoHomeFolder == null) + if (autoHomeFolder == null) { - throw new IllegalStateException("Home folder not created lazily for auto created users"); + throw new IllegalStateException("Home folder not created lazily for auto created users"); } - - - + // All done ApplicationContextHelper.closeApplicationContext(); System.exit(0); @@ -177,7 +186,7 @@ public class PersonServiceLoader Thread waiter; int batchSize; - + int batchCount; ApplicationContext ctx; @@ -239,9 +248,8 @@ public class PersonServiceLoader double deltaMs = (double) (end - start) / 1000000.0D; double ave = deltaMs / (double) batchSize; System.out.println("\n" - + Thread.currentThread().getName() +"\n" - + "Batch users created: \n" + " Batch Number: " + i + "\n" + " Batch Size: " + batchSize + "\n" + " Batch Time (ms): " - + Math.floor(deltaMs) + "\n" + " Average (ms): " + Math.floor(ave)); + + Thread.currentThread().getName() + "\n" + "Batch users created: \n" + " Batch Number: " + i + "\n" + " Batch Size: " + batchSize + "\n" + + " Batch Time (ms): " + Math.floor(deltaMs) + "\n" + " Average (ms): " + Math.floor(ave)); } } catch (Exception e) diff --git a/source/java/org/alfresco/repo/security/person/PersonTest.java b/source/java/org/alfresco/repo/security/person/PersonTest.java index 2cc33c7520..40995383ed 100644 --- a/source/java/org/alfresco/repo/security/person/PersonTest.java +++ b/source/java/org/alfresco/repo/security/person/PersonTest.java @@ -34,6 +34,7 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.alfresco.model.ContentModel; +import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; @@ -48,6 +49,7 @@ import org.alfresco.service.transaction.TransactionService; import org.alfresco.util.BaseSpringTest; import org.alfresco.util.EqualsHelper; import org.alfresco.util.GUID; +import org.alfresco.util.PropertyMap; public class PersonTest extends BaseSpringTest { @@ -97,6 +99,53 @@ public class PersonTest extends BaseSpringTest super.onTearDownInTransaction(); } + public void xtestLazyHomeFolderCreation() + { + String firstName = "" + System.currentTimeMillis(); + String lastName = String.format("%05d", -1); + final String username = GUID.generate(); + String emailAddress = String.format("%s.%s@xyz.com", firstName, lastName); + PropertyMap properties = new PropertyMap(7); + properties.put(ContentModel.PROP_USERNAME, username); + properties.put(ContentModel.PROP_FIRSTNAME, firstName); + properties.put(ContentModel.PROP_LASTNAME, lastName); + properties.put(ContentModel.PROP_EMAIL, emailAddress); + final NodeRef madePerson = personService.createPerson(properties); + + NodeRef homeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(madePerson, ContentModel.PROP_HOMEFOLDER)); + if (homeFolder != null) + { + throw new IllegalStateException("Home folder created eagerly"); + } + + setComplete(); + endTransaction(); + startNewTransaction(); + + RetryingTransactionHelper helper = transactionService.getRetryingTransactionHelper(); + helper.doInTransaction(new RetryingTransactionCallback() + { + public Void execute() throws Throwable + { + assertTrue(personService.personExists(username)); + NodeRef person = personService.getPerson(username); + assertEquals(madePerson, person); + NodeRef homeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(madePerson, ContentModel.PROP_HOMEFOLDER)); + if (homeFolder == null) + { + throw new IllegalStateException("Home folder not created lazily"); + } + return null; + } + }, true, false); + + homeFolder = DefaultTypeConverter.INSTANCE.convert(NodeRef.class, nodeService.getProperty(madePerson, ContentModel.PROP_HOMEFOLDER)); + if (homeFolder == null) + { + throw new IllegalStateException("Home folder not created lazily"); + } + } + public void testZones() { assertNull(authorityService.getAuthorityZones("derek"));