mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-10-08 14:51:49 +00:00
Compare commits
47 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b2c749f850 | ||
|
0174949fbf | ||
|
65ee4c725a | ||
|
8e33924701 | ||
|
2f8ea7bff1 | ||
|
263337c720 | ||
|
226aaf8503 | ||
|
86f971f713 | ||
|
0958e866b0 | ||
|
ad6caede9c | ||
|
44a2d5e6e3 | ||
|
858f839ee0 | ||
|
5908e9f4c1 | ||
|
453326c4d8 | ||
|
0aaa9bcbba | ||
|
0870a8cacf | ||
|
8176f82e78 | ||
|
7fc6463c78 | ||
|
4555dd3939 | ||
|
41c8488634 | ||
|
439a17302a | ||
|
c1ee9467c8 | ||
|
3443ea9eb7 | ||
|
4fb14adfd9 | ||
|
dded4a461b | ||
|
93dedd01c2 | ||
|
eb0a064b31 | ||
|
db30d7fbfe | ||
|
ba5f94b848 | ||
|
4a9eef0356 | ||
|
0c681258e9 | ||
|
2c28b04efa | ||
|
8027a579ab | ||
|
81768de342 | ||
|
6bec0c84fe | ||
|
9efdb7aeb1 | ||
|
51f669bd48 | ||
|
51092c7d4f | ||
|
4ae12096ab | ||
|
ce829f9ebb | ||
|
1222326741 | ||
|
d9ce80ab31 | ||
|
bcf7df9e48 | ||
|
094e3189cb | ||
|
d22936a36a | ||
|
66b3c95837 | ||
|
a40e10cd12 |
13
.github/workflows/ci.yml
vendored
13
.github/workflows/ci.yml
vendored
@@ -36,8 +36,16 @@ jobs:
|
|||||||
!contains(github.event.head_commit.message, '[force')
|
!contains(github.event.head_commit.message, '[force')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v7.0.0
|
with:
|
||||||
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v7.0.0
|
fetch-depth: 0
|
||||||
|
- uses: Alfresco/alfresco-build-tools/.github/actions/get-build-info@v8.2.0
|
||||||
|
- uses: Alfresco/alfresco-build-tools/.github/actions/free-hosted-runner-disk-space@v8.2.0
|
||||||
|
- uses: Alfresco/alfresco-build-tools/.github/actions/setup-java-build@v8.2.0
|
||||||
|
- id: changed-files
|
||||||
|
uses: Alfresco/alfresco-build-tools/.github/actions/github-list-changes@v8.2.0
|
||||||
|
with:
|
||||||
|
write-list-to-env: true
|
||||||
|
- uses: Alfresco/alfresco-build-tools/.github/actions/pre-commit@v8.2.0
|
||||||
- name: "Init"
|
- name: "Init"
|
||||||
run: bash ./scripts/ci/init.sh
|
run: bash ./scripts/ci/init.sh
|
||||||
- name: "Prepare maven cache and check compilation"
|
- name: "Prepare maven cache and check compilation"
|
||||||
@@ -45,6 +53,7 @@ jobs:
|
|||||||
- name: "Clean Maven cache"
|
- name: "Clean Maven cache"
|
||||||
run: bash ./scripts/ci/cleanup_cache.sh
|
run: bash ./scripts/ci/cleanup_cache.sh
|
||||||
|
|
||||||
|
|
||||||
veracode:
|
veracode:
|
||||||
name: "Source Clear Scan (SCA)"
|
name: "Source Clear Scan (SCA)"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
14
.pre-commit-config.yaml
Normal file
14
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
repos:
|
||||||
|
- repo: https://github.com/Yelp/detect-secrets
|
||||||
|
rev: v1.5.0
|
||||||
|
hooks:
|
||||||
|
- id: detect-secrets
|
||||||
|
args: ["--baseline", ".secrets.baseline"]
|
||||||
|
- repo: local
|
||||||
|
hooks:
|
||||||
|
- id: check-format-and-headers
|
||||||
|
name: Check format and headers and fix if necessary
|
||||||
|
entry: ./scripts/hooks/check-format-and-headers.sh
|
||||||
|
language: script
|
||||||
|
files: ".*.java"
|
||||||
|
pass_filenames: false
|
1864
.secrets.baseline
Normal file
1864
.secrets.baseline
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,9 +3,53 @@ Thanks for your interest in contributing to this project!
|
|||||||
|
|
||||||
The following is a set of guidelines for contributing to this library. Most of them will make the life of the reviewer easier and therefore decrease the time required for the patch be included in the next version.
|
The following is a set of guidelines for contributing to this library. Most of them will make the life of the reviewer easier and therefore decrease the time required for the patch be included in the next version.
|
||||||
|
|
||||||
Because this project forms a part of Alfresco Content Services, the guidelines are hosted in the [Alfresco Social Community](http://community.alfresco.com/community/ecm) where they can be referenced from multiple projects.
|
The project uses [pre-commit](https://pre-commit.com/) to format code (with [Spotless](https://github.com/diffplug/spotless)), validate license headers and check for secrets (with [detect-secrets](https://github.com/Yelp/detect-secrets)). To install the pre-commit hooks then first install pre-commit and then run:
|
||||||
|
```shell
|
||||||
|
pre-commit install
|
||||||
|
```
|
||||||
|
When you make a commit then these hooks will run and check the modified files. If it makes changes then you can review them and then `git commit` again to accept the changes.
|
||||||
|
|
||||||
Read an [overview on how this project is goverened](https://community.alfresco.com/docs/DOC-6385-project-overview-repository).
|
#### Code Quality
|
||||||
|
This project uses `spotless` that enforces `alfresco-formatter.xml` to ensure code quality.
|
||||||
|
|
||||||
|
To check code-style violations you can use:
|
||||||
|
```bash
|
||||||
|
mvn spotless:check
|
||||||
|
```
|
||||||
|
To reformat files you can use:
|
||||||
|
```bash
|
||||||
|
mvn spotless:apply
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Secret Detection
|
||||||
|
|
||||||
|
We are using [detect-secrets](https://github.com/Yelp/detect-secrets) to try to avoid accidentally publishing secret keys.
|
||||||
|
If you have pre-commit installed then this should run automatically when making a commit. Usually there should be no issues,
|
||||||
|
but if it finds a potential issue (e.g. a high entropy string) then you will see the following:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
Detect secrets...........................................................Failed
|
||||||
|
- hook id: detect-secrets
|
||||||
|
- exit code: 1
|
||||||
|
|
||||||
|
ERROR: Potential secrets about to be committed to git repo!
|
||||||
|
|
||||||
|
Secret Type: Secret Keyword
|
||||||
|
Location: test.txt:1
|
||||||
|
```
|
||||||
|
|
||||||
|
If this is a false positive and you actually want to commit the string then run these two commands:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
detect-secrets scan --baseline .secrets.baseline
|
||||||
|
detect-secrets audit .secrets.baseline
|
||||||
|
```
|
||||||
|
|
||||||
|
This will update the baseline file to include your new code and then allow you to review the detected secret and mark it as a false positive.
|
||||||
|
Once you are finished then you can add `.secrets.baseline` to the staged changes and you should be able to create a commit.
|
||||||
|
|
||||||
|
|
||||||
|
Because this project forms a part of Alfresco Content Services, the guidelines are hosted in the [Alfresco Social Community](https://hub.alfresco.com/t5/alfresco-content-services-ecm/ct-p/ECM-software) where they can be referenced from multiple projects.
|
||||||
|
|
||||||
You can report an issue in the ALF project of the [Alfresco issue tracker](http://issues.alfresco.com).
|
You can report an issue in the ALF project of the [Alfresco issue tracker](http://issues.alfresco.com).
|
||||||
|
|
||||||
|
401
alfresco-formatter.xml
Normal file
401
alfresco-formatter.xml
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<profiles version="23">
|
||||||
|
<profile kind="CodeFormatterProfile" name="Spotless" version="23">
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment" value="common_lines"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration" value="common_lines"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.align_with_spaces" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_record_components" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_logical_operator" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line" value="one_line_if_empty"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line" value="one_line_if_empty"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause" value="common_lines"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line" value="one_line_if_empty"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_shift_operator" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="next_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_parameters" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_loops" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_switch_case_arrow_operator" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation" value="common_lines"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.text_block_indentation" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_module_statements" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line" value="one_line_if_empty"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_permitted_types" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="next_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_annotations" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines" value="2147483647"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="next_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_not_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration" value="common_lines"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_type_arguments" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="49"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_permitted_types_in_type_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.javadoc_do_not_separate_block_tags" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.indent_tag_description" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_constructor" value="next_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_string_concatenation" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_shift_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_shift_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_additive_operator" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_relational_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_logical_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation" value="common_lines"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration" value="common_lines"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement" value="common_lines"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement" value="common_lines"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_switch_body_block_on_one_line" value="one_line_never"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_arrow" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="999"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_method_body_on_one_line" value="one_line_if_empty"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line" value="one_line_if_empty"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="next_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line" value="one_line_if_empty"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_additive_operator" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_relational_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line" value="one_line_if_empty"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="next_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_relational_operator" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_additive_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.align_selector_in_method_invocation_on_expression_first_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_record_declaration" value="next_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_switch_case_with_arrow_on_one_line" value="one_line_never"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_switch_case_with_colon" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="49"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="49"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="next_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_additive_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="49"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_conditional_operator" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_shift_operator" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause" value="common_lines"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_code_block_on_one_line" value="one_line_if_empty"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_assignment_operator" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="next_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_switch_case_with_arrow" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line" value="one_line_if_empty"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="49"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line" value="one_line_if_empty"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assertion_message" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_logical_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_relational_operator" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line" value="false"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_logical_operator" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration" value="common_lines"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_permitted_types" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line" value="one_line_if_empty"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="next_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="next_line"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block" value="0"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.wrap_before_string_concatenation" value="true"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="999"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||||
|
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
# Version label
|
# Version label
|
||||||
version.major=7
|
version.major=7
|
||||||
version.minor=4
|
version.minor=4
|
||||||
version.revision=3
|
version.revision=2
|
||||||
version.label=
|
version.label=
|
||||||
|
|
||||||
# Edition label
|
# Edition label
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@@ -9,6 +9,6 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<organization>
|
<organization>
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<developers>
|
<developers>
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<developers>
|
<developers>
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<developers>
|
<developers>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
39
pom.xml
39
pom.xml
@@ -2,7 +2,7 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<name>Alfresco Community Repo Parent</name>
|
<name>Alfresco Community Repo Parent</name>
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<acs.version.major>7</acs.version.major>
|
<acs.version.major>7</acs.version.major>
|
||||||
<acs.version.minor>4</acs.version.minor>
|
<acs.version.minor>4</acs.version.minor>
|
||||||
<acs.version.revision>3</acs.version.revision>
|
<acs.version.revision>2</acs.version.revision>
|
||||||
<acs.version.label />
|
<acs.version.label />
|
||||||
<amp.min.version>${acs.version.major}.0.0</amp.min.version>
|
<amp.min.version>${acs.version.major}.0.0</amp.min.version>
|
||||||
|
|
||||||
@@ -52,12 +52,12 @@
|
|||||||
<dependency.alfresco-messaging-repo.version>1.2.20</dependency.alfresco-messaging-repo.version>
|
<dependency.alfresco-messaging-repo.version>1.2.20</dependency.alfresco-messaging-repo.version>
|
||||||
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
|
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
|
||||||
<dependency.activiti.version>5.23.0</dependency.activiti.version>
|
<dependency.activiti.version>5.23.0</dependency.activiti.version>
|
||||||
<dependency.alfresco-transform-core.version>5.1.5</dependency.alfresco-transform-core.version>
|
<dependency.alfresco-transform-service.version>4.1.3</dependency.alfresco-transform-service.version>
|
||||||
<dependency.alfresco-transform-service.version>4.1.5</dependency.alfresco-transform-service.version>
|
<dependency.alfresco-transform-core.version>5.1.3</dependency.alfresco-transform-core.version>
|
||||||
<dependency.alfresco-greenmail.version>6.5</dependency.alfresco-greenmail.version>
|
<dependency.alfresco-greenmail.version>6.5</dependency.alfresco-greenmail.version>
|
||||||
<dependency.acs-event-model.version>0.0.18</dependency.acs-event-model.version>
|
<dependency.acs-event-model.version>0.0.18</dependency.acs-event-model.version>
|
||||||
|
|
||||||
<dependency.spring.version>5.3.34</dependency.spring.version>
|
<dependency.spring.version>5.3.39</dependency.spring.version>
|
||||||
<dependency.antlr.version>3.5.3</dependency.antlr.version>
|
<dependency.antlr.version>3.5.3</dependency.antlr.version>
|
||||||
<dependency.jackson.version>2.15.4</dependency.jackson.version>
|
<dependency.jackson.version>2.15.4</dependency.jackson.version>
|
||||||
<dependency.cxf.version>3.5.5</dependency.cxf.version>
|
<dependency.cxf.version>3.5.5</dependency.cxf.version>
|
||||||
@@ -118,6 +118,9 @@
|
|||||||
|
|
||||||
<alfresco.maven-plugin.version>2.2.0</alfresco.maven-plugin.version>
|
<alfresco.maven-plugin.version>2.2.0</alfresco.maven-plugin.version>
|
||||||
<license-maven-plugin.version>2.0.1.alfresco-2</license-maven-plugin.version>
|
<license-maven-plugin.version>2.0.1.alfresco-2</license-maven-plugin.version>
|
||||||
|
<spotless-plugin.version>2.43.0</spotless-plugin.version>
|
||||||
|
<!-- Do not match any files by default, but this can be overridden from the command line. -->
|
||||||
|
<spotless-include-list>NO_AUTOMATED_FORMATTING</spotless-include-list>
|
||||||
|
|
||||||
<dependency.postgresql.version>42.5.2</dependency.postgresql.version>
|
<dependency.postgresql.version>42.5.2</dependency.postgresql.version>
|
||||||
<dependency.mysql.version>8.0.30</dependency.mysql.version>
|
<dependency.mysql.version>8.0.30</dependency.mysql.version>
|
||||||
@@ -151,7 +154,7 @@
|
|||||||
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
|
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
|
||||||
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
|
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
|
||||||
<url>https://github.com/Alfresco/alfresco-community-repo</url>
|
<url>https://github.com/Alfresco/alfresco-community-repo</url>
|
||||||
<tag>22.108</tag>
|
<tag>22.36</tag>
|
||||||
</scm>
|
</scm>
|
||||||
|
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
@@ -1021,6 +1024,26 @@
|
|||||||
<skipDeploy>true</skipDeploy>
|
<skipDeploy>true</skipDeploy>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.diffplug.spotless</groupId>
|
||||||
|
<artifactId>spotless-maven-plugin</artifactId>
|
||||||
|
<version>${spotless-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<java>
|
||||||
|
<includes>
|
||||||
|
${spotless-include-list}
|
||||||
|
</includes>
|
||||||
|
<eclipse>
|
||||||
|
<file>alfresco-formatter.xml</file>
|
||||||
|
</eclipse>
|
||||||
|
<importOrder>
|
||||||
|
<order>\#java|\#javax|\#jakarta,\#,\#org.alfresco,java|javax|jakarta,,org.alfresco</order>
|
||||||
|
</importOrder>
|
||||||
|
<removeUnusedImports />
|
||||||
|
<formatAnnotations />
|
||||||
|
</java>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</pluginManagement>
|
</pluginManagement>
|
||||||
<plugins>
|
<plugins>
|
||||||
@@ -1028,6 +1051,10 @@
|
|||||||
<groupId>org.codehaus.mojo</groupId>
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
<artifactId>license-maven-plugin</artifactId>
|
<artifactId>license-maven-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.diffplug.spotless</groupId>
|
||||||
|
<artifactId>spotless-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>org.alfresco</groupId>
|
<groupId>org.alfresco</groupId>
|
||||||
<artifactId>alfresco-community-repo</artifactId>
|
<artifactId>alfresco-community-repo</artifactId>
|
||||||
<version>22.108</version>
|
<version>22.36</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,493 +1,484 @@
|
|||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
* provided under the following open source license terms:
|
* provided under the following open source license terms:
|
||||||
*
|
*
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Lesser General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.repo.content;
|
package org.alfresco.repo.content;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
|
||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.apache.commons.logging.Log;
|
||||||
import org.alfresco.repo.cache.SimpleCache;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.alfresco.service.cmr.repository.ContentIOException;
|
|
||||||
import org.alfresco.service.cmr.repository.ContentReader;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
import org.alfresco.util.GUID;
|
import org.alfresco.service.cmr.repository.ContentIOException;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
import org.apache.commons.logging.Log;
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.alfresco.util.GUID;
|
||||||
|
import org.alfresco.util.Pair;
|
||||||
/**
|
|
||||||
* A store providing support for content store implementations that provide
|
/**
|
||||||
* routing of content read and write requests based on context.
|
* A store providing support for content store implementations that provide routing of content read and write requests based on context.
|
||||||
*
|
*
|
||||||
* @see ContentContext
|
* @see ContentContext
|
||||||
*
|
*
|
||||||
* @since 2.1
|
* @since 2.1
|
||||||
* @author Derek Hulley
|
* @author Derek Hulley
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractRoutingContentStore implements ContentStore
|
public abstract class AbstractRoutingContentStore implements ContentStore
|
||||||
{
|
{
|
||||||
private static Log logger = LogFactory.getLog(AbstractRoutingContentStore.class);
|
private static Log logger = LogFactory.getLog(AbstractRoutingContentStore.class);
|
||||||
|
|
||||||
private String instanceKey = GUID.generate();
|
private String instanceKey = GUID.generate();
|
||||||
private SimpleCache<Pair<String, String>, ContentStore> storesByContentUrl;
|
private SimpleCache<Pair<String, String>, ContentStore> storesByContentUrl;
|
||||||
private ReadLock storesCacheReadLock;
|
private ReadLock storesCacheReadLock;
|
||||||
private WriteLock storesCacheWriteLock;
|
private WriteLock storesCacheWriteLock;
|
||||||
|
|
||||||
protected AbstractRoutingContentStore()
|
protected AbstractRoutingContentStore()
|
||||||
{
|
{
|
||||||
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
storesCacheReadLock = lock.readLock();
|
storesCacheReadLock = lock.readLock();
|
||||||
storesCacheWriteLock = lock.writeLock();
|
storesCacheWriteLock = lock.writeLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param storesCache cache of stores used to access URLs
|
* @param storesCache
|
||||||
*/
|
* cache of stores used to access URLs
|
||||||
public void setStoresCache(SimpleCache<Pair<String, String>, ContentStore> storesCache)
|
*/
|
||||||
{
|
public void setStoresCache(SimpleCache<Pair<String, String>, ContentStore> storesCache)
|
||||||
this.storesByContentUrl = storesCache;
|
{
|
||||||
}
|
this.storesByContentUrl = storesCache;
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @return Returns a list of all possible stores available for reading or writing
|
/**
|
||||||
*/
|
* @return Returns a list of all possible stores available for reading or writing
|
||||||
protected abstract List<ContentStore> getAllStores();
|
*/
|
||||||
|
protected abstract List<ContentStore> getAllStores();
|
||||||
/**
|
|
||||||
* Get a content store based on the context provided. The applicability of the
|
/**
|
||||||
* context and even the types of context allowed are up to the implementation, but
|
* Get a content store based on the context provided. The applicability of the context and even the types of context allowed are up to the implementation, but normally there should be a fallback case for when the parameters are not adequate to make a decision.
|
||||||
* normally there should be a fallback case for when the parameters are not adequate
|
*
|
||||||
* to make a decision.
|
* @param ctx
|
||||||
*
|
* the context to use to make the choice
|
||||||
* @param ctx the context to use to make the choice
|
* @return Returns the store most appropriate for the given context and <b>never <tt>null</tt></b>
|
||||||
* @return Returns the store most appropriate for the given context and
|
*/
|
||||||
* <b>never <tt>null</tt></b>
|
protected abstract ContentStore selectWriteStore(ContentContext ctx);
|
||||||
*/
|
|
||||||
protected abstract ContentStore selectWriteStore(ContentContext ctx);
|
/**
|
||||||
|
* Checks the cache for the store and ensures that the URL is in the store.
|
||||||
/**
|
*
|
||||||
* Checks the cache for the store and ensures that the URL is in the store.
|
* @param contentUrl
|
||||||
*
|
* the content URL to search for
|
||||||
* @param contentUrl the content URL to search for
|
* @return Returns the store matching the content URL
|
||||||
* @return Returns the store matching the content URL
|
*/
|
||||||
*/
|
private ContentStore selectReadStore(String contentUrl)
|
||||||
private ContentStore selectReadStore(String contentUrl)
|
{
|
||||||
{
|
Pair<String, String> cacheKey = new Pair<String, String>(instanceKey, contentUrl);
|
||||||
Pair<String, String> cacheKey = new Pair<String, String>(instanceKey, contentUrl);
|
storesCacheReadLock.lock();
|
||||||
storesCacheReadLock.lock();
|
try
|
||||||
try
|
{
|
||||||
{
|
// Check if the store is in the cache
|
||||||
// Check if the store is in the cache
|
ContentStore store = storesByContentUrl.get(cacheKey);
|
||||||
ContentStore store = storesByContentUrl.get(cacheKey);
|
if (store != null)
|
||||||
if (store != null)
|
{
|
||||||
{
|
// We found a store that was previously used
|
||||||
// We found a store that was previously used
|
try
|
||||||
try
|
{
|
||||||
{
|
// It is possible for content to be removed from a store and
|
||||||
// It is possible for content to be removed from a store and
|
// it might have moved into another store.
|
||||||
// it might have moved into another store.
|
if (store.exists(contentUrl))
|
||||||
if (store.exists(contentUrl))
|
{
|
||||||
{
|
// We found a store and can use it
|
||||||
// We found a store and can use it
|
return store;
|
||||||
return store;
|
}
|
||||||
}
|
}
|
||||||
}
|
catch (UnsupportedContentUrlException e)
|
||||||
catch (UnsupportedContentUrlException e)
|
{
|
||||||
{
|
// This is odd. The store that previously supported the content URL
|
||||||
// This is odd. The store that previously supported the content URL
|
// no longer does so. I can't think of a reason why that would be.
|
||||||
// no longer does so. I can't think of a reason why that would be.
|
throw new AlfrescoRuntimeException(
|
||||||
throw new AlfrescoRuntimeException(
|
"Found a content store that previously supported a URL, but no longer does: \n" +
|
||||||
"Found a content store that previously supported a URL, but no longer does: \n" +
|
" Store: " + store + "\n" +
|
||||||
" Store: " + store + "\n" +
|
" Content URL: " + contentUrl);
|
||||||
" Content URL: " + contentUrl);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
finally
|
||||||
finally
|
{
|
||||||
{
|
storesCacheReadLock.unlock();
|
||||||
storesCacheReadLock.unlock();
|
}
|
||||||
}
|
// Get the write lock and double check
|
||||||
// Get the write lock and double check
|
storesCacheWriteLock.lock();
|
||||||
storesCacheWriteLock.lock();
|
try
|
||||||
try
|
{
|
||||||
{
|
// Double check
|
||||||
// Double check
|
ContentStore store = storesByContentUrl.get(cacheKey);
|
||||||
ContentStore store = storesByContentUrl.get(cacheKey);
|
if (store != null && store.exists(contentUrl))
|
||||||
if (store != null && store.exists(contentUrl))
|
{
|
||||||
{
|
// We found a store and can use it
|
||||||
// We found a store and can use it
|
if (logger.isDebugEnabled())
|
||||||
if (logger.isDebugEnabled())
|
{
|
||||||
{
|
logger.debug(
|
||||||
logger.debug(
|
"Found mapped store for content URL: \n" +
|
||||||
"Found mapped store for content URL: \n" +
|
" Content URL: " + contentUrl + "\n" +
|
||||||
" Content URL: " + contentUrl + "\n" +
|
" Store: " + store);
|
||||||
" Store: " + store);
|
}
|
||||||
}
|
return store;
|
||||||
return store;
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
store = null;
|
||||||
store = null;
|
}
|
||||||
}
|
// It isn't, so search all the stores
|
||||||
// It isn't, so search all the stores
|
List<ContentStore> stores = getAllStores();
|
||||||
List<ContentStore> stores = getAllStores();
|
// Keep track of the unsupported state of the content URL - it might be a rubbish URL
|
||||||
// Keep track of the unsupported state of the content URL - it might be a rubbish URL
|
boolean contentUrlSupported = false;
|
||||||
boolean contentUrlSupported = false;
|
for (ContentStore storeInList : stores)
|
||||||
for (ContentStore storeInList : stores)
|
{
|
||||||
{
|
boolean exists = false;
|
||||||
boolean exists = false;
|
try
|
||||||
try
|
{
|
||||||
{
|
exists = storeInList.exists(contentUrl);
|
||||||
exists = storeInList.exists(contentUrl);
|
// At least the content URL was supported
|
||||||
// At least the content URL was supported
|
contentUrlSupported = true;
|
||||||
contentUrlSupported = true;
|
}
|
||||||
}
|
catch (UnsupportedContentUrlException e)
|
||||||
catch (UnsupportedContentUrlException e)
|
{
|
||||||
{
|
// The store can't handle the content URL
|
||||||
// The store can't handle the content URL
|
}
|
||||||
}
|
if (!exists)
|
||||||
if (!exists)
|
{
|
||||||
{
|
// It is not in the store
|
||||||
// It is not in the store
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
// We found one
|
||||||
// We found one
|
store = storeInList;
|
||||||
store = storeInList;
|
// Put the value in the cache
|
||||||
// Put the value in the cache
|
storesByContentUrl.put(cacheKey, store);
|
||||||
storesByContentUrl.put(cacheKey, store);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
// Check if the content URL was supported
|
||||||
// Check if the content URL was supported
|
if (!contentUrlSupported)
|
||||||
if (!contentUrlSupported)
|
{
|
||||||
{
|
throw new UnsupportedContentUrlException(this, contentUrl);
|
||||||
throw new UnsupportedContentUrlException(this, contentUrl);
|
}
|
||||||
}
|
// Done
|
||||||
// Done
|
if (logger.isDebugEnabled())
|
||||||
if (logger.isDebugEnabled())
|
{
|
||||||
{
|
logger.debug(
|
||||||
logger.debug(
|
"Mapped content URL to store for reading: \n" +
|
||||||
"Mapped content URL to store for reading: \n" +
|
" Content URL: " + contentUrl + "\n" +
|
||||||
" Content URL: " + contentUrl + "\n" +
|
" Store: " + store);
|
||||||
" Store: " + store);
|
}
|
||||||
}
|
return store;
|
||||||
return store;
|
}
|
||||||
}
|
finally
|
||||||
finally
|
{
|
||||||
{
|
storesCacheWriteLock.unlock();
|
||||||
storesCacheWriteLock.unlock();
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
/**
|
* @return Returns <tt>true</tt> if the URL is supported by any of the stores.
|
||||||
* @return Returns <tt>true</tt> if the URL is supported by any of the stores.
|
*/
|
||||||
*/
|
public boolean isContentUrlSupported(String contentUrl)
|
||||||
public boolean isContentUrlSupported(String contentUrl)
|
{
|
||||||
{
|
List<ContentStore> stores = getAllStores();
|
||||||
List<ContentStore> stores = getAllStores();
|
boolean supported = false;
|
||||||
boolean supported = false;
|
for (ContentStore store : stores)
|
||||||
for (ContentStore store : stores)
|
{
|
||||||
{
|
if (store.isContentUrlSupported(contentUrl))
|
||||||
if (store.isContentUrlSupported(contentUrl))
|
{
|
||||||
{
|
supported = true;
|
||||||
supported = true;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
// Done
|
||||||
// Done
|
if (logger.isDebugEnabled())
|
||||||
if (logger.isDebugEnabled())
|
{
|
||||||
{
|
logger.debug("The url " + (supported ? "is" : "is not") + " supported by at least one store.");
|
||||||
logger.debug("The url " + (supported ? "is" : "is not") + " supported by at least one store.");
|
}
|
||||||
}
|
return supported;
|
||||||
return supported;
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
/**
|
* @return Returns <tt>true</tt> if write is supported by any of the stores.
|
||||||
* @return Returns <tt>true</tt> if write is supported by any of the stores.
|
*/
|
||||||
*/
|
public boolean isWriteSupported()
|
||||||
public boolean isWriteSupported()
|
{
|
||||||
{
|
List<ContentStore> stores = getAllStores();
|
||||||
List<ContentStore> stores = getAllStores();
|
boolean supported = false;
|
||||||
boolean supported = false;
|
for (ContentStore store : stores)
|
||||||
for (ContentStore store : stores)
|
{
|
||||||
{
|
if (store.isWriteSupported())
|
||||||
if (store.isWriteSupported())
|
{
|
||||||
{
|
supported = true;
|
||||||
supported = true;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
}
|
||||||
}
|
// Done
|
||||||
// Done
|
if (logger.isDebugEnabled())
|
||||||
if (logger.isDebugEnabled())
|
{
|
||||||
{
|
logger.debug("Writing " + (supported ? "is" : "is not") + " supported by at least one store.");
|
||||||
logger.debug("Writing " + (supported ? "is" : "is not") + " supported by at least one store.");
|
}
|
||||||
}
|
return supported;
|
||||||
return supported;
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
/**
|
* @return Returns <b>.</b> always
|
||||||
* @return Returns <b>.</b> always
|
*/
|
||||||
*/
|
public String getRootLocation()
|
||||||
public String getRootLocation()
|
{
|
||||||
{
|
return ".";
|
||||||
return ".";
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
/**
|
* @return Returns <tt>-1</tt> always
|
||||||
* @return Returns <tt>-1</tt> always
|
*/
|
||||||
*/
|
@Override
|
||||||
@Override
|
public long getSpaceFree()
|
||||||
public long getSpaceFree()
|
{
|
||||||
{
|
return -1L;
|
||||||
return -1L;
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
/**
|
* @return Returns <tt>-1</tt> always
|
||||||
* @return Returns <tt>-1</tt> always
|
*/
|
||||||
*/
|
@Override
|
||||||
@Override
|
public long getSpaceTotal()
|
||||||
public long getSpaceTotal()
|
{
|
||||||
{
|
return -1L;
|
||||||
return -1L;
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
/**
|
* @see #selectReadStore(String)
|
||||||
* @see #selectReadStore(String)
|
*/
|
||||||
*/
|
public boolean exists(String contentUrl) throws ContentIOException
|
||||||
public boolean exists(String contentUrl) throws ContentIOException
|
{
|
||||||
{
|
ContentStore store = selectReadStore(contentUrl);
|
||||||
ContentStore store = selectReadStore(contentUrl);
|
return (store != null);
|
||||||
return (store != null);
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
/**
|
* @return Returns a valid reader from one of the stores otherwise a {@link EmptyContentReader} is returned.
|
||||||
* @return Returns a valid reader from one of the stores otherwise
|
*/
|
||||||
* a {@link EmptyContentReader} is returned.
|
public ContentReader getReader(String contentUrl) throws ContentIOException
|
||||||
*/
|
{
|
||||||
public ContentReader getReader(String contentUrl) throws ContentIOException
|
ContentStore store = selectReadStore(contentUrl);
|
||||||
{
|
if (store != null)
|
||||||
ContentStore store = selectReadStore(contentUrl);
|
{
|
||||||
if (store != null)
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
logger.debug("Getting reader from store: \n" +
|
||||||
{
|
" Content URL: " + contentUrl + "\n" +
|
||||||
logger.debug("Getting reader from store: \n" +
|
" Store: " + store);
|
||||||
" Content URL: " + contentUrl + "\n" +
|
}
|
||||||
" Store: " + store);
|
return store.getReader(contentUrl);
|
||||||
}
|
}
|
||||||
return store.getReader(contentUrl);
|
else
|
||||||
}
|
{
|
||||||
else
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled())
|
logger.debug("Getting empty reader for content URL: " + contentUrl);
|
||||||
{
|
}
|
||||||
logger.debug("Getting empty reader for content URL: " + contentUrl);
|
return new EmptyContentReader(contentUrl);
|
||||||
}
|
}
|
||||||
return new EmptyContentReader(contentUrl);
|
}
|
||||||
}
|
|
||||||
}
|
/**
|
||||||
|
* Selects a store for the given context and caches store that was used.
|
||||||
/**
|
*
|
||||||
* Selects a store for the given context and caches store that was used.
|
* @see #selectWriteStore(ContentContext)
|
||||||
*
|
*/
|
||||||
* @see #selectWriteStore(ContentContext)
|
public ContentWriter getWriter(ContentContext context) throws ContentIOException
|
||||||
*/
|
{
|
||||||
public ContentWriter getWriter(ContentContext context) throws ContentIOException
|
String contentUrl = context.getContentUrl();
|
||||||
{
|
Pair<String, String> cacheKey = new Pair<String, String>(instanceKey, contentUrl);
|
||||||
String contentUrl = context.getContentUrl();
|
if (contentUrl != null)
|
||||||
Pair<String, String> cacheKey = new Pair<String, String>(instanceKey, contentUrl);
|
{
|
||||||
if (contentUrl != null)
|
// Check to see if it is in the cache
|
||||||
{
|
storesCacheReadLock.lock();
|
||||||
// Check to see if it is in the cache
|
try
|
||||||
storesCacheReadLock.lock();
|
{
|
||||||
try
|
// Check if the store is in the cache
|
||||||
{
|
ContentStore store = storesByContentUrl.get(cacheKey);
|
||||||
// Check if the store is in the cache
|
if (store != null)
|
||||||
ContentStore store = storesByContentUrl.get(cacheKey);
|
{
|
||||||
if (store != null)
|
throw new ContentExistsException(this, contentUrl);
|
||||||
{
|
}
|
||||||
throw new ContentExistsException(this, contentUrl);
|
/* We could go further and check each store for the existence of the URL, but that would be overkill. The main problem we need to prevent is the simultaneous access of the same store. The router represents a single store and therefore if the URL is present in any of the stores, it is effectively present in all of them. */
|
||||||
}
|
}
|
||||||
/*
|
finally
|
||||||
* We could go further and check each store for the existence of the URL,
|
{
|
||||||
* but that would be overkill. The main problem we need to prevent is
|
storesCacheReadLock.unlock();
|
||||||
* the simultaneous access of the same store. The router represents
|
}
|
||||||
* a single store and therefore if the URL is present in any of the stores,
|
}
|
||||||
* it is effectively present in all of them.
|
// Select the store for writing
|
||||||
*/
|
ContentStore store = selectWriteStore(context);
|
||||||
}
|
// Check that we were given a valid store
|
||||||
finally
|
if (store == null)
|
||||||
{
|
{
|
||||||
storesCacheReadLock.unlock();
|
throw new NullPointerException(
|
||||||
}
|
"Unable to find a writer. 'selectWriteStore' may not return null: \n" +
|
||||||
}
|
" Router: " + this + "\n" +
|
||||||
// Select the store for writing
|
" Chose: " + store);
|
||||||
ContentStore store = selectWriteStore(context);
|
}
|
||||||
// Check that we were given a valid store
|
else if (!store.isWriteSupported())
|
||||||
if (store == null)
|
{
|
||||||
{
|
throw new AlfrescoRuntimeException(
|
||||||
throw new NullPointerException(
|
"A write store was chosen that doesn't support writes: \n" +
|
||||||
"Unable to find a writer. 'selectWriteStore' may not return null: \n" +
|
" Router: " + this + "\n" +
|
||||||
" Router: " + this + "\n" +
|
" Chose: " + store);
|
||||||
" Chose: " + store);
|
}
|
||||||
}
|
ContentWriter writer = store.getWriter(context);
|
||||||
else if (!store.isWriteSupported())
|
String newContentUrl = writer.getContentUrl();
|
||||||
{
|
Pair<String, String> newCacheKey = new Pair<String, String>(instanceKey, newContentUrl);
|
||||||
throw new AlfrescoRuntimeException(
|
// Cache the store against the URL
|
||||||
"A write store was chosen that doesn't support writes: \n" +
|
storesCacheWriteLock.lock();
|
||||||
" Router: " + this + "\n" +
|
try
|
||||||
" Chose: " + store);
|
{
|
||||||
}
|
storesByContentUrl.put(newCacheKey, store);
|
||||||
ContentWriter writer = store.getWriter(context);
|
}
|
||||||
String newContentUrl = writer.getContentUrl();
|
finally
|
||||||
Pair<String, String> newCacheKey = new Pair<String, String>(instanceKey, newContentUrl);
|
{
|
||||||
// Cache the store against the URL
|
storesCacheWriteLock.unlock();
|
||||||
storesCacheWriteLock.lock();
|
}
|
||||||
try
|
// Done
|
||||||
{
|
if (logger.isDebugEnabled())
|
||||||
storesByContentUrl.put(newCacheKey, store);
|
{
|
||||||
}
|
logger.debug(
|
||||||
finally
|
"Got writer and cache URL from store: \n" +
|
||||||
{
|
" Context: " + context + "\n" +
|
||||||
storesCacheWriteLock.unlock();
|
" Writer: " + writer + "\n" +
|
||||||
}
|
" Store: " + store);
|
||||||
// Done
|
}
|
||||||
if (logger.isDebugEnabled())
|
return writer;
|
||||||
{
|
}
|
||||||
logger.debug(
|
|
||||||
"Got writer and cache URL from store: \n" +
|
public ContentWriter getWriter(ContentReader existingContentReader, String newContentUrl) throws ContentIOException
|
||||||
" Context: " + context + "\n" +
|
{
|
||||||
" Writer: " + writer + "\n" +
|
return getWriter(new ContentContext(existingContentReader, newContentUrl));
|
||||||
" Store: " + store);
|
}
|
||||||
}
|
|
||||||
return writer;
|
/**
|
||||||
}
|
* This operation has to be performed on all the stores in order to maintain the {@link ContentStore#exists(String)} contract.
|
||||||
|
*/
|
||||||
public ContentWriter getWriter(ContentReader existingContentReader, String newContentUrl) throws ContentIOException
|
public boolean delete(String contentUrl) throws ContentIOException
|
||||||
{
|
{
|
||||||
return getWriter(new ContentContext(existingContentReader, newContentUrl));
|
boolean deleted = true;
|
||||||
}
|
List<ContentStore> stores = getAllStores();
|
||||||
|
for (ContentStore store : stores)
|
||||||
/**
|
{
|
||||||
* This operation has to be performed on all the stores in order to maintain the
|
if (store.isWriteSupported())
|
||||||
* {@link ContentStore#exists(String)} contract.
|
{
|
||||||
*/
|
deleted &= store.delete(contentUrl);
|
||||||
public boolean delete(String contentUrl) throws ContentIOException
|
}
|
||||||
{
|
}
|
||||||
boolean deleted = true;
|
// Done
|
||||||
List<ContentStore> stores = getAllStores();
|
if (logger.isDebugEnabled())
|
||||||
for (ContentStore store : stores)
|
{
|
||||||
{
|
logger.debug("Deleted content URL from stores: \n" +
|
||||||
if (store.isWriteSupported())
|
" Stores: " + stores.size() + "\n" +
|
||||||
{
|
" Deleted: " + deleted);
|
||||||
deleted &= store.delete(contentUrl);
|
}
|
||||||
}
|
return deleted;
|
||||||
}
|
}
|
||||||
// Done
|
|
||||||
if (logger.isDebugEnabled())
|
/**
|
||||||
{
|
* {@inheritDoc}
|
||||||
logger.debug("Deleted content URL from stores: \n" +
|
*/
|
||||||
" Stores: " + stores.size() + "\n" +
|
@Override
|
||||||
" Deleted: " + deleted);
|
public Map<String, String> getStorageProperties(String contentUrl)
|
||||||
}
|
{
|
||||||
return deleted;
|
ContentStore contentStore = selectReadStore(contentUrl);
|
||||||
}
|
|
||||||
|
if (contentStore == null)
|
||||||
/**
|
{
|
||||||
* {@inheritDoc}
|
logNoContentStore(contentUrl);
|
||||||
*/
|
return Collections.emptyMap();
|
||||||
@Override
|
}
|
||||||
public Map<String, String> getStorageProperties(String contentUrl)
|
final String message = "Getting storage properties from store: ";
|
||||||
{
|
logExecution(contentUrl, contentStore, message);
|
||||||
ContentStore contentStore = selectReadStore(contentUrl);
|
|
||||||
|
return contentStore.getStorageProperties(contentUrl);
|
||||||
if (contentStore == null)
|
}
|
||||||
{
|
|
||||||
logNoContentStore(contentUrl);
|
/**
|
||||||
return Collections.emptyMap();
|
* {@inheritDoc}
|
||||||
}
|
*/
|
||||||
final String message = "Getting storage properties from store: ";
|
@Override
|
||||||
logExecution(contentUrl, contentStore, message);
|
public boolean requestSendContentToArchive(String contentUrl, Map<String, Serializable> archiveParams)
|
||||||
|
{
|
||||||
return contentStore.getStorageProperties(contentUrl);
|
final ContentStore contentStore = selectReadStore(contentUrl);
|
||||||
}
|
if (contentStore == null)
|
||||||
|
{
|
||||||
/**
|
logNoContentStore(contentUrl);
|
||||||
* {@inheritDoc}
|
return ContentStore.super.requestSendContentToArchive(contentUrl, archiveParams);
|
||||||
*/
|
}
|
||||||
@Override
|
final String message = "Sending content to archive: ";
|
||||||
public boolean requestSendContentToArchive(String contentUrl, Map<String, Serializable> archiveParams)
|
logExecution(contentUrl, contentStore, message);
|
||||||
{
|
return contentStore.requestSendContentToArchive(contentUrl, archiveParams);
|
||||||
final ContentStore contentStore = selectReadStore(contentUrl);
|
}
|
||||||
if (contentStore == null)
|
|
||||||
{
|
/**
|
||||||
logNoContentStore(contentUrl);
|
* {@inheritDoc}
|
||||||
return ContentStore.super.requestSendContentToArchive(contentUrl, archiveParams);
|
*/
|
||||||
}
|
@Override
|
||||||
final String message = "Sending content to archive: ";
|
public boolean requestRestoreContentFromArchive(String contentUrl, Map<String, Serializable> restoreParams)
|
||||||
logExecution(contentUrl, contentStore, message);
|
{
|
||||||
return contentStore.requestSendContentToArchive(contentUrl, archiveParams);
|
final ContentStore contentStore = selectReadStore(contentUrl);
|
||||||
}
|
if (contentStore == null)
|
||||||
|
{
|
||||||
/**
|
logNoContentStore(contentUrl);
|
||||||
* {@inheritDoc}
|
return ContentStore.super.requestRestoreContentFromArchive(contentUrl, restoreParams);
|
||||||
*/
|
}
|
||||||
@Override
|
final String message = "Restoring content from archive: ";
|
||||||
public boolean requestRestoreContentFromArchive(String contentUrl, Map<String, Serializable> restoreParams)
|
logExecution(contentUrl, contentStore, message);
|
||||||
{
|
return contentStore.requestRestoreContentFromArchive(contentUrl, restoreParams);
|
||||||
final ContentStore contentStore = selectReadStore(contentUrl);
|
}
|
||||||
if (contentStore == null)
|
|
||||||
{
|
private void logExecution(final String contentUrl, final ContentStore contentStore, final String message)
|
||||||
logNoContentStore(contentUrl);
|
{
|
||||||
return ContentStore.super.requestRestoreContentFromArchive(contentUrl, restoreParams);
|
if (logger.isTraceEnabled())
|
||||||
}
|
{
|
||||||
final String message = "Restoring content from archive: ";
|
logger.trace(message + "\n" +
|
||||||
logExecution(contentUrl, contentStore, message);
|
" Content URL: " + contentUrl + "\n" +
|
||||||
return ContentStore.super.requestRestoreContentFromArchive(contentUrl, restoreParams);
|
" Store: " + contentStore);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private void logExecution(final String contentUrl, final ContentStore contentStore, final String message)
|
|
||||||
{
|
private void logNoContentStore(String contentUrl)
|
||||||
if (logger.isTraceEnabled())
|
{
|
||||||
{
|
if (logger.isTraceEnabled())
|
||||||
logger.trace(message + "\n" +
|
{
|
||||||
" Content URL: " + contentUrl + "\n" +
|
logger.trace("Content Store not found for content URL: " + contentUrl);
|
||||||
" Store: " + contentStore);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logNoContentStore(String contentUrl)
|
|
||||||
{
|
|
||||||
if (logger.isTraceEnabled())
|
|
||||||
{
|
|
||||||
logger.trace("Content Store not found for content URL: " + contentUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -40,6 +40,9 @@ import java.util.Objects;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.event.v1.model.ContentInfo;
|
import org.alfresco.repo.event.v1.model.ContentInfo;
|
||||||
@@ -48,6 +51,7 @@ import org.alfresco.repo.event.v1.model.UserInfo;
|
|||||||
import org.alfresco.repo.event2.filter.EventFilterRegistry;
|
import org.alfresco.repo.event2.filter.EventFilterRegistry;
|
||||||
import org.alfresco.repo.event2.filter.NodeAspectFilter;
|
import org.alfresco.repo.event2.filter.NodeAspectFilter;
|
||||||
import org.alfresco.repo.event2.filter.NodePropertyFilter;
|
import org.alfresco.repo.event2.filter.NodePropertyFilter;
|
||||||
|
import org.alfresco.repo.event2.mapper.PropertyMapper;
|
||||||
import org.alfresco.repo.node.MLPropertyInterceptor;
|
import org.alfresco.repo.node.MLPropertyInterceptor;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||||
@@ -66,9 +70,6 @@ import org.alfresco.service.namespace.NamespaceService;
|
|||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.util.PathUtil;
|
import org.alfresco.util.PathUtil;
|
||||||
import org.alfresco.util.PropertyCheck;
|
import org.alfresco.util.PropertyCheck;
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper for {@link NodeResource} objects.
|
* Helper for {@link NodeResource} objects.
|
||||||
@@ -79,14 +80,15 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
{
|
{
|
||||||
private static final Log LOGGER = LogFactory.getLog(NodeResourceHelper.class);
|
private static final Log LOGGER = LogFactory.getLog(NodeResourceHelper.class);
|
||||||
|
|
||||||
protected NodeService nodeService;
|
protected NodeService nodeService;
|
||||||
protected DictionaryService dictionaryService;
|
protected DictionaryService dictionaryService;
|
||||||
protected PersonService personService;
|
protected PersonService personService;
|
||||||
protected EventFilterRegistry eventFilterRegistry;
|
protected EventFilterRegistry eventFilterRegistry;
|
||||||
protected NamespaceService namespaceService;
|
protected NamespaceService namespaceService;
|
||||||
protected PermissionService permissionService;
|
protected PermissionService permissionService;
|
||||||
|
protected PropertyMapper propertyMapper;
|
||||||
|
|
||||||
private NodeAspectFilter nodeAspectFilter;
|
private NodeAspectFilter nodeAspectFilter;
|
||||||
private NodePropertyFilter nodePropertyFilter;
|
private NodePropertyFilter nodePropertyFilter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -98,6 +100,7 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
PropertyCheck.mandatory(this, "eventFilterRegistry", eventFilterRegistry);
|
PropertyCheck.mandatory(this, "eventFilterRegistry", eventFilterRegistry);
|
||||||
PropertyCheck.mandatory(this, "namespaceService", namespaceService);
|
PropertyCheck.mandatory(this, "namespaceService", namespaceService);
|
||||||
PropertyCheck.mandatory(this, "permissionService", permissionService);
|
PropertyCheck.mandatory(this, "permissionService", permissionService);
|
||||||
|
PropertyCheck.mandatory(this, "propertyMapper", propertyMapper);
|
||||||
|
|
||||||
this.nodeAspectFilter = eventFilterRegistry.getNodeAspectFilter();
|
this.nodeAspectFilter = eventFilterRegistry.getNodeAspectFilter();
|
||||||
this.nodePropertyFilter = eventFilterRegistry.getNodePropertyFilter();
|
this.nodePropertyFilter = eventFilterRegistry.getNodePropertyFilter();
|
||||||
@@ -122,7 +125,7 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
{
|
{
|
||||||
this.permissionService = permissionService;
|
this.permissionService = permissionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
// To make IntelliJ stop complaining about unused method!
|
// To make IntelliJ stop complaining about unused method!
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public void setEventFilterRegistry(EventFilterRegistry eventFilterRegistry)
|
public void setEventFilterRegistry(EventFilterRegistry eventFilterRegistry)
|
||||||
@@ -135,6 +138,11 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
this.namespaceService = namespaceService;
|
this.namespaceService = namespaceService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPropertyMapper(PropertyMapper propertyMapper)
|
||||||
|
{
|
||||||
|
this.propertyMapper = propertyMapper;
|
||||||
|
}
|
||||||
|
|
||||||
public NodeResource.Builder createNodeResourceBuilder(NodeRef nodeRef)
|
public NodeResource.Builder createNodeResourceBuilder(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
final QName type = nodeService.getType(nodeRef);
|
final QName type = nodeService.getType(nodeRef);
|
||||||
@@ -146,20 +154,20 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
Map<String, UserInfo> mapUserCache = new HashMap<>(2);
|
Map<String, UserInfo> mapUserCache = new HashMap<>(2);
|
||||||
|
|
||||||
return NodeResource.builder().setId(nodeRef.getId())
|
return NodeResource.builder().setId(nodeRef.getId())
|
||||||
.setName((String) properties.get(ContentModel.PROP_NAME))
|
.setName((String) properties.get(ContentModel.PROP_NAME))
|
||||||
.setNodeType(getQNamePrefixString(type))
|
.setNodeType(getQNamePrefixString(type))
|
||||||
.setIsFile(isSubClass(type, ContentModel.TYPE_CONTENT))
|
.setIsFile(isSubClass(type, ContentModel.TYPE_CONTENT))
|
||||||
.setIsFolder(isSubClass(type, ContentModel.TYPE_FOLDER))
|
.setIsFolder(isSubClass(type, ContentModel.TYPE_FOLDER))
|
||||||
.setCreatedByUser(getUserInfo((String) properties.get(ContentModel.PROP_CREATOR), mapUserCache))
|
.setCreatedByUser(getUserInfo((String) properties.get(ContentModel.PROP_CREATOR), mapUserCache))
|
||||||
.setCreatedAt(getZonedDateTime((Date)properties.get(ContentModel.PROP_CREATED)))
|
.setCreatedAt(getZonedDateTime((Date) properties.get(ContentModel.PROP_CREATED)))
|
||||||
.setModifiedByUser(getUserInfo((String) properties.get(ContentModel.PROP_MODIFIER), mapUserCache))
|
.setModifiedByUser(getUserInfo((String) properties.get(ContentModel.PROP_MODIFIER), mapUserCache))
|
||||||
.setModifiedAt(getZonedDateTime((Date)properties.get(ContentModel.PROP_MODIFIED)))
|
.setModifiedAt(getZonedDateTime((Date) properties.get(ContentModel.PROP_MODIFIED)))
|
||||||
.setContent(getContentInfo(properties))
|
.setContent(getContentInfo(properties))
|
||||||
.setPrimaryAssocQName(getPrimaryAssocQName(nodeRef))
|
.setPrimaryAssocQName(getPrimaryAssocQName(nodeRef))
|
||||||
.setPrimaryHierarchy(PathUtil.getNodeIdsInReverse(path, false))
|
.setPrimaryHierarchy(PathUtil.getNodeIdsInReverse(path, false))
|
||||||
.setProperties(mapToNodeProperties(properties))
|
.setProperties(mapToNodeProperties(properties))
|
||||||
.setLocalizedProperties(mapToNodeLocalizedProperties(properties))
|
.setLocalizedProperties(mapToNodeLocalizedProperties(properties))
|
||||||
.setAspectNames(getMappedAspects(nodeRef));
|
.setAspectNames(getMappedAspects(nodeRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSubClass(QName className, QName ofClassQName)
|
private boolean isSubClass(QName className, QName ofClassQName)
|
||||||
@@ -167,17 +175,18 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
return dictionaryService.isSubClass(className, ofClassQName);
|
return dictionaryService.isSubClass(className, ofClassQName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPrimaryAssocQName(NodeRef nodeRef)
|
private String getPrimaryAssocQName(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
String result = null;
|
String result = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ChildAssociationRef primaryParent = nodeService.getPrimaryParent(nodeRef);
|
ChildAssociationRef primaryParent = nodeService.getPrimaryParent(nodeRef);
|
||||||
if(primaryParent != null && primaryParent.getQName() != null)
|
if (primaryParent != null && primaryParent.getQName() != null)
|
||||||
{
|
{
|
||||||
result = primaryParent.getQName().getPrefixedQName(namespaceService).getPrefixString();
|
result = primaryParent.getQName().getPrefixedQName(namespaceService).getPrefixString();
|
||||||
}
|
}
|
||||||
} catch (NamespaceException namespaceException)
|
}
|
||||||
|
catch (NamespaceException namespaceException)
|
||||||
{
|
{
|
||||||
LOGGER.error("Cannot return a valid primary association QName: " + namespaceException.getMessage());
|
LOGGER.error("Cannot return a valid primary association QName: " + namespaceException.getMessage());
|
||||||
}
|
}
|
||||||
@@ -211,8 +220,8 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
{
|
{
|
||||||
v = ((MLText) v).getDefaultValue();
|
v = ((MLText) v).getDefaultValue();
|
||||||
}
|
}
|
||||||
|
Serializable mappedValue = propertyMapper.map(k, v);
|
||||||
filteredProps.put(getQNamePrefixString(k), v);
|
filteredProps.put(getQNamePrefixString(k), mappedValue);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -228,7 +237,10 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
{
|
{
|
||||||
final MLText mlTextValue = (MLText) v;
|
final MLText mlTextValue = (MLText) v;
|
||||||
final HashMap<String, String> localizedValues = new HashMap<>(mlTextValue.size());
|
final HashMap<String, String> localizedValues = new HashMap<>(mlTextValue.size());
|
||||||
mlTextValue.forEach((locale, text) -> localizedValues.put(locale.toString(), text));
|
mlTextValue.forEach((locale, text) -> {
|
||||||
|
Serializable mappedValue = propertyMapper.map(k, text);
|
||||||
|
localizedValues.put(locale.toString(), (String) mappedValue);
|
||||||
|
});
|
||||||
filteredProps.put(getQNamePrefixString(k), localizedValues);
|
filteredProps.put(getQNamePrefixString(k), localizedValues);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -255,7 +267,7 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
{
|
{
|
||||||
String sysUserName = AuthenticationUtil.getSystemUserName();
|
String sysUserName = AuthenticationUtil.getSystemUserName();
|
||||||
if (userName.equals(sysUserName) || (AuthenticationUtil.isMtEnabled()
|
if (userName.equals(sysUserName) || (AuthenticationUtil.isMtEnabled()
|
||||||
&& userName.startsWith(sysUserName + "@")))
|
&& userName.startsWith(sysUserName + "@")))
|
||||||
{
|
{
|
||||||
userInfo = new UserInfo(userName, userName, "");
|
userInfo = new UserInfo(userName, userName, "");
|
||||||
}
|
}
|
||||||
@@ -302,11 +314,11 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the QName in the format prefix:local, but in the exceptional case where there is no registered prefix
|
* Returns the QName in the format prefix:local, but in the exceptional case where there is no registered prefix returns it in the form {uri}local.
|
||||||
* returns it in the form {uri}local.
|
|
||||||
*
|
*
|
||||||
* @param k QName
|
* @param k
|
||||||
* @return a String representing the QName in the format prefix:local or {uri}local.
|
* QName
|
||||||
|
* @return a String representing the QName in the format prefix:local or {uri}local.
|
||||||
*/
|
*/
|
||||||
public String getQNamePrefixString(QName k)
|
public String getQNamePrefixString(QName k)
|
||||||
{
|
{
|
||||||
@@ -338,7 +350,7 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
|
|
||||||
public QName getNodeType(NodeRef nodeRef)
|
public QName getNodeType(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
return nodeService.getType(nodeRef);
|
return nodeService.getType(nodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Serializable getProperty(NodeRef nodeRef, QName qName)
|
public Serializable getProperty(NodeRef nodeRef, QName qName)
|
||||||
@@ -348,13 +360,14 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
|
|
||||||
public Map<QName, Serializable> getProperties(NodeRef nodeRef)
|
public Map<QName, Serializable> getProperties(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
//We need to have full MLText properties here. This is why we are marking the current thread as MLAware
|
// We need to have full MLText properties here. This is why we are marking the current thread as MLAware
|
||||||
final boolean toRestore = MLPropertyInterceptor.isMLAware();
|
final boolean toRestore = MLPropertyInterceptor.isMLAware();
|
||||||
MLPropertyInterceptor.setMLAware(true);
|
MLPropertyInterceptor.setMLAware(true);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return nodeService.getProperties(nodeRef);
|
return nodeService.getProperties(nodeRef);
|
||||||
} finally
|
}
|
||||||
|
finally
|
||||||
{
|
{
|
||||||
MLPropertyInterceptor.setMLAware(toRestore);
|
MLPropertyInterceptor.setMLAware(toRestore);
|
||||||
}
|
}
|
||||||
@@ -373,7 +386,7 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Map<String, Map<String, String>> getLocalizedPropertiesBefore(Map<String, Map<String, String>> locPropsBefore,
|
static Map<String, Map<String, String>> getLocalizedPropertiesBefore(Map<String, Map<String, String>> locPropsBefore,
|
||||||
Map<String, Map<String, String>> locPropsAfter)
|
Map<String, Map<String, String>> locPropsAfter)
|
||||||
{
|
{
|
||||||
final Map<String, Map<String, String>> result = new HashMap<>(locPropsBefore.size());
|
final Map<String, Map<String, String>> result = new HashMap<>(locPropsBefore.size());
|
||||||
|
|
||||||
@@ -406,7 +419,7 @@ public class NodeResourceHelper implements InitializingBean
|
|||||||
{
|
{
|
||||||
return mapToNodeAspects(nodeService.getAspects(nodeRef));
|
return mapToNodeAspects(nodeService.getAspects(nodeRef));
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getPrimaryHierarchy(NodeRef nodeRef, boolean showLeaf)
|
public List<String> getPrimaryHierarchy(NodeRef nodeRef, boolean showLeaf)
|
||||||
{
|
{
|
||||||
final Path path = nodeService.getPath(nodeRef);
|
final Path path = nodeService.getPath(nodeRef);
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -26,160 +26,50 @@
|
|||||||
package org.alfresco.repo.event2.filter;
|
package org.alfresco.repo.event2.filter;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.repo.event2.shared.CSVStringToListParser;
|
||||||
import org.alfresco.service.namespace.NamespaceException;
|
import org.alfresco.repo.event2.shared.QNameMatcher;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.repo.event2.shared.TypeDefExpander;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract {@link EventFilter} implementation, containing common event filtering
|
* Abstract {@link EventFilter} implementation, containing common event filtering functionality for the {@link QName} type.
|
||||||
* functionality for the {@link QName} type.
|
|
||||||
*
|
*
|
||||||
* @author Jamal Kaabi-Mofrad
|
* @author Jamal Kaabi-Mofrad
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractNodeEventFilter implements EventFilter<QName>
|
public abstract class AbstractNodeEventFilter implements EventFilter<QName>
|
||||||
{
|
{
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractNodeEventFilter.class);
|
protected TypeDefExpander typeDefExpander;
|
||||||
|
|
||||||
private static final String MARKER_INCLUDE_SUBTYPES = "include_subtypes";
|
private QNameMatcher qNameMatcher;
|
||||||
private static final String WILDCARD = "*";
|
|
||||||
|
|
||||||
protected DictionaryService dictionaryService;
|
|
||||||
protected NamespaceService namespaceService;
|
|
||||||
|
|
||||||
private Set<QName> excludedTypes;
|
|
||||||
private Set<String> excludedNamespaceURI;
|
|
||||||
|
|
||||||
public AbstractNodeEventFilter()
|
|
||||||
{
|
|
||||||
this.excludedTypes = new HashSet<>();
|
|
||||||
this.excludedNamespaceURI = new HashSet<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void init()
|
public final void init()
|
||||||
{
|
{
|
||||||
preprocessExcludedTypes(getExcludedTypes());
|
qNameMatcher = new QNameMatcher(getExcludedTypes());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDictionaryService(DictionaryService dictionaryService)
|
public void setTypeDefExpander(TypeDefExpander typeDefExpander)
|
||||||
{
|
{
|
||||||
this.dictionaryService = dictionaryService;
|
this.typeDefExpander = typeDefExpander;
|
||||||
}
|
|
||||||
|
|
||||||
public void setNamespaceService(NamespaceService namespaceService)
|
|
||||||
{
|
|
||||||
this.namespaceService = namespaceService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isExcluded(QName qName)
|
public boolean isExcluded(QName qName)
|
||||||
{
|
{
|
||||||
if (qName != null)
|
return qNameMatcher.isMatching(qName);
|
||||||
{
|
|
||||||
return excludedTypes.contains(qName) || excludedNamespaceURI.contains(qName.getNamespaceURI());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Set<QName> getExcludedTypes();
|
protected abstract Set<QName> getExcludedTypes();
|
||||||
|
|
||||||
protected List<String> parseFilterList(String unparsedFilterList)
|
protected List<String> parseFilterList(String unparsedFilterList)
|
||||||
{
|
{
|
||||||
List<String> list = new LinkedList<>();
|
return CSVStringToListParser.parse(unparsedFilterList);
|
||||||
|
|
||||||
StringTokenizer st = new StringTokenizer(unparsedFilterList, ",");
|
|
||||||
while (st.hasMoreTokens())
|
|
||||||
{
|
|
||||||
String entry = st.nextToken().trim();
|
|
||||||
if (!entry.isEmpty())
|
|
||||||
{
|
|
||||||
if (!entry.equals("none") && !entry.contains("${"))
|
|
||||||
{
|
|
||||||
list.add(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes the user-defined list of types into valid QNames. It
|
|
||||||
* validates them against the dictionary and also supports wildcards
|
|
||||||
*/
|
|
||||||
private void preprocessExcludedTypes(Set<QName> excluded)
|
|
||||||
{
|
|
||||||
excluded.forEach(qName -> {
|
|
||||||
if (WILDCARD.equals(qName.getLocalName()))
|
|
||||||
{
|
|
||||||
//excludedPrefixes.add(getPrefix(qName));
|
|
||||||
excludedNamespaceURI.add(qName.getNamespaceURI());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
excludedTypes.add(qName);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled())
|
|
||||||
{
|
|
||||||
LOGGER.debug("Excluded namespace URIs:" + excludedNamespaceURI);
|
|
||||||
LOGGER.debug("Excluded types:" + excludedTypes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private QName getQName(String type)
|
|
||||||
{
|
|
||||||
return QName.createQName(type, namespaceService);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Collection<QName> expandTypeDef(String typeDef)
|
protected Collection<QName> expandTypeDef(String typeDef)
|
||||||
{
|
{
|
||||||
if ((typeDef == null) || typeDef.isEmpty() || typeDef.equals("none") || typeDef.contains("${"))
|
return typeDefExpander.expand(typeDef);
|
||||||
{
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeDef.indexOf(' ') < 0)
|
|
||||||
{
|
|
||||||
return Collections.singleton(getQName(typeDef));
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] typeDefParts = typeDef.split(" ");
|
|
||||||
if (typeDefParts.length != 2)
|
|
||||||
{
|
|
||||||
LOGGER.warn("Ignoring invalid blacklist type pattern: " + typeDef);
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeDefParts[1].equals(MARKER_INCLUDE_SUBTYPES))
|
|
||||||
{
|
|
||||||
if (typeDefParts[0].indexOf('*') >= 0)
|
|
||||||
{
|
|
||||||
LOGGER.warn("Ignoring invalid blacklist type pattern: " + typeDef);
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
QName baseType;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
baseType = getQName(typeDefParts[0]);
|
|
||||||
}
|
|
||||||
catch (NamespaceException ne)
|
|
||||||
{
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return dictionaryService.getSubTypes(baseType, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGGER.warn("Ignoring invalid blacklist type pattern: " + typeDef);
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.event2.filter;
|
package org.alfresco.repo.event2.filter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -43,24 +44,26 @@ public class NodePropertyFilter extends AbstractNodeEventFilter
|
|||||||
// These properties are included as top-level info,
|
// These properties are included as top-level info,
|
||||||
// so exclude them from the properties object
|
// so exclude them from the properties object
|
||||||
private static final Set<QName> EXCLUDED_TOP_LEVEL_PROPS = Set.of(ContentModel.PROP_NAME,
|
private static final Set<QName> EXCLUDED_TOP_LEVEL_PROPS = Set.of(ContentModel.PROP_NAME,
|
||||||
ContentModel.PROP_MODIFIER,
|
ContentModel.PROP_MODIFIER,
|
||||||
ContentModel.PROP_MODIFIED,
|
ContentModel.PROP_MODIFIED,
|
||||||
ContentModel.PROP_CREATOR,
|
ContentModel.PROP_CREATOR,
|
||||||
ContentModel.PROP_CREATED,
|
ContentModel.PROP_CREATED,
|
||||||
ContentModel.PROP_CONTENT);
|
ContentModel.PROP_CONTENT);
|
||||||
|
|
||||||
private final List<String> nodeAspectsBlackList;
|
private final List<String> nodePropertiesBlackList = new ArrayList<>();
|
||||||
|
|
||||||
public NodePropertyFilter()
|
public NodePropertyFilter(String userConfiguredProperties)
|
||||||
{
|
{
|
||||||
this.nodeAspectsBlackList = parseFilterList(FILTERED_PROPERTIES);
|
super();
|
||||||
|
nodePropertiesBlackList.addAll(parseFilterList(FILTERED_PROPERTIES));
|
||||||
|
nodePropertiesBlackList.addAll(parseFilterList(userConfiguredProperties));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<QName> getExcludedTypes()
|
public Set<QName> getExcludedTypes()
|
||||||
{
|
{
|
||||||
Set<QName> result = new HashSet<>(EXCLUDED_TOP_LEVEL_PROPS);
|
Set<QName> result = new HashSet<>(EXCLUDED_TOP_LEVEL_PROPS);
|
||||||
nodeAspectsBlackList.forEach(nodeAspect -> result.addAll(expandTypeDef(nodeAspect)));
|
nodePropertiesBlackList.forEach(nodeProperty -> result.addAll(expandTypeDef(nodeProperty)));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -31,6 +31,7 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,10 +42,13 @@ import org.alfresco.service.namespace.QName;
|
|||||||
public class NodeTypeFilter extends AbstractNodeEventFilter
|
public class NodeTypeFilter extends AbstractNodeEventFilter
|
||||||
{
|
{
|
||||||
private final List<String> nodeTypesBlackList;
|
private final List<String> nodeTypesBlackList;
|
||||||
|
private final DictionaryService dictionaryService;
|
||||||
|
|
||||||
public NodeTypeFilter(String filteredNodeTypes)
|
public NodeTypeFilter(String filteredNodeTypes, DictionaryService dictionaryService)
|
||||||
{
|
{
|
||||||
|
super();
|
||||||
this.nodeTypesBlackList = parseFilterList(filteredNodeTypes);
|
this.nodeTypesBlackList = parseFilterList(filteredNodeTypes);
|
||||||
|
this.dictionaryService = dictionaryService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2025 - 2025 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.event2.mapper;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
public interface PropertyMapper
|
||||||
|
{
|
||||||
|
PropertyMapper NO_OP = (propertyQName, value) -> value;
|
||||||
|
|
||||||
|
Serializable map(QName propertyQName, Serializable value);
|
||||||
|
}
|
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2025 - 2025 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.event2.mapper;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import org.alfresco.repo.event2.shared.CSVStringToListParser;
|
||||||
|
import org.alfresco.repo.event2.shared.TypeDefExpander;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
public class PropertyMapperFactory
|
||||||
|
{
|
||||||
|
private final TypeDefExpander typeDefExpander;
|
||||||
|
|
||||||
|
public PropertyMapperFactory(TypeDefExpander typeDefExpander)
|
||||||
|
{
|
||||||
|
this.typeDefExpander = typeDefExpander;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyMapper createPropertyMapper(String enabled, String userConfiguredSensitiveProperties, String userConfiguredReplacementText)
|
||||||
|
{
|
||||||
|
if ("false".equalsIgnoreCase(enabled))
|
||||||
|
{
|
||||||
|
return PropertyMapper.NO_OP;
|
||||||
|
}
|
||||||
|
Set<QName> sensitiveProperties = Optional.ofNullable(userConfiguredSensitiveProperties)
|
||||||
|
.filter(Predicate.not(String::isEmpty))
|
||||||
|
.map(CSVStringToListParser::parse)
|
||||||
|
.map(typeDefExpander::expand)
|
||||||
|
.orElse(Set.of());
|
||||||
|
return new ReplaceSensitivePropertyWithTextMapper(sensitiveProperties, userConfiguredReplacementText);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2025 - 2025 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.event2.mapper;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.event2.shared.QNameMatcher;
|
||||||
|
import org.alfresco.repo.transfer.TransferModel;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
public class ReplaceSensitivePropertyWithTextMapper implements PropertyMapper
|
||||||
|
{
|
||||||
|
private static final Set<QName> DEFAULT_SENSITIVE_PROPERTIES = Set.of(
|
||||||
|
ContentModel.PROP_PASSWORD,
|
||||||
|
ContentModel.PROP_SALT,
|
||||||
|
ContentModel.PROP_PASSWORD_HASH,
|
||||||
|
TransferModel.PROP_PASSWORD);
|
||||||
|
private static final String DEFAULT_REPLACEMENT_TEXT = "SENSITIVE_DATA_REMOVED";
|
||||||
|
|
||||||
|
private final QNameMatcher qNameMatcher;
|
||||||
|
private final String replacementText;
|
||||||
|
|
||||||
|
public ReplaceSensitivePropertyWithTextMapper(Set<QName> userConfiguredSensitiveProperties, String userConfiguredReplacementText)
|
||||||
|
{
|
||||||
|
Set<QName> sensitiveProperties = Optional.ofNullable(userConfiguredSensitiveProperties)
|
||||||
|
.filter(Predicate.not(Collection::isEmpty))
|
||||||
|
.orElse(DEFAULT_SENSITIVE_PROPERTIES);
|
||||||
|
qNameMatcher = new QNameMatcher(sensitiveProperties);
|
||||||
|
replacementText = Optional.ofNullable(userConfiguredReplacementText)
|
||||||
|
.filter(Predicate.not(String::isEmpty))
|
||||||
|
.filter(userInput -> !userInput.contains("${"))
|
||||||
|
.orElse(DEFAULT_REPLACEMENT_TEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Serializable map(QName propertyQName, Serializable value)
|
||||||
|
{
|
||||||
|
if (qNameMatcher.isMatching(propertyQName))
|
||||||
|
{
|
||||||
|
return replacementText;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2025 - 2025 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.event2.shared;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
public final class CSVStringToListParser
|
||||||
|
{
|
||||||
|
private CSVStringToListParser()
|
||||||
|
{}
|
||||||
|
|
||||||
|
public static List<String> parse(String userInputCSV)
|
||||||
|
{
|
||||||
|
List<String> list = new LinkedList<>();
|
||||||
|
|
||||||
|
StringTokenizer st = new StringTokenizer(userInputCSV, ",");
|
||||||
|
while (st.hasMoreTokens())
|
||||||
|
{
|
||||||
|
String entry = st.nextToken().trim();
|
||||||
|
if (!entry.isEmpty() && !entry.equals("none") && !entry.contains("${"))
|
||||||
|
{
|
||||||
|
list.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2025 - 2025 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.event2.shared;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
public class QNameMatcher
|
||||||
|
{
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(QNameMatcher.class);
|
||||||
|
private static final String WILDCARD = "*";
|
||||||
|
|
||||||
|
private final Set<QName> matchingTypes;
|
||||||
|
private final Set<String> matchingNamespaceURIs;
|
||||||
|
|
||||||
|
public QNameMatcher(Set<QName> qNamesToMatch)
|
||||||
|
{
|
||||||
|
matchingTypes = new HashSet<>();
|
||||||
|
matchingNamespaceURIs = new HashSet<>();
|
||||||
|
|
||||||
|
qNamesToMatch.forEach(qName -> {
|
||||||
|
if (WILDCARD.equals(qName.getLocalName()))
|
||||||
|
{
|
||||||
|
matchingNamespaceURIs.add(qName.getNamespaceURI());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
matchingTypes.add(qName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled())
|
||||||
|
{
|
||||||
|
LOGGER.debug("Matching namespace URIs:" + matchingNamespaceURIs);
|
||||||
|
LOGGER.debug("Matching types:" + matchingTypes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMatching(QName qName)
|
||||||
|
{
|
||||||
|
if (qName != null)
|
||||||
|
{
|
||||||
|
return matchingTypes.contains(qName) || matchingNamespaceURIs.contains(qName.getNamespaceURI());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2025 - 2025 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.event2.shared;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceException;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
public class TypeDefExpander
|
||||||
|
{
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(TypeDefExpander.class);
|
||||||
|
private static final String MARKER_INCLUDE_SUBTYPES = "include_subtypes";
|
||||||
|
|
||||||
|
private final DictionaryService dictionaryService;
|
||||||
|
private final NamespaceService namespaceService;
|
||||||
|
|
||||||
|
public TypeDefExpander(DictionaryService dictionaryService, NamespaceService namespaceService)
|
||||||
|
{
|
||||||
|
this.dictionaryService = dictionaryService;
|
||||||
|
this.namespaceService = namespaceService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<QName> expand(Collection<String> types)
|
||||||
|
{
|
||||||
|
Set<QName> result = new HashSet<>();
|
||||||
|
types.forEach(type -> result.addAll(expand(type)));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<QName> expand(String typeDef)
|
||||||
|
{
|
||||||
|
if ((typeDef == null) || typeDef.isEmpty() || typeDef.equals("none") || typeDef.contains("${"))
|
||||||
|
{
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeDef.indexOf(' ') < 0)
|
||||||
|
{
|
||||||
|
return Collections.singleton(getQName(typeDef));
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] typeDefParts = typeDef.split(" ");
|
||||||
|
if (typeDefParts.length != 2)
|
||||||
|
{
|
||||||
|
LOGGER.warn("Ignoring invalid type pattern: " + typeDef);
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeDefParts[1].equals(MARKER_INCLUDE_SUBTYPES))
|
||||||
|
{
|
||||||
|
if (typeDefParts[0].indexOf('*') >= 0)
|
||||||
|
{
|
||||||
|
LOGGER.warn("Ignoring invalid type pattern: " + typeDef);
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
QName baseType;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
baseType = getQName(typeDefParts[0]);
|
||||||
|
}
|
||||||
|
catch (NamespaceException ne)
|
||||||
|
{
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return dictionaryService.getSubTypes(baseType, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.warn("Ignoring invalid type pattern: " + typeDef);
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private QName getQName(String type)
|
||||||
|
{
|
||||||
|
return QName.createQName(type, namespaceService);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,112 +0,0 @@
|
|||||||
/*
|
|
||||||
* #%L
|
|
||||||
* Alfresco Repository
|
|
||||||
* %%
|
|
||||||
* Copyright (C) 2024 Alfresco Software Limited
|
|
||||||
* %%
|
|
||||||
* This file is part of the Alfresco software.
|
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
|
||||||
* the paid license agreement will prevail. Otherwise, the software is
|
|
||||||
* provided under the following open source license terms:
|
|
||||||
*
|
|
||||||
* Alfresco is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Alfresco is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
* #L%
|
|
||||||
*/
|
|
||||||
package org.alfresco.repo.rendition2.script;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.alfresco.repo.jscript.BaseScopableProcessorExtension;
|
|
||||||
import org.alfresco.repo.jscript.ScriptNode;
|
|
||||||
import org.alfresco.repo.rendition2.RenditionService2;
|
|
||||||
import org.alfresco.service.ServiceRegistry;
|
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@code ScriptRenditionService2} class provides a scripting interface for working with Rendition Service 2.
|
|
||||||
* It allows rendering source nodes with specified rendition definitions and retrieving renditions associated with a node.
|
|
||||||
*/
|
|
||||||
@SuppressWarnings({"PMD.ProperLogger", "PMD.FieldNamingConventions"})
|
|
||||||
public class ScriptRenditionService2 extends BaseScopableProcessorExtension
|
|
||||||
{
|
|
||||||
private static final Log logger = LogFactory.getLog(ScriptRenditionService2.class);
|
|
||||||
|
|
||||||
private ServiceRegistry serviceRegistry;
|
|
||||||
private RenditionService2 renditionService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the {@link ServiceRegistry} to be used by this script object.
|
|
||||||
*
|
|
||||||
* @param serviceRegistry The ServiceRegistry to be set.
|
|
||||||
*/
|
|
||||||
public void setServiceRegistry(ServiceRegistry serviceRegistry)
|
|
||||||
{
|
|
||||||
this.serviceRegistry = serviceRegistry;
|
|
||||||
this.renditionService = serviceRegistry.getRenditionService2();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Renders the specified source node with the given rendition definition.
|
|
||||||
* Since renditionService2 is designed to asynchronous, no result is returned.
|
|
||||||
*
|
|
||||||
* @param sourceNode The source node to be rendered.
|
|
||||||
* @param renditionName The name of the rendition definition, like "pdf".
|
|
||||||
*/
|
|
||||||
public void render(ScriptNode sourceNode, String renditionName)
|
|
||||||
{
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
{
|
|
||||||
String msg = "Rendering source node '" +
|
|
||||||
sourceNode +
|
|
||||||
"' with renditionDef '" + renditionName +
|
|
||||||
"'";
|
|
||||||
logger.debug(msg);
|
|
||||||
}
|
|
||||||
this.renditionService.render(sourceNode.getNodeRef(), renditionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves an array of {@link ScriptNode} objects representing renditions associated with the specified node.
|
|
||||||
*
|
|
||||||
* @param node The node for which to retrieve renditions.
|
|
||||||
* @return An array of {@code ScriptNode} objects representing renditions.
|
|
||||||
*/
|
|
||||||
public ScriptNode[] getRenditions(ScriptNode node)
|
|
||||||
{
|
|
||||||
List<ChildAssociationRef> renditions = this.renditionService.getRenditions(node.getNodeRef());
|
|
||||||
|
|
||||||
ScriptNode[] renditionObjs = new ScriptNode[renditions.size()];
|
|
||||||
for (int i = 0; i < renditions.size(); i++)
|
|
||||||
{
|
|
||||||
renditionObjs[i] = new ScriptNode(renditions.get(i).getChildRef(), serviceRegistry);
|
|
||||||
}
|
|
||||||
|
|
||||||
return renditionObjs;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a {@link ScriptNode} object representing the rendition with the specified name associated with the given node.
|
|
||||||
*
|
|
||||||
* @param node The node for which to retrieve the rendition.
|
|
||||||
* @param renditionName The name of the rendition.
|
|
||||||
* @return A {@code ScriptNode} object representing the specified rendition, or {@code null} if not found.
|
|
||||||
*/
|
|
||||||
public ScriptNode getRenditionByName(ScriptNode node, String renditionName)
|
|
||||||
{
|
|
||||||
ChildAssociationRef result = this.renditionService.getRenditionByName(node.getNodeRef(), renditionName);
|
|
||||||
return result == null ? null : new ScriptNode(result.getChildRef(), serviceRegistry);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -3,23 +3,30 @@
|
|||||||
|
|
||||||
<beans>
|
<beans>
|
||||||
|
|
||||||
|
<bean id="event2TypeDefExpander" class="org.alfresco.repo.event2.shared.TypeDefExpander">
|
||||||
|
<constructor-arg ref="dictionaryService"/>
|
||||||
|
<constructor-arg ref="namespaceService"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<!-- Event2 Filters -->
|
<!-- Event2 Filters -->
|
||||||
<bean id="event2FilterRegistry" class="org.alfresco.repo.event2.filter.EventFilterRegistry"/>
|
<bean id="event2FilterRegistry" class="org.alfresco.repo.event2.filter.EventFilterRegistry"/>
|
||||||
|
|
||||||
<bean id="abstractNodeEventFilter" class="org.alfresco.repo.event2.filter.AbstractNodeEventFilter" abstract="true" init-method="init">
|
<bean id="abstractNodeEventFilter" class="org.alfresco.repo.event2.filter.AbstractNodeEventFilter" abstract="true" init-method="init">
|
||||||
<property name="dictionaryService" ref="dictionaryService"/>
|
<property name="typeDefExpander" ref="event2TypeDefExpander"/>
|
||||||
<property name="namespaceService" ref="namespaceService"/>
|
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="event2NodeTypeFilter" class="org.alfresco.repo.event2.filter.NodeTypeFilter" parent="abstractNodeEventFilter">
|
<bean id="event2NodeTypeFilter" class="org.alfresco.repo.event2.filter.NodeTypeFilter" parent="abstractNodeEventFilter">
|
||||||
<constructor-arg value="${repo.event2.filter.nodeTypes}"/>
|
<constructor-arg value="${repo.event2.filter.nodeTypes}"/>
|
||||||
|
<constructor-arg ref="dictionaryService"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="event2NodeAspectFilter" class="org.alfresco.repo.event2.filter.NodeAspectFilter" parent="abstractNodeEventFilter">
|
<bean id="event2NodeAspectFilter" class="org.alfresco.repo.event2.filter.NodeAspectFilter" parent="abstractNodeEventFilter">
|
||||||
<constructor-arg value="${repo.event2.filter.nodeAspects}"/>
|
<constructor-arg value="${repo.event2.filter.nodeAspects}"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="event2NodePropertyFilter" class="org.alfresco.repo.event2.filter.NodePropertyFilter" parent="abstractNodeEventFilter"/>
|
<bean id="event2NodePropertyFilter" class="org.alfresco.repo.event2.filter.NodePropertyFilter" parent="abstractNodeEventFilter">
|
||||||
|
<constructor-arg value="${repo.event2.filter.nodeProperties}"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="event2UserFilter" class="org.alfresco.repo.event2.filter.EventUserFilter">
|
<bean id="event2UserFilter" class="org.alfresco.repo.event2.filter.EventUserFilter">
|
||||||
<constructor-arg value="${repo.event2.filter.users}"/>
|
<constructor-arg value="${repo.event2.filter.users}"/>
|
||||||
@@ -31,6 +38,16 @@
|
|||||||
</bean>
|
</bean>
|
||||||
<!-- End of Event2 Filters -->
|
<!-- End of Event2 Filters -->
|
||||||
|
|
||||||
|
<bean id="event2PropertyMapperFactory" class="org.alfresco.repo.event2.mapper.PropertyMapperFactory">
|
||||||
|
<constructor-arg ref="event2TypeDefExpander"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="event2PropertyMapper" factory-bean="event2PropertyMapperFactory" factory-method="createPropertyMapper">
|
||||||
|
<constructor-arg value="${repo.event2.mapper.enabled}"/>
|
||||||
|
<constructor-arg value="${repo.event2.mapper.overrideDefaultProperties}"/>
|
||||||
|
<constructor-arg value="${repo.event2.mapper.overrideReplacementText}"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="baseEventGeneratorV2" abstract="true">
|
<bean id="baseEventGeneratorV2" abstract="true">
|
||||||
<property name="policyComponent" ref="policyComponent"/>
|
<property name="policyComponent" ref="policyComponent"/>
|
||||||
<property name="nodeService" ref="nodeService"/>
|
<property name="nodeService" ref="nodeService"/>
|
||||||
@@ -55,6 +72,7 @@
|
|||||||
<property name="eventFilterRegistry" ref="event2FilterRegistry"/>
|
<property name="eventFilterRegistry" ref="event2FilterRegistry"/>
|
||||||
<property name="namespaceService" ref="namespaceService"/>
|
<property name="namespaceService" ref="namespaceService"/>
|
||||||
<property name="permissionService" ref="permissionService"/>
|
<property name="permissionService" ref="permissionService"/>
|
||||||
|
<property name="propertyMapper" ref="event2PropertyMapper"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="nodeResourceHelper" class="org.alfresco.repo.event2.NodeResourceHelper" parent="baseNodeResourceHelper"/>
|
<bean id="nodeResourceHelper" class="org.alfresco.repo.event2.NodeResourceHelper" parent="baseNodeResourceHelper"/>
|
||||||
|
@@ -176,11 +176,4 @@
|
|||||||
|
|
||||||
<!-- The definitions are read from json files (possibly added to a volume via k8 ConfigMaps) -->
|
<!-- The definitions are read from json files (possibly added to a volume via k8 ConfigMaps) -->
|
||||||
|
|
||||||
<!-- JavaScript API support -->
|
</beans>
|
||||||
<bean id="renditionService2Script"
|
|
||||||
class="org.alfresco.repo.rendition2.script.ScriptRenditionService2"
|
|
||||||
parent="baseJavaScriptExtension">
|
|
||||||
<property name="extensionName" value="renditionService2" />
|
|
||||||
<property name="serviceRegistry" ref="ServiceRegistry" />
|
|
||||||
</bean>
|
|
||||||
</beans>
|
|
@@ -3,7 +3,7 @@
|
|||||||
repository.name=Main Repository
|
repository.name=Main Repository
|
||||||
|
|
||||||
# Schema number
|
# Schema number
|
||||||
version.schema=18300
|
version.schema=18200
|
||||||
|
|
||||||
# Directory configuration
|
# Directory configuration
|
||||||
|
|
||||||
@@ -1227,6 +1227,10 @@ repo.event2.filter.childAssocTypes=rn:rendition
|
|||||||
# Comma separated list of users which should be excluded
|
# Comma separated list of users which should be excluded
|
||||||
# Note: username's case-sensitivity depends on the {user.name.caseSensitive} setting
|
# Note: username's case-sensitivity depends on the {user.name.caseSensitive} setting
|
||||||
repo.event2.filter.users=
|
repo.event2.filter.users=
|
||||||
|
repo.event2.filter.nodeProperties=
|
||||||
|
repo.event2.mapper.enabled=true
|
||||||
|
repo.event2.mapper.overrideDefaultProperties=
|
||||||
|
repo.event2.mapper.overrideReplacementText=
|
||||||
# Topic name
|
# Topic name
|
||||||
repo.event2.topic.endpoint=amqp:topic:alfresco.repo.event2
|
repo.event2.topic.endpoint=amqp:topic:alfresco.repo.event2
|
||||||
# Thread pool for async enqueue of repo events
|
# Thread pool for async enqueue of repo events
|
||||||
|
@@ -21,391 +21,430 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
package org.alfresco.repo.cache.lookup;
|
package org.alfresco.repo.cache.lookup;
|
||||||
|
|
||||||
import java.sql.Savepoint;
|
import static org.junit.Assert.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeMap;
|
import java.sql.Savepoint;
|
||||||
|
import java.util.Map;
|
||||||
import junit.framework.AssertionFailedError;
|
import java.util.TreeMap;
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
import org.junit.Before;
|
||||||
import org.alfresco.repo.cache.MemoryCache;
|
import org.junit.Test;
|
||||||
import org.alfresco.repo.cache.SimpleCache;
|
import org.mockito.Mockito;
|
||||||
import org.alfresco.repo.cache.lookup.EntityLookupCache.EntityLookupCallbackDAO;
|
import org.springframework.dao.DuplicateKeyException;
|
||||||
import org.alfresco.repo.domain.control.ControlDAO;
|
|
||||||
import org.alfresco.util.EqualsHelper;
|
import org.alfresco.repo.cache.MemoryCache;
|
||||||
import org.alfresco.util.Pair;
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
import org.mockito.Mockito;
|
import org.alfresco.repo.cache.lookup.EntityLookupCache.EntityLookupCallbackDAO;
|
||||||
import org.springframework.dao.DuplicateKeyException;
|
import org.alfresco.repo.domain.control.ControlDAO;
|
||||||
|
import org.alfresco.util.EqualsHelper;
|
||||||
/**
|
import org.alfresco.util.Pair;
|
||||||
* A cache for two-way lookups of database entities. These are characterized by having a unique
|
|
||||||
* key (perhaps a database ID) and a separate unique key that identifies the object.
|
/**
|
||||||
* <p>
|
* A cache for two-way lookups of database entities. These are characterized by having a unique key (perhaps a database ID) and a separate unique key that identifies the object.
|
||||||
* The keys must have good <code>equals</code> and </code>hashCode</code> implementations and
|
* <p>
|
||||||
* must respect the case-sensitivity of the use-case.
|
* The keys must have good <code>equals</code> and </code>hashCode</code> implementations and must respect the case-sensitivity of the use-case.
|
||||||
*
|
*
|
||||||
* @author Derek Hulley
|
* @author Derek Hulley
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
public class EntityLookupCacheTest extends TestCase implements EntityLookupCallbackDAO<Long, Object, String>
|
public class EntityLookupCacheTest implements EntityLookupCallbackDAO<Long, Object, String>
|
||||||
{
|
{
|
||||||
SimpleCache<Long, Object> cache;
|
SimpleCache<Long, Object> cache;
|
||||||
private EntityLookupCache<Long, Object, String> entityLookupCacheA;
|
private EntityLookupCache<Long, Object, String> entityLookupCacheA;
|
||||||
private EntityLookupCache<Long, Object, String> entityLookupCacheB;
|
private EntityLookupCache<Long, Object, String> entityLookupCacheB;
|
||||||
private TreeMap<Long, String> database;
|
private TreeMap<Long, String> database;
|
||||||
private ControlDAO controlDAO;
|
private ControlDAO controlDAO;
|
||||||
|
|
||||||
@Override
|
@Before
|
||||||
protected void setUp() throws Exception
|
public void setUp() throws Exception
|
||||||
{
|
{
|
||||||
cache = new MemoryCache<Long, Object>();
|
cache = new MemoryCache<Long, Object>();
|
||||||
entityLookupCacheA = new EntityLookupCache<Long, Object, String>(cache, "A", this);
|
entityLookupCacheA = new EntityLookupCache<Long, Object, String>(cache, "A", this);
|
||||||
entityLookupCacheB = new EntityLookupCache<Long, Object, String>(cache, "B", this);
|
entityLookupCacheB = new EntityLookupCache<Long, Object, String>(cache, "B", this);
|
||||||
database = new TreeMap<Long, String>();
|
database = new TreeMap<Long, String>();
|
||||||
|
|
||||||
controlDAO = Mockito.mock(ControlDAO.class);
|
controlDAO = Mockito.mock(ControlDAO.class);
|
||||||
Mockito.when(controlDAO.createSavepoint(Mockito.anyString())).thenReturn(Mockito.mock(Savepoint.class));
|
Mockito.when(controlDAO.createSavepoint(Mockito.anyString())).thenReturn(Mockito.mock(Savepoint.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testLookupsUsingIncorrectValue() throws Exception
|
@Test
|
||||||
{
|
public void testLookupsUsingIncorrectValue() throws Exception
|
||||||
try
|
{
|
||||||
{
|
try
|
||||||
// Keep the "database" empty
|
{
|
||||||
entityLookupCacheA.getByValue(this);
|
// Keep the "database" empty
|
||||||
}
|
entityLookupCacheA.getByValue(this);
|
||||||
catch (AssertionFailedError e)
|
}
|
||||||
{
|
catch (AssertionError e)
|
||||||
// Expected
|
{
|
||||||
}
|
// Expected
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public void testLookupAgainstEmpty() throws Exception
|
|
||||||
{
|
@Test
|
||||||
TestValue value = new TestValue("AAA");
|
public void testLookupAgainstEmpty() throws Exception
|
||||||
Pair<Long, Object> entityPair = entityLookupCacheA.getByValue(value);
|
{
|
||||||
assertNull(entityPair);
|
TestValue value = new TestValue("AAA");
|
||||||
assertTrue(database.isEmpty());
|
Pair<Long, Object> entityPair = entityLookupCacheA.getByValue(value);
|
||||||
|
assertNull(entityPair);
|
||||||
// Now do lookup or create
|
assertTrue(database.isEmpty());
|
||||||
entityPair = entityLookupCacheA.getOrCreateByValue(value);
|
|
||||||
assertNotNull("Expected a value to be found", entityPair);
|
// Now do lookup or create
|
||||||
Long entityId = entityPair.getFirst();
|
entityPair = entityLookupCacheA.getOrCreateByValue(value);
|
||||||
assertTrue("Database ID should have been created", database.containsKey(entityId));
|
assertNotNull("Expected a value to be found", entityPair);
|
||||||
assertEquals("Database value incorrect", value.val, database.get(entityId));
|
Long entityId = entityPair.getFirst();
|
||||||
|
assertTrue("Database ID should have been created", database.containsKey(entityId));
|
||||||
// Do lookup or create again
|
assertEquals("Database value incorrect", value.val, database.get(entityId));
|
||||||
entityPair = entityLookupCacheA.getOrCreateByValue(value);
|
|
||||||
assertNotNull("Expected a value to be found", entityPair);
|
// Do lookup or create again
|
||||||
assertEquals("Expected same entity ID", entityId, entityPair.getFirst());
|
entityPair = entityLookupCacheA.getOrCreateByValue(value);
|
||||||
|
assertNotNull("Expected a value to be found", entityPair);
|
||||||
// Look it up using the value
|
assertEquals("Expected same entity ID", entityId, entityPair.getFirst());
|
||||||
entityPair = entityLookupCacheA.getByValue(value);
|
|
||||||
assertNotNull("Lookup after create should work", entityPair);
|
// Look it up using the value
|
||||||
|
entityPair = entityLookupCacheA.getByValue(value);
|
||||||
// Look it up using the ID
|
assertNotNull("Lookup after create should work", entityPair);
|
||||||
entityPair = entityLookupCacheA.getByKey(entityId);
|
|
||||||
assertNotNull("Lookup by key should work after create", entityPair);
|
// Look it up using the ID
|
||||||
assertTrue("Looked-up type incorrect", entityPair.getSecond() instanceof TestValue);
|
entityPair = entityLookupCacheA.getByKey(entityId);
|
||||||
assertEquals("Looked-up type value incorrect", value, entityPair.getSecond());
|
assertNotNull("Lookup by key should work after create", entityPair);
|
||||||
}
|
assertTrue("Looked-up type incorrect", entityPair.getSecond() instanceof TestValue);
|
||||||
|
assertEquals("Looked-up type value incorrect", value, entityPair.getSecond());
|
||||||
public void testLookupAgainstExisting() throws Exception
|
}
|
||||||
{
|
|
||||||
// Put some values in the "database"
|
@Test
|
||||||
createValue(new TestValue("AAA"));
|
public void testLookupAgainstExisting() throws Exception
|
||||||
createValue(new TestValue("BBB"));
|
{
|
||||||
createValue(new TestValue("CCC"));
|
// Put some values in the "database"
|
||||||
|
createValue(new TestValue("AAA"));
|
||||||
// Look up by value
|
createValue(new TestValue("BBB"));
|
||||||
Pair<Long, Object> entityPair = entityLookupCacheA.getByValue(new TestValue("AAA"));
|
createValue(new TestValue("CCC"));
|
||||||
assertNotNull("Expected value to be found", entityPair);
|
|
||||||
assertEquals("ID is incorrect", new Long(1), entityPair.getFirst());
|
// Look up by value
|
||||||
|
Pair<Long, Object> entityPair = entityLookupCacheA.getByValue(new TestValue("AAA"));
|
||||||
// Look up by ID
|
assertNotNull("Expected value to be found", entityPair);
|
||||||
entityPair = entityLookupCacheA.getByKey(new Long(2));
|
assertEquals("ID is incorrect", new Long(1), entityPair.getFirst());
|
||||||
assertNotNull("Expected value to be found", entityPair);
|
|
||||||
|
// Look up by ID
|
||||||
// Do lookup or create
|
entityPair = entityLookupCacheA.getByKey(new Long(2));
|
||||||
entityPair = entityLookupCacheA.getByValue(new TestValue("CCC"));
|
assertNotNull("Expected value to be found", entityPair);
|
||||||
assertNotNull("Expected value to be found", entityPair);
|
|
||||||
assertEquals("ID is incorrect", new Long(3), entityPair.getFirst());
|
// Do lookup or create
|
||||||
}
|
entityPair = entityLookupCacheA.getByValue(new TestValue("CCC"));
|
||||||
|
assertNotNull("Expected value to be found", entityPair);
|
||||||
public void testRegions() throws Exception
|
assertEquals("ID is incorrect", new Long(3), entityPair.getFirst());
|
||||||
{
|
}
|
||||||
TestValue valueAAA = new TestValue("AAA");
|
|
||||||
Pair<Long, Object> entityPairAAA = entityLookupCacheA.getOrCreateByValue(valueAAA);
|
@Test
|
||||||
assertNotNull(entityPairAAA);
|
public void testRegions() throws Exception
|
||||||
assertEquals("AAA", database.get(entityPairAAA.getFirst()));
|
{
|
||||||
assertEquals(2, cache.getKeys().size());
|
TestValue valueAAA = new TestValue("AAA");
|
||||||
|
Pair<Long, Object> entityPairAAA = entityLookupCacheA.getOrCreateByValue(valueAAA);
|
||||||
TestValue valueBBB = new TestValue("BBB");
|
assertNotNull(entityPairAAA);
|
||||||
Pair<Long, Object> entityPairBBB = entityLookupCacheB.getOrCreateByValue(valueBBB);
|
assertEquals("AAA", database.get(entityPairAAA.getFirst()));
|
||||||
assertNotNull(entityPairBBB);
|
assertEquals(2, cache.getKeys().size());
|
||||||
assertEquals("BBB", database.get(entityPairBBB.getFirst()));
|
|
||||||
assertEquals(4, cache.getKeys().size());
|
TestValue valueBBB = new TestValue("BBB");
|
||||||
|
Pair<Long, Object> entityPairBBB = entityLookupCacheB.getOrCreateByValue(valueBBB);
|
||||||
// Now cross-check against the caches and make sure that the cache
|
assertNotNull(entityPairBBB);
|
||||||
entityPairBBB = entityLookupCacheA.getByValue(valueBBB);
|
assertEquals("BBB", database.get(entityPairBBB.getFirst()));
|
||||||
assertEquals(6, cache.getKeys().size());
|
assertEquals(4, cache.getKeys().size());
|
||||||
entityPairBBB = entityLookupCacheB.getByValue(valueAAA);
|
|
||||||
assertEquals(8, cache.getKeys().size());
|
// Now cross-check against the caches and make sure that the cache
|
||||||
}
|
entityPairBBB = entityLookupCacheA.getByValue(valueBBB);
|
||||||
|
assertEquals(6, cache.getKeys().size());
|
||||||
public void testNullLookups() throws Exception
|
entityPairBBB = entityLookupCacheB.getByValue(valueAAA);
|
||||||
{
|
assertEquals(8, cache.getKeys().size());
|
||||||
TestValue valueNull = null;
|
}
|
||||||
Pair<Long, Object> entityPairNull = entityLookupCacheA.getOrCreateByValue(valueNull);
|
|
||||||
assertNotNull(entityPairNull);
|
@Test
|
||||||
assertTrue(database.containsKey(entityPairNull.getFirst()));
|
public void testNullLookups() throws Exception
|
||||||
assertNull(database.get(entityPairNull.getFirst()));
|
{
|
||||||
assertEquals(2, cache.getKeys().size());
|
TestValue valueNull = null;
|
||||||
|
Pair<Long, Object> entityPairNull = entityLookupCacheA.getOrCreateByValue(valueNull);
|
||||||
// Look it up again
|
assertNotNull(entityPairNull);
|
||||||
Pair<Long, Object> entityPairCheck = entityLookupCacheA.getOrCreateByValue(valueNull);
|
assertTrue(database.containsKey(entityPairNull.getFirst()));
|
||||||
assertNotNull(entityPairNull);
|
assertNull(database.get(entityPairNull.getFirst()));
|
||||||
assertTrue(database.containsKey(entityPairNull.getFirst()));
|
assertEquals(2, cache.getKeys().size());
|
||||||
assertNull(database.get(entityPairNull.getFirst()));
|
|
||||||
assertEquals(entityPairNull, entityPairCheck);
|
// Look it up again
|
||||||
}
|
Pair<Long, Object> entityPairCheck = entityLookupCacheA.getOrCreateByValue(valueNull);
|
||||||
|
assertNotNull(entityPairNull);
|
||||||
public void testGetOrCreate() throws Exception
|
assertTrue(database.containsKey(entityPairNull.getFirst()));
|
||||||
{
|
assertNull(database.get(entityPairNull.getFirst()));
|
||||||
TestValue valueOne = new TestValue(getName() + "-ONE");
|
assertEquals(entityPairNull, entityPairCheck);
|
||||||
Pair<Long, Object> entityPairOne = entityLookupCacheA.getOrCreateByValue(valueOne);
|
}
|
||||||
assertNotNull(entityPairOne);
|
|
||||||
Long id = entityPairOne.getFirst();
|
@Test
|
||||||
assertEquals(valueOne.val, database.get(id));
|
public void testGetOrCreate() throws Exception
|
||||||
assertEquals(2, cache.getKeys().size());
|
{
|
||||||
|
TestValue valueOne = new TestValue(getClass().getName() + "-ONE");
|
||||||
Pair<Long, Object> entityPairOneCheck = entityLookupCacheA.getOrCreateByValue(valueOne);
|
Pair<Long, Object> entityPairOne = entityLookupCacheA.getOrCreateByValue(valueOne);
|
||||||
assertNotNull(entityPairOneCheck);
|
assertNotNull(entityPairOne);
|
||||||
assertEquals(id, entityPairOneCheck.getFirst());
|
Long id = entityPairOne.getFirst();
|
||||||
}
|
assertEquals(valueOne.val, database.get(id));
|
||||||
|
assertEquals(2, cache.getKeys().size());
|
||||||
public void testCreateOrGet() throws Exception
|
|
||||||
{
|
Pair<Long, Object> entityPairOneCheck = entityLookupCacheA.getOrCreateByValue(valueOne);
|
||||||
TestValue valueOne = new TestValue(getName() + "-ONE");
|
assertNotNull(entityPairOneCheck);
|
||||||
Pair<Long, Object> entityPairOne = entityLookupCacheA.createOrGetByValue(valueOne, controlDAO);
|
assertEquals(id, entityPairOneCheck.getFirst());
|
||||||
assertNotNull(entityPairOne);
|
}
|
||||||
Long id = entityPairOne.getFirst();
|
|
||||||
assertEquals(valueOne.val, database.get(id));
|
@Test
|
||||||
assertEquals(1, cache.getKeys().size());
|
public void testCreateOrGet() throws Exception
|
||||||
|
{
|
||||||
Pair<Long, Object> entityPairOneCheck = entityLookupCacheA.createOrGetByValue(valueOne, controlDAO);
|
TestValue valueOne = new TestValue(getClass().getName() + "-ONE");
|
||||||
assertNotNull(entityPairOneCheck);
|
Pair<Long, Object> entityPairOne = entityLookupCacheA.createOrGetByValue(valueOne, controlDAO);
|
||||||
assertEquals(id, entityPairOneCheck.getFirst());
|
assertNotNull(entityPairOne);
|
||||||
}
|
Long id = entityPairOne.getFirst();
|
||||||
|
assertEquals(valueOne.val, database.get(id));
|
||||||
public void testUpdate() throws Exception
|
// We cache both by value and by key, so we should have 2 entries
|
||||||
{
|
assertEquals(2, cache.getKeys().size());
|
||||||
TestValue valueOne = new TestValue(getName() + "-ONE");
|
|
||||||
TestValue valueTwo = new TestValue(getName() + "-TWO");
|
Pair<Long, Object> entityPairOneCheck = entityLookupCacheA.createOrGetByValue(valueOne, controlDAO);
|
||||||
Pair<Long, Object> entityPairOne = entityLookupCacheA.getOrCreateByValue(valueOne);
|
assertNotNull(entityPairOneCheck);
|
||||||
assertNotNull(entityPairOne);
|
assertEquals(id, entityPairOneCheck.getFirst());
|
||||||
Long id = entityPairOne.getFirst();
|
}
|
||||||
assertEquals(valueOne.val, database.get(id));
|
|
||||||
assertEquals(2, cache.getKeys().size());
|
@Test
|
||||||
|
public void testUpdate() throws Exception
|
||||||
// Update
|
{
|
||||||
int updateCount = entityLookupCacheA.updateValue(id, valueTwo);
|
TestValue valueOne = new TestValue(getClass().getName() + "-ONE");
|
||||||
assertEquals("Update count was incorrect.", 1, updateCount);
|
TestValue valueTwo = new TestValue(getClass().getName() + "-TWO");
|
||||||
assertEquals(valueTwo.val, database.get(id));
|
Pair<Long, Object> entityPairOne = entityLookupCacheA.getOrCreateByValue(valueOne);
|
||||||
assertEquals(2, cache.getKeys().size());
|
assertNotNull(entityPairOne);
|
||||||
}
|
Long id = entityPairOne.getFirst();
|
||||||
|
assertEquals(valueOne.val, database.get(id));
|
||||||
public void testDeleteByKey() throws Exception
|
assertEquals(2, cache.getKeys().size());
|
||||||
{
|
|
||||||
TestValue valueOne = new TestValue(getName() + "-ONE");
|
// Update
|
||||||
Pair<Long, Object> entityPairOne = entityLookupCacheA.getOrCreateByValue(valueOne);
|
int updateCount = entityLookupCacheA.updateValue(id, valueTwo);
|
||||||
assertNotNull(entityPairOne);
|
assertEquals("Update count was incorrect.", 1, updateCount);
|
||||||
Long id = entityPairOne.getFirst();
|
assertEquals(valueTwo.val, database.get(id));
|
||||||
assertEquals(valueOne.val, database.get(id));
|
assertEquals(2, cache.getKeys().size());
|
||||||
assertEquals(2, cache.getKeys().size());
|
}
|
||||||
|
|
||||||
// Delete
|
@Test
|
||||||
int deleteCount = entityLookupCacheA.deleteByKey(id);
|
public void testDeleteByKey() throws Exception
|
||||||
assertEquals("Delete count was incorrect.", 1, deleteCount);
|
{
|
||||||
assertNull(database.get(id));
|
TestValue valueOne = new TestValue(getClass().getName() + "-ONE");
|
||||||
assertEquals(0, cache.getKeys().size());
|
Pair<Long, Object> entityPairOne = entityLookupCacheA.getOrCreateByValue(valueOne);
|
||||||
}
|
assertNotNull(entityPairOne);
|
||||||
|
Long id = entityPairOne.getFirst();
|
||||||
public void testDeleteByValue() throws Exception
|
assertEquals(valueOne.val, database.get(id));
|
||||||
{
|
assertEquals(2, cache.getKeys().size());
|
||||||
TestValue valueOne = new TestValue(getName() + "-ONE");
|
|
||||||
Pair<Long, Object> entityPairOne = entityLookupCacheA.getOrCreateByValue(valueOne);
|
// Delete
|
||||||
assertNotNull(entityPairOne);
|
int deleteCount = entityLookupCacheA.deleteByKey(id);
|
||||||
Long id = entityPairOne.getFirst();
|
assertEquals("Delete count was incorrect.", 1, deleteCount);
|
||||||
assertEquals(valueOne.val, database.get(id));
|
assertNull(database.get(id));
|
||||||
assertEquals(2, cache.getKeys().size());
|
assertEquals(0, cache.getKeys().size());
|
||||||
|
}
|
||||||
// Delete
|
|
||||||
int deleteCount = entityLookupCacheA.deleteByValue(valueOne);
|
@Test
|
||||||
assertEquals("Delete count was incorrect.", 1, deleteCount);
|
public void testDeleteByValue() throws Exception
|
||||||
assertNull(database.get(id));
|
{
|
||||||
assertEquals(0, cache.getKeys().size());
|
TestValue valueOne = new TestValue(getClass().getName() + "-ONE");
|
||||||
}
|
Pair<Long, Object> entityPairOne = entityLookupCacheA.getOrCreateByValue(valueOne);
|
||||||
|
assertNotNull(entityPairOne);
|
||||||
public void testClear() throws Exception
|
Long id = entityPairOne.getFirst();
|
||||||
{
|
assertEquals(valueOne.val, database.get(id));
|
||||||
TestValue valueOne = new TestValue(getName() + "-ONE");
|
assertEquals(2, cache.getKeys().size());
|
||||||
Pair<Long, Object> entityPairOne = entityLookupCacheA.getOrCreateByValue(valueOne);
|
|
||||||
assertNotNull(entityPairOne);
|
// Delete
|
||||||
Long id = entityPairOne.getFirst();
|
int deleteCount = entityLookupCacheA.deleteByValue(valueOne);
|
||||||
assertEquals(valueOne.val, database.get(id));
|
assertEquals("Delete count was incorrect.", 1, deleteCount);
|
||||||
assertEquals(2, cache.getKeys().size());
|
assertNull(database.get(id));
|
||||||
|
assertEquals(0, cache.getKeys().size());
|
||||||
// Clear it
|
}
|
||||||
entityLookupCacheA.clear();
|
|
||||||
assertEquals(valueOne.val, database.get(id)); // Must still be in database
|
@Test
|
||||||
assertEquals(0, cache.getKeys().size()); // ... but cache must be empty
|
public void testClear() throws Exception
|
||||||
}
|
{
|
||||||
|
TestValue valueOne = new TestValue(getClass().getName() + "-ONE");
|
||||||
/**
|
Pair<Long, Object> entityPairOne = entityLookupCacheA.getOrCreateByValue(valueOne);
|
||||||
* Helper class to represent business object
|
assertNotNull(entityPairOne);
|
||||||
*/
|
Long id = entityPairOne.getFirst();
|
||||||
private static class TestValue
|
assertEquals(valueOne.val, database.get(id));
|
||||||
{
|
assertEquals(2, cache.getKeys().size());
|
||||||
private final String val;
|
|
||||||
private TestValue(String val)
|
// Clear it
|
||||||
{
|
entityLookupCacheA.clear();
|
||||||
this.val = val;
|
assertEquals(valueOne.val, database.get(id)); // Must still be in database
|
||||||
}
|
assertEquals(0, cache.getKeys().size()); // ... but cache must be empty
|
||||||
@Override
|
}
|
||||||
public boolean equals(Object obj)
|
|
||||||
{
|
@Test
|
||||||
if (obj == null || !(obj instanceof TestValue))
|
public void testGetCachedValue() throws Exception
|
||||||
{
|
{
|
||||||
return false;
|
// Create a new value
|
||||||
}
|
TestValue valueCached = new TestValue(getClass().getName() + "-CACHED");
|
||||||
return val.equals( ((TestValue)obj).val );
|
Pair<Long, Object> entityPairOne = entityLookupCacheA.createOrGetByValue(valueCached, controlDAO);
|
||||||
}
|
assertNotNull(entityPairOne);
|
||||||
@Override
|
Long id = entityPairOne.getFirst();
|
||||||
public int hashCode()
|
// We cache both by value and by key, so we should have 2 entries
|
||||||
{
|
assertEquals(2, cache.getKeys().size());
|
||||||
return val.hashCode();
|
|
||||||
}
|
// Check the cache for the previously created value
|
||||||
|
Pair<Long, Object> entityPairCacheCheck = entityLookupCacheA.getCachedEntityByValue(valueCached);
|
||||||
}
|
assertNotNull(entityPairCacheCheck);
|
||||||
|
assertEquals(id, entityPairCacheCheck.getFirst());
|
||||||
public String getValueKey(Object value)
|
|
||||||
{
|
// Clear the cache and attempt to retrieve it again
|
||||||
assertNotNull(value);
|
entityLookupCacheA.clear();
|
||||||
assertTrue(value instanceof TestValue);
|
entityPairCacheCheck = entityLookupCacheA.getCachedEntityByValue(valueCached);
|
||||||
String dbValue = ((TestValue)value).val;
|
|
||||||
return dbValue;
|
// Since we are only retrieving from cache, the value should not be found
|
||||||
}
|
assertNull(entityPairCacheCheck);
|
||||||
|
}
|
||||||
public Pair<Long, Object> findByKey(Long key)
|
|
||||||
{
|
/**
|
||||||
assertNotNull(key);
|
* Helper class to represent business object
|
||||||
|
*/
|
||||||
String dbValue = database.get(key);
|
private static class TestValue
|
||||||
if (dbValue == null)
|
{
|
||||||
{
|
private final String val;
|
||||||
return null;
|
|
||||||
}
|
private TestValue(String val)
|
||||||
// Make a value object
|
{
|
||||||
TestValue value = new TestValue(dbValue);
|
this.val = val;
|
||||||
return new Pair<Long, Object>(key, value);
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
public Pair<Long, Object> findByValue(Object value)
|
public boolean equals(Object obj)
|
||||||
{
|
{
|
||||||
assertTrue(value == null || value instanceof TestValue);
|
if (obj == null || !(obj instanceof TestValue))
|
||||||
String dbValue = (value == null) ? null : ((TestValue)value).val;
|
{
|
||||||
|
return false;
|
||||||
for (Map.Entry<Long, String> entry : database.entrySet())
|
}
|
||||||
{
|
return val.equals(((TestValue) obj).val);
|
||||||
if (EqualsHelper.nullSafeEquals(entry.getValue(), dbValue))
|
}
|
||||||
{
|
|
||||||
return new Pair<Long, Object>(entry.getKey(), entry.getValue());
|
@Override
|
||||||
}
|
public int hashCode()
|
||||||
}
|
{
|
||||||
return null;
|
return val.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
}
|
||||||
* Simulate creation of a new database entry
|
|
||||||
*/
|
public String getValueKey(Object value)
|
||||||
public Pair<Long, Object> createValue(Object value)
|
{
|
||||||
{
|
assertNotNull(value);
|
||||||
assertTrue(value == null || value instanceof TestValue);
|
assertTrue(value instanceof TestValue);
|
||||||
String dbValue = (value == null) ? null : ((TestValue)value).val;
|
String dbValue = ((TestValue) value).val;
|
||||||
|
return dbValue;
|
||||||
// Kick out any duplicate values
|
}
|
||||||
if (database.containsValue(dbValue))
|
|
||||||
{
|
public Pair<Long, Object> findByKey(Long key)
|
||||||
throw new DuplicateKeyException("Value is duplicated: " + value);
|
{
|
||||||
}
|
assertNotNull(key);
|
||||||
|
|
||||||
// Get the last key
|
String dbValue = database.get(key);
|
||||||
Long lastKey = database.isEmpty() ? null : database.lastKey();
|
if (dbValue == null)
|
||||||
Long newKey = null;
|
{
|
||||||
if (lastKey == null)
|
return null;
|
||||||
{
|
}
|
||||||
newKey = new Long(1);
|
// Make a value object
|
||||||
}
|
TestValue value = new TestValue(dbValue);
|
||||||
else
|
return new Pair<Long, Object>(key, value);
|
||||||
{
|
}
|
||||||
newKey = new Long(lastKey.longValue() + 1);
|
|
||||||
}
|
public Pair<Long, Object> findByValue(Object value)
|
||||||
database.put(newKey, dbValue);
|
{
|
||||||
return new Pair<Long, Object>(newKey, value);
|
assertTrue(value == null || value instanceof TestValue);
|
||||||
}
|
String dbValue = (value == null) ? null : ((TestValue) value).val;
|
||||||
|
|
||||||
public int updateValue(Long key, Object value)
|
for (Map.Entry<Long, String> entry : database.entrySet())
|
||||||
{
|
{
|
||||||
assertNotNull(key);
|
if (EqualsHelper.nullSafeEquals(entry.getValue(), dbValue))
|
||||||
assertTrue(value == null || value instanceof TestValue);
|
{
|
||||||
|
return new Pair<Long, Object>(entry.getKey(), entry.getValue());
|
||||||
// Find it
|
}
|
||||||
Pair<Long, Object> entityPair = findByKey(key);
|
}
|
||||||
if (entityPair == null)
|
return null;
|
||||||
{
|
}
|
||||||
return 0;
|
|
||||||
}
|
/**
|
||||||
else
|
* Simulate creation of a new database entry
|
||||||
{
|
*/
|
||||||
database.put(key, ((TestValue)value).val);
|
public Pair<Long, Object> createValue(Object value)
|
||||||
return 1;
|
{
|
||||||
}
|
assertTrue(value == null || value instanceof TestValue);
|
||||||
}
|
String dbValue = (value == null) ? null : ((TestValue) value).val;
|
||||||
|
|
||||||
public int deleteByKey(Long key)
|
// Kick out any duplicate values
|
||||||
{
|
if (database.containsValue(dbValue))
|
||||||
assertNotNull(key);
|
{
|
||||||
|
throw new DuplicateKeyException("Value is duplicated: " + value);
|
||||||
if (database.containsKey(key))
|
}
|
||||||
{
|
|
||||||
database.remove(key);
|
// Get the last key
|
||||||
return 1;
|
Long lastKey = database.isEmpty() ? null : database.lastKey();
|
||||||
}
|
Long newKey = null;
|
||||||
else
|
if (lastKey == null)
|
||||||
{
|
{
|
||||||
return 0;
|
newKey = new Long(1);
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
public int deleteByValue(Object value)
|
newKey = new Long(lastKey.longValue() + 1);
|
||||||
{
|
}
|
||||||
assertTrue(value == null || value instanceof TestValue);
|
database.put(newKey, dbValue);
|
||||||
|
return new Pair<Long, Object>(newKey, value);
|
||||||
// Find it
|
}
|
||||||
Pair<Long, Object> entityPair = findByValue(value);
|
|
||||||
if (entityPair == null)
|
public int updateValue(Long key, Object value)
|
||||||
{
|
{
|
||||||
return 0;
|
assertNotNull(key);
|
||||||
}
|
assertTrue(value == null || value instanceof TestValue);
|
||||||
else
|
|
||||||
{
|
// Find it
|
||||||
database.remove(entityPair.getFirst());
|
Pair<Long, Object> entityPair = findByKey(key);
|
||||||
return 1;
|
if (entityPair == null)
|
||||||
}
|
{
|
||||||
}
|
return 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
database.put(key, ((TestValue) value).val);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int deleteByKey(Long key)
|
||||||
|
{
|
||||||
|
assertNotNull(key);
|
||||||
|
|
||||||
|
if (database.containsKey(key))
|
||||||
|
{
|
||||||
|
database.remove(key);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int deleteByValue(Object value)
|
||||||
|
{
|
||||||
|
assertTrue(value == null || value instanceof TestValue);
|
||||||
|
|
||||||
|
// Find it
|
||||||
|
Pair<Long, Object> entityPair = findByValue(value);
|
||||||
|
if (entityPair == null)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
database.remove(entityPair.getFirst());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2025 - 2025 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.event2;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.alfresco.repo.event2.shared.CSVStringToListParser;
|
||||||
|
|
||||||
|
public class CSVStringToListParserUnitTest
|
||||||
|
{
|
||||||
|
@Test
|
||||||
|
public void shouldIgnoreEmptySpacesAndNoneValueAndTemplateStringsAndParseTheRest()
|
||||||
|
{
|
||||||
|
String userInputCSV = "a,,none,2,${test}, ,*";
|
||||||
|
|
||||||
|
List<String> result = CSVStringToListParser.parse(userInputCSV);
|
||||||
|
|
||||||
|
List<String> expected = List.of("a", "2", "*");
|
||||||
|
assertEquals(expected, result);
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -35,6 +35,10 @@ import static org.mockito.Mockito.when;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.model.ForumModel;
|
import org.alfresco.model.ForumModel;
|
||||||
import org.alfresco.model.RenditionModel;
|
import org.alfresco.model.RenditionModel;
|
||||||
@@ -43,14 +47,12 @@ import org.alfresco.repo.event2.filter.EventUserFilter;
|
|||||||
import org.alfresco.repo.event2.filter.NodeAspectFilter;
|
import org.alfresco.repo.event2.filter.NodeAspectFilter;
|
||||||
import org.alfresco.repo.event2.filter.NodePropertyFilter;
|
import org.alfresco.repo.event2.filter.NodePropertyFilter;
|
||||||
import org.alfresco.repo.event2.filter.NodeTypeFilter;
|
import org.alfresco.repo.event2.filter.NodeTypeFilter;
|
||||||
|
import org.alfresco.repo.event2.shared.TypeDefExpander;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
import org.alfresco.service.namespace.NamespaceException;
|
import org.alfresco.service.namespace.NamespaceException;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.util.OneToManyHashBiMap;
|
import org.alfresco.util.OneToManyHashBiMap;
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.mockito.stubbing.Answer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests event filters.
|
* Tests event filters.
|
||||||
@@ -78,32 +80,32 @@ public class EventFilterUnitTest
|
|||||||
|
|
||||||
namespaceService = new MockNamespaceServiceImpl();
|
namespaceService = new MockNamespaceServiceImpl();
|
||||||
namespaceService.registerNamespace(NamespaceService.SYSTEM_MODEL_PREFIX,
|
namespaceService.registerNamespace(NamespaceService.SYSTEM_MODEL_PREFIX,
|
||||||
NamespaceService.SYSTEM_MODEL_1_0_URI);
|
NamespaceService.SYSTEM_MODEL_1_0_URI);
|
||||||
namespaceService.registerNamespace(NamespaceService.CONTENT_MODEL_PREFIX,
|
namespaceService.registerNamespace(NamespaceService.CONTENT_MODEL_PREFIX,
|
||||||
NamespaceService.CONTENT_MODEL_1_0_URI);
|
NamespaceService.CONTENT_MODEL_1_0_URI);
|
||||||
namespaceService.registerNamespace(NamespaceService.FORUMS_MODEL_PREFIX,
|
namespaceService.registerNamespace(NamespaceService.FORUMS_MODEL_PREFIX,
|
||||||
NamespaceService.FORUMS_MODEL_1_0_URI);
|
NamespaceService.FORUMS_MODEL_1_0_URI);
|
||||||
namespaceService.registerNamespace(NamespaceService.RENDITION_MODEL_PREFIX,
|
namespaceService.registerNamespace(NamespaceService.RENDITION_MODEL_PREFIX,
|
||||||
NamespaceService.RENDITION_MODEL_1_0_URI);
|
NamespaceService.RENDITION_MODEL_1_0_URI);
|
||||||
|
namespaceService.registerNamespace(ContentModel.USER_MODEL_PREFIX,
|
||||||
|
ContentModel.USER_MODEL_URI);
|
||||||
|
|
||||||
propertyFilter = new NodePropertyFilter();
|
TypeDefExpander typeDefExpander = new TypeDefExpander(dictionaryService, namespaceService);
|
||||||
propertyFilter.setNamespaceService(namespaceService);
|
|
||||||
propertyFilter.setDictionaryService(dictionaryService);
|
propertyFilter = new NodePropertyFilter("usr:password");
|
||||||
|
propertyFilter.setTypeDefExpander(typeDefExpander);
|
||||||
propertyFilter.init();
|
propertyFilter.init();
|
||||||
|
|
||||||
typeFilter = new NodeTypeFilter("sys:*, fm:*, cm:thumbnail");
|
typeFilter = new NodeTypeFilter("sys:*, fm:*, cm:thumbnail", dictionaryService);
|
||||||
typeFilter.setNamespaceService(namespaceService);
|
typeFilter.setTypeDefExpander(typeDefExpander);
|
||||||
typeFilter.setDictionaryService(dictionaryService);
|
|
||||||
typeFilter.init();
|
typeFilter.init();
|
||||||
|
|
||||||
aspectFilter = new NodeAspectFilter("cm:workingcopy");
|
aspectFilter = new NodeAspectFilter("cm:workingcopy");
|
||||||
aspectFilter.setNamespaceService(namespaceService);
|
aspectFilter.setTypeDefExpander(typeDefExpander);
|
||||||
aspectFilter.setDictionaryService(dictionaryService);
|
|
||||||
aspectFilter.init();
|
aspectFilter.init();
|
||||||
|
|
||||||
childAssociationTypeFilter = new ChildAssociationTypeFilter("rn:rendition");
|
childAssociationTypeFilter = new ChildAssociationTypeFilter("rn:rendition");
|
||||||
childAssociationTypeFilter.setNamespaceService(namespaceService);
|
childAssociationTypeFilter.setTypeDefExpander(typeDefExpander);
|
||||||
childAssociationTypeFilter.setDictionaryService(dictionaryService);
|
|
||||||
childAssociationTypeFilter.init();
|
childAssociationTypeFilter.init();
|
||||||
|
|
||||||
caseInsensitive_userFilter = new EventUserFilter("System, john.doe, null", false);
|
caseInsensitive_userFilter = new EventUserFilter("System, john.doe, null", false);
|
||||||
@@ -114,10 +116,12 @@ public class EventFilterUnitTest
|
|||||||
public void nodePropertyFilter()
|
public void nodePropertyFilter()
|
||||||
{
|
{
|
||||||
assertTrue("System properties are excluded by default.",
|
assertTrue("System properties are excluded by default.",
|
||||||
propertyFilter.isExcluded(ContentModel.PROP_NODE_UUID));
|
propertyFilter.isExcluded(ContentModel.PROP_NODE_UUID));
|
||||||
|
|
||||||
assertTrue("System properties are excluded by default.",
|
assertTrue("System properties are excluded by default.",
|
||||||
propertyFilter.isExcluded(ContentModel.PROP_NODE_DBID));
|
propertyFilter.isExcluded(ContentModel.PROP_NODE_DBID));
|
||||||
|
|
||||||
|
assertTrue("User configured properties are excluded.", propertyFilter.isExcluded(ContentModel.PROP_PASSWORD));
|
||||||
|
|
||||||
assertFalse(propertyFilter.isExcluded(ContentModel.PROP_TITLE));
|
assertFalse(propertyFilter.isExcluded(ContentModel.PROP_TITLE));
|
||||||
}
|
}
|
||||||
@@ -126,16 +130,16 @@ public class EventFilterUnitTest
|
|||||||
public void nodeTypeFilter()
|
public void nodeTypeFilter()
|
||||||
{
|
{
|
||||||
assertTrue("Thumbnail node type should have been filtered.",
|
assertTrue("Thumbnail node type should have been filtered.",
|
||||||
typeFilter.isExcluded(ContentModel.TYPE_THUMBNAIL));
|
typeFilter.isExcluded(ContentModel.TYPE_THUMBNAIL));
|
||||||
|
|
||||||
assertTrue("System folder node types are excluded by default.",
|
assertTrue("System folder node types are excluded by default.",
|
||||||
typeFilter.isExcluded(ContentModel.TYPE_SYSTEM_FOLDER));
|
typeFilter.isExcluded(ContentModel.TYPE_SYSTEM_FOLDER));
|
||||||
|
|
||||||
assertTrue("System node type should have been filtered (sys:*).",
|
assertTrue("System node type should have been filtered (sys:*).",
|
||||||
typeFilter.isExcluded(QName.createQName("sys:testSomeSystemType", namespaceService)));
|
typeFilter.isExcluded(QName.createQName("sys:testSomeSystemType", namespaceService)));
|
||||||
|
|
||||||
assertTrue("Forum node type should have been filtered (fm:*).",
|
assertTrue("Forum node type should have been filtered (fm:*).",
|
||||||
typeFilter.isExcluded(ForumModel.TYPE_POST));
|
typeFilter.isExcluded(ForumModel.TYPE_POST));
|
||||||
|
|
||||||
assertFalse(typeFilter.isExcluded(ContentModel.TYPE_FOLDER));
|
assertFalse(typeFilter.isExcluded(ContentModel.TYPE_FOLDER));
|
||||||
}
|
}
|
||||||
@@ -144,7 +148,7 @@ public class EventFilterUnitTest
|
|||||||
public void nodeAspectFilter()
|
public void nodeAspectFilter()
|
||||||
{
|
{
|
||||||
assertTrue("Working copy aspect should have been filtered.",
|
assertTrue("Working copy aspect should have been filtered.",
|
||||||
aspectFilter.isExcluded(ContentModel.ASPECT_WORKING_COPY));
|
aspectFilter.isExcluded(ContentModel.ASPECT_WORKING_COPY));
|
||||||
|
|
||||||
assertFalse(aspectFilter.isExcluded(ContentModel.ASPECT_TITLED));
|
assertFalse(aspectFilter.isExcluded(ContentModel.ASPECT_TITLED));
|
||||||
}
|
}
|
||||||
@@ -157,41 +161,41 @@ public class EventFilterUnitTest
|
|||||||
|
|
||||||
assertFalse(childAssociationTypeFilter.isExcluded(ContentModel.ASSOC_CONTAINS));
|
assertFalse(childAssociationTypeFilter.isExcluded(ContentModel.ASSOC_CONTAINS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void userFilter_case_insensitive()
|
public void userFilter_case_insensitive()
|
||||||
{
|
{
|
||||||
assertTrue("System user should have been filtered.",
|
assertTrue("System user should have been filtered.",
|
||||||
caseInsensitive_userFilter.isExcluded("System"));
|
caseInsensitive_userFilter.isExcluded("System"));
|
||||||
|
|
||||||
assertTrue("System user should have been filtered (case-insensitive).",
|
assertTrue("System user should have been filtered (case-insensitive).",
|
||||||
caseInsensitive_userFilter.isExcluded("SYSTEM"));
|
caseInsensitive_userFilter.isExcluded("SYSTEM"));
|
||||||
|
|
||||||
assertTrue("'null' user should have been filtered.",
|
assertTrue("'null' user should have been filtered.",
|
||||||
caseInsensitive_userFilter.isExcluded("null"));
|
caseInsensitive_userFilter.isExcluded("null"));
|
||||||
|
|
||||||
assertTrue("john.doe user should have been filtered.",
|
assertTrue("john.doe user should have been filtered.",
|
||||||
caseInsensitive_userFilter.isExcluded("John.Doe"));
|
caseInsensitive_userFilter.isExcluded("John.Doe"));
|
||||||
|
|
||||||
assertFalse("'jane.doe' user should not have been filtered.",
|
assertFalse("'jane.doe' user should not have been filtered.",
|
||||||
caseInsensitive_userFilter.isExcluded("jane.doe"));
|
caseInsensitive_userFilter.isExcluded("jane.doe"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void userFilter_case_sensitive()
|
public void userFilter_case_sensitive()
|
||||||
{
|
{
|
||||||
assertFalse("'system' user should not have been filtered.",
|
assertFalse("'system' user should not have been filtered.",
|
||||||
caseSensitive_userFilter.isExcluded("system"));
|
caseSensitive_userFilter.isExcluded("system"));
|
||||||
assertTrue("'System' user should have been filtered.",
|
assertTrue("'System' user should have been filtered.",
|
||||||
caseSensitive_userFilter.isExcluded("System"));
|
caseSensitive_userFilter.isExcluded("System"));
|
||||||
|
|
||||||
assertFalse("'John.Doe' user should not have been filtered.",
|
assertFalse("'John.Doe' user should not have been filtered.",
|
||||||
caseSensitive_userFilter.isExcluded("John.Doe"));
|
caseSensitive_userFilter.isExcluded("John.Doe"));
|
||||||
assertTrue("'john.doe' user should have been filtered.",
|
assertTrue("'john.doe' user should have been filtered.",
|
||||||
caseSensitive_userFilter.isExcluded("john.doe"));
|
caseSensitive_userFilter.isExcluded("john.doe"));
|
||||||
|
|
||||||
assertFalse("'jane.doe' user should not have been filtered.",
|
assertFalse("'jane.doe' user should not have been filtered.",
|
||||||
caseSensitive_userFilter.isExcluded("jane.doe"));
|
caseSensitive_userFilter.isExcluded("jane.doe"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2025 - 2025 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.event2;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.event2.mapper.PropertyMapper;
|
||||||
|
import org.alfresco.repo.event2.mapper.ReplaceSensitivePropertyWithTextMapper;
|
||||||
|
import org.alfresco.repo.transfer.TransferModel;
|
||||||
|
|
||||||
|
public class PropertyMapperUnitTest
|
||||||
|
{
|
||||||
|
private static final String DEFAULT_REPLACEMENT_TEXT = "SENSITIVE_DATA_REMOVED";
|
||||||
|
private static final String USER_CONFIGURED_REPLACEMENT_TEXT = "HIDDEN_BY_SECURITY_CONFIG";
|
||||||
|
|
||||||
|
private final PropertyMapper defaultPropertyMapper = new ReplaceSensitivePropertyWithTextMapper(null, null);
|
||||||
|
private final PropertyMapper userConfiguredpropertyMapper = new ReplaceSensitivePropertyWithTextMapper(
|
||||||
|
Set.of(ContentModel.PROP_PASSWORD, TransferModel.PROP_PASSWORD),
|
||||||
|
USER_CONFIGURED_REPLACEMENT_TEXT);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReplacePropertyValueWhenItsOneOfTheDefaultSensitivePropertiesWhenUsingDefaultConfig()
|
||||||
|
{
|
||||||
|
assertEquals(DEFAULT_REPLACEMENT_TEXT, defaultPropertyMapper.map(ContentModel.PROP_PASSWORD, "test_pass"));
|
||||||
|
assertEquals(DEFAULT_REPLACEMENT_TEXT, defaultPropertyMapper.map(ContentModel.PROP_SALT, UUID.randomUUID().toString()));
|
||||||
|
assertEquals(DEFAULT_REPLACEMENT_TEXT, defaultPropertyMapper.map(ContentModel.PROP_PASSWORD_HASH, "r4nD0M_h4sH"));
|
||||||
|
assertEquals(DEFAULT_REPLACEMENT_TEXT, defaultPropertyMapper.map(TransferModel.PROP_PASSWORD, "pyramid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotReplacePropertyValueWhenItsNotOneOfTheDefaultSensitivePropertiesWhenUsingDefaultConfig()
|
||||||
|
{
|
||||||
|
assertEquals("Bob", defaultPropertyMapper.map(ContentModel.PROP_USERNAME, "Bob"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldReplacePropertyValueWhenItsOneOfTheDefaultSensitivePropertiesWhenUsingUserConfig()
|
||||||
|
{
|
||||||
|
assertEquals(USER_CONFIGURED_REPLACEMENT_TEXT, userConfiguredpropertyMapper.map(ContentModel.PROP_PASSWORD, "test_pass"));
|
||||||
|
|
||||||
|
assertEquals(USER_CONFIGURED_REPLACEMENT_TEXT, userConfiguredpropertyMapper.map(TransferModel.PROP_PASSWORD, "pyramid"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldNotReplacePropertyValueWhenItsNotOneOfTheDefaultSensitivePropertiesWhenUsingUserConfig()
|
||||||
|
{
|
||||||
|
String randomUuid = UUID.randomUUID().toString();
|
||||||
|
assertEquals(randomUuid, userConfiguredpropertyMapper.map(ContentModel.PROP_SALT, randomUuid));
|
||||||
|
assertEquals("r4nD0M_h4sH", userConfiguredpropertyMapper.map(ContentModel.PROP_PASSWORD_HASH, "r4nD0M_h4sH"));
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2025 - 2025 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.event2;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.event2.shared.QNameMatcher;
|
||||||
|
import org.alfresco.repo.transfer.TransferModel;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
public class QNameMatcherUnitTest
|
||||||
|
{
|
||||||
|
@Test
|
||||||
|
public void shouldMatchOnlyQNamesFromUserModelURI()
|
||||||
|
{
|
||||||
|
QNameMatcher qNameMatcher = new QNameMatcher(Set.of(QName.createQName(ContentModel.USER_MODEL_URI, "*")));
|
||||||
|
|
||||||
|
assertTrue(qNameMatcher.isMatching(ContentModel.PROP_USER_USERNAME));
|
||||||
|
assertTrue(qNameMatcher.isMatching(ContentModel.TYPE_USER));
|
||||||
|
assertFalse(qNameMatcher.isMatching(ContentModel.PROP_TITLE));
|
||||||
|
assertFalse(qNameMatcher.isMatching(TransferModel.PROP_USERNAME));
|
||||||
|
assertFalse(qNameMatcher.isMatching(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldOnlyMatchSpecificQName()
|
||||||
|
{
|
||||||
|
QNameMatcher qNameMatcher = new QNameMatcher(Set.of(ContentModel.PROP_USER_USERNAME));
|
||||||
|
|
||||||
|
assertTrue(qNameMatcher.isMatching(ContentModel.PROP_USER_USERNAME));
|
||||||
|
assertFalse(qNameMatcher.isMatching(ContentModel.PROP_NAME));
|
||||||
|
assertFalse(qNameMatcher.isMatching(ContentModel.PROP_USERNAME));
|
||||||
|
assertFalse(qNameMatcher.isMatching(TransferModel.PROP_USERNAME));
|
||||||
|
assertFalse(qNameMatcher.isMatching(null));
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
* Copyright (C) 2005 - 2025 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -23,7 +23,6 @@
|
|||||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.alfresco.repo.event2;
|
package org.alfresco.repo.event2;
|
||||||
|
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -31,12 +30,15 @@ import org.junit.runners.Suite;
|
|||||||
import org.junit.runners.Suite.SuiteClasses;
|
import org.junit.runners.Suite.SuiteClasses;
|
||||||
|
|
||||||
@RunWith(Suite.class)
|
@RunWith(Suite.class)
|
||||||
@SuiteClasses({ EventFilterUnitTest.class,
|
@SuiteClasses({EventFilterUnitTest.class,
|
||||||
EventConsolidatorUnitTest.class,
|
EventConsolidatorUnitTest.class,
|
||||||
EventJSONSchemaUnitTest.class,
|
EventJSONSchemaUnitTest.class,
|
||||||
EventGeneratorQueueUnitTest.class,
|
EventGeneratorQueueUnitTest.class,
|
||||||
NodeResourceHelperUnitTest.class
|
NodeResourceHelperUnitTest.class,
|
||||||
|
PropertyMapperUnitTest.class,
|
||||||
|
QNameMatcherUnitTest.class,
|
||||||
|
CSVStringToListParserUnitTest.class,
|
||||||
|
TypeDefExpanderUnitTest.class
|
||||||
})
|
})
|
||||||
public class RepoEvent2UnitSuite
|
public class RepoEvent2UnitSuite
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2025 - 2025 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.event2;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.model.DataListModel;
|
||||||
|
import org.alfresco.repo.event2.shared.TypeDefExpander;
|
||||||
|
import org.alfresco.repo.transfer.TransferModel;
|
||||||
|
import org.alfresco.repo.workflow.WorkflowModel;
|
||||||
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
public class TypeDefExpanderUnitTest
|
||||||
|
{
|
||||||
|
private DictionaryService dictionaryService;
|
||||||
|
private NamespaceService namespaceService;
|
||||||
|
private TypeDefExpander typeDefExpander;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp()
|
||||||
|
{
|
||||||
|
dictionaryService = mock(DictionaryService.class);
|
||||||
|
namespaceService = mock(NamespaceService.class);
|
||||||
|
typeDefExpander = new TypeDefExpander(dictionaryService, namespaceService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpandWithValidType()
|
||||||
|
{
|
||||||
|
String input = "usr:username";
|
||||||
|
when(namespaceService.getNamespaceURI("usr")).thenReturn(ContentModel.USER_MODEL_URI);
|
||||||
|
|
||||||
|
Collection<QName> result = typeDefExpander.expand(input);
|
||||||
|
|
||||||
|
QName expected = ContentModel.PROP_USER_USERNAME;
|
||||||
|
assertEquals(expected, result.iterator().next());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpandWithValidTypeIncludingSubtypes()
|
||||||
|
{
|
||||||
|
String input = "cm:content include_subtypes";
|
||||||
|
when(namespaceService.getNamespaceURI("cm")).thenReturn(NamespaceService.CONTENT_MODEL_1_0_URI);
|
||||||
|
Set<QName> subtypes = Set.of(TransferModel.TYPE_TRANSFER_RECORD, DataListModel.TYPE_EVENT, WorkflowModel.TYPE_TASK);
|
||||||
|
when(dictionaryService.getSubTypes(ContentModel.TYPE_CONTENT, true)).thenReturn(subtypes);
|
||||||
|
|
||||||
|
Collection<QName> result = typeDefExpander.expand(input);
|
||||||
|
|
||||||
|
assertEquals(subtypes, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExpandWithInvalidTypes()
|
||||||
|
{
|
||||||
|
Set<String> input = Stream.of(null, " ", "none", "${test.prop}").collect(Collectors.toSet());
|
||||||
|
|
||||||
|
Collection<QName> result = typeDefExpander.expand(input);
|
||||||
|
|
||||||
|
assertTrue(result.isEmpty());
|
||||||
|
}
|
||||||
|
}
|
@@ -43,7 +43,7 @@ identity-service.enable-pkce=true
|
|||||||
identity-service.ignore-oauth-query-parameter=true
|
identity-service.ignore-oauth-query-parameter=true
|
||||||
identity-service.credentials.secret=11111
|
identity-service.credentials.secret=11111
|
||||||
identity-service.credentials.provider=secret
|
identity-service.credentials.provider=secret
|
||||||
identity-service.client-socket-timeout=1000
|
identity-service.client-socket-timeout=3000
|
||||||
identity-service.client-connection-timeout=3000
|
identity-service.client-connection-timeout=3000
|
||||||
identity-service.authentication.enable-username-password-authentication=false
|
identity-service.authentication.enable-username-password-authentication=false
|
||||||
|
|
||||||
|
@@ -59,13 +59,13 @@ services:
|
|||||||
CLIENT_SSL_TRUST_STORE_TYPE: "JCEKS"
|
CLIENT_SSL_TRUST_STORE_TYPE: "JCEKS"
|
||||||
keycloak:
|
keycloak:
|
||||||
profiles: ["with-sso"]
|
profiles: ["with-sso"]
|
||||||
image: quay.io/keycloak/keycloak:25.0.6
|
image: quay.io/keycloak/keycloak:26.1.0
|
||||||
environment:
|
environment:
|
||||||
- KEYCLOAK_ADMIN=admin
|
- KC_BOOTSTRAP_ADMIN_USERNAME=admin
|
||||||
- KEYCLOAK_ADMIN_PASSWORD=admin
|
- KC_BOOTSTRAP_ADMIN_PASSWORD=admin
|
||||||
- KC_DB=dev-mem
|
- KC_DB=dev-file
|
||||||
command: ["start-dev", "--import-realm", "--http-relative-path=/auth", "--hostname=localhost", "--http-enabled=true"]
|
command: ["start-dev", "--import-realm", "--http-relative-path=/auth", "--hostname=localhost", "--http-enabled=true"]
|
||||||
volumes:
|
volumes:
|
||||||
- ../../../repository/src/test/resources/realms/alfresco-realm.json:/opt/keycloak/data/import/alfresco-realm.json
|
- ../../../repository/src/test/resources/realms/alfresco-realm.json:/opt/keycloak/data/import/alfresco-realm.json
|
||||||
ports:
|
ports:
|
||||||
- 8999:8080
|
- 8999:8080
|
||||||
|
21
scripts/hooks/check-format-and-headers.sh
Executable file
21
scripts/hooks/check-format-and-headers.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set +x
|
||||||
|
|
||||||
|
if [[ -z ${GITHUB_MODIFIED_FILES} ]]
|
||||||
|
then
|
||||||
|
modified_files=$(git diff --cached --name-only --diff-filter=ACMR)
|
||||||
|
else
|
||||||
|
modified_files=${GITHUB_MODIFIED_FILES}
|
||||||
|
fi
|
||||||
|
|
||||||
|
include_list=""
|
||||||
|
for file in ${modified_files}
|
||||||
|
do
|
||||||
|
include_list="${include_list},${file}"
|
||||||
|
done
|
||||||
|
include_list=${include_list:1}
|
||||||
|
|
||||||
|
mvn spotless:apply validate -DlicenseUpdateHeaders=true -Pags,all-tas-tests -Dspotless-include-list="${include_list}" > /dev/null || true
|
||||||
|
|
||||||
|
set -x
|
Reference in New Issue
Block a user