mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 10:38:19 +08:00
Compare commits
105 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 85266283c4 | |||
| b0a9f6505c | |||
| 8c40eb20ea | |||
| 25ff7ab350 | |||
| ad90251596 | |||
| ed05374054 | |||
| b5681f2412 | |||
| bd9923ab7e | |||
| 9dece6004e | |||
| 654782afe1 | |||
| 903f0239b2 | |||
| dda929c0a9 | |||
| 2482048449 | |||
| f54ee83938 | |||
| f5316eb320 | |||
| 500eebefde | |||
| d9cb95b2e9 | |||
| ce6554c3f1 | |||
| 7dcd690a05 | |||
| f376f22ad0 | |||
| ab586c4b00 | |||
| 64cbfaa974 | |||
| 3cab343919 | |||
| 1ad8c1f407 | |||
| 4e6db50049 | |||
| e62cef5644 | |||
| d6a56003aa | |||
| 8a5870300d | |||
| 42885b2a12 | |||
| 96216d5126 | |||
| d890ce1b94 | |||
| d1ff4f7014 | |||
| 9f3089566c | |||
| 79105bf400 | |||
| 2b0b74af92 | |||
| c65d164167 | |||
| 74bde0c7ea | |||
| 7fba61cb64 | |||
| b609e1d174 | |||
| bdbd484690 | |||
| cc5383b0f2 | |||
| 35d2653f56 | |||
| d6fa7710dc | |||
| fdb6d81bf0 | |||
| 6a03d446a3 | |||
| 4a0e6b0676 | |||
| fc4a11bc3e | |||
| e95abd6b37 | |||
| 0b4304474e | |||
| f36fb81249 | |||
| b17c157e18 | |||
| c86985017f | |||
| cb7562cd8c | |||
| ae6aaa0461 | |||
| c96a6c7e49 | |||
| 74b5e80cbc | |||
| 51c5c333e9 | |||
| f09ed5bbc5 | |||
| f0abdd87e3 | |||
| 7f091669c7 | |||
| 8dbee35757 | |||
| 1a2eaff1e6 | |||
| 36364bc09b | |||
| fcb4ced610 | |||
| 5df66e59d2 | |||
| 809cd5b268 | |||
| 661527a80f | |||
| 9883e75f05 | |||
| c3297d168f | |||
| 627e0ba391 | |||
| b29935ae47 | |||
| e1a907203e | |||
| 3cd1ddb3ad | |||
| b46e116712 | |||
| 44194d6055 | |||
| 47fd058f44 | |||
| c73fcafb15 | |||
| beb6d93f7b | |||
| d62aa14ca7 | |||
| a439ca5cde | |||
| 0736153fd6 | |||
| 0bce5f1a22 | |||
| feb43bb382 | |||
| 0bfd15aaad | |||
| 15f395a8e0 | |||
| a61040a0e2 | |||
| 8766b4d77b | |||
| 8c1214612a | |||
| 608d92f834 | |||
| ad6ab9eb36 | |||
| 0eda8d8a0f | |||
| b19691b5a4 | |||
| c7331aa556 | |||
| a440c050e5 | |||
| b9d45a9bb9 | |||
| 67482de7a9 | |||
| 04bedbef07 | |||
| a4abfb733a | |||
| 76d276436b | |||
| e7198f22d5 | |||
| 5bd20e173f | |||
| 15c4bb13e8 | |||
| b74eb5c035 | |||
| ed3a68af1e | |||
| 447b82c880 |
@@ -1,3 +1,6 @@
|
|||||||
# configured Javadoc
|
# configured Javadoc
|
||||||
|
|
||||||
Based on [Github Pages](https://pages.github.com/), please see [JavaDoc](https://carmjos.github.io/configured) 。
|
Based
|
||||||
|
on [Github Pages](https://pages.github.com/),
|
||||||
|
please
|
||||||
|
see [JavaDoc](https://carmjos.github.io/configured) 。
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
# Documentation
|
# Documentation
|
||||||
|
|
||||||
|
See [wiki](https://github.com/CarmJos/configured/wiki).
|
||||||
|
|||||||
+346
@@ -0,0 +1,346 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_style = space
|
||||||
|
tab_width = 4
|
||||||
|
|
||||||
|
[*.java]
|
||||||
|
indent_size = 4
|
||||||
|
max_line_length = 120
|
||||||
|
ij_java_align_consecutive_assignments = false
|
||||||
|
ij_java_align_consecutive_variable_declarations = false
|
||||||
|
ij_java_align_group_field_declarations = false
|
||||||
|
ij_java_align_multiline_annotation_parameters = false
|
||||||
|
ij_java_align_multiline_array_initializer_expression = false
|
||||||
|
ij_java_align_multiline_assignment = false
|
||||||
|
ij_java_align_multiline_binary_operation = false
|
||||||
|
ij_java_align_multiline_chained_methods = false
|
||||||
|
ij_java_align_multiline_deconstruction_list_components = true
|
||||||
|
ij_java_align_multiline_extends_list = false
|
||||||
|
ij_java_align_multiline_for = true
|
||||||
|
ij_java_align_multiline_method_parentheses = false
|
||||||
|
ij_java_align_multiline_parameters = true
|
||||||
|
ij_java_align_multiline_parameters_in_calls = false
|
||||||
|
ij_java_align_multiline_parenthesized_expression = false
|
||||||
|
ij_java_align_multiline_records = true
|
||||||
|
ij_java_align_multiline_resources = true
|
||||||
|
ij_java_align_multiline_ternary_operation = false
|
||||||
|
ij_java_align_multiline_text_blocks = false
|
||||||
|
ij_java_align_multiline_throws_list = false
|
||||||
|
ij_java_align_subsequent_simple_methods = false
|
||||||
|
ij_java_align_throws_keyword = false
|
||||||
|
ij_java_align_types_in_multi_catch = true
|
||||||
|
ij_java_annotation_new_line_in_record_component = false
|
||||||
|
ij_java_annotation_parameter_wrap = off
|
||||||
|
ij_java_array_initializer_new_line_after_left_brace = false
|
||||||
|
ij_java_array_initializer_right_brace_on_new_line = false
|
||||||
|
ij_java_array_initializer_wrap = off
|
||||||
|
ij_java_assert_statement_colon_on_next_line = false
|
||||||
|
ij_java_assert_statement_wrap = off
|
||||||
|
ij_java_assignment_wrap = off
|
||||||
|
ij_java_binary_operation_sign_on_next_line = false
|
||||||
|
ij_java_binary_operation_wrap = off
|
||||||
|
ij_java_blank_lines_after_anonymous_class_header = 0
|
||||||
|
ij_java_blank_lines_after_class_header = 0
|
||||||
|
ij_java_blank_lines_after_imports = 1
|
||||||
|
ij_java_blank_lines_after_package = 1
|
||||||
|
ij_java_blank_lines_around_class = 1
|
||||||
|
ij_java_blank_lines_around_field = 0
|
||||||
|
ij_java_blank_lines_around_field_in_interface = 0
|
||||||
|
ij_java_blank_lines_around_field_with_annotations = 0
|
||||||
|
ij_java_blank_lines_around_initializer = 1
|
||||||
|
ij_java_blank_lines_around_method = 1
|
||||||
|
ij_java_blank_lines_around_method_in_interface = 1
|
||||||
|
ij_java_blank_lines_before_class_end = 0
|
||||||
|
ij_java_blank_lines_before_imports = 1
|
||||||
|
ij_java_blank_lines_before_method_body = 0
|
||||||
|
ij_java_blank_lines_before_package = 0
|
||||||
|
ij_java_blank_lines_between_record_components = 0
|
||||||
|
ij_java_block_brace_style = end_of_line
|
||||||
|
ij_java_block_comment_add_space = false
|
||||||
|
ij_java_block_comment_at_first_column = true
|
||||||
|
ij_java_builder_methods =
|
||||||
|
ij_java_call_parameters_new_line_after_left_paren = false
|
||||||
|
ij_java_call_parameters_right_paren_on_new_line = false
|
||||||
|
ij_java_call_parameters_wrap = off
|
||||||
|
ij_java_case_statement_on_separate_line = true
|
||||||
|
ij_java_catch_on_new_line = false
|
||||||
|
ij_java_class_annotation_wrap = split_into_lines
|
||||||
|
ij_java_class_brace_style = end_of_line
|
||||||
|
ij_java_class_count_to_use_import_on_demand = 5
|
||||||
|
ij_java_class_names_in_javadoc = 1
|
||||||
|
ij_java_deconstruction_list_wrap = normal
|
||||||
|
ij_java_do_not_indent_top_level_class_members = false
|
||||||
|
ij_java_do_not_wrap_after_single_annotation = false
|
||||||
|
ij_java_do_not_wrap_after_single_annotation_in_parameter = false
|
||||||
|
ij_java_do_while_brace_force = never
|
||||||
|
ij_java_doc_add_blank_line_after_description = true
|
||||||
|
ij_java_doc_add_blank_line_after_param_comments = false
|
||||||
|
ij_java_doc_add_blank_line_after_return = false
|
||||||
|
ij_java_doc_add_p_tag_on_empty_lines = true
|
||||||
|
ij_java_doc_align_exception_comments = true
|
||||||
|
ij_java_doc_align_param_comments = true
|
||||||
|
ij_java_doc_do_not_wrap_if_one_line = false
|
||||||
|
ij_java_doc_enable_formatting = true
|
||||||
|
ij_java_doc_enable_leading_asterisks = true
|
||||||
|
ij_java_doc_indent_on_continuation = false
|
||||||
|
ij_java_doc_keep_empty_lines = true
|
||||||
|
ij_java_doc_keep_empty_parameter_tag = true
|
||||||
|
ij_java_doc_keep_empty_return_tag = true
|
||||||
|
ij_java_doc_keep_empty_throws_tag = true
|
||||||
|
ij_java_doc_keep_invalid_tags = true
|
||||||
|
ij_java_doc_param_description_on_new_line = false
|
||||||
|
ij_java_doc_preserve_line_breaks = false
|
||||||
|
ij_java_doc_use_throws_not_exception_tag = true
|
||||||
|
ij_java_else_on_new_line = false
|
||||||
|
ij_java_entity_dd_prefix =
|
||||||
|
ij_java_entity_dd_suffix = EJB
|
||||||
|
ij_java_entity_eb_prefix =
|
||||||
|
ij_java_entity_eb_suffix = Bean
|
||||||
|
ij_java_entity_hi_prefix =
|
||||||
|
ij_java_entity_hi_suffix = Home
|
||||||
|
ij_java_entity_lhi_prefix = Local
|
||||||
|
ij_java_entity_lhi_suffix = Home
|
||||||
|
ij_java_entity_li_prefix = Local
|
||||||
|
ij_java_entity_li_suffix =
|
||||||
|
ij_java_entity_pk_class = java.lang.String
|
||||||
|
ij_java_entity_ri_prefix =
|
||||||
|
ij_java_entity_ri_suffix =
|
||||||
|
ij_java_entity_vo_prefix =
|
||||||
|
ij_java_entity_vo_suffix = VO
|
||||||
|
ij_java_enum_constants_wrap = off
|
||||||
|
ij_java_enum_field_annotation_wrap = off
|
||||||
|
ij_java_extends_keyword_wrap = off
|
||||||
|
ij_java_extends_list_wrap = off
|
||||||
|
ij_java_field_annotation_wrap = split_into_lines
|
||||||
|
ij_java_field_name_prefix =
|
||||||
|
ij_java_field_name_suffix =
|
||||||
|
ij_java_filter_class_prefix =
|
||||||
|
ij_java_filter_class_suffix =
|
||||||
|
ij_java_filter_dd_prefix =
|
||||||
|
ij_java_filter_dd_suffix =
|
||||||
|
ij_java_finally_on_new_line = false
|
||||||
|
ij_java_for_brace_force = never
|
||||||
|
ij_java_for_statement_new_line_after_left_paren = false
|
||||||
|
ij_java_for_statement_right_paren_on_new_line = false
|
||||||
|
ij_java_for_statement_wrap = off
|
||||||
|
ij_java_generate_final_locals = false
|
||||||
|
ij_java_generate_final_parameters = false
|
||||||
|
ij_java_generate_use_type_annotation_before_type = true
|
||||||
|
ij_java_if_brace_force = never
|
||||||
|
ij_java_imports_layout = @*, *, |, javax.**, java.**, |, $*
|
||||||
|
ij_java_indent_case_from_switch = true
|
||||||
|
ij_java_insert_inner_class_imports = false
|
||||||
|
ij_java_insert_override_annotation = true
|
||||||
|
ij_java_keep_blank_lines_before_right_brace = 2
|
||||||
|
ij_java_keep_blank_lines_between_package_declaration_and_header = 2
|
||||||
|
ij_java_keep_blank_lines_in_code = 2
|
||||||
|
ij_java_keep_blank_lines_in_declarations = 2
|
||||||
|
ij_java_keep_builder_methods_indents = false
|
||||||
|
ij_java_keep_control_statement_in_one_line = true
|
||||||
|
ij_java_keep_first_column_comment = true
|
||||||
|
ij_java_keep_indents_on_empty_lines = false
|
||||||
|
ij_java_keep_line_breaks = true
|
||||||
|
ij_java_keep_multiple_expressions_in_one_line = false
|
||||||
|
ij_java_keep_simple_blocks_in_one_line = false
|
||||||
|
ij_java_keep_simple_classes_in_one_line = false
|
||||||
|
ij_java_keep_simple_lambdas_in_one_line = false
|
||||||
|
ij_java_keep_simple_methods_in_one_line = false
|
||||||
|
ij_java_label_indent_absolute = false
|
||||||
|
ij_java_label_indent_size = 0
|
||||||
|
ij_java_lambda_brace_style = end_of_line
|
||||||
|
ij_java_layout_on_demand_import_from_same_package_first = true
|
||||||
|
ij_java_layout_static_imports_separately = true
|
||||||
|
ij_java_line_comment_add_space = false
|
||||||
|
ij_java_line_comment_add_space_on_reformat = false
|
||||||
|
ij_java_line_comment_at_first_column = true
|
||||||
|
ij_java_listener_class_prefix =
|
||||||
|
ij_java_listener_class_suffix =
|
||||||
|
ij_java_local_variable_name_prefix =
|
||||||
|
ij_java_local_variable_name_suffix =
|
||||||
|
ij_java_message_dd_prefix =
|
||||||
|
ij_java_message_dd_suffix = EJB
|
||||||
|
ij_java_message_eb_prefix =
|
||||||
|
ij_java_message_eb_suffix = Bean
|
||||||
|
ij_java_method_annotation_wrap = split_into_lines
|
||||||
|
ij_java_method_brace_style = end_of_line
|
||||||
|
ij_java_method_call_chain_wrap = off
|
||||||
|
ij_java_method_parameters_new_line_after_left_paren = false
|
||||||
|
ij_java_method_parameters_right_paren_on_new_line = false
|
||||||
|
ij_java_method_parameters_wrap = off
|
||||||
|
ij_java_modifier_list_wrap = false
|
||||||
|
ij_java_multi_catch_types_wrap = normal
|
||||||
|
ij_java_names_count_to_use_import_on_demand = 3
|
||||||
|
ij_java_new_line_after_lparen_in_annotation = false
|
||||||
|
ij_java_new_line_after_lparen_in_deconstruction_pattern = true
|
||||||
|
ij_java_new_line_after_lparen_in_record_header = false
|
||||||
|
ij_java_new_line_when_body_is_presented = false
|
||||||
|
ij_java_packages_to_use_import_on_demand = java.awt.*, javax.swing.*
|
||||||
|
ij_java_parameter_annotation_wrap = off
|
||||||
|
ij_java_parameter_name_prefix =
|
||||||
|
ij_java_parameter_name_suffix =
|
||||||
|
ij_java_parentheses_expression_new_line_after_left_paren = false
|
||||||
|
ij_java_parentheses_expression_right_paren_on_new_line = false
|
||||||
|
ij_java_place_assignment_sign_on_next_line = false
|
||||||
|
ij_java_prefer_longer_names = true
|
||||||
|
ij_java_prefer_parameters_wrap = false
|
||||||
|
ij_java_preserve_module_imports = true
|
||||||
|
ij_java_record_components_wrap = normal
|
||||||
|
ij_java_repeat_annotations =
|
||||||
|
ij_java_repeat_synchronized = true
|
||||||
|
ij_java_replace_instanceof_and_cast = false
|
||||||
|
ij_java_replace_null_check = true
|
||||||
|
ij_java_replace_sum_lambda_with_method_ref = true
|
||||||
|
ij_java_resource_list_new_line_after_left_paren = false
|
||||||
|
ij_java_resource_list_right_paren_on_new_line = false
|
||||||
|
ij_java_resource_list_wrap = off
|
||||||
|
ij_java_rparen_on_new_line_in_annotation = false
|
||||||
|
ij_java_rparen_on_new_line_in_deconstruction_pattern = true
|
||||||
|
ij_java_rparen_on_new_line_in_record_header = false
|
||||||
|
ij_java_servlet_class_prefix =
|
||||||
|
ij_java_servlet_class_suffix =
|
||||||
|
ij_java_servlet_dd_prefix =
|
||||||
|
ij_java_servlet_dd_suffix =
|
||||||
|
ij_java_session_dd_prefix =
|
||||||
|
ij_java_session_dd_suffix = EJB
|
||||||
|
ij_java_session_eb_prefix =
|
||||||
|
ij_java_session_eb_suffix = Bean
|
||||||
|
ij_java_session_hi_prefix =
|
||||||
|
ij_java_session_hi_suffix = Home
|
||||||
|
ij_java_session_lhi_prefix = Local
|
||||||
|
ij_java_session_lhi_suffix = Home
|
||||||
|
ij_java_session_li_prefix = Local
|
||||||
|
ij_java_session_li_suffix =
|
||||||
|
ij_java_session_ri_prefix =
|
||||||
|
ij_java_session_ri_suffix =
|
||||||
|
ij_java_session_si_prefix =
|
||||||
|
ij_java_session_si_suffix = Service
|
||||||
|
ij_java_space_after_closing_angle_bracket_in_type_argument = false
|
||||||
|
ij_java_space_after_colon = true
|
||||||
|
ij_java_space_after_comma = true
|
||||||
|
ij_java_space_after_comma_in_type_arguments = true
|
||||||
|
ij_java_space_after_for_semicolon = true
|
||||||
|
ij_java_space_after_quest = true
|
||||||
|
ij_java_space_after_type_cast = true
|
||||||
|
ij_java_space_before_annotation_array_initializer_left_brace = false
|
||||||
|
ij_java_space_before_annotation_parameter_list = false
|
||||||
|
ij_java_space_before_array_initializer_left_brace = false
|
||||||
|
ij_java_space_before_catch_keyword = true
|
||||||
|
ij_java_space_before_catch_left_brace = true
|
||||||
|
ij_java_space_before_catch_parentheses = true
|
||||||
|
ij_java_space_before_class_left_brace = true
|
||||||
|
ij_java_space_before_colon = true
|
||||||
|
ij_java_space_before_colon_in_foreach = true
|
||||||
|
ij_java_space_before_comma = false
|
||||||
|
ij_java_space_before_deconstruction_list = false
|
||||||
|
ij_java_space_before_do_left_brace = true
|
||||||
|
ij_java_space_before_else_keyword = true
|
||||||
|
ij_java_space_before_else_left_brace = true
|
||||||
|
ij_java_space_before_finally_keyword = true
|
||||||
|
ij_java_space_before_finally_left_brace = true
|
||||||
|
ij_java_space_before_for_left_brace = true
|
||||||
|
ij_java_space_before_for_parentheses = true
|
||||||
|
ij_java_space_before_for_semicolon = false
|
||||||
|
ij_java_space_before_if_left_brace = true
|
||||||
|
ij_java_space_before_if_parentheses = true
|
||||||
|
ij_java_space_before_method_call_parentheses = false
|
||||||
|
ij_java_space_before_method_left_brace = true
|
||||||
|
ij_java_space_before_method_parentheses = false
|
||||||
|
ij_java_space_before_opening_angle_bracket_in_type_parameter = false
|
||||||
|
ij_java_space_before_quest = true
|
||||||
|
ij_java_space_before_switch_left_brace = true
|
||||||
|
ij_java_space_before_switch_parentheses = true
|
||||||
|
ij_java_space_before_synchronized_left_brace = true
|
||||||
|
ij_java_space_before_synchronized_parentheses = true
|
||||||
|
ij_java_space_before_try_left_brace = true
|
||||||
|
ij_java_space_before_try_parentheses = true
|
||||||
|
ij_java_space_before_type_parameter_list = false
|
||||||
|
ij_java_space_before_while_keyword = true
|
||||||
|
ij_java_space_before_while_left_brace = true
|
||||||
|
ij_java_space_before_while_parentheses = true
|
||||||
|
ij_java_space_inside_one_line_enum_braces = false
|
||||||
|
ij_java_space_within_empty_array_initializer_braces = false
|
||||||
|
ij_java_space_within_empty_method_call_parentheses = false
|
||||||
|
ij_java_space_within_empty_method_parentheses = false
|
||||||
|
ij_java_spaces_around_additive_operators = true
|
||||||
|
ij_java_spaces_around_annotation_eq = true
|
||||||
|
ij_java_spaces_around_assignment_operators = true
|
||||||
|
ij_java_spaces_around_bitwise_operators = true
|
||||||
|
ij_java_spaces_around_equality_operators = true
|
||||||
|
ij_java_spaces_around_lambda_arrow = true
|
||||||
|
ij_java_spaces_around_logical_operators = true
|
||||||
|
ij_java_spaces_around_method_ref_dbl_colon = false
|
||||||
|
ij_java_spaces_around_multiplicative_operators = true
|
||||||
|
ij_java_spaces_around_relational_operators = true
|
||||||
|
ij_java_spaces_around_shift_operators = true
|
||||||
|
ij_java_spaces_around_type_bounds_in_type_parameters = true
|
||||||
|
ij_java_spaces_around_unary_operator = false
|
||||||
|
ij_java_spaces_inside_block_braces_when_body_is_present = false
|
||||||
|
ij_java_spaces_within_angle_brackets = false
|
||||||
|
ij_java_spaces_within_annotation_parentheses = false
|
||||||
|
ij_java_spaces_within_array_initializer_braces = false
|
||||||
|
ij_java_spaces_within_braces = false
|
||||||
|
ij_java_spaces_within_brackets = false
|
||||||
|
ij_java_spaces_within_cast_parentheses = false
|
||||||
|
ij_java_spaces_within_catch_parentheses = false
|
||||||
|
ij_java_spaces_within_deconstruction_list = false
|
||||||
|
ij_java_spaces_within_for_parentheses = false
|
||||||
|
ij_java_spaces_within_if_parentheses = false
|
||||||
|
ij_java_spaces_within_method_call_parentheses = false
|
||||||
|
ij_java_spaces_within_method_parentheses = false
|
||||||
|
ij_java_spaces_within_parentheses = false
|
||||||
|
ij_java_spaces_within_record_header = false
|
||||||
|
ij_java_spaces_within_switch_parentheses = false
|
||||||
|
ij_java_spaces_within_synchronized_parentheses = false
|
||||||
|
ij_java_spaces_within_try_parentheses = false
|
||||||
|
ij_java_spaces_within_while_parentheses = false
|
||||||
|
ij_java_special_else_if_treatment = true
|
||||||
|
ij_java_static_field_name_prefix =
|
||||||
|
ij_java_static_field_name_suffix =
|
||||||
|
ij_java_subclass_name_prefix =
|
||||||
|
ij_java_subclass_name_suffix = Impl
|
||||||
|
ij_java_switch_expressions_wrap = normal
|
||||||
|
ij_java_ternary_operation_signs_on_next_line = false
|
||||||
|
ij_java_ternary_operation_wrap = off
|
||||||
|
ij_java_test_name_prefix =
|
||||||
|
ij_java_test_name_suffix = Test
|
||||||
|
ij_java_throws_keyword_wrap = off
|
||||||
|
ij_java_throws_list_wrap = off
|
||||||
|
ij_java_use_external_annotations = false
|
||||||
|
ij_java_use_fq_class_names = false
|
||||||
|
ij_java_use_relative_indents = false
|
||||||
|
ij_java_use_single_class_imports = true
|
||||||
|
ij_java_variable_annotation_wrap = off
|
||||||
|
ij_java_visibility = public
|
||||||
|
ij_java_while_brace_force = never
|
||||||
|
ij_java_while_on_new_line = false
|
||||||
|
ij_java_wrap_comments = false
|
||||||
|
ij_java_wrap_first_method_in_call_chain = false
|
||||||
|
ij_java_wrap_long_lines = false
|
||||||
|
ij_java_wrap_semicolon_after_call_chain = false
|
||||||
|
|
||||||
|
[*.xml]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
tab_width = 4
|
||||||
|
max_line_length = 120
|
||||||
|
|
||||||
|
[*.json]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
tab_width = 2
|
||||||
|
max_line_length = 120
|
||||||
|
|
||||||
|
[*.{yml,yaml}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
tab_width = 2
|
||||||
|
max_line_length = 120
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
max_line_length = 500
|
||||||
|
trim_trailing_whitespace = false
|
||||||
@@ -1,2 +1 @@
|
|||||||
github: [ CarmJos ]
|
github: [ CarmJos ]
|
||||||
custom: [ 'https://donate.carm.cc' ]
|
|
||||||
|
|||||||
@@ -1,37 +1,34 @@
|
|||||||
---
|
---
|
||||||
name: 问题提交
|
name: Submit bugs&issues
|
||||||
about: 描述问题并提交,帮助我们对其进行检查与修复。
|
about: Describe the problem and submit it to help us review and fix it.
|
||||||
title: ''
|
title: 'fix: '
|
||||||
labels: bug
|
labels: bug
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### **问题简述**
|
### **Description**
|
||||||
|
|
||||||
用简短的话语描述一下大概问题。
|
<!-- Describe the general problem in short words.-->
|
||||||
|
|
||||||
### **问题来源**
|
### **Operations**
|
||||||
|
|
||||||
描述一下通过哪些操作才发现的问题,如:
|
<!--
|
||||||
|
Describe the problem discovered through what operations, such as:
|
||||||
|
|
||||||
1. 使用了 '...'
|
1. Clicked '...'
|
||||||
2. 输入了 '....'
|
2. Typed '....'
|
||||||
3. 出现了报错 '....'
|
3. Error says '....'
|
||||||
|
-->
|
||||||
|
|
||||||
### **预期结果** (可选)
|
### **Expected result** _(Optional)_
|
||||||
|
|
||||||
如果问题不发生,应该是什么情况
|
### **Screenshots & Error Logs**
|
||||||
|
|
||||||
### **问题截图/问题报错**
|
### **Environment**
|
||||||
|
|
||||||
如果有报错或输出,请提供截图。
|
- System: `Windows 10` / `Ubuntu` / `...`
|
||||||
|
- Java version: `JDK11` / `OPENJDK8` / `JRE8` / `...`
|
||||||
|
|
||||||
### **操作环境**
|
### **Anything else...**
|
||||||
|
|
||||||
- 系统环境: `Windows 10` / `Ubuntu` / `...`
|
<!-- If there are other supplements, they can be described here. -->
|
||||||
- Java版本: `JDK11` / `OPENJDK8` / `JRE8` / `...`
|
|
||||||
|
|
||||||
### **其他补充**
|
|
||||||
|
|
||||||
如有其他补充,可以在这里描述。
|
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
---
|
---
|
||||||
name: 功能需求
|
name: Features
|
||||||
about: 希望我们提供更多的功能。
|
about: Ask for new features.
|
||||||
title: ''
|
title: 'feat: '
|
||||||
labels: enhancement
|
labels: enhancement
|
||||||
assignees: ''
|
assignees: ''
|
||||||
---
|
---
|
||||||
|
|
||||||
### **功能简述**
|
### **Description**
|
||||||
|
|
||||||
简单的描述一下你想要的功能
|
<!-- Describe the features in short words.-->
|
||||||
|
|
||||||
### **需求来源**
|
### **Source**
|
||||||
|
|
||||||
简单的描述一下为什么需要这个功能。
|
<!-- Describe the reason that you need this feature in short words.-->
|
||||||
|
|
||||||
### **功能参考**(可选)
|
### **Examples** _(Optional)_
|
||||||
|
|
||||||
如果有相关功能的参考,如文本、截图,请提供给我们。
|
<!--Any screenshots or example codes please.-->
|
||||||
|
|
||||||
### **附加内容**
|
### **Additional details**
|
||||||
|
|
||||||
如果有什么小细节需要重点注意,请在这里告诉我们。
|
<!--If there are any small details that need to be highlighted, please let us know here.-->
|
||||||
|
|||||||
@@ -38,11 +38,11 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v3
|
uses: github/codeql-action/init@v4
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
@@ -53,7 +53,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v3
|
uses: github/codeql-action/autobuild@v4
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
@@ -67,4 +67,4 @@ jobs:
|
|||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v3
|
uses: github/codeql-action/analyze@v4
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- name: "Set up JDK"
|
- name: "Set up JDK"
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v5
|
||||||
with:
|
with:
|
||||||
java-version: '11'
|
java-version: '21'
|
||||||
distribution: 'adopt'
|
distribution: 'adopt'
|
||||||
cache: maven
|
cache: maven
|
||||||
server-id: github
|
server-id: github
|
||||||
@@ -87,11 +87,11 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- name: "Set up JDK"
|
- name: "Set up JDK"
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v5
|
||||||
with:
|
with:
|
||||||
java-version: '11'
|
java-version: '21'
|
||||||
distribution: 'adopt'
|
distribution: 'adopt'
|
||||||
cache: maven
|
cache: maven
|
||||||
server-id: central
|
server-id: central
|
||||||
|
|||||||
@@ -15,18 +15,18 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- name: "Set up JDK"
|
- name: "Set up JDK"
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v5
|
||||||
with:
|
with:
|
||||||
java-version: '11'
|
java-version: '21'
|
||||||
distribution: 'adopt'
|
distribution: 'adopt'
|
||||||
- name: "Package"
|
- name: "Package"
|
||||||
run: mvn -B package --file pom.xml -Dgpg.skip
|
run: mvn -B package --file pom.xml -Dgpg.skip
|
||||||
- name: "Target Stage"
|
- name: "Target Stage"
|
||||||
run: mkdir staging && cp */target/*.jar staging
|
run: mkdir staging && cp */target/*.jar staging
|
||||||
- name: "Upload artifact"
|
- name: "Upload artifact"
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: Artifact
|
name: Artifact
|
||||||
path: staging
|
path: staging
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule ".wiki"]
|
||||||
|
path = .wiki
|
||||||
|
url = https://github.com/CarmJos/configured.wiki.git
|
||||||
Submodule
+1
Submodule .wiki added at c79c6f4a43
@@ -0,0 +1,75 @@
|
|||||||
|
# Code of Conduct
|
||||||
|
|
||||||
|
(English primary version – a brief Chinese note may follow. 中文提示:本文件英文为主,若理解存在困难可联系维护者。)
|
||||||
|
|
||||||
|
This project adopts the principles of the Contributor Covenant v2.1 (https://www.contributor-covenant.org/version/2/1/code_of_conduct/) with project‑specific clarifications below. By participating you agree to uphold this Code.
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
We strive to provide a harassment‑free, inclusive, friendly, and productive environment for everyone, regardless of age, body, disability, ethnicity, sex characteristics, gender identity or expression, level of experience, education, socio‑economic status, nationality, personal appearance, race, caste, religion (or lack thereof), sexual identity or orientation, or technical choices.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
Examples of behavior that contributes to a positive environment:
|
||||||
|
- Showing empathy and respect to all participants
|
||||||
|
- Giving and gracefully accepting constructive feedback
|
||||||
|
- Focusing on what is best for the project and community
|
||||||
|
- Being honest about mistakes and seeking improvement
|
||||||
|
- Using welcoming and inclusive language
|
||||||
|
|
||||||
|
Examples of unacceptable behavior include:
|
||||||
|
- Harassment, discrimination, or derogatory comments
|
||||||
|
- Trolling, insulting or antagonistic remarks, personal or political attacks
|
||||||
|
- Public or private harassment or sustained disruption of activities
|
||||||
|
- Publishing others’ private information without explicit permission
|
||||||
|
- Sexualized language, imagery, or unwelcome advances
|
||||||
|
- Any other conduct reasonably deemed inappropriate or unsafe
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
This Code applies within all project spaces (repository code, issues, pull requests, discussions, wiki, CI logs) and in public spaces whenever an individual is representing the project or community.
|
||||||
|
|
||||||
|
## Responsibilities & Enforcement
|
||||||
|
Project maintainers ("maintainers") are responsible for clarifying standards and taking appropriate, fair, and consistent corrective action.
|
||||||
|
|
||||||
|
Maintainers may remove or edit contributions that violate this Code (comments, commits, code, wiki edits, issues, discussions) and may temporarily or permanently ban any contributor for abusive, harassing, or otherwise harmful behavior.
|
||||||
|
|
||||||
|
## Reporting
|
||||||
|
Report violations privately via:
|
||||||
|
- Email: carm@carm.cc
|
||||||
|
|
||||||
|
Please include (if possible):
|
||||||
|
- Links, timestamps, or message IDs
|
||||||
|
- Description of what happened and why it is a concern
|
||||||
|
- Screenshots or logs (if relevant)
|
||||||
|
- Preferred or suggested resolution
|
||||||
|
|
||||||
|
We aim to acknowledge reports within 72 hours and provide an initial assessment within 7 days. All good‑faith reports will be treated confidentially and only shared with individuals who need the information to resolve the issue.
|
||||||
|
|
||||||
|
## Enforcement Guidelines
|
||||||
|
Maintainers will use these guidelines to determine the impact of an incident and consequences:
|
||||||
|
|
||||||
|
1. Correction
|
||||||
|
- Impact: Use of inappropriate language or other unprofessional conduct.
|
||||||
|
- Consequence: Private or public warning, request for change.
|
||||||
|
2. Warning
|
||||||
|
- Impact: A single severe incident or repeated inappropriate behavior.
|
||||||
|
- Consequence: Official warning; continued misconduct leads to escalation.
|
||||||
|
3. Temporary Suspension
|
||||||
|
- Impact: Persistent violations despite previous warnings.
|
||||||
|
- Consequence: Temporary participation suspension (issues/PRs/discussions). Conditions for reinstatement communicated.
|
||||||
|
4. Permanent Ban
|
||||||
|
- Impact: Demonstrated pattern of harassment, hate, or threats; refusal to reform.
|
||||||
|
- Consequence: Permanent removal from community spaces.
|
||||||
|
|
||||||
|
## Conflicts of Interest
|
||||||
|
Maintainers will recuse themselves from enforcement decisions where they have a personal conflict. A neutral maintainer or external trusted community member may be asked to assist when appropriate.
|
||||||
|
|
||||||
|
## Appeals
|
||||||
|
If you believe an enforcement action was made in error or was unfair, you may appeal by emailing the same reporting address within 14 days, providing context and justification.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
Portions adapted from Contributor Covenant v2.1 and other open source community best practices.
|
||||||
|
|
||||||
|
## Changes & Versioning
|
||||||
|
Substantive changes to this Code will be announced in the repository (Release Notes / CHANGELOG / Discussions). Historical versions will remain accessible via Git history.
|
||||||
|
|
||||||
|
---
|
||||||
|
If unsure whether something is acceptable: choose respect, transparency, and ask a maintainer before acting.
|
||||||
+210
@@ -0,0 +1,210 @@
|
|||||||
|
# Contributing Guide
|
||||||
|
|
||||||
|
> English is the primary language. A brief Chinese hint: 若需中文协助可在 Issue 中说明。
|
||||||
|
|
||||||
|
Thank you for investing time in contributing! This document describes how to propose changes and how we maintain quality and consistency across the project.
|
||||||
|
|
||||||
|
## Quick Links
|
||||||
|
- Code of Conduct: ./CODE_OF_CONDUCT.md
|
||||||
|
- Security Policy: ./SECURITY.md
|
||||||
|
- Issues: https://github.com/CarmJos/configured/issues
|
||||||
|
- Discussions / Q&A: (open an Issue if Discussions are disabled)
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
1. Principles
|
||||||
|
2. Scope of Contributions
|
||||||
|
3. Getting Started (Environment & Build)
|
||||||
|
4. Project Structure
|
||||||
|
5. Branching & Workflow
|
||||||
|
6. Issue Workflow
|
||||||
|
7. Pull Request Guidelines
|
||||||
|
8. Commit Message Convention
|
||||||
|
9. Coding Standards
|
||||||
|
10. Testing Guidelines
|
||||||
|
11. Documentation & JavaDoc
|
||||||
|
12. Dependency Policy
|
||||||
|
13. Versioning & Releases
|
||||||
|
14. Performance Expectations
|
||||||
|
15. Internationalization / Language
|
||||||
|
16. FAQ for Contributors
|
||||||
|
17. Attribution
|
||||||
|
|
||||||
|
---
|
||||||
|
## 1. Principles
|
||||||
|
We value: correctness, clarity, minimalism, maintainability, security-by-default, and performance without premature complexity. Every contribution should move at least one of these forward while not regressing the others.
|
||||||
|
|
||||||
|
## 2. Scope of Contributions
|
||||||
|
Acceptable contributions include (but are not limited to):
|
||||||
|
- Bug fixes & test coverage improvements
|
||||||
|
- Performance optimizations with measurable benefit
|
||||||
|
- New configuration providers (storage backends) with generic value
|
||||||
|
- Validation or serialization helpers
|
||||||
|
- Documentation, examples, or tutorials
|
||||||
|
- Tooling that improves developer productivity or release robustness
|
||||||
|
|
||||||
|
Out-of-scope (likely to be declined):
|
||||||
|
- Vendor lock‑in features narrowly targeting one proprietary platform (unless optional & isolated)
|
||||||
|
- Large feature branches without prior design discussion
|
||||||
|
- Unbounded abstraction that increases complexity with unclear user value
|
||||||
|
|
||||||
|
## 3. Getting Started (Environment & Build)
|
||||||
|
Requirements:
|
||||||
|
- JDK 8 (minimum). Later JDKs may work but target bytecode is 1.8.
|
||||||
|
- Maven 3.8+ (Wrapper optional; project assumes standard mvn).
|
||||||
|
|
||||||
|
Build all modules:
|
||||||
|
```bash
|
||||||
|
mvn -q clean verify
|
||||||
|
```
|
||||||
|
Skip tests (NOT recommended for PR validation):
|
||||||
|
```bash
|
||||||
|
mvn -q clean install -DskipTests
|
||||||
|
```
|
||||||
|
Run a single module:
|
||||||
|
```bash
|
||||||
|
mvn -q -pl core -am test
|
||||||
|
```
|
||||||
|
Generate JavaDoc (already bound in build):
|
||||||
|
```bash
|
||||||
|
mvn -q javadoc:javadoc
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Project Structure (High-level)
|
||||||
|
- core/ : Fundamental abstractions (Configuration, Value types, factories)
|
||||||
|
- features/ : Optional, orthogonal enhancements (validators, section, text, etc.)
|
||||||
|
- providers/ : Concrete persistence / parsing backends (yaml, gson, hocon, sql, mongodb, temp)
|
||||||
|
- demo/ : Usage demonstrations & sample scenarios
|
||||||
|
|
||||||
|
Rules:
|
||||||
|
- Core must not depend on feature or provider modules.
|
||||||
|
- Features must not form cycles; prefer depending only on core.
|
||||||
|
- Providers should keep external dependencies minimal and shaded/isolated only if necessary.
|
||||||
|
|
||||||
|
## 5. Branching & Workflow
|
||||||
|
- main (or master): Stable; only fast‑forward / squash from reviewed PRs.
|
||||||
|
- feature/<short-name>: New feature work. Open draft PR early for feedback.
|
||||||
|
- fix/<issue-id>-<slug>: Bug fix referencing an Issue.
|
||||||
|
- chore/<topic>: Build, infra, docs improvements.
|
||||||
|
|
||||||
|
Never force push to main. Force pushes allowed only to your own feature branches.
|
||||||
|
|
||||||
|
## 6. Issue Workflow
|
||||||
|
1. Search existing issues first to avoid duplication.
|
||||||
|
2. Provide reproduction steps (minimal code or config) for bugs.
|
||||||
|
3. Label suggestions as enhancement; performance items as perf.
|
||||||
|
4. For larger features, open a design issue summarizing: Problem, Motivation, Proposed API, Alternatives.
|
||||||
|
|
||||||
|
## 7. Pull Request Guidelines
|
||||||
|
Checklist before opening a PR:
|
||||||
|
- Linked to at least one Issue (unless trivial doc fix)
|
||||||
|
- Passes `mvn verify`
|
||||||
|
- Adds or updates tests covering new behavior / bug
|
||||||
|
- Includes JavaDoc / README / CHANGELOG fragment if user-facing
|
||||||
|
- No unrelated refactors or formatting churn
|
||||||
|
- Minimal diff: avoid reordering imports unless enforced by style
|
||||||
|
|
||||||
|
Review expectations:
|
||||||
|
- Maintainers strive to respond within 5 business days.
|
||||||
|
- Use constructive, action‑oriented comments.
|
||||||
|
- Resolve conversations or explain why not.
|
||||||
|
- Squash commits if they are noisy; retain meaningful logical grouping.
|
||||||
|
|
||||||
|
## 8. Commit Message Convention
|
||||||
|
Use Conventional Commits (https://www.conventionalcommits.org/) with optional scope:
|
||||||
|
```
|
||||||
|
<type>(<scope>): <short imperative summary>
|
||||||
|
|
||||||
|
<body>(optional)
|
||||||
|
|
||||||
|
<footer>(breaking changes, issue references)
|
||||||
|
```
|
||||||
|
Types used:
|
||||||
|
- feat: New feature (user visible)
|
||||||
|
- fix: Bug fix
|
||||||
|
- perf: Performance improvement
|
||||||
|
- refactor: Internal restructuring without behavior change
|
||||||
|
- docs: Documentation only
|
||||||
|
- test: Add or fix tests
|
||||||
|
- build: Build system or dependency changes
|
||||||
|
- ci: Continuous integration changes
|
||||||
|
- chore: Maintenance tasks
|
||||||
|
- style: Formatting (rare; avoid large style‑only changes)
|
||||||
|
|
||||||
|
Breaking changes: add `!` after type/scope or include `BREAKING CHANGE:` footer.
|
||||||
|
|
||||||
|
## 9. Coding Standards
|
||||||
|
- Java: Follow effective Java principles; prefer explicit types over inference for public APIs.
|
||||||
|
- Nullability: Use JetBrains annotations (`@NotNull`, `@Nullable`) where helpful.
|
||||||
|
- Immutability: Favor immutable value objects; avoid exposing mutable internal state.
|
||||||
|
- Exceptions: Use specific exception types; no swallowing silently. Validate inputs early.
|
||||||
|
- Logging: Keep core logging minimal; let consumers decide verbosity. Avoid println.
|
||||||
|
- APIs: Minimize surface; avoid exposing prematurely general interfaces.
|
||||||
|
- Annotations: Provide meaningful config path / comments metadata clearly.
|
||||||
|
|
||||||
|
### Style
|
||||||
|
- Indentation: 4 spaces.
|
||||||
|
- Line length guideline: ≤ 140 chars (soft limit).
|
||||||
|
- Avoid wildcard imports.
|
||||||
|
|
||||||
|
## 10. Testing Guidelines
|
||||||
|
- Use JUnit (current: JUnit 4). Prefer deterministic, isolated tests.
|
||||||
|
- Each bug fix must include a regression test failing before the fix.
|
||||||
|
- Avoid time‑sensitive sleeps; prefer deterministic constructs.
|
||||||
|
- Keep provider-specific integration tests under provider module.
|
||||||
|
- Use random data cautiously; if used, log seed for reproduction.
|
||||||
|
|
||||||
|
Command:
|
||||||
|
```bash
|
||||||
|
mvn -q test
|
||||||
|
```
|
||||||
|
|
||||||
|
## 11. Documentation & JavaDoc
|
||||||
|
- Public classes & methods: brief JavaDoc describing contract, thread-safety, nullability.
|
||||||
|
- Add code examples when clarifying complex usage.
|
||||||
|
- Update README or module README for new feature flags or environment variables.
|
||||||
|
- Keep demo module aligned with latest recommended usage.
|
||||||
|
|
||||||
|
## 12. Dependency Policy
|
||||||
|
- Keep transitive dependency footprint lean.
|
||||||
|
- No large frameworks for simple utilities.
|
||||||
|
- Justify each new dependency in PR description (purpose, size, maintenance risk).
|
||||||
|
- Prefer stable, well-adopted libraries with permissive licenses compatible with LGPL.
|
||||||
|
- Security-sensitive libs (parsers, DB drivers) should be periodically updated.
|
||||||
|
|
||||||
|
## 13. Versioning & Releases
|
||||||
|
- Follows Semantic Versioning (MAJOR.MINOR.PATCH).
|
||||||
|
- Public API additions => MINOR bump.
|
||||||
|
- Backwards-compatible bug fix => PATCH.
|
||||||
|
- Backwards-incompatible change => MAJOR (document rationale & migration).
|
||||||
|
- Release steps (maintainers):
|
||||||
|
1. Ensure main is green (CI all passing)
|
||||||
|
2. Update CHANGELOG (if present) or Release Notes draft
|
||||||
|
3. Bump versions via maven-release-plugin (ensure GPG & staging configured)
|
||||||
|
4. Tag + push; verify publication (Central / GitHub Packages)
|
||||||
|
5. Publish GitHub Release with highlights + migration notes
|
||||||
|
|
||||||
|
## 14. Performance Expectations
|
||||||
|
- Avoid unnecessary object churn in hot paths.
|
||||||
|
- Profile before large rewrites. Provide benchmark or allocation stats if claiming improvement.
|
||||||
|
- Defer I/O and heavy parsing until needed (lazy loading pattern).
|
||||||
|
|
||||||
|
## 15. Internationalization / Language
|
||||||
|
- Primary language: English for code, comments, issues, PRs.
|
||||||
|
- Chinese clarifications acceptable if accompanied by English.
|
||||||
|
|
||||||
|
## 16. FAQ for Contributors
|
||||||
|
Q: Can I add a new provider?
|
||||||
|
A: Yes—open a design Issue first summarizing data model, external dependencies, and test strategy.
|
||||||
|
|
||||||
|
Q: How do I mark experimental APIs?
|
||||||
|
A: Add JavaDoc: `@apiNote Experimental: subject to change without notice.` and avoid wide promotion.
|
||||||
|
|
||||||
|
Q: Why Java 8 target?
|
||||||
|
A: Maximizes compatibility across server & embedded environments.
|
||||||
|
|
||||||
|
## 17. Attribution
|
||||||
|
Portions inspired by widely adopted open-source guidelines (Kotlin, Spring, Apache projects) and Conventional Commits.
|
||||||
|
|
||||||
|
---
|
||||||
|
Thank you for helping build a robust configuration ecosystem!
|
||||||
|
|
||||||
@@ -6,7 +6,6 @@
|
|||||||
[](https://github.com/CarmJos/configured/actions/workflows/maven.yml)
|
[](https://github.com/CarmJos/configured/actions/workflows/maven.yml)
|
||||||
[](https://www.codefactor.io/repository/github/carmjos/configured)
|
[](https://www.codefactor.io/repository/github/carmjos/configured)
|
||||||

|

|
||||||

|
|
||||||
|
|
||||||
README LANGUAGES [ [**English**](README.md) | [中文](README_CN.md) ]
|
README LANGUAGES [ [**English**](README.md) | [中文](README_CN.md) ]
|
||||||
</div>
|
</div>
|
||||||
@@ -24,8 +23,8 @@ Supported **JSON**, **YAML**, **Hocon**, **TOML**, **SQL**, **MongoDB**... and m
|
|||||||
|
|
||||||
## Features & Advantages
|
## Features & Advantages
|
||||||
|
|
||||||
Supported [YAML](impl/yaml), [JSON](impl/json), [HOCON](impl/hocon) and [SQL](impl/sql) based configuration files
|
Supported [YAML](providers/yaml), [JSON](providers/json), [HOCON](providers/hocon) and [SQL](providers/sql)
|
||||||
format.
|
based configuration files format.
|
||||||
|
|
||||||
- Class-based mechanism for initializing, loading, retrieving, and updating configuration files, ensuring convenience
|
- Class-based mechanism for initializing, loading, retrieving, and updating configuration files, ensuring convenience
|
||||||
and efficiency.
|
and efficiency.
|
||||||
@@ -37,14 +36,14 @@ format.
|
|||||||
|
|
||||||
For the latest JavaDoc release, [CLICK HERE](https://CarmJos.github.io/configured).
|
For the latest JavaDoc release, [CLICK HERE](https://CarmJos.github.io/configured).
|
||||||
|
|
||||||
For a detailed development guide, [CLICK HERE](.doc/README.md).
|
For a detailed development guide, see [wiki](https://github.com/CarmJos/configured/wiki).
|
||||||
|
|
||||||
### Preview
|
### Preview
|
||||||
|
|
||||||
To quickly demonstrate the applicability of the project, here are a few practical demonstrations:
|
To quickly demonstrate the applicability of the project, here are a few practical demonstrations:
|
||||||
|
|
||||||
- [Database configuration.](demo/src/main/java/cc/carm/lib/configuration/demo/DatabaseConfiguration.java)
|
- [Database configuration.](demo/src/main/java/cc/carm/lib/configuration/demo/DatabaseConfiguration.java)
|
||||||
- [Demonstration of all types of configuration instance classes.](demo/src/main/java/cc/carm/lib/configuration/demo/tests/conf/DemoConfiguration.java)
|
- [Demonstration of configurations instance classes.](demo/src/main/java/cc/carm/lib/configuration/demo/tests/conf/DemoConfiguration.java)
|
||||||
|
|
||||||
Check out all code demonstrations [HERE](demo/src/main/java/cc/carm/lib/configuration/demo/DatabaseConfiguration.java).
|
Check out all code demonstrations [HERE](demo/src/main/java/cc/carm/lib/configuration/demo/DatabaseConfiguration.java).
|
||||||
For more examples, see the [Development Guide](.doc/README.md).
|
For more examples, see the [Development Guide](.doc/README.md).
|
||||||
@@ -250,7 +249,7 @@ with more platforms to be supported soon.
|
|||||||
|
|
||||||
## Support and Donation
|
## Support and Donation
|
||||||
|
|
||||||
If you appreciate this plugin, consider supporting me with a donation!
|
If you appreciate this plugin, consider supporting me with a [donation](https://github.com/sponsors/CarmJos)!
|
||||||
|
|
||||||
Thank you for supporting open-source projects!
|
Thank you for supporting open-source projects!
|
||||||
|
|
||||||
@@ -267,3 +266,4 @@ strong support and active contribution to this project!
|
|||||||
|
|
||||||
This project's source code is licensed under
|
This project's source code is licensed under
|
||||||
the [GNU LESSER GENERAL PUBLIC LICENSE](https://www.gnu.org/licenses/lgpl-3.0.html).
|
the [GNU LESSER GENERAL PUBLIC LICENSE](https://www.gnu.org/licenses/lgpl-3.0.html).
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -6,7 +6,6 @@
|
|||||||
[](https://github.com/CarmJos/configured/actions/workflows/maven.yml)
|
[](https://github.com/CarmJos/configured/actions/workflows/maven.yml)
|
||||||
[](https://www.codefactor.io/repository/github/carmjos/configured)
|
[](https://www.codefactor.io/repository/github/carmjos/configured)
|
||||||

|

|
||||||

|
|
||||||
|
|
||||||
README LANGUAGES [ [English](README.md) | [**中文**](README_CN.md) ]
|
README LANGUAGES [ [English](README.md) | [**中文**](README_CN.md) ]
|
||||||
|
|
||||||
@@ -42,7 +41,7 @@ README LANGUAGES [ [English](README.md) | [**中文**](README_CN.md) ]
|
|||||||
- [全种类配置实例类演示](demo/src/main/java/cc/carm/lib/configuration/demo/tests/conf/DemoConfiguration.java)
|
- [全种类配置实例类演示](demo/src/main/java/cc/carm/lib/configuration/demo/tests/conf/DemoConfiguration.java)
|
||||||
|
|
||||||
您可以 [点击这里](demo/src/main/java/cc/carm/lib/configuration/demo)
|
您可以 [点击这里](demo/src/main/java/cc/carm/lib/configuration/demo)
|
||||||
直接查看现有的代码演示,更多复杂情况演示详见 [开发介绍](.doc/README.md) 。
|
直接查看现有的代码演示,更多复杂情况演示详见 [开发介绍](https://github.com/CarmJos/configured/wiki) 。
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
|
||||||
@@ -269,7 +268,7 @@ configured for MineCraft!
|
|||||||
|
|
||||||
## 支持与捐赠
|
## 支持与捐赠
|
||||||
|
|
||||||
若您觉得本插件做的不错,您可以通过捐赠支持我!
|
若您觉得本插件做的不错,您可以通过[捐赠](https://github.com/sponsors/CarmJos)支持我!
|
||||||
|
|
||||||
感谢您对开源项目的支持!
|
感谢您对开源项目的支持!
|
||||||
|
|
||||||
|
|||||||
+102
@@ -0,0 +1,102 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
English is the authoritative language of this document.
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
We generally provide security fixes only for the latest released MINOR version (most recent tag on the default branch). Older versions may receive fixes only if the vulnerability is critical and a patch is low risk.
|
||||||
|
|
||||||
|
| Version | Status |
|
||||||
|
|----------|-------------------------|
|
||||||
|
| Latest | Security fixes |
|
||||||
|
| < Latest | Not routinely supported |
|
||||||
|
|
||||||
|
If you rely on an older version you are strongly encouraged to upgrade promptly after each release.
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
Please DO NOT open a public Issue for suspected security problems.
|
||||||
|
|
||||||
|
Instead, email: carm@carm.cc with:
|
||||||
|
|
||||||
|
- A clear description of the issue and potential impact
|
||||||
|
- Steps to reproduce (minimal code / configuration)
|
||||||
|
- Affected version(s) and environment (JDK, OS)
|
||||||
|
- Any known workarounds
|
||||||
|
- Preferred public credit name (optional)
|
||||||
|
|
||||||
|
You will receive an acknowledgement within 72 hours (workdays) confirming receipt.
|
||||||
|
|
||||||
|
## Assessment & Disclosure Process
|
||||||
|
|
||||||
|
1. Triage & validation (attempt reproduction, scope impact)
|
||||||
|
2. Determine severity (CVSS or qualitative: Low / Moderate / High / Critical)
|
||||||
|
3. Prepare a private fix / patch + regression tests
|
||||||
|
4. Coordinate an embargoed release window (typically ≤14 days after validation for High/Critical)
|
||||||
|
5. Release a new version (and possibly backport if warranted)
|
||||||
|
6. Publish security advisory (GitHub Security Advisory + Release Notes) including mitigation steps
|
||||||
|
|
||||||
|
We may reject reports that are clearly non‑security bugs (e.g., feature requests, performance tuning) or issues requiring unreasonable preconditions (e.g., attacker already has full local code execution).
|
||||||
|
|
||||||
|
## Non-Qualifying Issues (Examples)
|
||||||
|
|
||||||
|
- Missing rate limits on non-authenticated, non-state-changing operations
|
||||||
|
- Denial-of-service requiring unrealistic resource constraints or already solved via JVM flags
|
||||||
|
- Vulnerabilities only exploitable on unsupported / EOL Java versions
|
||||||
|
- Social engineering, SPF/DMARC issues beyond this codebase’s control
|
||||||
|
|
||||||
|
## Coordinated Disclosure
|
||||||
|
|
||||||
|
If you plan to blog or speak publicly about the vulnerability prior to patch availability, please coordinate timing so users can upgrade safely.
|
||||||
|
|
||||||
|
## Dependency Security
|
||||||
|
|
||||||
|
We periodically review dependency versions for CVEs. You can help by:
|
||||||
|
|
||||||
|
- Submitting PRs that upgrade vulnerable libraries with changelog & compatibility notes
|
||||||
|
- Avoiding unnecessary new dependencies
|
||||||
|
|
||||||
|
## Cryptographic Material
|
||||||
|
|
||||||
|
This project does not bundle custom cryptographic primitives. If you discover misuse of crypto APIs or insecure random number use in security-sensitive areas, treat it as a security report.
|
||||||
|
|
||||||
|
## Reporting Format Template (Recommended)
|
||||||
|
|
||||||
|
```
|
||||||
|
Subject: [Security Report] <short title>
|
||||||
|
|
||||||
|
Affected Component: (module / class)
|
||||||
|
Version(s) Tested: x.y.z (and earlier if known)
|
||||||
|
Environment: JDK x, OS
|
||||||
|
|
||||||
|
Summary:
|
||||||
|
Describe the vulnerability and impact.
|
||||||
|
|
||||||
|
Reproduction Steps:
|
||||||
|
1. ...
|
||||||
|
2. ...
|
||||||
|
3. ...
|
||||||
|
|
||||||
|
Expected vs Actual:
|
||||||
|
|
||||||
|
Potential Impact:
|
||||||
|
|
||||||
|
Workarounds / Mitigations (if any):
|
||||||
|
|
||||||
|
Credit: (name / handle / anonymous)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Credit & Acknowledgement
|
||||||
|
|
||||||
|
We will list (with permission) reporters who submit valid, first responsibly disclosed security issues in the release notes / advisory.
|
||||||
|
|
||||||
|
## GPG / Integrity
|
||||||
|
|
||||||
|
Release artifacts are signed (see project docs). Always verify signatures and checksums when consuming artifacts from Maven Central or GitHub Packages.
|
||||||
|
|
||||||
|
## Questions
|
||||||
|
|
||||||
|
For general (non-sensitive) questions, open an Issue labeled `question` rather than using the security email.
|
||||||
|
|
||||||
|
Thank you for helping keep the ecosystem safe.
|
||||||
|
|
||||||
+8
-1
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<properties>
|
<properties>
|
||||||
@@ -18,6 +18,13 @@
|
|||||||
<artifactId>configured-core</artifactId>
|
<artifactId>configured-core</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Core</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>
|
||||||
|
The core module of Configured framework,
|
||||||
|
providing essential configuration management functionality.
|
||||||
|
</description>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ package cc.carm.lib.configuration;
|
|||||||
* The root interface of the configuration file interfaces,
|
* The root interface of the configuration file interfaces,
|
||||||
* which is used to label a class as a configuration.
|
* which is used to label a class as a configuration.
|
||||||
*/
|
*/
|
||||||
public interface Configuration { }
|
public interface Configuration {
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,16 +2,19 @@ package cc.carm.lib.configuration.adapter;
|
|||||||
|
|
||||||
import cc.carm.lib.configuration.function.DataFunction;
|
import cc.carm.lib.configuration.function.DataFunction;
|
||||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
|
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.lang.reflect.Array;
|
||||||
import java.util.HashSet;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.util.Set;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
public class ValueAdapterRegistry {
|
public class ValueAdapterRegistry {
|
||||||
|
|
||||||
protected final Set<ValueAdapter<?>> adapters = new HashSet<>();
|
protected final Set<ValueAdapter<?>> adapters = new HashSet<>();
|
||||||
|
protected final Map<ValueType<?>, ValueAdapter<?>> adapterCache = new HashMap<>();
|
||||||
|
|
||||||
public <FROM, TO> void register(@NotNull Class<FROM> from, @NotNull Class<TO> to,
|
public <FROM, TO> void register(@NotNull Class<FROM> from, @NotNull Class<TO> to,
|
||||||
@Nullable DataFunction<FROM, TO> parser,
|
@Nullable DataFunction<FROM, TO> parser,
|
||||||
@@ -32,6 +35,7 @@ public class ValueAdapterRegistry {
|
|||||||
|
|
||||||
public void register(@NotNull ValueAdapter<?>... adapter) {
|
public void register(@NotNull ValueAdapter<?>... adapter) {
|
||||||
adapters.addAll(Arrays.asList(adapter));
|
adapters.addAll(Arrays.asList(adapter));
|
||||||
|
adapterCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> void register(@NotNull Class<T> type, @NotNull ValueSerializer<T> serializer) {
|
public <T> void register(@NotNull Class<T> type, @NotNull ValueSerializer<T> serializer) {
|
||||||
@@ -79,19 +83,31 @@ public class ValueAdapterRegistry {
|
|||||||
|
|
||||||
public void unregister(@NotNull ValueType<?> type) {
|
public void unregister(@NotNull ValueType<?> type) {
|
||||||
adapters.removeIf(adapter -> adapter.type().equals(type));
|
adapters.removeIf(adapter -> adapter.type().equals(type));
|
||||||
|
adapterCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> @Nullable ValueAdapter<T> adapterOf(@NotNull ValueType<T> type) {
|
public <T> @Nullable ValueAdapter<T> adapterOf(@NotNull ValueType<T> type) {
|
||||||
ValueAdapter<?> matched = adapters.stream()
|
if (adapterCache.containsKey(type)) {
|
||||||
.filter(adapter -> adapter.type().equals(type))
|
return (ValueAdapter<T>) adapterCache.get(type);
|
||||||
.findFirst().orElse(null);
|
}
|
||||||
if (matched != null) return (ValueAdapter<T>) matched;
|
|
||||||
|
|
||||||
// If no adapter found, try to find the adapter for the super type
|
for (ValueAdapter<?> adapter : adapters) {
|
||||||
return (ValueAdapter<T>) adapters.stream()
|
if (adapter.type().equals(type)) {
|
||||||
.filter(adapter -> adapter.type().isSubtypeOf(type))
|
adapterCache.put(type, adapter);
|
||||||
.findFirst().orElse(null);
|
return (ValueAdapter<T>) adapter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ValueAdapter<?> adapter : adapters) {
|
||||||
|
if (adapter.type().isSubtypeOf(type)) {
|
||||||
|
adapterCache.put(type, adapter);
|
||||||
|
return (ValueAdapter<T>) adapter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
adapterCache.put(type, null);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> ValueAdapter<T> adapterOf(@NotNull T value) {
|
public <T> ValueAdapter<T> adapterOf(@NotNull T value) {
|
||||||
@@ -107,21 +123,186 @@ public class ValueAdapterRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public <T> T deserialize(@NotNull ConfigurationHolder<?> holder, @NotNull ValueType<T> type, @Nullable Object source) throws Exception {
|
public <T> T deserialize(@NotNull ConfigurationHolder<?> holder, @NotNull ValueType<T> type, @Nullable Object source) throws Exception {
|
||||||
if (source == null) return null; // Null check
|
if (source == null) return null;
|
||||||
if (type.isInstance(source)) return type.cast(source); // Not required to deserialize
|
|
||||||
|
Type typeInstance = type.getType();
|
||||||
|
if (!(typeInstance instanceof ParameterizedType) && type.isInstance(source)) {
|
||||||
|
return type.cast(source);
|
||||||
|
}
|
||||||
|
|
||||||
ValueAdapter<T> adapter = adapterOf(type);
|
ValueAdapter<T> adapter = adapterOf(type);
|
||||||
if (adapter == null) throw new RuntimeException("No adapter for type " + type);
|
if (adapter != null) {
|
||||||
return adapter.parse(holder, type, source);
|
return adapter.parse(holder, type, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return deserializeWithoutAdapter(holder, type, source, typeInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T deserializeWithoutAdapter(@NotNull ConfigurationHolder<?> holder, @NotNull ValueType<T> type,
|
||||||
|
@NotNull Object source, @NotNull Type typeInstance) throws Exception {
|
||||||
|
Class<?> rawType = type.getRawType();
|
||||||
|
|
||||||
|
if (rawType.isArray()) {
|
||||||
|
return deserializeArray(holder, type, source, rawType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeInstance instanceof ParameterizedType) {
|
||||||
|
return deserializeParameterized(holder, type, source, (ParameterizedType) typeInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("No adapter for type " + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T deserializeArray(@NotNull ConfigurationHolder<?> holder, @NotNull ValueType<T> type,
|
||||||
|
@NotNull Object source, @NotNull Class<?> rawType) throws Exception {
|
||||||
|
List<?> list;
|
||||||
|
if (source instanceof List<?>) {
|
||||||
|
list = (List<?>) source;
|
||||||
|
} else {
|
||||||
|
// For non-list sources, treat as single element array
|
||||||
|
list = Collections.singletonList(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = list.size();
|
||||||
|
if (size == 0) {
|
||||||
|
return type.cast(Array.newInstance(rawType.getComponentType(), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<?> componentType = rawType.getComponentType();
|
||||||
|
Object[] array = (Object[]) Array.newInstance(componentType, size);
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
array[i] = deserialize(holder, componentType, list.get(i));
|
||||||
|
}
|
||||||
|
return type.cast(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T> T deserializeParameterized(@NotNull ConfigurationHolder<?> holder, @NotNull ValueType<T> type,
|
||||||
|
@NotNull Object source, @NotNull ParameterizedType pt) throws Exception {
|
||||||
|
Type rawType = pt.getRawType();
|
||||||
|
Type[] typeArgs = pt.getActualTypeArguments();
|
||||||
|
|
||||||
|
if (rawType == List.class || rawType == Collection.class || rawType == ArrayList.class) {
|
||||||
|
return (T) deserializeCollection(holder, source, typeArgs[0], ArrayList::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawType == Set.class || rawType == HashSet.class) {
|
||||||
|
return (T) deserializeCollection(holder, source, typeArgs[0], HashSet::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawType == Map.class || rawType == LinkedHashMap.class) {
|
||||||
|
return (T) deserializeMap(holder, source, typeArgs[0], typeArgs[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("No adapter for parameterized type " + type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<?> deserializeCollection(@NotNull ConfigurationHolder<?> holder, @NotNull Object source,
|
||||||
|
@NotNull Type elementType, @NotNull java.util.function.Supplier<Collection<Object>> collectionFactory) throws Exception {
|
||||||
|
ValueType<?> elementValueType = ValueType.of(elementType);
|
||||||
|
List<?> sourceList = deserializeList(holder, elementValueType, source);
|
||||||
|
|
||||||
|
if (sourceList.isEmpty()) {
|
||||||
|
return collectionFactory.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<Object> result = collectionFactory.get();
|
||||||
|
if (result instanceof ArrayList) {
|
||||||
|
((ArrayList<Object>) result).ensureCapacity(sourceList.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Object item : sourceList) {
|
||||||
|
Object deserializedItem = deserialize(holder, elementValueType, item);
|
||||||
|
if (deserializedItem != null) {
|
||||||
|
result.add(deserializedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Object, Object> deserializeMap(@NotNull ConfigurationHolder<?> holder, @NotNull Object source,
|
||||||
|
@NotNull Type keyType, @NotNull Type valueType) throws Exception {
|
||||||
|
Map<?, ?> sourceMap;
|
||||||
|
if (source instanceof Map<?, ?>) {
|
||||||
|
sourceMap = (Map<?, ?>) source;
|
||||||
|
} else if (source instanceof ConfigureSection) {
|
||||||
|
sourceMap = ((ConfigureSection) source).asMap();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Cannot deserialize to Map from " + source.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
int mapSize = sourceMap.size();
|
||||||
|
if (mapSize == 0) {
|
||||||
|
return new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueType<?> keyValueType = ValueType.of(keyType);
|
||||||
|
ValueType<?> valueValueType = ValueType.of(valueType);
|
||||||
|
Map<Object, Object> resultMap = new LinkedHashMap<>(mapSize);
|
||||||
|
|
||||||
|
for (Map.Entry<?, ?> entry : sourceMap.entrySet()) {
|
||||||
|
Object key = deserialize(holder, keyValueType, entry.getKey());
|
||||||
|
Object value = deserialize(holder, valueValueType, entry.getValue());
|
||||||
|
resultMap.put(key, value);
|
||||||
|
}
|
||||||
|
return resultMap;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public <T> Object serialize(@NotNull ConfigurationHolder<?> holder, @Nullable T value) throws Exception {
|
public <T> Object serialize(@NotNull ConfigurationHolder<?> holder, @Nullable T value) throws Exception {
|
||||||
if (value == null) return null; // Null check
|
if (value == null) return null; // Null check
|
||||||
|
|
||||||
ValueType<T> type = ValueType.of(value);
|
ValueType<T> type = ValueType.of(value);
|
||||||
ValueAdapter<T> adapter = adapterOf(type);
|
ValueAdapter<T> adapter = adapterOf(type);
|
||||||
if (adapter == null) return value; // No adapters, try to return the original value
|
if (adapter != null) return adapter.serialize(holder, type, value);
|
||||||
return adapter.serialize(holder, type, value);
|
|
||||||
|
if (value.getClass().isArray()) {
|
||||||
|
Object[] array = (Object[]) value;
|
||||||
|
List<Object> serializedList = new ArrayList<>(array.length);
|
||||||
|
for (Object item : array) {
|
||||||
|
serializedList.add(serialize(holder, item));
|
||||||
|
}
|
||||||
|
return serializedList;
|
||||||
|
} else if (value instanceof Collection<?>) {
|
||||||
|
Collection<?> collection = (Collection<?>) value;
|
||||||
|
List<Object> serializedList = new ArrayList<>(collection.size());
|
||||||
|
for (Object item : collection) {
|
||||||
|
serializedList.add(serialize(holder, item));
|
||||||
|
}
|
||||||
|
return serializedList;
|
||||||
|
} else if (value instanceof Map<?, ?>) {
|
||||||
|
Map<?, ?> map = (Map<?, ?>) value;
|
||||||
|
Map<Object, Object> serializedMap = new LinkedHashMap<>(map.size());
|
||||||
|
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||||
|
Object key = serialize(holder, entry.getKey());
|
||||||
|
Object val = serialize(holder, entry.getValue());
|
||||||
|
serializedMap.put(key, val);
|
||||||
|
}
|
||||||
|
return serializedMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return value; // No adapters, and cannot handle, try to return the original value
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T> List<T> deserializeList(@NotNull ConfigurationHolder<?> holder,
|
||||||
|
@NotNull ValueType<T> type, @Nullable Object source) throws Exception {
|
||||||
|
if (source == null) return Collections.emptyList(); // Null check
|
||||||
|
if (source instanceof List<?>) {
|
||||||
|
List<?> list = (List<?>) source;
|
||||||
|
List<T> result = new ArrayList<>(list.size());
|
||||||
|
for (Object item : list) {
|
||||||
|
T deserializedItem = deserialize(holder, type, item);
|
||||||
|
if (deserializedItem != null) {
|
||||||
|
result.add(deserializedItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else { // Maybe singleton? Let's try to deserialize it as a single element list
|
||||||
|
T deserializedItem = deserialize(holder, type, source);
|
||||||
|
if (deserializedItem != null) {
|
||||||
|
return Collections.singletonList(deserializedItem);
|
||||||
|
} else return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,26 @@
|
|||||||
package cc.carm.lib.configuration.adapter;
|
package cc.carm.lib.configuration.adapter;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to get the generic type.
|
* {@link ValueType} used to get the generic type of the value,
|
||||||
|
* It can be used to check if an object is an instance of a specific type,
|
||||||
|
* and to cast objects to the correct type.
|
||||||
|
* <p>
|
||||||
|
* Java's type system is not capable of retaining generic type information at runtime.
|
||||||
|
* This class is used to represent a type with its generic parameters.
|
||||||
|
* </p>
|
||||||
*/
|
*/
|
||||||
public abstract class ValueType<T> {
|
public abstract class ValueType<T> {
|
||||||
|
|
||||||
|
public static final ValueType<Object> OBJECT = ofPrimitiveType(Object.class);
|
||||||
public static final ValueType<String> STRING = ofPrimitiveType(String.class);
|
public static final ValueType<String> STRING = ofPrimitiveType(String.class);
|
||||||
public static final ValueType<Integer> INTEGER = ofPrimitiveType(Integer.class);
|
public static final ValueType<Integer> INTEGER = ofPrimitiveType(Integer.class);
|
||||||
public static final ValueType<Integer> INTEGER_TYPE = ofPrimitiveType(int.class);
|
public static final ValueType<Integer> INTEGER_TYPE = ofPrimitiveType(int.class);
|
||||||
@@ -43,7 +52,7 @@ public abstract class ValueType<T> {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> ValueType<T> of(final Type type) {
|
public static <T> ValueType<T> of(final Type type) {
|
||||||
if (type == null) throw new NullPointerException("Type cannot be null");
|
if (type == null) throw new NullPointerException("Type cannot be null");
|
||||||
if (type instanceof Class<?>) { // Try handle primitive types
|
if (type instanceof Class<?>) { // Try to fast handle primitive types
|
||||||
Class<?> clazz = (Class<?>) type;
|
Class<?> clazz = (Class<?>) type;
|
||||||
for (ValueType<?> valueType : PRIMITIVE_TYPES) {
|
for (ValueType<?> valueType : PRIMITIVE_TYPES) {
|
||||||
if (valueType.getRawType() == clazz) {
|
if (valueType.getRawType() == clazz) {
|
||||||
@@ -63,6 +72,18 @@ public abstract class ValueType<T> {
|
|||||||
return of(List.class, paramType);
|
return of(List.class, paramType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> ValueType<List<T>> ofList(final @NotNull ValueType<T> paramType) {
|
||||||
|
return of(List.class, paramType.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <K, V> ValueType<Map<K, V>> ofMap(final @NotNull Class<K> keyType, final @NotNull Class<V> valueType) {
|
||||||
|
return of(Map.class, keyType, valueType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <K, V> ValueType<Map<K, V>> ofMap(final @NotNull ValueType<K> keyType, final @NotNull ValueType<V> valueType) {
|
||||||
|
return of(Map.class, keyType.getType(), valueType.getType());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the generic type of the complex type.
|
* Get the generic type of the complex type.
|
||||||
*
|
*
|
||||||
@@ -91,6 +112,7 @@ public abstract class ValueType<T> {
|
|||||||
return of(parameterizedType);
|
return of(parameterizedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
private static <T> ValueType<T> ofPrimitiveType(Class<T> clazz) {
|
private static <T> ValueType<T> ofPrimitiveType(Class<T> clazz) {
|
||||||
return new ValueType<T>(clazz) {
|
return new ValueType<T>(clazz) {
|
||||||
};
|
};
|
||||||
@@ -110,40 +132,65 @@ public abstract class ValueType<T> {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this ValueType is a subtype of the given Class.
|
||||||
|
*
|
||||||
|
* @param target The target Class to check against
|
||||||
|
* @return true if this ValueType is a subtype of the target Class, false otherwise
|
||||||
|
*/
|
||||||
public boolean isSubtypeOf(Class<?> target) {
|
public boolean isSubtypeOf(Class<?> target) {
|
||||||
Class<?> rawType = getRawType();
|
Class<?> rawType = getRawType();
|
||||||
return target.isAssignableFrom(rawType);
|
return target.isAssignableFrom(rawType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this ValueType is a subtype of the given ValueType.
|
||||||
|
*
|
||||||
|
* @param target The target ValueType to check against
|
||||||
|
* @return true if this ValueType is a subtype of the target, false otherwise
|
||||||
|
*/
|
||||||
public boolean isSubtypeOf(ValueType<?> target) {
|
public boolean isSubtypeOf(ValueType<?> target) {
|
||||||
return target.isSubtypeOf(getRawType());
|
return target.isSubtypeOf(getRawType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given object is an instance of the type represented by this ValueType.
|
||||||
|
*
|
||||||
|
* @param obj The object to check
|
||||||
|
* @return true if the object is an instance of the type, false otherwise
|
||||||
|
*/
|
||||||
public boolean isInstance(Object obj) {
|
public boolean isInstance(Object obj) {
|
||||||
return obj != null && getRawType().isInstance(obj);
|
return obj != null && getRawType().isInstance(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 提取当前 ValueType 的原始类型(Class 对象)。
|
* Extracts the raw type from the generic type.
|
||||||
*
|
*
|
||||||
* @return 对应的 Class 对象
|
* @return The raw type of the generic type
|
||||||
* @throws IllegalStateException 如果无法提取出原始类型
|
* @throws IllegalStateException if the type is not a Class or ParameterizedType
|
||||||
*/
|
*/
|
||||||
public Class<?> getRawType() {
|
@SuppressWarnings("unchecked")
|
||||||
|
public Class<T> getRawType() {
|
||||||
if (type instanceof Class<?>) {
|
if (type instanceof Class<?>) {
|
||||||
return (Class<?>) type;
|
return (Class<T>) type;
|
||||||
}
|
}
|
||||||
if (type instanceof ParameterizedType) {
|
if (type instanceof ParameterizedType) {
|
||||||
ParameterizedType pt = (ParameterizedType) type;
|
ParameterizedType pt = (ParameterizedType) type;
|
||||||
Type raw = pt.getRawType();
|
Type raw = pt.getRawType();
|
||||||
if (raw instanceof Class<?>) {
|
if (raw instanceof Class<?>) {
|
||||||
return (Class<?>) raw;
|
return (Class<T>) raw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Unsupported type: " + type);
|
throw new IllegalStateException("Unsupported type: " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Casts the object to the type represented by this ValueType.
|
||||||
|
*
|
||||||
|
* @param obj The object to cast
|
||||||
|
* @return The object cast to the type represented by this ValueType
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public T cast(Object obj) {
|
public T cast(Object obj) {
|
||||||
if (!isInstance(obj)) {
|
if (!isInstance(obj)) {
|
||||||
@@ -152,6 +199,12 @@ public abstract class ValueType<T> {
|
|||||||
return (T) obj;
|
return (T) obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the type.
|
||||||
|
* Like "{@code java.util.List<java.lang.String>}" or "java.lang.Integer".
|
||||||
|
*
|
||||||
|
* @return String representation of the type
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (type instanceof Class<?>) {
|
if (type instanceof Class<?>) {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import cc.carm.lib.configuration.source.meta.ConfigurationMetadata;
|
|||||||
import cc.carm.lib.configuration.value.ConfigValue;
|
import cc.carm.lib.configuration.value.ConfigValue;
|
||||||
import cc.carm.lib.configuration.value.ValueManifest;
|
import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.NotNullByDefault;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
@@ -17,7 +16,6 @@ import java.util.function.Consumer;
|
|||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@NotNullByDefault
|
|
||||||
public abstract class AbstractConfigBuilder<
|
public abstract class AbstractConfigBuilder<
|
||||||
TYPE, UNIT, RESULT extends ConfigValue<TYPE, UNIT>, HOLDER extends ConfigurationHolder<?>,
|
TYPE, UNIT, RESULT extends ConfigValue<TYPE, UNIT>, HOLDER extends ConfigurationHolder<?>,
|
||||||
SELF extends AbstractConfigBuilder<TYPE, UNIT, RESULT, HOLDER, SELF>
|
SELF extends AbstractConfigBuilder<TYPE, UNIT, RESULT, HOLDER, SELF>
|
||||||
|
|||||||
+55
@@ -0,0 +1,55 @@
|
|||||||
|
package cc.carm.lib.configuration.builder.collection;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueType;
|
||||||
|
import cc.carm.lib.configuration.builder.impl.AbstractSectionBuilder;
|
||||||
|
import cc.carm.lib.configuration.function.ValueHandler;
|
||||||
|
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||||
|
import cc.carm.lib.configuration.value.impl.CollectionConfigValue;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public abstract class SectionCollectionBuilder<
|
||||||
|
V, C extends Collection<V>,
|
||||||
|
RESULT extends CollectionConfigValue<V, C, ?>,
|
||||||
|
SELF extends SectionCollectionBuilder<V, C, RESULT, SELF>
|
||||||
|
> extends AbstractSectionBuilder<C, V, RESULT, SELF> {
|
||||||
|
|
||||||
|
protected @NotNull Supplier<? extends C> constructor;
|
||||||
|
|
||||||
|
public SectionCollectionBuilder(@NotNull Supplier<? extends C> constructor,
|
||||||
|
@NotNull ValueType<V> paramType,
|
||||||
|
@NotNull ValueHandler<ConfigureSection, V> parser,
|
||||||
|
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer) {
|
||||||
|
super(new ValueType<C>() {
|
||||||
|
}, paramType, parser, serializer);
|
||||||
|
this.constructor = constructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final @NotNull SELF defaults(@NotNull V... values) {
|
||||||
|
return defaults(c -> c.addAll(Arrays.asList(values)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public final @NotNull SELF defaults(@NotNull Consumer<C> constructor) {
|
||||||
|
return defaults(() -> {
|
||||||
|
C collection = this.constructor.get();
|
||||||
|
constructor.accept(collection);
|
||||||
|
return collection;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public SELF constructor(@NotNull Supplier<? extends C> constructor) {
|
||||||
|
this.constructor = constructor;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SELF construct(@NotNull C collection) {
|
||||||
|
return constructor(() -> collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+138
@@ -0,0 +1,138 @@
|
|||||||
|
package cc.carm.lib.configuration.builder.collection;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueType;
|
||||||
|
import cc.carm.lib.configuration.function.ValueHandler;
|
||||||
|
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||||
|
import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
|
import cc.carm.lib.configuration.value.impl.CollectionConfigValue;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class SimpleCollectionCreator<V, C extends Collection<V>, RESULT extends CollectionConfigValue<V, C, ?>> {
|
||||||
|
|
||||||
|
public static <V, C extends Collection<V>, RESULT extends CollectionConfigValue<V, C, ?>>
|
||||||
|
@NotNull SimpleCollectionCreator<V, C, RESULT> create(
|
||||||
|
@NotNull ValueType<V> type,
|
||||||
|
@NotNull Supplier<? extends C> defaultConstructor,
|
||||||
|
@NotNull CollectionValueFactory<V, C, RESULT> factory) {
|
||||||
|
return new SimpleCollectionCreator<>(type, defaultConstructor, factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final @NotNull Supplier<? extends C> defaultConstructor;
|
||||||
|
protected final @NotNull ValueType<V> type;
|
||||||
|
|
||||||
|
protected final @NotNull CollectionValueFactory<V, C, RESULT> factory;
|
||||||
|
|
||||||
|
public SimpleCollectionCreator(@NotNull ValueType<V> type,
|
||||||
|
@NotNull Supplier<? extends C> defaultConstructor,
|
||||||
|
@NotNull CollectionValueFactory<V, C, RESULT> factory) {
|
||||||
|
this.defaultConstructor = defaultConstructor;
|
||||||
|
this.type = type;
|
||||||
|
this.factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <S> @NotNull Source<S, V, C, RESULT> from(@NotNull Class<S> sourceType) {
|
||||||
|
return from(ValueType.of(sourceType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <S> @NotNull Source<S, V, C, RESULT> from(@NotNull ValueType<S> sourceType) {
|
||||||
|
return new Source<S, V, C, RESULT>(
|
||||||
|
defaultConstructor, sourceType, type,
|
||||||
|
ValueHandler.required(type),
|
||||||
|
ValueHandler.required(sourceType),
|
||||||
|
factory
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull SimpleCollectionCreator.Source<Object, V, C, RESULT> fromObject() {
|
||||||
|
return new Source<Object, V, C, RESULT>(
|
||||||
|
defaultConstructor, ValueType.OBJECT, type,
|
||||||
|
ValueHandler.deserialize(type), ValueHandler.toObject(),
|
||||||
|
factory
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull SimpleCollectionCreator.Source<String, V, C, RESULT> fromString() {
|
||||||
|
return new Source<String, V, C, RESULT>(
|
||||||
|
defaultConstructor, ValueType.STRING, type,
|
||||||
|
ValueHandler.required(type), ValueHandler.stringValue(),
|
||||||
|
factory
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull SimpleCollectionCreator.Section<V, C, RESULT> fromSection() {
|
||||||
|
return new Section<V, C, RESULT>(
|
||||||
|
defaultConstructor, type,
|
||||||
|
ValueHandler.required(type), ValueHandler.required(),
|
||||||
|
factory
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface CollectionValueFactory<V, C, RESULT> {
|
||||||
|
@NotNull RESULT build(
|
||||||
|
@NotNull ValueManifest<C, V> manifest,
|
||||||
|
@NotNull Supplier<? extends C> constructor,
|
||||||
|
@NotNull ValueAdapter<V> paramAdapter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Source<SOURCE, V, C extends Collection<V>, RESULT extends CollectionConfigValue<V, C, ?>>
|
||||||
|
extends SourceCollectionBuilder<SOURCE, V, C, RESULT, Source<SOURCE, V, C, RESULT>> {
|
||||||
|
|
||||||
|
protected final @NotNull CollectionValueFactory<V, C, RESULT> factory;
|
||||||
|
|
||||||
|
public Source(
|
||||||
|
@NotNull Supplier<? extends C> constructor,
|
||||||
|
@NotNull ValueType<SOURCE> sourceType,
|
||||||
|
@NotNull ValueType<V> paramType,
|
||||||
|
@NotNull ValueHandler<SOURCE, V> parser,
|
||||||
|
@NotNull ValueHandler<V, SOURCE> serializer,
|
||||||
|
@NotNull CollectionValueFactory<V, C, RESULT> factory) {
|
||||||
|
super(constructor, sourceType, paramType, parser, serializer);
|
||||||
|
this.factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @NotNull SimpleCollectionCreator.Source<SOURCE, V, C, RESULT> self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull RESULT build() {
|
||||||
|
return factory.build(buildManifest(), constructor, buildAdapter());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Section<V, C extends Collection<V>, RESULT extends CollectionConfigValue<V, C, ?>>
|
||||||
|
extends SectionCollectionBuilder<V, C, RESULT, Section<V, C, RESULT>> {
|
||||||
|
protected final @NotNull CollectionValueFactory<V, C, RESULT> factory;
|
||||||
|
|
||||||
|
public Section(
|
||||||
|
@NotNull Supplier<? extends C> constructor,
|
||||||
|
@NotNull ValueType<V> paramType,
|
||||||
|
@NotNull ValueHandler<ConfigureSection, V> parser,
|
||||||
|
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer,
|
||||||
|
@NotNull CollectionValueFactory<V, C, RESULT> factory) {
|
||||||
|
super(constructor, paramType, parser, serializer);
|
||||||
|
this.factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @NotNull SimpleCollectionCreator.Section<V, C, RESULT> self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull RESULT build() {
|
||||||
|
return factory.build(buildManifest(), constructor, buildAdapter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
package cc.carm.lib.configuration.builder.collection;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueType;
|
||||||
|
import cc.carm.lib.configuration.builder.impl.AbstractSourceBuilder;
|
||||||
|
import cc.carm.lib.configuration.function.ValueHandler;
|
||||||
|
import cc.carm.lib.configuration.value.impl.CollectionConfigValue;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public abstract class SourceCollectionBuilder<
|
||||||
|
SOURCE, V, C extends Collection<V>,
|
||||||
|
RESULT extends CollectionConfigValue<V, C, ?>,
|
||||||
|
SELF extends SourceCollectionBuilder<SOURCE, V, C, RESULT, SELF>
|
||||||
|
>
|
||||||
|
extends AbstractSourceBuilder<C, SOURCE, V, RESULT, SELF> {
|
||||||
|
|
||||||
|
protected @NotNull Supplier<? extends C> constructor;
|
||||||
|
|
||||||
|
public SourceCollectionBuilder(@NotNull Supplier<? extends C> constructor,
|
||||||
|
@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<V> paramType,
|
||||||
|
@NotNull ValueHandler<SOURCE, V> parser, @NotNull ValueHandler<V, SOURCE> serializer) {
|
||||||
|
super(new ValueType<C>() {
|
||||||
|
}, sourceType, paramType, parser, serializer);
|
||||||
|
this.constructor = constructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final @NotNull SELF defaults(@NotNull V... values) {
|
||||||
|
return defaults(c -> c.addAll(Arrays.asList(values)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public final @NotNull SELF defaults(@NotNull Consumer<C> constructor) {
|
||||||
|
return defaults(() -> {
|
||||||
|
C collection = this.constructor.get();
|
||||||
|
constructor.accept(collection);
|
||||||
|
return collection;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public SELF constructor(@NotNull Supplier<? extends C> constructor) {
|
||||||
|
this.constructor = constructor;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SELF construct(@NotNull C collection) {
|
||||||
|
return constructor(() -> collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+26
-15
@@ -1,6 +1,8 @@
|
|||||||
package cc.carm.lib.configuration.builder.impl;
|
package cc.carm.lib.configuration.builder.impl;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueParser;
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueSerializer;
|
||||||
import cc.carm.lib.configuration.adapter.ValueType;
|
import cc.carm.lib.configuration.adapter.ValueType;
|
||||||
import cc.carm.lib.configuration.builder.CommonConfigBuilder;
|
import cc.carm.lib.configuration.builder.CommonConfigBuilder;
|
||||||
import cc.carm.lib.configuration.function.DataFunction;
|
import cc.carm.lib.configuration.function.DataFunction;
|
||||||
@@ -15,8 +17,11 @@ public abstract class AbstractSourceBuilder<
|
|||||||
|
|
||||||
protected final @NotNull ValueType<SOURCE> sourceType;
|
protected final @NotNull ValueType<SOURCE> sourceType;
|
||||||
protected final @NotNull ValueType<UNIT> paramType;
|
protected final @NotNull ValueType<UNIT> paramType;
|
||||||
protected @NotNull ValueHandler<SOURCE, UNIT> valueParser;
|
|
||||||
protected @NotNull ValueHandler<UNIT, SOURCE> valueSerializer;
|
@SuppressWarnings("NotNullFieldNotInitialized") // Already initialized in constructor
|
||||||
|
protected @NotNull ValueParser<UNIT> valueParser;
|
||||||
|
@SuppressWarnings("NotNullFieldNotInitialized") // Already initialized in constructor
|
||||||
|
protected @NotNull ValueSerializer<UNIT> valueSerializer;
|
||||||
|
|
||||||
protected AbstractSourceBuilder(@NotNull ValueType<V> type,
|
protected AbstractSourceBuilder(@NotNull ValueType<V> type,
|
||||||
@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<UNIT> paramType,
|
@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<UNIT> paramType,
|
||||||
@@ -25,8 +30,8 @@ public abstract class AbstractSourceBuilder<
|
|||||||
super(type);
|
super(type);
|
||||||
this.sourceType = sourceType;
|
this.sourceType = sourceType;
|
||||||
this.paramType = paramType;
|
this.paramType = paramType;
|
||||||
this.valueParser = parser;
|
parse(parser);
|
||||||
this.valueSerializer = serializer;
|
serialize(serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull SELF parse(@NotNull DataFunction<SOURCE, UNIT> parser) {
|
public @NotNull SELF parse(@NotNull DataFunction<SOURCE, UNIT> parser) {
|
||||||
@@ -34,29 +39,35 @@ public abstract class AbstractSourceBuilder<
|
|||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull SELF parse(@NotNull ValueHandler<SOURCE, UNIT> parser) {
|
public @NotNull SELF parse(@NotNull ValueHandler<SOURCE, UNIT> parser) {
|
||||||
|
return parser((holder, type, data) -> {
|
||||||
|
SOURCE source = holder.deserialize(this.sourceType, data);
|
||||||
|
return parser.handle(holder, source);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull SELF parser(@NotNull ValueParser<UNIT> parser) {
|
||||||
this.valueParser = parser;
|
this.valueParser = parser;
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull SELF serialize(@NotNull ValueHandler<UNIT, SOURCE> serializer) {
|
public @NotNull SELF serialize(@NotNull ValueHandler<UNIT, SOURCE> serializer) {
|
||||||
this.valueSerializer = serializer;
|
return serializer((holder, type, data) -> {
|
||||||
return self();
|
SOURCE source = serializer.handle(holder, data);
|
||||||
|
return holder.serialize(source);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull SELF serialize(@NotNull DataFunction<UNIT, SOURCE> serializer) {
|
public @NotNull SELF serialize(@NotNull DataFunction<UNIT, SOURCE> serializer) {
|
||||||
return serialize((p, value) -> serializer.handle(value));
|
return serialize((p, value) -> serializer.handle(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @NotNull SELF serializer(@NotNull ValueSerializer<UNIT> serializer) {
|
||||||
|
this.valueSerializer = serializer;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
protected ValueAdapter<UNIT> buildAdapter() {
|
protected ValueAdapter<UNIT> buildAdapter() {
|
||||||
return new ValueAdapter<>(this.paramType)
|
return new ValueAdapter<>(this.paramType, this.valueSerializer, this.valueParser);
|
||||||
.parser((holder, type, data) -> {
|
|
||||||
SOURCE source = holder.deserialize(this.sourceType, data);
|
|
||||||
return this.valueParser.handle(holder, source);
|
|
||||||
})
|
|
||||||
.serializer((holder, type, data) -> {
|
|
||||||
SOURCE source = this.valueSerializer.handle(holder, data);
|
|
||||||
return holder.serialize(source);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.builder.list;
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.adapter.ValueType;
|
|
||||||
import cc.carm.lib.configuration.function.ValueHandler;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class ConfigListBuilder<V> {
|
|
||||||
|
|
||||||
protected final @NotNull ValueType<V> type;
|
|
||||||
|
|
||||||
public ConfigListBuilder(@NotNull ValueType<V> type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <S> @NotNull SourceListBuilder<S, V> from(@NotNull Class<S> sourceType) {
|
|
||||||
return from(ValueType.of(sourceType));
|
|
||||||
}
|
|
||||||
|
|
||||||
public <S> @NotNull SourceListBuilder<S, V> from(@NotNull ValueType<S> sourceType) {
|
|
||||||
return new SourceListBuilder<>(
|
|
||||||
ArrayList::new, sourceType, type,
|
|
||||||
ValueHandler.required(type),
|
|
||||||
ValueHandler.required(sourceType)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull SourceListBuilder<String, V> fromString() {
|
|
||||||
return new SourceListBuilder<>(
|
|
||||||
ArrayList::new, ValueType.STRING, type,
|
|
||||||
ValueHandler.required(type), ValueHandler.stringValue()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull SectionListBuilder<V> fromSection() {
|
|
||||||
return new SectionListBuilder<>(
|
|
||||||
ArrayList::new, type,
|
|
||||||
ValueHandler.required(type), ValueHandler.required()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package cc.carm.lib.configuration.builder.list;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueType;
|
||||||
|
import cc.carm.lib.configuration.builder.collection.SimpleCollectionCreator;
|
||||||
|
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ConfigListCreator<V> extends SimpleCollectionCreator<V, List<V>, ConfiguredList<V>> {
|
||||||
|
|
||||||
|
public ConfigListCreator(@NotNull ValueType<V> type) {
|
||||||
|
super(type, ArrayList::new, ConfiguredList::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.builder.list;
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.adapter.ValueType;
|
|
||||||
import cc.carm.lib.configuration.builder.impl.AbstractSectionBuilder;
|
|
||||||
import cc.carm.lib.configuration.function.ValueHandler;
|
|
||||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public class SectionListBuilder<V>
|
|
||||||
extends AbstractSectionBuilder<List<V>, V, ConfiguredList<V>, SectionListBuilder<V>> {
|
|
||||||
|
|
||||||
protected @NotNull Supplier<? extends List<V>> constructor;
|
|
||||||
|
|
||||||
public SectionListBuilder(@NotNull Supplier<? extends List<V>> constructor,
|
|
||||||
@NotNull ValueType<V> paramType,
|
|
||||||
@NotNull ValueHandler<ConfigureSection, V> parser,
|
|
||||||
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer) {
|
|
||||||
super(new ValueType<List<V>>() {
|
|
||||||
}, paramType, parser, serializer);
|
|
||||||
this.constructor = constructor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SafeVarargs
|
|
||||||
public final @NotNull SectionListBuilder<V> defaults(@NotNull V... values) {
|
|
||||||
return defaults(new ArrayList<>(Arrays.asList(values)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public final @NotNull SectionListBuilder<V> defaults(@NotNull Collection<V> values) {
|
|
||||||
return defaults(new ArrayList<>(values));
|
|
||||||
}
|
|
||||||
|
|
||||||
public final @NotNull SectionListBuilder<V> defaults(@NotNull Consumer<List<V>> constructor) {
|
|
||||||
return defaults(() -> {
|
|
||||||
List<V> list = new ArrayList<>();
|
|
||||||
constructor.accept(list);
|
|
||||||
return list;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public SectionListBuilder<V> constructor(@NotNull Supplier<? extends List<V>> constructor) {
|
|
||||||
this.constructor = constructor;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <LIST extends List<V>> SectionListBuilder<V> construct(@NotNull LIST list) {
|
|
||||||
return constructor(() -> list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected @NotNull SectionListBuilder<V> self() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull ConfiguredList<V> build() {
|
|
||||||
return new ConfiguredList<>(buildManifest(), constructor, buildAdapter());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.builder.list;
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.adapter.ValueType;
|
|
||||||
import cc.carm.lib.configuration.builder.impl.AbstractSourceBuilder;
|
|
||||||
import cc.carm.lib.configuration.function.ValueHandler;
|
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
|
||||||
public class SourceListBuilder<SOURCE, V>
|
|
||||||
extends AbstractSourceBuilder<List<V>, SOURCE, V, ConfiguredList<V>, SourceListBuilder<SOURCE, V>> {
|
|
||||||
|
|
||||||
protected @NotNull Supplier<? extends List<V>> constructor;
|
|
||||||
|
|
||||||
public SourceListBuilder(@NotNull Supplier<? extends List<V>> constructor,
|
|
||||||
@NotNull ValueType<SOURCE> sourceType, @NotNull ValueType<V> paramType,
|
|
||||||
@NotNull ValueHandler<SOURCE, V> parser, @NotNull ValueHandler<V, SOURCE> serializer) {
|
|
||||||
super(new ValueType<List<V>>() {
|
|
||||||
}, sourceType, paramType, parser, serializer);
|
|
||||||
this.constructor = constructor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SafeVarargs
|
|
||||||
public final @NotNull SourceListBuilder<SOURCE, V> defaults(@NotNull V... values) {
|
|
||||||
return defaults(new ArrayList<>(Arrays.asList(values)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public final @NotNull SourceListBuilder<SOURCE, V> defaults(@NotNull Collection<V> values) {
|
|
||||||
return defaults(new ArrayList<>(values));
|
|
||||||
}
|
|
||||||
|
|
||||||
public final @NotNull SourceListBuilder<SOURCE, V> defaults(@NotNull Consumer<List<V>> constructor) {
|
|
||||||
return defaults(() -> {
|
|
||||||
List<V> list = new ArrayList<>();
|
|
||||||
constructor.accept(list);
|
|
||||||
return list;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public SourceListBuilder<SOURCE, V> constructor(@NotNull Supplier<? extends List<V>> constructor) {
|
|
||||||
this.constructor = constructor;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <LIST extends List<V>> SourceListBuilder<SOURCE, V> construct(@NotNull LIST list) {
|
|
||||||
return constructor(() -> list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected @NotNull SourceListBuilder<SOURCE, V> self() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull ConfiguredList<V> build() {
|
|
||||||
return new ConfiguredList<>(buildManifest(), this.constructor, buildAdapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -49,6 +49,15 @@ public class ConfigMapBuilder<M extends Map<K, V>, K, V> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public @NotNull <S> SourceMapBuilder<M, Object, K, V> fromObject() {
|
||||||
|
return from(
|
||||||
|
ValueType.OBJECT,
|
||||||
|
ValueHandler.deserialize(keyType), ValueHandler.stringValue(),
|
||||||
|
ValueHandler.deserialize(valueType), ValueHandler.toObject()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public @NotNull SourceMapBuilder<M, String, K, V> fromString() {
|
public @NotNull SourceMapBuilder<M, String, K, V> fromString() {
|
||||||
return from(
|
return from(
|
||||||
ValueType.STRING,
|
ValueType.STRING,
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package cc.carm.lib.configuration.function;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface DataConsumer<T> {
|
public interface DataConsumer<T> extends Serializable {
|
||||||
|
|
||||||
void accept(@NotNull T data) throws Exception;
|
void accept(@NotNull T data) throws Exception;
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ package cc.carm.lib.configuration.function;
|
|||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface DataFunction<T, R> {
|
public interface DataFunction<T, R> extends Serializable {
|
||||||
|
|
||||||
@NotNull R handle(@NotNull T data) throws Exception;
|
@NotNull R handle(@NotNull T data) throws Exception;
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package cc.carm.lib.configuration.function;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface DataValidator<T> {
|
public interface DataValidator<T> extends Serializable {
|
||||||
|
|
||||||
void validate(@Nullable T value) throws Exception;
|
void validate(@Nullable T value) throws Exception;
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ package cc.carm.lib.configuration.function;
|
|||||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ValueComposer<T, U> {
|
public interface ValueComposer<T, U> extends Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accept the value and the data, and then compose the value.
|
* Accept the value and the data, and then compose the value.
|
||||||
|
|||||||
@@ -7,10 +7,11 @@ import org.jetbrains.annotations.Contract;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ValueHandler<T, R> {
|
public interface ValueHandler<T, R> extends Serializable {
|
||||||
|
|
||||||
@Nullable R handle(@NotNull ConfigurationHolder<?> holder, @NotNull T data) throws Exception;
|
@Nullable R handle(@NotNull ConfigurationHolder<?> holder, @NotNull T data) throws Exception;
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ import cc.carm.lib.configuration.source.ConfigurationHolder;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ValueValidator<T> {
|
public interface ValueValidator<T> extends Serializable {
|
||||||
|
|
||||||
void validate(@NotNull ConfigurationHolder<?> holder, @Nullable T value) throws Exception;
|
void validate(@NotNull ConfigurationHolder<?> holder, @Nullable T value) throws Exception;
|
||||||
|
|
||||||
|
|||||||
@@ -851,6 +851,8 @@ public interface ConfigureSection {
|
|||||||
return getList(path, obj -> {
|
return getList(path, obj -> {
|
||||||
if (obj instanceof ConfigureSection) {
|
if (obj instanceof ConfigureSection) {
|
||||||
return (ConfigureSection) obj;
|
return (ConfigureSection) obj;
|
||||||
|
} else if (obj instanceof Map) {
|
||||||
|
return createSection(childPath(path), (Map<?, ?>) obj);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package cc.carm.lib.configuration.value;
|
package cc.carm.lib.configuration.value;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@@ -54,7 +55,18 @@ public abstract class ConfigValue<T, U> extends ValueManifest<T, U> {
|
|||||||
* @return Configured value or default value
|
* @return Configured value or default value
|
||||||
*/
|
*/
|
||||||
public T getOrDefault() {
|
public T getOrDefault() {
|
||||||
return optional().orElse(defaults());
|
return getOr(defaults());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the configured value, or returns the specified default value if not present.
|
||||||
|
*
|
||||||
|
* @param defaults The default value to return if the configured value is not present
|
||||||
|
* @return Configured value or specified default value
|
||||||
|
*/
|
||||||
|
@Contract("!null -> !null")
|
||||||
|
public T getOr(T defaults) {
|
||||||
|
return optional().orElse(defaults);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,210 @@
|
|||||||
|
package cc.carm.lib.configuration.value.impl;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueParser;
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueSerializer;
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueType;
|
||||||
|
import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base implementation of a collection config value, like {@link List} or {@link Set}.
|
||||||
|
*
|
||||||
|
* @param <V> Value type
|
||||||
|
* @param <C> Collection type
|
||||||
|
* @param <SELF> Self reference type (used for internal call or recursive generics)
|
||||||
|
*/
|
||||||
|
public abstract class CollectionConfigValue<
|
||||||
|
V, C extends Collection<V>,
|
||||||
|
SELF extends CollectionConfigValue<V, C, SELF>
|
||||||
|
> extends CachedConfigValue<C, V> implements Collection<V> {
|
||||||
|
|
||||||
|
protected final @NotNull Supplier<? extends C> constructor;
|
||||||
|
protected final @NotNull ValueAdapter<V> paramAdapter;
|
||||||
|
|
||||||
|
public CollectionConfigValue(@NotNull ValueManifest<C, V> manifest,
|
||||||
|
@NotNull Supplier<? extends C> constructor,
|
||||||
|
@NotNull ValueAdapter<V> paramAdapter) {
|
||||||
|
super(manifest);
|
||||||
|
this.constructor = constructor;
|
||||||
|
this.paramAdapter = paramAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Adapter of this value.
|
||||||
|
*/
|
||||||
|
public @NotNull ValueAdapter<V> adapter() {
|
||||||
|
return this.paramAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ValueType<V> paramType() {
|
||||||
|
return adapter().type();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Value's parser, parse base object to value.
|
||||||
|
*/
|
||||||
|
public @Nullable ValueParser<V> parser() {
|
||||||
|
return parserFor(adapter());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Value's serializer, parse value to base object.
|
||||||
|
*/
|
||||||
|
public @Nullable ValueSerializer<V> serializer() {
|
||||||
|
return serializerFor(adapter());
|
||||||
|
}
|
||||||
|
|
||||||
|
private @NotNull C createCollection() {
|
||||||
|
return constructor.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull C get() {
|
||||||
|
if (!cacheExpired()) return getCachedOrDefault(createCollection());
|
||||||
|
// Data that is outdated and needs to be parsed again.
|
||||||
|
C set = createCollection();
|
||||||
|
try {
|
||||||
|
List<?> data = config().contains(path()) ? config().getList(path()) : null;
|
||||||
|
if (data == null) return getDefaultFirst(set);
|
||||||
|
|
||||||
|
ValueParser<V> parser = parser();
|
||||||
|
if (parser == null) return getDefaultFirst(set);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (Object dataVal : data) {
|
||||||
|
if (dataVal == null) continue;
|
||||||
|
try {
|
||||||
|
set.add(withValidated(parser.parse(holder(), paramType(), dataVal)));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throwing(path + "[" + i + "]", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throwing(ex);
|
||||||
|
}
|
||||||
|
return updateCache(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(@Nullable C collection) {
|
||||||
|
updateCache(collection);
|
||||||
|
if (collection == null) {
|
||||||
|
setData(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueSerializer<V> serializer = serializer();
|
||||||
|
if (serializer == null) return;
|
||||||
|
|
||||||
|
List<Object> data = new ArrayList<>();
|
||||||
|
for (V val : collection) {
|
||||||
|
if (val == null) continue;
|
||||||
|
try {
|
||||||
|
data.add(serializer.serialize(holder(), paramType(), withValidated(val)));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throwing(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull C copy() {
|
||||||
|
C other = createCollection();
|
||||||
|
other.addAll(resolve());
|
||||||
|
return other;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract @NotNull SELF self();
|
||||||
|
|
||||||
|
public <T> @NotNull T handle(Function<C, T> function) {
|
||||||
|
C list = resolve();
|
||||||
|
T result = function.apply(list);
|
||||||
|
set(list);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull SELF modify(Consumer<C> consumer) {
|
||||||
|
C list = resolve();
|
||||||
|
consumer.accept(list);
|
||||||
|
set(list);
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return resolve().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return resolve().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
return resolve().contains(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Iterator<V> iterator() {
|
||||||
|
return resolve().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Object @NotNull [] toArray() {
|
||||||
|
return resolve().toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public <T> T @NotNull [] toArray(@NotNull T[] a) {
|
||||||
|
return resolve().toArray(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAll(@NotNull Collection<?> c) {
|
||||||
|
return new HashSet<>(resolve()).containsAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(V v) {
|
||||||
|
handle(list -> list.add(v));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean addAll(@NotNull Collection<? extends V> c) {
|
||||||
|
return handle(list -> list.addAll(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Object o) {
|
||||||
|
return handle(list -> list.remove(o));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean removeAll(@NotNull Collection<?> c) {
|
||||||
|
return handle(list -> list.removeAll(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean retainAll(@NotNull Collection<?> c) {
|
||||||
|
return handle(list -> list.retainAll(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
modify(Collection::clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,37 +1,33 @@
|
|||||||
package cc.carm.lib.configuration.value.standard;
|
package cc.carm.lib.configuration.value.standard;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||||
import cc.carm.lib.configuration.adapter.ValueParser;
|
|
||||||
import cc.carm.lib.configuration.adapter.ValueSerializer;
|
|
||||||
import cc.carm.lib.configuration.adapter.ValueType;
|
import cc.carm.lib.configuration.adapter.ValueType;
|
||||||
import cc.carm.lib.configuration.builder.list.ConfigListBuilder;
|
import cc.carm.lib.configuration.builder.collection.SimpleCollectionCreator;
|
||||||
import cc.carm.lib.configuration.builder.list.SourceListBuilder;
|
import cc.carm.lib.configuration.builder.list.ConfigListCreator;
|
||||||
import cc.carm.lib.configuration.value.ValueManifest;
|
import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
import cc.carm.lib.configuration.value.impl.CachedConfigValue;
|
import cc.carm.lib.configuration.value.impl.CollectionConfigValue;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements List<V> {
|
public class ConfiguredList<V> extends CollectionConfigValue<V, List<V>, ConfiguredList<V>> implements List<V> {
|
||||||
|
|
||||||
public static <T> @NotNull ConfigListBuilder<T> builderOf(@NotNull Class<T> type) {
|
public static <T> @NotNull ConfigListCreator<T> builderOf(@NotNull Class<T> type) {
|
||||||
return builderOf(ValueType.of(type));
|
return builderOf(ValueType.of(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> @NotNull ConfigListBuilder<T> builderOf(@NotNull ValueType<T> type) {
|
public static <T> @NotNull ConfigListCreator<T> builderOf(@NotNull ValueType<T> type) {
|
||||||
return new ConfigListBuilder<>(type);
|
return new ConfigListCreator<>(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> @NotNull SourceListBuilder<T, T> with(@NotNull Class<T> registeredType) {
|
public static <T>
|
||||||
|
@NotNull SimpleCollectionCreator.Source<Object, T, List<T>, ConfiguredList<T>> with(@NotNull Class<T> registeredType) {
|
||||||
return with(ValueType.of(registeredType));
|
return with(ValueType.of(registeredType));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> @NotNull SourceListBuilder<T, T> with(@NotNull ValueType<T> registeredType) {
|
public static <T> @NotNull SimpleCollectionCreator.Source<Object, T, List<T>, ConfiguredList<T>> with(@NotNull ValueType<T> registeredType) {
|
||||||
return new ConfigListBuilder<>(registeredType).from(registeredType);
|
return builderOf(registeredType).fromObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
@@ -42,94 +38,10 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements
|
|||||||
return with(ValueType.of(value)).defaults(list).build();
|
return with(ValueType.of(value)).defaults(list).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final @NotNull Supplier<? extends List<V>> constructor;
|
|
||||||
protected final @NotNull ValueAdapter<V> paramAdapter;
|
|
||||||
|
|
||||||
public ConfiguredList(@NotNull ValueManifest<List<V>, V> manifest,
|
public ConfiguredList(@NotNull ValueManifest<List<V>, V> manifest,
|
||||||
@NotNull Supplier<? extends List<V>> constructor,
|
@NotNull Supplier<? extends List<V>> constructor,
|
||||||
@NotNull ValueAdapter<V> paramAdapter) {
|
@NotNull ValueAdapter<V> paramAdapter) {
|
||||||
super(manifest);
|
super(manifest, constructor, paramAdapter);
|
||||||
this.constructor = constructor;
|
|
||||||
this.paramAdapter = paramAdapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Adapter of this value.
|
|
||||||
*/
|
|
||||||
public @NotNull ValueAdapter<V> adapter() {
|
|
||||||
return this.paramAdapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull ValueType<V> paramType() {
|
|
||||||
return adapter().type();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Value's parser, parse base object to value.
|
|
||||||
*/
|
|
||||||
public @Nullable ValueParser<V> parser() {
|
|
||||||
return parserFor(adapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Value's serializer, parse value to base object.
|
|
||||||
*/
|
|
||||||
public @Nullable ValueSerializer<V> serializer() {
|
|
||||||
return serializerFor(adapter());
|
|
||||||
}
|
|
||||||
|
|
||||||
private @NotNull List<V> createList() {
|
|
||||||
return constructor.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull List<V> get() {
|
|
||||||
if (!cacheExpired()) return getCachedOrDefault(createList());
|
|
||||||
// Data that is outdated and needs to be parsed again.
|
|
||||||
List<V> list = createList();
|
|
||||||
try {
|
|
||||||
List<?> data = config().contains(path()) ? config().getList(path()) : null;
|
|
||||||
if (data == null) return getDefaultFirst(list);
|
|
||||||
|
|
||||||
ValueParser<V> parser = parser();
|
|
||||||
if (parser == null) return getDefaultFirst(list);
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
for (Object dataVal : data) {
|
|
||||||
if (dataVal == null) continue;
|
|
||||||
try {
|
|
||||||
list.add(withValidated(parser.parse(holder(), paramType(), dataVal)));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throwing(path + "[" + i + "]", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throwing(ex);
|
|
||||||
}
|
|
||||||
return updateCache(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void set(@Nullable List<V> list) {
|
|
||||||
updateCache(list);
|
|
||||||
if (list == null) {
|
|
||||||
setData(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueSerializer<V> serializer = serializer();
|
|
||||||
if (serializer == null) return;
|
|
||||||
|
|
||||||
List<Object> data = new ArrayList<>();
|
|
||||||
for (V val : list) {
|
|
||||||
if (val == null) continue;
|
|
||||||
try {
|
|
||||||
data.add(serializer.serialize(holder(), paramType(), withValidated(val)));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throwing(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setData(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -137,21 +49,8 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements
|
|||||||
return resolve().get(index);
|
return resolve().get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull List<V> copy() {
|
@Override
|
||||||
return new ArrayList<>(resolve());
|
public @NotNull ConfiguredList<V> self() {
|
||||||
}
|
|
||||||
|
|
||||||
public <T> @NotNull T handle(Function<List<V>, T> function) {
|
|
||||||
List<V> list = resolve();
|
|
||||||
T result = function.apply(list);
|
|
||||||
set(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @NotNull ConfiguredList<V> modify(Consumer<List<V>> consumer) {
|
|
||||||
List<V> list = resolve();
|
|
||||||
consumer.accept(list);
|
|
||||||
set(list);
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,89 +59,22 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements
|
|||||||
return handle(list -> list.set(index, element));
|
return handle(list -> list.set(index, element));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return resolve().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return resolve().isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean contains(Object o) {
|
|
||||||
return resolve().contains(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Iterator<V> iterator() {
|
|
||||||
return resolve().iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Object @NotNull [] toArray() {
|
|
||||||
return resolve().toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public <T> T @NotNull [] toArray(@NotNull T[] a) {
|
|
||||||
return resolve().toArray(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsAll(@NotNull Collection<?> c) {
|
|
||||||
return new HashSet<>(resolve()).containsAll(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean add(V v) {
|
|
||||||
handle(list -> list.add(v));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void add(int index, V element) {
|
public void add(int index, V element) {
|
||||||
modify(list -> list.add(index, element));
|
modify(list -> list.add(index, element));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean addAll(@NotNull Collection<? extends V> c) {
|
|
||||||
return handle(list -> list.addAll(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean addAll(int index, @NotNull Collection<? extends V> c) {
|
public boolean addAll(int index, @NotNull Collection<? extends V> c) {
|
||||||
return handle(list -> list.addAll(index, c));
|
return handle(list -> list.addAll(index, c));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean remove(Object o) {
|
|
||||||
return handle(list -> list.remove(o));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public V remove(int index) {
|
public V remove(int index) {
|
||||||
return handle(list -> list.remove(index));
|
return handle(list -> list.remove(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean removeAll(@NotNull Collection<?> c) {
|
|
||||||
return handle(list -> list.removeAll(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean retainAll(@NotNull Collection<?> c) {
|
|
||||||
return handle(list -> list.retainAll(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
modify(List::clear);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int indexOf(Object o) {
|
public int indexOf(Object o) {
|
||||||
@@ -272,4 +104,5 @@ public class ConfiguredList<V> extends CachedConfigValue<List<V>, V> implements
|
|||||||
return resolve().subList(fromIndex, toIndex);
|
return resolve().subList(fromIndex, toIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ import cc.carm.lib.configuration.adapter.ValueParser;
|
|||||||
import cc.carm.lib.configuration.adapter.ValueSerializer;
|
import cc.carm.lib.configuration.adapter.ValueSerializer;
|
||||||
import cc.carm.lib.configuration.adapter.ValueType;
|
import cc.carm.lib.configuration.adapter.ValueType;
|
||||||
import cc.carm.lib.configuration.builder.map.ConfigMapCreator;
|
import cc.carm.lib.configuration.builder.map.ConfigMapCreator;
|
||||||
|
import cc.carm.lib.configuration.builder.map.SourceMapBuilder;
|
||||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||||
import cc.carm.lib.configuration.value.ValueManifest;
|
import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
import cc.carm.lib.configuration.value.impl.CachedConfigValue;
|
import cc.carm.lib.configuration.value.impl.CachedConfigValue;
|
||||||
@@ -31,6 +32,16 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>, V> impleme
|
|||||||
return new ConfigMapCreator<>(ValueType.of(keyType), ValueType.of(valueType));
|
return new ConfigMapCreator<>(ValueType.of(keyType), ValueType.of(valueType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static @NotNull <K, V>
|
||||||
|
SourceMapBuilder<LinkedHashMap<K, V>, Object, K, V> with(@NotNull Class<K> keyType, @NotNull Class<V> valueType) {
|
||||||
|
return with(ValueType.of(keyType), ValueType.of(valueType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull <K, V>
|
||||||
|
SourceMapBuilder<LinkedHashMap<K, V>, Object, K, V> with(@NotNull ValueType<K> keyType, @NotNull ValueType<V> valueType) {
|
||||||
|
return new ConfigMapCreator<>(keyType, valueType).asLinkedMap().fromObject();
|
||||||
|
}
|
||||||
|
|
||||||
public static <K, V> ConfiguredMap<K, V> of(@NotNull Supplier<? extends Map<K, V>> constructor,
|
public static <K, V> ConfiguredMap<K, V> of(@NotNull Supplier<? extends Map<K, V>> constructor,
|
||||||
@NotNull ValueAdapter<K> keyAdapter, @NotNull ValueAdapter<V> valueAdapter) {
|
@NotNull ValueAdapter<K> keyAdapter, @NotNull ValueAdapter<V> valueAdapter) {
|
||||||
return new ConfiguredMap<>(new ValueManifest<>(new ValueType<Map<K, V>>() {
|
return new ConfiguredMap<>(new ValueManifest<>(new ValueType<Map<K, V>>() {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
//import java.util.LinkedList;
|
//import java.util.LinkedList;
|
||||||
//import java.util.List;
|
//import java.util.List;
|
||||||
//
|
//
|
||||||
///**
|
/// **
|
||||||
// * @author Chris2018998
|
// * @author Chris2018998
|
||||||
// */
|
// */
|
||||||
//public class OffsetUtil {
|
//public class OffsetUtil {
|
||||||
@@ -25,15 +25,15 @@
|
|||||||
// } catch (NoSuchFieldException | IllegalAccessException e) {
|
// } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
// e.printStackTrace();
|
// e.printStackTrace();
|
||||||
// }
|
// }
|
||||||
//// try {
|
/// / try {
|
||||||
//// unsafe = AccessController.doPrivileged((PrivilegedExceptionAction<Unsafe>) () -> {
|
/// / unsafe = AccessController.doPrivileged((PrivilegedExceptionAction<Unsafe>) () -> {
|
||||||
//// Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
|
/// / Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
|
||||||
//// theUnsafe.setAccessible(true);
|
/// / theUnsafe.setAccessible(true);
|
||||||
//// return (Unsafe) theUnsafe.get(null);
|
/// / return (Unsafe) theUnsafe.get(null);
|
||||||
//// });
|
/// / });
|
||||||
//// } catch (Throwable e) {
|
/// / } catch (Throwable e) {
|
||||||
//// System.err.println("Unable to load unsafe");
|
/// / System.err.println("Unable to load unsafe");
|
||||||
//// }
|
/// / }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// public static List<FieldOffset> getClassMemberOffset(Class<?> beanClass) {
|
// public static List<FieldOffset> getClassMemberOffset(Class<?> beanClass) {
|
||||||
|
|||||||
+14
-2
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<properties>
|
<properties>
|
||||||
@@ -17,11 +17,16 @@
|
|||||||
<maven.deploy.skip>true</maven.deploy.skip>
|
<maven.deploy.skip>true</maven.deploy.skip>
|
||||||
|
|
||||||
<deps.mysql-driver.version>8.0.33</deps.mysql-driver.version>
|
<deps.mysql-driver.version>8.0.33</deps.mysql-driver.version>
|
||||||
<log4j.version>2.24.3</log4j.version>
|
<log4j.version>2.26.0</log4j.version>
|
||||||
</properties>
|
</properties>
|
||||||
<artifactId>configured-demo</artifactId>
|
<artifactId>configured-demo</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Demo</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Demonstrate & tests module.</description>
|
||||||
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -146,6 +151,13 @@
|
|||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skip>true</skip>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
<artifactId>kotlin-maven-plugin</artifactId>
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ public class ConfigurationTest {
|
|||||||
System.out.println("> Test Kotlin value after:");
|
System.out.println("> Test Kotlin value after:");
|
||||||
System.out.println(KotlinConfiguration.INSTANCE.getLINKED_MAP().get());
|
System.out.println(KotlinConfiguration.INSTANCE.getLINKED_MAP().get());
|
||||||
|
|
||||||
|
System.out.println("> Test Set value -> " + KotlinConfiguration.INSTANCE.getBLACK_LIST().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void save(ConfigurationHolder<?> provider) {
|
public static void save(ConfigurationHolder<?> provider) {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import cc.carm.lib.configuration.Configuration
|
|||||||
import cc.carm.lib.configuration.annotation.ConfigPath
|
import cc.carm.lib.configuration.annotation.ConfigPath
|
||||||
import cc.carm.lib.configuration.annotation.ConfigVersion
|
import cc.carm.lib.configuration.annotation.ConfigVersion
|
||||||
import cc.carm.lib.configuration.kotlin.value.*
|
import cc.carm.lib.configuration.kotlin.value.*
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
@ConfigPath(root = true)
|
@ConfigPath(root = true)
|
||||||
object KotlinConfiguration : Configuration {
|
object KotlinConfiguration : Configuration {
|
||||||
@@ -17,6 +16,10 @@ object KotlinConfiguration : Configuration {
|
|||||||
defaults("Carm Jos")
|
defaults("Carm Jos")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val BLACK_LIST = setFrom(String::class) {
|
||||||
|
defaults("404", "404", "123")
|
||||||
|
}
|
||||||
|
|
||||||
val NICKNAME = mapFrom(String::class, ::mutableMapOf) {
|
val NICKNAME = mapFrom(String::class, ::mutableMapOf) {
|
||||||
defaultMap(mapOf("Carm Jos" to "Carm"))
|
defaultMap(mapOf("Carm Jos" to "Carm"))
|
||||||
parse { v -> v }
|
parse { v -> v }
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.util.Map;
|
|||||||
public class YamlTests {
|
public class YamlTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() throws Exception {
|
||||||
|
|
||||||
ConfigurationHolder<YAMLSource> holder = YAMLConfigFactory.from("target/tests.yml")
|
ConfigurationHolder<YAMLSource> holder = YAMLConfigFactory.from("target/tests.yml")
|
||||||
.resourcePath("configs/sample.yml").build();
|
.resourcePath("configs/sample.yml").build();
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<artifactId>configured-parent</artifactId>
|
||||||
|
<version>4.2.1</version>
|
||||||
|
<relativePath>../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>${project.jdk.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<artifactId>configured-feature-collections</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Collections Feature</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides more collection type support for the Configured framework.</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>configured-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>configured-gson</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
+96
@@ -0,0 +1,96 @@
|
|||||||
|
package cc.carm.lib.configuration.builder.set;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueType;
|
||||||
|
import cc.carm.lib.configuration.builder.collection.SectionCollectionBuilder;
|
||||||
|
import cc.carm.lib.configuration.builder.collection.SourceCollectionBuilder;
|
||||||
|
import cc.carm.lib.configuration.function.ValueHandler;
|
||||||
|
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||||
|
import cc.carm.lib.configuration.value.collections.ConfiguredSet;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class ConfigSetBuilder<V> {
|
||||||
|
|
||||||
|
protected final @NotNull ValueType<V> type;
|
||||||
|
|
||||||
|
public ConfigSetBuilder(@NotNull ValueType<V> type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <S> @NotNull SourceBuilder<S, V> from(@NotNull Class<S> sourceType) {
|
||||||
|
return from(ValueType.of(sourceType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <S> @NotNull SourceBuilder<S, V> from(@NotNull ValueType<S> sourceType) {
|
||||||
|
return new SourceBuilder<>(
|
||||||
|
sourceType, type,
|
||||||
|
ValueHandler.required(type),
|
||||||
|
ValueHandler.required(sourceType)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ConfigSetBuilder.SourceBuilder<Object, V> fromObject() {
|
||||||
|
return new SourceBuilder<>(
|
||||||
|
ValueType.OBJECT, type,
|
||||||
|
ValueHandler.deserialize(type), ValueHandler.toObject()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ConfigSetBuilder.SourceBuilder<String, V> fromString() {
|
||||||
|
return new SourceBuilder<>(
|
||||||
|
ValueType.STRING, type,
|
||||||
|
ValueHandler.required(type), ValueHandler.stringValue()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ConfigSetBuilder.SectionBuilder<V> fromSection() {
|
||||||
|
return new SectionBuilder<>(type, ValueHandler.required(type), ValueHandler.required());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class SourceBuilder<SOURCE, V> extends SourceCollectionBuilder<SOURCE, V, Set<V>, ConfiguredSet<V>, SourceBuilder<SOURCE, V>> {
|
||||||
|
|
||||||
|
public SourceBuilder(@NotNull ValueType<SOURCE> sourceType,
|
||||||
|
@NotNull ValueType<V> paramType,
|
||||||
|
@NotNull ValueHandler<SOURCE, V> parser,
|
||||||
|
@NotNull ValueHandler<V, SOURCE> serializer) {
|
||||||
|
super(LinkedHashSet::new, sourceType, paramType, parser, serializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @NotNull ConfigSetBuilder.SourceBuilder<SOURCE, V> self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ConfiguredSet<V> build() {
|
||||||
|
return new ConfiguredSet<>(buildManifest(), constructor, buildAdapter());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SectionBuilder<V> extends SectionCollectionBuilder<V, Set<V>, ConfiguredSet<V>, SectionBuilder<V>> {
|
||||||
|
|
||||||
|
public SectionBuilder(@NotNull ValueType<V> paramType,
|
||||||
|
@NotNull ValueHandler<ConfigureSection, V> parser,
|
||||||
|
@NotNull ValueHandler<V, ? extends Map<String, Object>> serializer) {
|
||||||
|
super(LinkedHashSet::new, paramType, parser, serializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @NotNull ConfigSetBuilder.SectionBuilder<V> self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ConfiguredSet<V> build() {
|
||||||
|
return new ConfiguredSet<>(buildManifest(), constructor, buildAdapter());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
package cc.carm.lib.configuration.value.collections;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueType;
|
||||||
|
import cc.carm.lib.configuration.builder.set.ConfigSetBuilder;
|
||||||
|
import cc.carm.lib.configuration.value.ValueManifest;
|
||||||
|
import cc.carm.lib.configuration.value.impl.CollectionConfigValue;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class ConfiguredSet<V> extends CollectionConfigValue<V, Set<V>, ConfiguredSet<V>> implements Set<V> {
|
||||||
|
|
||||||
|
public static <T> @NotNull ConfigSetBuilder<T> builderOf(@NotNull Class<T> type) {
|
||||||
|
return builderOf(ValueType.of(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> @NotNull ConfigSetBuilder<T> builderOf(@NotNull ValueType<T> type) {
|
||||||
|
return new ConfigSetBuilder<>(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> @NotNull ConfigSetBuilder.SourceBuilder<Object, T> with(@NotNull Class<T> registeredType) {
|
||||||
|
return with(ValueType.of(registeredType));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> @NotNull ConfigSetBuilder.SourceBuilder<Object, T> with(@NotNull ValueType<T> registeredType) {
|
||||||
|
return builderOf(registeredType).fromObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public static <T> @NotNull ConfiguredSet<T> of(@NotNull T value, @NotNull T... values) {
|
||||||
|
Set<T> list = new LinkedHashSet<>();
|
||||||
|
list.add(value);
|
||||||
|
Collections.addAll(list, values);
|
||||||
|
return with(ValueType.of(value)).defaults(list).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConfiguredSet(@NotNull ValueManifest<Set<V>, V> manifest,
|
||||||
|
@NotNull Supplier<? extends Set<V>> constructor,
|
||||||
|
@NotNull ValueAdapter<V> paramAdapter) {
|
||||||
|
super(manifest, constructor, paramAdapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ConfiguredSet<V> self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
@@ -19,6 +19,10 @@
|
|||||||
<artifactId>configured-feature-commentable</artifactId>
|
<artifactId>configured-feature-commentable</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Commentable Feature</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Enables comment support for configuration files in the Configured framework.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
@@ -19,6 +19,10 @@
|
|||||||
<artifactId>configured-feature-file</artifactId>
|
<artifactId>configured-feature-file</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - File Feature</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides file-based configuration support for the Configured framework.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
|
|||||||
-2
@@ -1,7 +1,5 @@
|
|||||||
package cc.carm.lib.configuration.source.option;
|
package cc.carm.lib.configuration.source.option;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.source.option.ConfigurationOption;
|
|
||||||
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
|||||||
+12
-3
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
@@ -14,18 +14,27 @@
|
|||||||
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
|
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
<kotlin.version>2.1.20</kotlin.version>
|
<kotlin.version>2.3.21</kotlin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<artifactId>configured-feature-kotlin</artifactId>
|
<artifactId>configured-feature-kotlin</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Kotlin Feature</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides Kotlin language support and extensions for the Configured framework.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>configured-core</artifactId>
|
<artifactId>configured-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>configured-feature-collections</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||||
@@ -77,7 +86,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jetbrains.dokka</groupId>
|
<groupId>org.jetbrains.dokka</groupId>
|
||||||
<artifactId>dokka-maven-plugin</artifactId>
|
<artifactId>dokka-maven-plugin</artifactId>
|
||||||
<version>2.0.0</version>
|
<version>2.2.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>pre-site</phase>
|
<phase>pre-site</phase>
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package cc.carm.lib.configuration.kotlin.value
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueType
|
||||||
|
import cc.carm.lib.configuration.builder.collection.SimpleCollectionCreator
|
||||||
|
import cc.carm.lib.configuration.builder.set.ConfigSetBuilder
|
||||||
|
import cc.carm.lib.configuration.value.collections.ConfiguredSet
|
||||||
|
import cc.carm.lib.configuration.value.standard.ConfiguredList
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
inline fun <S : Any, reified V> listFrom(
|
||||||
|
clazz: KClass<S>, block: (SimpleCollectionCreator.Source<S, V, List<V>, ConfiguredList<V>>.() -> Unit)
|
||||||
|
): ConfiguredList<V> {
|
||||||
|
return listFrom(clazz.java, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <S : Any, reified V> listFrom(
|
||||||
|
clazz: Class<S>, block: (SimpleCollectionCreator.Source<S, V, List<V>, ConfiguredList<V>>.() -> Unit)
|
||||||
|
): ConfiguredList<V> {
|
||||||
|
return listFrom(ValueType.of(clazz), block)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <S : Any, reified V> listFrom(
|
||||||
|
valueType: ValueType<S>, block: (SimpleCollectionCreator.Source<S, V, List<V>, ConfiguredList<V>>.() -> Unit)
|
||||||
|
): ConfiguredList<V> {
|
||||||
|
val configBuilder = ConfiguredList.builderOf(V::class.java)
|
||||||
|
val sourceValueBuilder: SimpleCollectionCreator.Source<S, V, List<V>, ConfiguredList<V>> =
|
||||||
|
if (valueType.rawType == String::class.java) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
configBuilder.fromString() as SimpleCollectionCreator.Source<S, V, List<V>, ConfiguredList<V>>
|
||||||
|
} else configBuilder.from(valueType)
|
||||||
|
return sourceValueBuilder.also(block).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <S : Any, reified V> setFrom(
|
||||||
|
clazz: KClass<S>, block: (ConfigSetBuilder.SourceBuilder<S, V>.() -> Unit)
|
||||||
|
): ConfiguredSet<V> {
|
||||||
|
return setFrom(clazz.java, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <S : Any, reified V> setFrom(
|
||||||
|
clazz: Class<S>, block: (ConfigSetBuilder.SourceBuilder<S, V>.() -> Unit)
|
||||||
|
): ConfiguredSet<V> {
|
||||||
|
return setFrom(ValueType.of(clazz), block)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <S : Any, reified V> setFrom(
|
||||||
|
valueType: ValueType<S>, block: (ConfigSetBuilder.SourceBuilder<S, V>.() -> Unit)
|
||||||
|
): ConfiguredSet<V> {
|
||||||
|
val configBuilder = ConfiguredSet.builderOf(V::class.java)
|
||||||
|
val sourceValueBuilder: ConfigSetBuilder.SourceBuilder<S, V> =
|
||||||
|
if (valueType.rawType == String::class.java) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
configBuilder.fromString() as ConfigSetBuilder.SourceBuilder<S, V>
|
||||||
|
} else configBuilder.from(valueType)
|
||||||
|
return sourceValueBuilder.also(block).build()
|
||||||
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package cc.carm.lib.configuration.kotlin.value
|
|
||||||
|
|
||||||
import cc.carm.lib.configuration.adapter.ValueType
|
|
||||||
import cc.carm.lib.configuration.builder.list.SourceListBuilder
|
|
||||||
import cc.carm.lib.configuration.value.standard.ConfiguredList
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
inline fun <S : Any, reified V> listFrom(
|
|
||||||
clazz: KClass<S>, block: (SourceListBuilder<S, V>.() -> Unit)
|
|
||||||
): ConfiguredList<V> {
|
|
||||||
return listFrom(clazz.java, block)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <S : Any, reified V> listFrom(
|
|
||||||
clazz: Class<S>, block: (SourceListBuilder<S, V>.() -> Unit)
|
|
||||||
): ConfiguredList<V> {
|
|
||||||
return listFrom(ValueType.of(clazz), block)
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <S : Any, reified V> listFrom(
|
|
||||||
valueType: ValueType<S>, block: (SourceListBuilder<S, V>.() -> Unit)
|
|
||||||
): ConfiguredList<V> {
|
|
||||||
val configBuilder = ConfiguredList.builderOf(V::class.java)
|
|
||||||
val sourceValueBuilder: SourceListBuilder<S, V> = if (valueType.rawType == String::class.java) {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
configBuilder.fromString() as SourceListBuilder<S, V>
|
|
||||||
} else configBuilder.from(valueType)
|
|
||||||
return sourceValueBuilder.also(block).build()
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<artifactId>configured-parent</artifactId>
|
||||||
|
<version>4.2.1</version>
|
||||||
|
<relativePath>../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>${project.jdk.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
|
<kotlin.version>2.3.10</kotlin.version>
|
||||||
|
</properties>
|
||||||
|
<artifactId>configured-feature-multi</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Record Feature</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides Java record type support for the Configured framework.</description>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<artifactId>configured-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<artifactId>configured-feature-file</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<artifactId>configured-yaml</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
package cc.carm.lib.configuration.multi;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public abstract class MultiConfiguration<K, T> {
|
||||||
|
|
||||||
|
protected final ConcurrentHashMap<K, T> valuesCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public MultiConfiguration() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the value of the key from the holder, and return the value.
|
||||||
|
*
|
||||||
|
* @param key The key of the value to read.
|
||||||
|
* @param holder The holder of the value to read.
|
||||||
|
* @return The value of the key, or null if the value is not exist.
|
||||||
|
*/
|
||||||
|
public abstract T read(@NotNull K key, @NotNull ConfigurationHolder<?> holder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write (and save) the value of the key to the holder, then update the cache.
|
||||||
|
*
|
||||||
|
* @param holder The holder of the value to write.
|
||||||
|
* @param value The value to write, which should not be null.
|
||||||
|
*/
|
||||||
|
public abstract void write(@NotNull ConfigurationHolder<?> holder, @NotNull T value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all holders of the configuration, which should be a concurrent map to support concurrent access.
|
||||||
|
*
|
||||||
|
* @return All holders of the configuration.
|
||||||
|
*/
|
||||||
|
public abstract @NotNull Map<K, ConfigurationHolder<?>> holders();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the holder of the key.
|
||||||
|
* If the holder of the key is not exist,
|
||||||
|
* it should be created then return the created holder.
|
||||||
|
*
|
||||||
|
* @param key The key of the holder to get.
|
||||||
|
* @return The holder of the key.
|
||||||
|
*/
|
||||||
|
public abstract @NotNull ConfigurationHolder<?> holder(@NotNull K key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the holder of the key, and remove the value of the key from the cache.
|
||||||
|
* Also delete the configuration file if necessary.
|
||||||
|
*
|
||||||
|
* @param key The key of the holder to remove.
|
||||||
|
*/
|
||||||
|
public abstract void removeHolder(@NotNull K key);
|
||||||
|
|
||||||
|
public void loadAll() {
|
||||||
|
for (Map.Entry<K, ConfigurationHolder<?>> entry : holders().entrySet()) {
|
||||||
|
K key = entry.getKey();
|
||||||
|
ConfigurationHolder<?> holder = entry.getValue();
|
||||||
|
try {
|
||||||
|
T loaded = read(key, holder);
|
||||||
|
if (loaded != null) {
|
||||||
|
valuesCache.put(key, loaded);
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveAll() {
|
||||||
|
for (Map.Entry<K, T> entry : valuesCache.entrySet()) {
|
||||||
|
K key = entry.getKey();
|
||||||
|
T value = entry.getValue();
|
||||||
|
ConfigurationHolder<?> holder = holder(key);
|
||||||
|
try {
|
||||||
|
write(holder, value);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all keys in the cache.
|
||||||
|
*
|
||||||
|
* @return All keys in the cache.
|
||||||
|
*/
|
||||||
|
public @NotNull Set<K> keys() {
|
||||||
|
return valuesCache.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all values in the cache.
|
||||||
|
*
|
||||||
|
* @return All values in the cache.
|
||||||
|
*/
|
||||||
|
public @NotNull Map<K, T> values() {
|
||||||
|
return this.valuesCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of the key, or null if the value is not exist.
|
||||||
|
*
|
||||||
|
* @param key The key of the value to get.
|
||||||
|
* @return The value of the key, or null if the value is not exist.
|
||||||
|
*/
|
||||||
|
public @Nullable T get(@NotNull K key) {
|
||||||
|
return valuesCache.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the value of the key, and return the old value.
|
||||||
|
*
|
||||||
|
* @param key The key of the value to update.
|
||||||
|
* @param value The new value, or null to remove the value.
|
||||||
|
* @return The old value, or null if the value is not exist.
|
||||||
|
*/
|
||||||
|
public @Nullable T update(@NotNull K key, @Nullable T value) {
|
||||||
|
if (value == null) {
|
||||||
|
T current = valuesCache.remove(key);
|
||||||
|
removeHolder(key);
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
ConfigurationHolder<?> holder = holder(key);
|
||||||
|
write(holder, value);
|
||||||
|
return valuesCache.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+73
@@ -0,0 +1,73 @@
|
|||||||
|
package cc.carm.lib.configuration.multi;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public abstract class MultiFileConfiguration<K, T> extends MultiConfiguration<K, T> {
|
||||||
|
|
||||||
|
protected final @NotNull File dataFolder;
|
||||||
|
protected final @NotNull String extensionSuffix; // e.g. ".yml"
|
||||||
|
|
||||||
|
protected final ConcurrentHashMap<K, ConfigurationHolder<?>> holders = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public MultiFileConfiguration(@NotNull File dataFolder, @NotNull String extensionSuffix) {
|
||||||
|
this.dataFolder = dataFolder;
|
||||||
|
this.extensionSuffix = extensionSuffix;
|
||||||
|
|
||||||
|
// Load existing configuration files
|
||||||
|
if (dataFolder.exists() && dataFolder.isDirectory()) {
|
||||||
|
File[] files = dataFolder.listFiles((dir, name) -> name.endsWith(extensionSuffix));
|
||||||
|
if (files != null) {
|
||||||
|
for (File file : files) {
|
||||||
|
String fileName = file.getName();
|
||||||
|
String keyStr = fileName.substring(0, fileName.length() - extensionSuffix.length()); // Remove extension suffix
|
||||||
|
try {
|
||||||
|
holders.put(extractKeyFromFilename(keyStr), loadHolder(file));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract K extractKeyFromFilename(@NotNull String fileName);
|
||||||
|
|
||||||
|
public String keyToFilename(@NotNull K key) {
|
||||||
|
return key.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract ConfigurationHolder<?> loadHolder(@NotNull File file);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Map<K, ConfigurationHolder<?>> holders() {
|
||||||
|
return this.holders;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ConfigurationHolder<?> holder(@NotNull K key) {
|
||||||
|
ConfigurationHolder<?> loaded = holders.get(key);
|
||||||
|
if (loaded != null) return loaded;
|
||||||
|
|
||||||
|
File file = new File(dataFolder, keyToFilename(key) + this.extensionSuffix);
|
||||||
|
ConfigurationHolder<?> created = loadHolder(file);
|
||||||
|
holders.put(key, created);
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeHolder(@NotNull K key) {
|
||||||
|
ConfigurationHolder<?> loaded = holders.remove(key);
|
||||||
|
if (loaded == null) return;
|
||||||
|
|
||||||
|
File file = new File(dataFolder, key + ".yml");
|
||||||
|
if (file.exists()) file.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package cc.carm.lib.configuration.tests;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.multi.MultiFileConfiguration;
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
|
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||||
|
import cc.carm.lib.configuration.source.yaml.YAMLConfigFactory;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MultiFileTests {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
|
||||||
|
ProfileStorage storage = new ProfileStorage(new File(new File("target"), "test-profiles"));
|
||||||
|
|
||||||
|
// Add (or create) a new entry to file.
|
||||||
|
UserProfile profile = new UserProfile(UUID.randomUUID(), "John Doe", "john@google.com", "123123123");
|
||||||
|
storage.update(profile.getUniqueId(), profile);
|
||||||
|
|
||||||
|
// Read files.
|
||||||
|
System.out.println("Current users: ");
|
||||||
|
storage.values().forEach((k, v) -> {
|
||||||
|
System.out.println("# " + k);
|
||||||
|
System.out.println("- " + v.getName() + " (" + v.getEmail() + ", " + v.getPhone() + ")");
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ProfileStorage extends MultiFileConfiguration<UUID, UserProfile> {
|
||||||
|
|
||||||
|
|
||||||
|
public ProfileStorage(@NotNull File dataFolder) {
|
||||||
|
super(dataFolder, ".yml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserProfile read(@NotNull UUID key, @NotNull ConfigurationHolder<?> holder) {
|
||||||
|
ConfigureSection conf = holder.config();
|
||||||
|
return new UserProfile(
|
||||||
|
key,
|
||||||
|
conf.getString("name", "Unknown"),
|
||||||
|
conf.getString("email", "unset"),
|
||||||
|
conf.getString("phone", "123123123")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(@NotNull ConfigurationHolder<?> holder, @NotNull UserProfile value) {
|
||||||
|
ConfigureSection conf = holder.config();
|
||||||
|
conf.set("name", value.getName());
|
||||||
|
conf.set("email", value.getEmail());
|
||||||
|
conf.set("phone", value.getPhone());
|
||||||
|
try {
|
||||||
|
holder.save();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UUID extractKeyFromFilename(@NotNull String fileName) {
|
||||||
|
return UUID.fromString(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConfigurationHolder<?> loadHolder(@NotNull File file) {
|
||||||
|
return YAMLConfigFactory.from(file).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package cc.carm.lib.configuration.tests;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UserProfile {
|
||||||
|
|
||||||
|
protected final @NotNull UUID uuid;
|
||||||
|
protected final @NotNull String name;
|
||||||
|
protected final @NotNull String email;
|
||||||
|
protected final @NotNull String phone;
|
||||||
|
|
||||||
|
public UserProfile(@NotNull UUID uuid, @NotNull String name, @NotNull String email, @NotNull String phone) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.name = name;
|
||||||
|
this.email = email;
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull UUID getUniqueId() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull String getPhone() {
|
||||||
|
return phone;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (!(o instanceof UserProfile)) return false;
|
||||||
|
UserProfile that = (UserProfile) o;
|
||||||
|
return Objects.equals(name, that.name) && Objects.equals(email, that.email) && Objects.equals(phone, that.phone);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name, email, phone);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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>
|
||||||
|
<parent>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<artifactId>configured-parent</artifactId>
|
||||||
|
<version>4.2.1</version>
|
||||||
|
<relativePath>../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>configured-feature-record</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Record Feature</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides Java record type support for the Configured framework.</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>16</maven.compiler.source>
|
||||||
|
<maven.compiler.target>16</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<artifactId>configured-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<artifactId>configured-temp</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>16</source>
|
||||||
|
<target>16</target>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
<compilerArgument>-parameters</compilerArgument>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
+114
@@ -0,0 +1,114 @@
|
|||||||
|
package cc.carm.lib.configured.adapter.record;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueAdapter;
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueParser;
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueSerializer;
|
||||||
|
import cc.carm.lib.configuration.adapter.ValueType;
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
|
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.RecordComponent;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class RecordAdapter<T extends Record> extends ValueAdapter<T> {
|
||||||
|
|
||||||
|
public static void register(ConfigurationHolder<?> holder) {
|
||||||
|
holder.adapters().register(of(Record.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <R extends Record> RecordAdapter<R> of(@NotNull Class<R> type) {
|
||||||
|
return of(ValueType.of(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <R extends Record> RecordAdapter<R> of(@NotNull ValueType<R> type) {
|
||||||
|
return new RecordAdapter<>(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RecordAdapter(@NotNull ValueType<T> type) {
|
||||||
|
super(type, serializer(type), parser(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <R extends Record> ValueSerializer<R> serializer(@NotNull ValueType<R> type) {
|
||||||
|
return (holder, type1, r) -> toMap(holder, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <R extends Record> ValueParser<R> parser(@NotNull ValueType<R> type) {
|
||||||
|
return (holder, valueType, value) -> {
|
||||||
|
if (value instanceof ConfigureSection section) {
|
||||||
|
return fromMap(holder, (Class<R>) valueType.getRawType(), section.asMap());
|
||||||
|
} else if (value instanceof Map<?, ?> map) {
|
||||||
|
return fromMap(holder, (Class<R>) valueType.getRawType(), (Map<String, Object>) map);
|
||||||
|
} else return null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <R extends Record> Map<String, Object> toMap(
|
||||||
|
@NotNull ConfigurationHolder<?> holder, @NotNull R record
|
||||||
|
) throws Exception {
|
||||||
|
Map<String, Object> map = new LinkedHashMap<>();
|
||||||
|
Class<?> recordClass = record.getClass();
|
||||||
|
if (!recordClass.isRecord()) {
|
||||||
|
throw new IllegalArgumentException("Object is not a record");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
for (RecordComponent component : recordClass.getRecordComponents()) {
|
||||||
|
String name = component.getName();
|
||||||
|
Method accessor = component.getAccessor();
|
||||||
|
accessor.setAccessible(true);
|
||||||
|
Object value = accessor.invoke(record);
|
||||||
|
map.put(name, serializeValue(holder, value));
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new RuntimeException("Failed to convert record to map", e);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <R extends Record> R fromMap(
|
||||||
|
@NotNull ConfigurationHolder<?> holder,
|
||||||
|
@NotNull Class<R> type, @NotNull Map<String, Object> data
|
||||||
|
) throws Exception {
|
||||||
|
RecordComponent[] components = type.getRecordComponents();
|
||||||
|
Object[] args = new Object[components.length];
|
||||||
|
for (int i = 0; i < components.length; i++) {
|
||||||
|
RecordComponent component = components[i];
|
||||||
|
args[i] = parseValue(holder, component, data.get(component.getName()));
|
||||||
|
}
|
||||||
|
return createInstance(type, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static Object parseValue(ConfigurationHolder<?> holder, RecordComponent component, Object value) throws Exception {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (component.getType().isRecord()) {
|
||||||
|
return fromMap(holder, component.getType().asSubclass(Record.class), (Map<String, Object>) value);
|
||||||
|
}
|
||||||
|
ValueType<?> valueType = ValueType.of(component.getGenericType());
|
||||||
|
return holder.deserialize(valueType, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object serializeValue(ConfigurationHolder<?> holder, Object value) throws Exception {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (value.getClass().isRecord()) {
|
||||||
|
return toMap(holder, (Record) value);
|
||||||
|
}
|
||||||
|
return holder.serialize(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> T createInstance(Class<T> t, Object[] args) throws Exception {
|
||||||
|
Class<?>[] paramTypes = Arrays.stream(t.getRecordComponents())
|
||||||
|
.map(RecordComponent::getType).toArray(Class[]::new);
|
||||||
|
Constructor<T> constructor = t.getDeclaredConstructor(paramTypes);
|
||||||
|
constructor.setAccessible(true); // Make sure the constructor is accessible
|
||||||
|
return constructor.newInstance(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
import cc.carm.lib.configuration.Configuration;
|
||||||
|
import cc.carm.lib.configuration.annotation.ConfigPath;
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
|
import cc.carm.lib.configuration.source.temp.TempConfigFactory;
|
||||||
|
import cc.carm.lib.configuration.value.standard.ConfiguredList;
|
||||||
|
import cc.carm.lib.configuration.value.standard.ConfiguredMap;
|
||||||
|
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||||
|
import cc.carm.lib.configured.adapter.record.RecordAdapter;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class RecordTest {
|
||||||
|
|
||||||
|
@ConfigPath(root = true)
|
||||||
|
interface ConfigA extends Configuration {
|
||||||
|
|
||||||
|
ConfiguredValue<Device> VAL = ConfiguredValue.of(new Device(
|
||||||
|
"device1",
|
||||||
|
"My Device",
|
||||||
|
UUID.fromString("123e4567-e89b-12d3-a456-426614174000"),
|
||||||
|
new Chip("chip1", null),
|
||||||
|
Arrays.asList(
|
||||||
|
new User("Alice", 30),
|
||||||
|
new User("Bob", 25)
|
||||||
|
),
|
||||||
|
Map.of(
|
||||||
|
"Cloud", new Connection("cloud.example.com", 443),
|
||||||
|
"Local", new Connection("127.0.0.1", 8080)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
ConfiguredMap<String, Device> DEVICES = ConfiguredMap.builderOf(Device.class)
|
||||||
|
.asHashMap().fromObject()
|
||||||
|
.defaults(m -> {
|
||||||
|
Device d = randomDevice();
|
||||||
|
m.put(d.id, d);
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ConfiguredList<Device> DEVICE_LIST = ConfiguredList.with(Device.class)
|
||||||
|
.defaults(Arrays.asList(randomDevice(), randomDevice()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigPath(root = true)
|
||||||
|
interface ConfigB extends Configuration {
|
||||||
|
|
||||||
|
ConfiguredValue<Device> VAL = ConfiguredValue.of(Device.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
|
||||||
|
ConfigurationHolder<?> holder = TempConfigFactory.create().build();
|
||||||
|
RecordAdapter.register(holder);
|
||||||
|
holder.initialize(ConfigA.class);
|
||||||
|
|
||||||
|
System.out.println("Device ID: " + ConfigA.VAL.resolve().id());
|
||||||
|
System.out.println("Device Name: " + ConfigA.VAL.resolve().name());
|
||||||
|
System.out.println("Device Serial: " + ConfigA.VAL.resolve().serial());
|
||||||
|
System.out.println("Chip ID: " + ConfigA.VAL.resolve().chip().id());
|
||||||
|
System.out.println("Chip Serial: " + ConfigA.VAL.resolve().chip().serialNumber());
|
||||||
|
for (User user : ConfigA.VAL.resolve().users()) {
|
||||||
|
System.out.println("Another Users: " + user.name() + ", Age: " + user.age());
|
||||||
|
}
|
||||||
|
|
||||||
|
printMap(holder.config().asMap(), 0);
|
||||||
|
|
||||||
|
ConfigA.DEVICES.forEach((k, v) -> {
|
||||||
|
System.out.println("Device Key: " + k + ", ID: " + v.id + ", Name: " + v.name);
|
||||||
|
});
|
||||||
|
|
||||||
|
ConfigA.DEVICE_LIST.forEach((v) -> {
|
||||||
|
System.out.println("Device ID: " + v.id + ", Name: " + v.name);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// List<User> parsed = holder.deserialize(ValueType.ofList(User.class), holder.config().getList("val.users"));
|
||||||
|
// System.out.println("Parsed Users: " + parsed);
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
ConfigurationHolder<?> anotherHolder = TempConfigFactory.create().defaults(() -> holder.config().asMap()).build();
|
||||||
|
RecordAdapter.register(anotherHolder);
|
||||||
|
|
||||||
|
anotherHolder.initialize(ConfigB.class);
|
||||||
|
|
||||||
|
System.out.println("Another Device ID: " + ConfigB.VAL.resolve().id());
|
||||||
|
System.out.println("Another Device Name: " + ConfigB.VAL.resolve().name());
|
||||||
|
System.out.println("Another Device Serial: " + ConfigB.VAL.resolve().serial());
|
||||||
|
System.out.println("Another Chip ID: " + ConfigB.VAL.resolve().chip().id());
|
||||||
|
System.out.println("Another Chip Serial: " + ConfigB.VAL.resolve().chip().serialNumber());
|
||||||
|
System.out.println("users: " + ConfigB.VAL.resolve().users().size());
|
||||||
|
for (User user : ConfigB.VAL.resolve().users()) {
|
||||||
|
System.out.println("Another Users: " + user.name() + ", Age: " + user.age());
|
||||||
|
}
|
||||||
|
ConfigB.VAL.resolve().connections.forEach((k, v) -> {
|
||||||
|
System.out.println("Connection " + k + ": " + v.address() + ":" + v.port());
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
record User(String name, int age) {
|
||||||
|
}
|
||||||
|
|
||||||
|
record Connection(String address, int port) {
|
||||||
|
}
|
||||||
|
|
||||||
|
record Device(String id, String name, UUID serial, Chip chip,
|
||||||
|
List<User> users,
|
||||||
|
Map<String, Connection> connections) {
|
||||||
|
}
|
||||||
|
|
||||||
|
record Chip(String id, @Nullable String serialNumber) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Device randomDevice() {
|
||||||
|
return new Device(
|
||||||
|
"device-" + UUID.randomUUID(),
|
||||||
|
"Device " + (int) (Math.random() * 100),
|
||||||
|
UUID.randomUUID(),
|
||||||
|
new Chip("chip-" + UUID.randomUUID(), "SN" + (int) (Math.random() * 10000)),
|
||||||
|
Arrays.asList(
|
||||||
|
new User("User" + (int) (Math.random() * 100), (int) (Math.random() * 50 + 10)),
|
||||||
|
new User("User" + (int) (Math.random() * 100), (int) (Math.random() * 50 + 10))
|
||||||
|
),
|
||||||
|
Map.of(
|
||||||
|
"Cloud", new Connection("cloud.example.com", 443),
|
||||||
|
"Local", new Connection("192.168.1." + (int) (Math.random() * 255), 8080)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void printMap(Map<String, Object> map, int indent) {
|
||||||
|
String indentStr = " ".repeat(indent);
|
||||||
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||||
|
if (entry.getValue() instanceof Map<?, ?> subMap) {
|
||||||
|
System.out.println(indentStr + entry.getKey() + ":");
|
||||||
|
printMap((Map<String, Object>) subMap, indent + 2);
|
||||||
|
} else if (entry.getValue() instanceof List<?> subList) {
|
||||||
|
System.out.println(indentStr + entry.getKey() + ":");
|
||||||
|
for (Object item : subList) {
|
||||||
|
if (item instanceof Map<?, ?> itemMap) {
|
||||||
|
System.out.println(indentStr + " - ");
|
||||||
|
printMap((Map<String, Object>) itemMap, indent + 2);
|
||||||
|
} else {
|
||||||
|
System.out.println(indentStr + " - " + item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println(indentStr + entry.getKey() + ": " + entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
@@ -19,6 +19,10 @@
|
|||||||
<artifactId>configured-feature-section</artifactId>
|
<artifactId>configured-feature-section</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Section Feature</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides section support for organizing configuration files in the Configured framework.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
@@ -19,6 +19,10 @@
|
|||||||
<artifactId>configured-feature-text</artifactId>
|
<artifactId>configured-feature-text</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Text Feature</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides text processing and formatting support for the Configured framework.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
-1
@@ -1,6 +1,5 @@
|
|||||||
package cc.carm.lib.configuration.value.text.function;
|
package cc.carm.lib.configuration.value.text.function;
|
||||||
|
|
||||||
import cc.carm.lib.configuration.value.text.data.TextContents;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|||||||
+2
-1
@@ -39,7 +39,8 @@ public abstract class ContentInserter<RECEIVER> implements Comparable<ContentIns
|
|||||||
@NotNull Insertable<RECEIVER, ?> insertions) {
|
@NotNull Insertable<RECEIVER, ?> insertions) {
|
||||||
Matcher matcher = matcher(line);
|
Matcher matcher = matcher(line);
|
||||||
if (!matcher.matches()) return null;
|
if (!matcher.matches()) return null;
|
||||||
if (!insertions.inserting(extractID(matcher))) return Collections.emptyList();
|
String id = extractID(matcher);
|
||||||
|
if (id == null || !insertions.inserting(id)) return Collections.emptyList();
|
||||||
return get(receiver, matcher, insertions);
|
return get(receiver, matcher, insertions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
@@ -47,8 +47,13 @@ public abstract class ContentReplacer<RECEIVER> implements Comparable<ContentRep
|
|||||||
Matcher matcher = matcher(text);
|
Matcher matcher = matcher(text);
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
|
try {
|
||||||
String replaced = get(receiver, matcher);
|
String replaced = get(receiver, matcher);
|
||||||
matcher.appendReplacement(sb, replaced == null ? "" : replaced);
|
matcher.appendReplacement(sb, replaced == null ? "" : replaced);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
// Do nothing if exception occurred.
|
||||||
|
ex.printStackTrace(); // for debug
|
||||||
|
}
|
||||||
}
|
}
|
||||||
matcher.appendTail(sb);
|
matcher.appendTail(sb);
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
@@ -19,6 +19,10 @@
|
|||||||
<artifactId>configured-feature-validators</artifactId>
|
<artifactId>configured-feature-validators</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Validators Feature</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides validation utilities for configuration values in the Configured framework.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
@@ -19,6 +19,10 @@
|
|||||||
<artifactId>configured-feature-versioned</artifactId>
|
<artifactId>configured-feature-versioned</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Versioned Feature</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Adds versioning support for configuration files in the Configured framework.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
|
|||||||
@@ -5,28 +5,31 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.jdk.version>1.8</project.jdk.version>
|
<project.jdk.version>8</project.jdk.version>
|
||||||
<maven.compiler.source>${project.jdk.version}</maven.compiler.source>
|
<maven.compiler.source>${project.jdk.version}</maven.compiler.source>
|
||||||
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
|
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
<kotlin.version>2.1.20</kotlin.version>
|
<kotlin.version>2.3.21</kotlin.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<modules>
|
<modules>
|
||||||
<module>core</module>
|
<module>core</module>
|
||||||
<module>features/section</module>
|
<module>features/section</module>
|
||||||
<module>features/file</module>
|
<module>features/file</module>
|
||||||
|
<module>features/collections</module>
|
||||||
<module>features/commentable</module>
|
<module>features/commentable</module>
|
||||||
<module>features/versioned</module>
|
<module>features/versioned</module>
|
||||||
<module>features/validators</module>
|
<module>features/validators</module>
|
||||||
<module>features/text</module>
|
<module>features/text</module>
|
||||||
<module>features/kotlin</module>
|
<module>features/kotlin</module>
|
||||||
|
<module>features/record</module>
|
||||||
|
|
||||||
|
<module>providers/temp</module>
|
||||||
<module>providers/yaml</module>
|
<module>providers/yaml</module>
|
||||||
<module>providers/gson</module>
|
<module>providers/gson</module>
|
||||||
<module>providers/hocon</module>
|
<module>providers/hocon</module>
|
||||||
@@ -34,10 +37,15 @@
|
|||||||
<module>providers/mongodb</module>
|
<module>providers/mongodb</module>
|
||||||
|
|
||||||
<module>demo</module>
|
<module>demo</module>
|
||||||
|
<module>features/multi</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<name>configured</name>
|
<name>configured</name>
|
||||||
<description>A simple, easy-to-use and universal solution for managing configuration files.</description>
|
<description>
|
||||||
|
"Once set, Simple get."
|
||||||
|
A simple, easy-to-use and universal solution
|
||||||
|
for managing configuration files.
|
||||||
|
</description>
|
||||||
<url>https://github.com/CarmJos/configured</url>
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
|
||||||
<developers>
|
<developers>
|
||||||
@@ -51,7 +59,7 @@
|
|||||||
</developers>
|
</developers>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
<connection>scm:git:git@github.com:CarmJos/Easy.configured</connection>
|
<connection>scm:git:git@github.com:CarmJos/configured</connection>
|
||||||
<developerConnection>scm:git:git@github.com:CarmJos/configured.git</developerConnection>
|
<developerConnection>scm:git:git@github.com:CarmJos/configured.git</developerConnection>
|
||||||
<url>https://github.com/CarmJos/configured</url>
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
<tag>HEAD</tag>
|
<tag>HEAD</tag>
|
||||||
@@ -76,22 +84,21 @@
|
|||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
|
|
||||||
<repository>
|
|
||||||
<id>carm-repo</id>
|
|
||||||
<name>Carm's Repo</name>
|
|
||||||
<url>https://repo.carm.cc/repository/maven-public/</url>
|
|
||||||
</repository>
|
|
||||||
|
|
||||||
<repository>
|
|
||||||
<id>nexus</id>
|
|
||||||
<url>https://mvn.lumine.io/repository/maven-public/</url>
|
|
||||||
</repository>
|
|
||||||
|
|
||||||
<repository>
|
<repository>
|
||||||
<id>central</id>
|
<id>central</id>
|
||||||
<url>https://repo1.maven.org/maven2/</url>
|
<url>https://repo1.maven.org/maven2/</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
|
||||||
|
<repository>
|
||||||
|
<id>sonatype</id>
|
||||||
|
<url>https://s01.oss.sonatype.org/content/groups/public/</url>
|
||||||
|
</repository>
|
||||||
|
|
||||||
|
<repository>
|
||||||
|
<id>jitpack.io</id>
|
||||||
|
<url>https://jitpack.io</url>
|
||||||
|
</repository>
|
||||||
|
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
@@ -115,7 +122,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains</groupId>
|
<groupId>org.jetbrains</groupId>
|
||||||
<artifactId>annotations</artifactId>
|
<artifactId>annotations</artifactId>
|
||||||
<version>26.0.2</version>
|
<version>26.1.0</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -128,7 +135,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>3.5.3</version>
|
<version>3.5.6</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<useSystemClassLoader>false</useSystemClassLoader>
|
<useSystemClassLoader>false</useSystemClassLoader>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -136,7 +143,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-gpg-plugin</artifactId>
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
<version>3.2.7</version>
|
<version>3.2.8</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>sign-artifacts</id>
|
<id>sign-artifacts</id>
|
||||||
@@ -156,7 +163,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-release-plugin</artifactId>
|
<artifactId>maven-release-plugin</artifactId>
|
||||||
<version>3.1.1</version>
|
<version>3.3.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<autoVersionSubmodules>true</autoVersionSubmodules>
|
<autoVersionSubmodules>true</autoVersionSubmodules>
|
||||||
<useReleaseProfile>false</useReleaseProfile>
|
<useReleaseProfile>false</useReleaseProfile>
|
||||||
@@ -171,7 +178,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-javadoc-plugin</artifactId>
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
<version>3.11.2</version>
|
<version>3.12.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<classifier>javadoc</classifier>
|
<classifier>javadoc</classifier>
|
||||||
<detectJavaApiLink>false</detectJavaApiLink>
|
<detectJavaApiLink>false</detectJavaApiLink>
|
||||||
@@ -198,7 +205,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.14.0</version>
|
<version>3.15.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>${project.jdk.version}</source>
|
<source>${project.jdk.version}</source>
|
||||||
<target>${project.jdk.version}</target>
|
<target>${project.jdk.version}</target>
|
||||||
@@ -210,13 +217,13 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>3.4.2</version>
|
<version>3.5.0</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-source-plugin</artifactId>
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
<version>3.3.1</version>
|
<version>3.4.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
@@ -230,7 +237,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.6.0</version>
|
<version>3.6.2</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
@@ -277,11 +284,14 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.sonatype.central</groupId>
|
<groupId>org.sonatype.central</groupId>
|
||||||
<artifactId>central-publishing-maven-plugin</artifactId>
|
<artifactId>central-publishing-maven-plugin</artifactId>
|
||||||
<version>0.7.0</version>
|
<version>0.10.0</version>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
<configuration>
|
<configuration>
|
||||||
<publishingServerId>central</publishingServerId>
|
<publishingServerId>central</publishingServerId>
|
||||||
<autoPublish>true</autoPublish>
|
<autoPublish>true</autoPublish>
|
||||||
|
<excludeArtifacts>
|
||||||
|
<excludeArtifact>configured-demo</excludeArtifact>
|
||||||
|
</excludeArtifacts>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
|||||||
@@ -1,8 +1,24 @@
|
|||||||
# configured-JSON
|
# configured-JSON
|
||||||
|
|
||||||
JSON file-based implementation, compatible with all Java environments.
|
JSON
|
||||||
|
file-based
|
||||||
|
implementation,
|
||||||
|
compatible
|
||||||
|
with
|
||||||
|
all
|
||||||
|
Java
|
||||||
|
environments.
|
||||||
|
|
||||||
**Remember that JSON does not support file comments.**
|
*
|
||||||
|
*Remember
|
||||||
|
that
|
||||||
|
JSON
|
||||||
|
does
|
||||||
|
not
|
||||||
|
support
|
||||||
|
file
|
||||||
|
comments.
|
||||||
|
**
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
@@ -18,6 +18,10 @@
|
|||||||
<artifactId>configured-gson</artifactId>
|
<artifactId>configured-gson</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Gson Provider</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides Gson (JSON) file support for the Configured framework.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -44,7 +48,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.13.0</version>
|
<version>2.14.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
# configured-HOCON
|
# configured-HOCON
|
||||||
|
|
||||||
HOCON file-based implementation, compatible with all Java environments.
|
HOCON
|
||||||
|
file-based
|
||||||
|
implementation,
|
||||||
|
compatible
|
||||||
|
with
|
||||||
|
all
|
||||||
|
Java
|
||||||
|
environments.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
@@ -18,6 +18,10 @@
|
|||||||
<artifactId>configured-hocon</artifactId>
|
<artifactId>configured-hocon</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - HOCON Provider</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides HOCON file support for the Configured framework.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.parent.groupId}</groupId>
|
<groupId>${project.parent.groupId}</groupId>
|
||||||
@@ -46,7 +50,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.typesafe</groupId>
|
<groupId>com.typesafe</groupId>
|
||||||
<artifactId>config</artifactId>
|
<artifactId>config</artifactId>
|
||||||
<version>1.4.3</version>
|
<version>1.4.9</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
+4
-1
@@ -9,7 +9,10 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class HOCONSource
|
public class HOCONSource
|
||||||
extends FileConfigSource<SourcedSection, Map<String, Object>, HOCONSource> {
|
extends FileConfigSource<SourcedSection, Map<String, Object>, HOCONSource> {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
@@ -14,9 +14,14 @@
|
|||||||
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
|
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
<deps.mongodb.version>5.4.0</deps.mongodb.version>
|
<deps.mongodb.version>5.8.0</deps.mongodb.version>
|
||||||
</properties>
|
</properties>
|
||||||
<artifactId>configured-mongodb</artifactId>
|
<artifactId>configured-mongodb</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - MongoDB Provider</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides MongoDB database support for the Configured framework.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
|
|||||||
+46
-13
@@ -1,8 +1,16 @@
|
|||||||
# configured-SQL
|
# configured-SQL
|
||||||
|
|
||||||
SQL database implementation, support for MySQL or MariaDB.
|
SQL
|
||||||
|
database
|
||||||
|
implementation,
|
||||||
|
support
|
||||||
|
for
|
||||||
|
MySQL
|
||||||
|
or
|
||||||
|
MariaDB.
|
||||||
|
|
||||||
## Table schema
|
## Table schema
|
||||||
|
|
||||||
```mysql
|
```mysql
|
||||||
CREATE TABLE IF NOT EXISTS conf
|
CREATE TABLE IF NOT EXISTS conf
|
||||||
(
|
(
|
||||||
@@ -16,8 +24,10 @@ CREATE TABLE IF NOT EXISTS conf
|
|||||||
`version` MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, # 配置项的版本
|
`version` MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, # 配置项的版本
|
||||||
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, # 创建时间
|
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, # 创建时间
|
||||||
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`namespace`, `path`)
|
PRIMARY KEY (`namespace`,
|
||||||
) ENGINE = InnoDB
|
`path`)
|
||||||
|
)
|
||||||
|
ENGINE = InnoDB
|
||||||
DEFAULT CHARSET = utf8mb4;
|
DEFAULT CHARSET = utf8mb4;
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -32,16 +42,30 @@ CREATE TABLE IF NOT EXISTS conf
|
|||||||
|
|
||||||
<repository>
|
<repository>
|
||||||
<!-- Using Maven Central Repository for secure and stable updates, though synchronization might be needed. -->
|
<!-- Using Maven Central Repository for secure and stable updates, though synchronization might be needed. -->
|
||||||
<id>maven</id>
|
<id>
|
||||||
<name>Maven Central</name>
|
maven
|
||||||
<url>https://repo1.maven.org/maven2</url>
|
</id>
|
||||||
|
<name>
|
||||||
|
Maven
|
||||||
|
Central
|
||||||
|
</name>
|
||||||
|
<url>
|
||||||
|
https://repo1.maven.org/maven2
|
||||||
|
</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
|
||||||
<repository>
|
<repository>
|
||||||
<!-- Using GitHub dependencies for real-time updates, configuration required (recommended). -->
|
<!-- Using GitHub dependencies for real-time updates, configuration required (recommended). -->
|
||||||
<id>configured</id>
|
<id>
|
||||||
<name>GitHub Packages</name>
|
configured
|
||||||
<url>https://maven.pkg.github.com/CarmJos/configured</url>
|
</id>
|
||||||
|
<name>
|
||||||
|
GitHub
|
||||||
|
Packages
|
||||||
|
</name>
|
||||||
|
<url>
|
||||||
|
https://maven.pkg.github.com/CarmJos/configured
|
||||||
|
</url>
|
||||||
</repository>
|
</repository>
|
||||||
|
|
||||||
</repositories>
|
</repositories>
|
||||||
@@ -53,10 +77,19 @@ CREATE TABLE IF NOT EXISTS conf
|
|||||||
<project>
|
<project>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>
|
||||||
<artifactId>configured-sql</artifactId>
|
cc.carm.lib
|
||||||
<version>[LATEST RELEASE]</version>
|
</groupId>
|
||||||
<scope>compile</scope>
|
<artifactId>
|
||||||
|
configured-sql
|
||||||
|
</artifactId>
|
||||||
|
<version>
|
||||||
|
[LATEST
|
||||||
|
RELEASE]
|
||||||
|
</version>
|
||||||
|
<scope>
|
||||||
|
compile
|
||||||
|
</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
@@ -16,6 +16,11 @@
|
|||||||
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
</properties>
|
</properties>
|
||||||
<artifactId>configured-sql</artifactId>
|
<artifactId>configured-sql</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - SQL Provider</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides SQL database support for the Configured framework.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
@@ -49,7 +54,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
<artifactId>gson</artifactId>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.13.0</version>
|
<version>2.14.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ public interface SQLOptions {
|
|||||||
/**
|
/**
|
||||||
* Whether to purge the configuration's in-database data when saving.
|
* Whether to purge the configuration's in-database data when saving.
|
||||||
*/
|
*/
|
||||||
ConfigurationOption<Boolean> PURGE = ConfigurationOption.of( true);
|
ConfigurationOption<Boolean> PURGE = ConfigurationOption.of(true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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>
|
||||||
|
<parent>
|
||||||
|
<artifactId>configured-parent</artifactId>
|
||||||
|
<groupId>cc.carm.lib</groupId>
|
||||||
|
<version>4.2.1</version>
|
||||||
|
<relativePath>../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>${project.jdk.version}</maven.compiler.source>
|
||||||
|
<maven.compiler.target>${project.jdk.version}</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<artifactId>configured-temp</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Configured - Temp Provider</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides a temporary in-memory configuration provider for the Configured framework.</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.parent.groupId}</groupId>
|
||||||
|
<artifactId>configured-core</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.parent.groupId}</groupId>
|
||||||
|
<artifactId>configured-feature-section</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
package cc.carm.lib.configuration.source.temp;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationFactory;
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class TempConfigFactory
|
||||||
|
extends ConfigurationFactory<TempSource, ConfigurationHolder<TempSource>, TempConfigFactory> {
|
||||||
|
|
||||||
|
public static @NotNull TempConfigFactory create() {
|
||||||
|
return new TempConfigFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<String, Object> defaults = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
public TempConfigFactory defaults(@NotNull Map<String, Object> defaults) {
|
||||||
|
this.defaults = defaults;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TempConfigFactory defaults(Supplier<Map<String, Object>> defaultsSupplier) {
|
||||||
|
return defaults(defaultsSupplier.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TempConfigFactory defaults(@NotNull Consumer<Map<String, Object>> defaultsConsumer) {
|
||||||
|
return defaults(() -> {
|
||||||
|
Map<String, Object> defaults = new LinkedHashMap<>();
|
||||||
|
defaultsConsumer.accept(defaults);
|
||||||
|
return defaults;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TempConfigFactory self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull ConfigurationHolder<TempSource> build() {
|
||||||
|
|
||||||
|
return new ConfigurationHolder<TempSource>(this.adapters, this.options, this.metadata, this.initializer) {
|
||||||
|
final @NotNull TempSource source = new TempSource(this, defaults);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull TempSource config() {
|
||||||
|
return this.source;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package cc.carm.lib.configuration.source.temp;
|
||||||
|
|
||||||
|
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||||
|
import cc.carm.lib.configuration.source.section.ConfigureSource;
|
||||||
|
import cc.carm.lib.configuration.source.section.SourcedSection;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class TempSource extends ConfigureSource<SourcedSection, Map<String, Object>, TempSource> {
|
||||||
|
|
||||||
|
|
||||||
|
protected @NotNull SourcedSection rootSection;
|
||||||
|
|
||||||
|
protected TempSource(@NotNull ConfigurationHolder<? extends TempSource> holder,
|
||||||
|
@NotNull Map<String, Object> defaults) {
|
||||||
|
super(holder, 0);
|
||||||
|
this.rootSection = SourcedSection.root(this, defaults);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @NotNull TempSource self() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull Map<String, Object> original() {
|
||||||
|
return section().data();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull SourcedSection section() {
|
||||||
|
return Objects.requireNonNull(this.rootSection, "Root section is not initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save() throws Exception {
|
||||||
|
// Nothing to do here.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onReload() throws Exception {
|
||||||
|
// Also nothing to do, because this is a temporary source.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,13 @@
|
|||||||
# configured-YAML
|
# configured-YAML
|
||||||
|
|
||||||
YAML file-based implementation, compatible with all Java environments.
|
YAML
|
||||||
|
file-based
|
||||||
|
implementation,
|
||||||
|
compatible
|
||||||
|
with
|
||||||
|
all
|
||||||
|
Java
|
||||||
|
environments.
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>configured-parent</artifactId>
|
<artifactId>configured-parent</artifactId>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<version>4.1.4</version>
|
<version>4.2.1</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<properties>
|
<properties>
|
||||||
@@ -19,6 +19,9 @@
|
|||||||
|
|
||||||
<artifactId>configured-yaml</artifactId>
|
<artifactId>configured-yaml</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
<name>Configured - YAML Provider</name>
|
||||||
|
<url>https://github.com/CarmJos/configured</url>
|
||||||
|
<description>Provides YAML file support for the Configured framework.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
@@ -60,7 +63,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.yaml</groupId>
|
<groupId>org.yaml</groupId>
|
||||||
<artifactId>snakeyaml</artifactId>
|
<artifactId>snakeyaml</artifactId>
|
||||||
<version>2.4</version>
|
<version>2.6</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|||||||
@@ -2,5 +2,12 @@
|
|||||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
"extends": [
|
"extends": [
|
||||||
"config:recommended"
|
"config:recommended"
|
||||||
|
],
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"matchUpdateTypes": ["minor", "patch"],
|
||||||
|
"matchCurrentVersion": "!/^0/",
|
||||||
|
"automerge": true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user