mirror of
https://github.com/CarmJos/EasyConfiguration.git
synced 2026-06-04 10:38:19 +08:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0bfd15aaad | |||
| 15f395a8e0 | |||
| a61040a0e2 | |||
| 8766b4d77b | |||
| 8c1214612a | |||
| 608d92f834 | |||
| ad6ab9eb36 | |||
| 0eda8d8a0f | |||
| b19691b5a4 | |||
| c7331aa556 | |||
| a440c050e5 | |||
| b9d45a9bb9 | |||
| 67482de7a9 | |||
| 04bedbef07 | |||
| a4abfb733a | |||
| 76d276436b | |||
| e7198f22d5 | |||
| 5bd20e173f | |||
| 15c4bb13e8 | |||
| b74eb5c035 | |||
| ed3a68af1e | |||
| 447b82c880 | |||
| 5700f8c1c6 | |||
| 1cf230d6b6 | |||
| 1ffd4b2f0b | |||
| 92ce780d6f | |||
| a2de3303e8 | |||
| 47a1981002 | |||
| b97bc5d1a9 | |||
| cc927fdc0e | |||
| 5dc2693106 | |||
| 472ce66ca7 | |||
| 796771554f | |||
| 28cb5d4c83 | |||
| a670aec986 | |||
| 51c54b9b53 | |||
| fa99385ff0 | |||
| 70a3b893a6 |
@@ -1,3 +1,6 @@
|
||||
# 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) 。
|
||||
|
||||
+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,37 +1,70 @@
|
||||
---
|
||||
name: 问题提交
|
||||
about: 描述问题并提交,帮助我们对其进行检查与修复。
|
||||
name:
|
||||
问题提交
|
||||
about:
|
||||
描述问题并提交,帮助我们对其进行检查与修复。
|
||||
title: ''
|
||||
labels: bug
|
||||
labels:
|
||||
bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### **问题简述**
|
||||
###
|
||||
*
|
||||
*问题简述
|
||||
**
|
||||
|
||||
用简短的话语描述一下大概问题。
|
||||
|
||||
### **问题来源**
|
||||
###
|
||||
*
|
||||
*问题来源
|
||||
**
|
||||
|
||||
描述一下通过哪些操作才发现的问题,如:
|
||||
|
||||
1. 使用了 '...'
|
||||
2. 输入了 '....'
|
||||
3. 出现了报错 '....'
|
||||
1.
|
||||
使用了 '...'
|
||||
2.
|
||||
输入了 '....'
|
||||
3.
|
||||
出现了报错 '....'
|
||||
|
||||
### **预期结果** (可选)
|
||||
###
|
||||
*
|
||||
*预期结果
|
||||
** (可选)
|
||||
|
||||
如果问题不发生,应该是什么情况
|
||||
|
||||
### **问题截图/问题报错**
|
||||
###
|
||||
*
|
||||
*问题截图/问题报错
|
||||
**
|
||||
|
||||
如果有报错或输出,请提供截图。
|
||||
|
||||
### **操作环境**
|
||||
###
|
||||
*
|
||||
*操作环境
|
||||
**
|
||||
|
||||
- 系统环境: `Windows 10` / `Ubuntu` / `...`
|
||||
- Java版本: `JDK11` / `OPENJDK8` / `JRE8` / `...`
|
||||
-
|
||||
系统环境:
|
||||
`Windows 10` /
|
||||
`Ubuntu` /
|
||||
`...`
|
||||
-
|
||||
Java版本:
|
||||
`JDK11` /
|
||||
`OPENJDK8` /
|
||||
`JRE8` /
|
||||
`...`
|
||||
|
||||
### **其他补充**
|
||||
###
|
||||
*
|
||||
*其他补充
|
||||
**
|
||||
|
||||
如有其他补充,可以在这里描述。
|
||||
|
||||
@@ -1,23 +1,38 @@
|
||||
---
|
||||
name: 功能需求
|
||||
about: 希望我们提供更多的功能。
|
||||
name:
|
||||
功能需求
|
||||
about:
|
||||
希望我们提供更多的功能。
|
||||
title: ''
|
||||
labels: enhancement
|
||||
labels:
|
||||
enhancement
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
### **功能简述**
|
||||
###
|
||||
*
|
||||
*功能简述
|
||||
**
|
||||
|
||||
简单的描述一下你想要的功能
|
||||
|
||||
### **需求来源**
|
||||
###
|
||||
*
|
||||
*需求来源
|
||||
**
|
||||
|
||||
简单的描述一下为什么需要这个功能。
|
||||
|
||||
### **功能参考**(可选)
|
||||
###
|
||||
*
|
||||
*功能参考
|
||||
**(可选)
|
||||
|
||||
如果有相关功能的参考,如文本、截图,请提供给我们。
|
||||
|
||||
### **附加内容**
|
||||
###
|
||||
*
|
||||
*附加内容
|
||||
**
|
||||
|
||||
如果有什么小细节需要重点注意,请在这里告诉我们。
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
|
||||
# This workflow checks out code, performs a Codacy security scan
|
||||
# and integrates the results with the
|
||||
# GitHub Advanced Security code scanning feature. For more information on
|
||||
# the Codacy security scan action usage and parameters, see
|
||||
# https://github.com/codacy/codacy-analysis-cli-action.
|
||||
# For more information on Codacy Analysis CLI in general, see
|
||||
# https://github.com/codacy/codacy-analysis-cli.
|
||||
|
||||
name: "Codacy Security Scan"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '27 16 * * 5'
|
||||
|
||||
jobs:
|
||||
codacy-security-scan:
|
||||
name: Codacy Security Scan
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Checkout the repository to the GitHub Actions runner
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis
|
||||
- name: Run Codacy Analysis CLI
|
||||
uses: codacy/codacy-analysis-cli-action@09916000460adeeedc96b9704f86deba53e2ad5d
|
||||
with:
|
||||
# Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository
|
||||
# You can also omit the token and run the tools that support default configurations
|
||||
project-token: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
||||
verbose: true
|
||||
output: results.sarif
|
||||
format: sarif
|
||||
# Adjust severity of non-security issues
|
||||
gh-code-scanning-compat: true
|
||||
# Force 0 exit code to allow SARIF file generation
|
||||
# This will handover control about PR rejection to the GitHub side
|
||||
max-allowed-issues: 2147483647
|
||||
|
||||
# Upload the SARIF file generated in the previous step
|
||||
- name: Upload SARIF results file
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
- name: "Set up JDK"
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '11'
|
||||
java-version: '21'
|
||||
distribution: 'adopt'
|
||||
cache: maven
|
||||
server-id: github
|
||||
@@ -91,7 +91,7 @@ jobs:
|
||||
- name: "Set up JDK"
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '11'
|
||||
java-version: '21'
|
||||
distribution: 'adopt'
|
||||
cache: maven
|
||||
server-id: central
|
||||
@@ -105,4 +105,4 @@ jobs:
|
||||
env:
|
||||
MAVEN_USERNAME: ${{ secrets.OSSRH_USER }}
|
||||
MAVEN_PASSWORD: ${{ secrets.OSSRH_PASS }}
|
||||
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
|
||||
MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }}
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
- name: "Set up JDK"
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: '11'
|
||||
java-version: '21'
|
||||
distribution: 'adopt'
|
||||
- name: "Package"
|
||||
run: mvn -B package --file pom.xml -Dgpg.skip
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
[](https://github.com/CarmJos/configured/actions/workflows/maven.yml)
|
||||
[](https://www.codefactor.io/repository/github/carmjos/configured)
|
||||

|
||||

|
||||
|
||||
README LANGUAGES [ [**English**](README.md) | [中文](README_CN.md) ]
|
||||
</div>
|
||||
@@ -24,8 +23,8 @@ Supported **JSON**, **YAML**, **Hocon**, **TOML**, **SQL**, **MongoDB**... and m
|
||||
|
||||
## Features & Advantages
|
||||
|
||||
Supported [YAML](impl/yaml), [JSON](impl/json), [HOCON](impl/hocon) and [SQL](impl/sql) based configuration files
|
||||
format.
|
||||
Supported [YAML](providers/yaml), [JSON](providers/json), [HOCON](providers/hocon) and [SQL](providers/sql)
|
||||
based configuration files format.
|
||||
|
||||
- Class-based mechanism for initializing, loading, retrieving, and updating configuration files, ensuring convenience
|
||||
and efficiency.
|
||||
@@ -44,7 +43,7 @@ For a detailed development guide, [CLICK HERE](.doc/README.md).
|
||||
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)
|
||||
- [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).
|
||||
For more examples, see the [Development Guide](.doc/README.md).
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
[](https://github.com/CarmJos/configured/actions/workflows/maven.yml)
|
||||
[](https://www.codefactor.io/repository/github/carmjos/configured)
|
||||

|
||||

|
||||
|
||||
README LANGUAGES [ [English](README.md) | [**中文**](README_CN.md) ]
|
||||
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<properties>
|
||||
@@ -39,4 +39,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -4,4 +4,5 @@ package cc.carm.lib.configuration;
|
||||
* The root interface of the configuration file interfaces,
|
||||
* which is used to label a class as a configuration.
|
||||
*/
|
||||
public interface Configuration { }
|
||||
public interface Configuration {
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.Objects;
|
||||
* @param <TYPE> The type of the target value
|
||||
*/
|
||||
public class ValueAdapter<TYPE>
|
||||
implements ValueSerializer<TYPE>, ValueParser<TYPE> {
|
||||
implements ValueSerializer<TYPE>, ValueParser<TYPE> {
|
||||
|
||||
protected final @NotNull ValueType<TYPE> type;
|
||||
|
||||
@@ -55,9 +55,9 @@ public class ValueAdapter<TYPE>
|
||||
|
||||
@Override
|
||||
public @Nullable Object serialize(
|
||||
@NotNull ConfigurationHolder<?> holder,
|
||||
@NotNull ValueType<? super TYPE> type,
|
||||
@NotNull TYPE value
|
||||
@NotNull ConfigurationHolder<?> holder,
|
||||
@NotNull ValueType<? super TYPE> type,
|
||||
@NotNull TYPE value
|
||||
) throws Exception {
|
||||
if (serializer == null) throw new UnsupportedOperationException("Serializer is not supported");
|
||||
return serializer.serialize(holder, type, value);
|
||||
@@ -65,9 +65,9 @@ public class ValueAdapter<TYPE>
|
||||
|
||||
@Override
|
||||
public @Nullable TYPE parse(
|
||||
@NotNull ConfigurationHolder<?> holder,
|
||||
@NotNull ValueType<? super TYPE> type,
|
||||
@NotNull Object value
|
||||
@NotNull ConfigurationHolder<?> holder,
|
||||
@NotNull ValueType<? super TYPE> type,
|
||||
@NotNull Object value
|
||||
) throws Exception {
|
||||
if (deserializer == null) throw new UnsupportedOperationException("Deserializer is not supported");
|
||||
return deserializer.parse(holder, type, value);
|
||||
|
||||
@@ -2,12 +2,13 @@ package cc.carm.lib.configuration.adapter;
|
||||
|
||||
import cc.carm.lib.configuration.function.DataFunction;
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.source.section.ConfigureSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.*;
|
||||
|
||||
public class ValueAdapterRegistry {
|
||||
|
||||
@@ -25,8 +26,8 @@ public class ValueAdapterRegistry {
|
||||
ValueAdapter<FROM> fromAdapter = adapterOf(from);
|
||||
if (fromAdapter == null) throw new IllegalArgumentException("No adapter for type " + from);
|
||||
register(to,
|
||||
serializer == null ? null : (provider, type, value) -> fromAdapter.serialize(provider, from, serializer.handle(value)),
|
||||
parser == null ? null : (provider, type, data) -> parser.handle(fromAdapter.parse(provider, from, data))
|
||||
serializer == null ? null : (provider, type, value) -> fromAdapter.serialize(provider, from, serializer.handle(value)),
|
||||
parser == null ? null : (provider, type, data) -> parser.handle(fromAdapter.parse(provider, from, data))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -84,14 +85,14 @@ public class ValueAdapterRegistry {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> @Nullable ValueAdapter<T> adapterOf(@NotNull ValueType<T> type) {
|
||||
ValueAdapter<?> matched = adapters.stream()
|
||||
.filter(adapter -> adapter.type().equals(type))
|
||||
.findFirst().orElse(null);
|
||||
.filter(adapter -> adapter.type().equals(type))
|
||||
.findFirst().orElse(null);
|
||||
if (matched != null) return (ValueAdapter<T>) matched;
|
||||
|
||||
// If no adapter found, try to find the adapter for the super type
|
||||
return (ValueAdapter<T>) adapters.stream()
|
||||
.filter(adapter -> adapter.type().isSubtypeOf(type))
|
||||
.findFirst().orElse(null);
|
||||
.filter(adapter -> adapter.type().isSubtypeOf(type))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public <T> ValueAdapter<T> adapterOf(@NotNull T value) {
|
||||
@@ -108,20 +109,106 @@ public class ValueAdapterRegistry {
|
||||
|
||||
public <T> T deserialize(@NotNull ConfigurationHolder<?> holder, @NotNull ValueType<T> type, @Nullable Object source) throws Exception {
|
||||
if (source == null) return null; // Null check
|
||||
if (type.isInstance(source)) return type.cast(source); // Not required to deserialize
|
||||
ValueAdapter<T> adapter = adapterOf(type);
|
||||
if (adapter == null) throw new RuntimeException("No adapter for type " + type);
|
||||
return adapter.parse(holder, type, source);
|
||||
if (!(type.getType() instanceof ParameterizedType) && type.isInstance(source)) {
|
||||
return type.cast(source); // Not required to deserialize
|
||||
}
|
||||
|
||||
ValueAdapter<T> adapter = adapterOf(type); // Try to find an existed adapter for the type
|
||||
if (adapter != null) {
|
||||
return adapter.parse(holder, type, source);
|
||||
} // If no adapter found, we will try to handle the type manually
|
||||
|
||||
if (type.getRawType().isArray()) { // For arrays.
|
||||
List<?> list = deserializeList(holder, type, source);
|
||||
Object[] array = (Object[]) java.lang.reflect.Array.newInstance(type.getRawType().getComponentType(), list.size());
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
array[i] = deserialize(holder, type.getRawType().getComponentType(), list.get(i));
|
||||
}
|
||||
return type.cast(array);
|
||||
} else if (type.getType() instanceof ParameterizedType) {
|
||||
ParameterizedType pt = (ParameterizedType) type.getType();
|
||||
Type rawType = pt.getRawType();
|
||||
Type[] typeArgs = pt.getActualTypeArguments();
|
||||
if (rawType == List.class || rawType == Collection.class || rawType == ArrayList.class) {
|
||||
return type.cast(new ArrayList<>(deserializeList(holder, ValueType.of(typeArgs[0]), source)));
|
||||
} else if (rawType == Set.class || rawType == HashSet.class) {
|
||||
return type.cast(new HashSet<>(deserializeList(holder, ValueType.of(typeArgs[0]), source)));
|
||||
} else if (rawType == Map.class || rawType == LinkedHashMap.class) {
|
||||
Map<?, ?> map;
|
||||
if (source instanceof Map<?, ?>) {
|
||||
map = (Map<?, ?>) source;
|
||||
} else if (source instanceof ConfigureSection) {
|
||||
map = ((ConfigureSection) source).asMap();
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot deserialize to Map from " + source.getClass());
|
||||
}
|
||||
Map<Object, Object> resultMap = new LinkedHashMap<>(map.size());
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
Object key = deserialize(holder, ValueType.of(typeArgs[0]), entry.getKey());
|
||||
Object value = deserialize(holder, ValueType.of(typeArgs[1]), entry.getValue());
|
||||
resultMap.put(key, value);
|
||||
}
|
||||
return type.cast(resultMap);
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No adapter for type " + type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public <T> Object serialize(@NotNull ConfigurationHolder<?> holder, @Nullable T value) throws Exception {
|
||||
if (value == null) return null; // Null check
|
||||
|
||||
ValueType<T> type = ValueType.of(value);
|
||||
ValueAdapter<T> adapter = adapterOf(type);
|
||||
if (adapter == null) return value; // No adapters, try to return the original value
|
||||
return adapter.serialize(holder, type, value);
|
||||
if (adapter != null) 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
public interface ValueParser<TYPE> {
|
||||
|
||||
@Nullable TYPE parse(
|
||||
@NotNull ConfigurationHolder<?> holder,
|
||||
@NotNull ValueType<? super TYPE> type, @NotNull Object data
|
||||
@NotNull ConfigurationHolder<?> holder,
|
||||
@NotNull ValueType<? super TYPE> type, @NotNull Object data
|
||||
) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
public interface ValueSerializer<TYPE> {
|
||||
|
||||
@Nullable Object serialize(
|
||||
@NotNull ConfigurationHolder<?> holder,
|
||||
@NotNull ValueType<? super TYPE> type, @NotNull TYPE value
|
||||
@NotNull ConfigurationHolder<?> holder,
|
||||
@NotNull ValueType<? super TYPE> type, @NotNull TYPE value
|
||||
) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
package cc.carm.lib.configuration.adapter;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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> {
|
||||
|
||||
@@ -31,8 +39,8 @@ public abstract class ValueType<T> {
|
||||
public static final ValueType<Character> CHAR_TYPE = ofPrimitiveType(char.class);
|
||||
|
||||
public static final ValueType<?>[] PRIMITIVE_TYPES = {
|
||||
STRING, INTEGER, LONG, DOUBLE, FLOAT, BOOLEAN, BYTE, SHORT, CHAR,
|
||||
INTEGER_TYPE, LONG_TYPE, DOUBLE_TYPE, FLOAT_TYPE, BOOLEAN_TYPE, BYTE_TYPE, SHORT_TYPE, CHAR_TYPE
|
||||
STRING, INTEGER, LONG, DOUBLE, FLOAT, BOOLEAN, BYTE, SHORT, CHAR,
|
||||
INTEGER_TYPE, LONG_TYPE, DOUBLE_TYPE, FLOAT_TYPE, BOOLEAN_TYPE, BYTE_TYPE, SHORT_TYPE, CHAR_TYPE
|
||||
};
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -43,7 +51,7 @@ public abstract class ValueType<T> {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> ValueType<T> of(final Type type) {
|
||||
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;
|
||||
for (ValueType<?> valueType : PRIMITIVE_TYPES) {
|
||||
if (valueType.getRawType() == clazz) {
|
||||
@@ -63,6 +71,18 @@ public abstract class ValueType<T> {
|
||||
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.
|
||||
*
|
||||
@@ -91,6 +111,7 @@ public abstract class ValueType<T> {
|
||||
return of(parameterizedType);
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
private static <T> ValueType<T> ofPrimitiveType(Class<T> clazz) {
|
||||
return new ValueType<T>(clazz) {
|
||||
};
|
||||
@@ -110,40 +131,65 @@ public abstract class ValueType<T> {
|
||||
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) {
|
||||
Class<?> rawType = getRawType();
|
||||
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) {
|
||||
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) {
|
||||
return obj != null && getRawType().isInstance(obj);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 提取当前 ValueType 的原始类型(Class 对象)。
|
||||
* Extracts the raw type from the generic type.
|
||||
*
|
||||
* @return 对应的 Class 对象
|
||||
* @throws IllegalStateException 如果无法提取出原始类型
|
||||
* @return The raw type of the generic type
|
||||
* @throws IllegalStateException if the type is not a Class or ParameterizedType
|
||||
*/
|
||||
public Class<?> getRawType() {
|
||||
@SuppressWarnings("unchecked")
|
||||
public Class<T> getRawType() {
|
||||
if (type instanceof Class<?>) {
|
||||
return (Class<?>) type;
|
||||
return (Class<T>) type;
|
||||
}
|
||||
if (type instanceof ParameterizedType) {
|
||||
ParameterizedType pt = (ParameterizedType) type;
|
||||
Type raw = pt.getRawType();
|
||||
if (raw instanceof Class<?>) {
|
||||
return (Class<?>) raw;
|
||||
return (Class<T>) raw;
|
||||
}
|
||||
}
|
||||
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")
|
||||
public T cast(Object obj) {
|
||||
if (!isInstance(obj)) {
|
||||
@@ -152,6 +198,12 @@ public abstract class ValueType<T> {
|
||||
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
|
||||
public String toString() {
|
||||
if (type instanceof Class<?>) {
|
||||
|
||||
+2
-2
@@ -11,11 +11,11 @@ import java.util.Arrays;
|
||||
public class PrimitiveAdapter<T> extends ValueAdapter<T> {
|
||||
|
||||
public static final String[] TRUE_VALUES = new String[]{
|
||||
"true", "yes", "on", "1", "enabled", "enable", "active"
|
||||
"true", "yes", "on", "1", "enabled", "enable", "active"
|
||||
};
|
||||
|
||||
public static final String[] FALSE_VALUES = new String[]{
|
||||
"false", "no", "off", "0", "disabled", "disable", "inactive"
|
||||
"false", "no", "off", "0", "disabled", "disable", "inactive"
|
||||
};
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
|
||||
+13
-13
@@ -12,27 +12,27 @@ import static cc.carm.lib.configuration.adapter.strandard.PrimitiveAdapter.*;
|
||||
public interface StandardAdapters {
|
||||
|
||||
@NotNull PrimitiveAdapter<?>[] PRIMITIVES = new PrimitiveAdapter[]{
|
||||
ofString(), ofBoolean(), ofBooleanType(), ofCharacter(), ofCharacterType(),
|
||||
ofInteger(), ofIntegerType(), ofLong(), ofLongType(), ofDouble(), ofDoubleType(),
|
||||
ofFloat(), ofFloatType(), ofShort(), ofShortType(), ofByte(), ofByteType()
|
||||
ofString(), ofBoolean(), ofBooleanType(), ofCharacter(), ofCharacterType(),
|
||||
ofInteger(), ofIntegerType(), ofLong(), ofLongType(), ofDouble(), ofDoubleType(),
|
||||
ofFloat(), ofFloatType(), ofShort(), ofShortType(), ofByte(), ofByteType()
|
||||
};
|
||||
|
||||
@NotNull ValueAdapter<Enum<?>> ENUMS = PrimitiveAdapter.ofEnum();
|
||||
|
||||
@NotNull ValueAdapter<UUID> UUID = new ValueAdapter<>(
|
||||
ValueType.of(UUID.class),
|
||||
(provider, type, value) -> value.toString(),
|
||||
(provider, type, value) -> java.util.UUID.fromString(value.toString())
|
||||
ValueType.of(UUID.class),
|
||||
(provider, type, value) -> value.toString(),
|
||||
(provider, type, value) -> java.util.UUID.fromString(value.toString())
|
||||
);
|
||||
|
||||
@NotNull ValueAdapter<ConfigureSection> SECTIONS = new ValueAdapter<>(
|
||||
ValueType.of(ConfigureSection.class),
|
||||
(provider, type, value) -> value,
|
||||
(provider, type, value) -> {
|
||||
if (value instanceof ConfigureSection) {
|
||||
return (ConfigureSection) value;
|
||||
} else throw new IllegalArgumentException("Value is not a ConfigurationSection");
|
||||
}
|
||||
ValueType.of(ConfigureSection.class),
|
||||
(provider, type, value) -> value,
|
||||
(provider, type, value) -> {
|
||||
if (value instanceof ConfigureSection) {
|
||||
return (ConfigureSection) value;
|
||||
} else throw new IllegalArgumentException("Value is not a ConfigurationSection");
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@@ -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.ValueManifest;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.NotNullByDefault;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
@@ -17,11 +16,10 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@NotNullByDefault
|
||||
public abstract class AbstractConfigBuilder<
|
||||
TYPE, UNIT, RESULT extends ConfigValue<TYPE, UNIT>, HOLDER extends ConfigurationHolder<?>,
|
||||
SELF extends AbstractConfigBuilder<TYPE, UNIT, RESULT, HOLDER, SELF>
|
||||
> {
|
||||
TYPE, UNIT, RESULT extends ConfigValue<TYPE, UNIT>, HOLDER extends ConfigurationHolder<?>,
|
||||
SELF extends AbstractConfigBuilder<TYPE, UNIT, RESULT, HOLDER, SELF>
|
||||
> {
|
||||
|
||||
protected final Class<? super HOLDER> providerClass;
|
||||
protected final ValueType<TYPE> type;
|
||||
@@ -156,8 +154,8 @@ public abstract class AbstractConfigBuilder<
|
||||
|
||||
protected @NotNull ValueManifest<TYPE, UNIT> buildManifest() {
|
||||
return new ValueManifest<>(
|
||||
type(), this.defaultValueSupplier, this.valueValidator,
|
||||
this.initializer, this.holder, this.path
|
||||
type(), this.defaultValueSupplier, this.valueValidator,
|
||||
this.initializer, this.holder, this.path
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@ import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.value.ConfigValue;
|
||||
|
||||
public abstract class CommonConfigBuilder<
|
||||
TYPE, UNIT,
|
||||
RESULT extends ConfigValue<TYPE, UNIT>,
|
||||
SELF extends CommonConfigBuilder<TYPE, UNIT, RESULT, SELF>
|
||||
> extends AbstractConfigBuilder<TYPE, UNIT, RESULT, ConfigurationHolder<?>, SELF> {
|
||||
TYPE, UNIT,
|
||||
RESULT extends ConfigValue<TYPE, UNIT>,
|
||||
SELF extends CommonConfigBuilder<TYPE, UNIT, RESULT, SELF>
|
||||
> extends AbstractConfigBuilder<TYPE, UNIT, RESULT, ConfigurationHolder<?>, SELF> {
|
||||
|
||||
protected CommonConfigBuilder(ValueType<TYPE> type) {
|
||||
super(ConfigurationHolder.class, type);
|
||||
|
||||
+13
-13
@@ -14,10 +14,10 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class AbstractSectionBuilder<
|
||||
TYPE, UNIT,
|
||||
RESULT extends ConfigValue<TYPE, UNIT>,
|
||||
SELF extends AbstractSectionBuilder<TYPE, UNIT, RESULT, SELF>
|
||||
> extends CommonConfigBuilder<TYPE, UNIT, RESULT, SELF> {
|
||||
TYPE, UNIT,
|
||||
RESULT extends ConfigValue<TYPE, UNIT>,
|
||||
SELF extends AbstractSectionBuilder<TYPE, UNIT, RESULT, SELF>
|
||||
> extends CommonConfigBuilder<TYPE, UNIT, RESULT, SELF> {
|
||||
|
||||
|
||||
protected final @NotNull ValueType<UNIT> paramType;
|
||||
@@ -62,15 +62,15 @@ public abstract class AbstractSectionBuilder<
|
||||
|
||||
protected ValueAdapter<UNIT> buildAdapter() {
|
||||
return new ValueAdapter<>(this.paramType)
|
||||
.parser((p, type, data) -> {
|
||||
ConfigureSection section = p.deserialize(ConfigureSection.class, data);
|
||||
if (section == null) return null;
|
||||
return this.parser.handle(p, section);
|
||||
})
|
||||
.serializer((p, type, data) -> {
|
||||
Map<String, Object> map = this.serializer.handle(p, data);
|
||||
return map == null || map.isEmpty() ? null : map;
|
||||
});
|
||||
.parser((p, type, data) -> {
|
||||
ConfigureSection section = p.deserialize(ConfigureSection.class, data);
|
||||
if (section == null) return null;
|
||||
return this.parser.handle(p, section);
|
||||
})
|
||||
.serializer((p, type, data) -> {
|
||||
Map<String, Object> map = this.serializer.handle(p, data);
|
||||
return map == null || map.isEmpty() ? null : map;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+11
-11
@@ -9,9 +9,9 @@ import cc.carm.lib.configuration.value.ConfigValue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class AbstractSourceBuilder<
|
||||
V, SOURCE, UNIT, RESULT extends ConfigValue<V, UNIT>,
|
||||
SELF extends AbstractSourceBuilder<V, SOURCE, UNIT, RESULT, SELF>
|
||||
> extends CommonConfigBuilder<V, UNIT, RESULT, SELF> {
|
||||
V, SOURCE, UNIT, RESULT extends ConfigValue<V, UNIT>,
|
||||
SELF extends AbstractSourceBuilder<V, SOURCE, UNIT, RESULT, SELF>
|
||||
> extends CommonConfigBuilder<V, UNIT, RESULT, SELF> {
|
||||
|
||||
protected final @NotNull ValueType<SOURCE> sourceType;
|
||||
protected final @NotNull ValueType<UNIT> paramType;
|
||||
@@ -49,14 +49,14 @@ public abstract class AbstractSourceBuilder<
|
||||
|
||||
protected ValueAdapter<UNIT> buildAdapter() {
|
||||
return new ValueAdapter<>(this.paramType)
|
||||
.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);
|
||||
});
|
||||
.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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -20,23 +20,23 @@ public class ConfigListBuilder<V> {
|
||||
|
||||
public <S> @NotNull SourceListBuilder<S, V> from(@NotNull ValueType<S> sourceType) {
|
||||
return new SourceListBuilder<>(
|
||||
ArrayList::new, sourceType, type,
|
||||
ValueHandler.required(type),
|
||||
ValueHandler.required(sourceType)
|
||||
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()
|
||||
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()
|
||||
ArrayList::new, type,
|
||||
ValueHandler.required(type), ValueHandler.required()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class SectionListBuilder<V>
|
||||
extends AbstractSectionBuilder<List<V>, V, ConfiguredList<V>, SectionListBuilder<V>> {
|
||||
extends AbstractSectionBuilder<List<V>, V, ConfiguredList<V>, SectionListBuilder<V>> {
|
||||
|
||||
protected @NotNull Supplier<? extends List<V>> constructor;
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ 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>> {
|
||||
extends AbstractSourceBuilder<List<V>, SOURCE, V, ConfiguredList<V>, SourceListBuilder<SOURCE, V>> {
|
||||
|
||||
protected @NotNull Supplier<? extends List<V>> constructor;
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@ public class ConfigMapBuilder<M extends Map<K, V>, K, V> {
|
||||
|
||||
public @NotNull <S> SourceMapBuilder<M, S, K, V> from(@NotNull ValueType<S> sourceType) {
|
||||
return from(
|
||||
sourceType,
|
||||
ValueHandler.required(keyType), ValueHandler.stringValue(),
|
||||
ValueHandler.required(valueType), ValueHandler.required()
|
||||
sourceType,
|
||||
ValueHandler.required(keyType), ValueHandler.stringValue(),
|
||||
ValueHandler.required(valueType), ValueHandler.required()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,35 +44,35 @@ public class ConfigMapBuilder<M extends Map<K, V>, K, V> {
|
||||
@NotNull ValueHandler<S, V> valueParser,
|
||||
@NotNull ValueHandler<V, S> valueSerializer) {
|
||||
return new SourceMapBuilder<>(
|
||||
this.constructor, sourceType, keyType, valueType,
|
||||
keyParser, keySerializer, valueParser, valueSerializer
|
||||
this.constructor, sourceType, keyType, valueType,
|
||||
keyParser, keySerializer, valueParser, valueSerializer
|
||||
);
|
||||
}
|
||||
|
||||
public @NotNull SourceMapBuilder<M, String, K, V> fromString() {
|
||||
return from(
|
||||
ValueType.STRING,
|
||||
ValueHandler.required(keyType), ValueHandler.stringValue(),
|
||||
ValueHandler.required(valueType), ValueHandler.stringValue()
|
||||
ValueType.STRING,
|
||||
ValueHandler.required(keyType), ValueHandler.stringValue(),
|
||||
ValueHandler.required(valueType), ValueHandler.stringValue()
|
||||
);
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<M, K, V> fromSection() {
|
||||
return fromSection(
|
||||
ValueHandler.required(keyType), ValueHandler.stringValue(),
|
||||
ValueHandler.required(valueType), ValueHandler.required()
|
||||
ValueHandler.required(keyType), ValueHandler.stringValue(),
|
||||
ValueHandler.required(valueType), ValueHandler.required()
|
||||
);
|
||||
}
|
||||
|
||||
public @NotNull SectionMapBuilder<M, K, V> fromSection(
|
||||
@NotNull ValueHandler<String, K> keyParser,
|
||||
@NotNull ValueHandler<K, String> keySerializer,
|
||||
@NotNull ValueHandler<ConfigureSection, V> valueParser,
|
||||
@NotNull ValueHandler<V, Map<String, Object>> valueSerializer
|
||||
@NotNull ValueHandler<String, K> keyParser,
|
||||
@NotNull ValueHandler<K, String> keySerializer,
|
||||
@NotNull ValueHandler<ConfigureSection, V> valueParser,
|
||||
@NotNull ValueHandler<V, Map<String, Object>> valueSerializer
|
||||
) {
|
||||
return new SectionMapBuilder<>(
|
||||
this.constructor, keyType, valueType,
|
||||
keyParser, keySerializer, valueParser, valueSerializer
|
||||
this.constructor, keyType, valueType,
|
||||
keyParser, keySerializer, valueParser, valueSerializer
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class SectionMapBuilder<MAP extends Map<K, V>, K, V>
|
||||
extends AbstractSectionBuilder<Map<K, V>, V, ConfiguredMap<K, V>, SectionMapBuilder<MAP, K, V>> {
|
||||
extends AbstractSectionBuilder<Map<K, V>, V, ConfiguredMap<K, V>, SectionMapBuilder<MAP, K, V>> {
|
||||
|
||||
protected final @NotNull ValueType<K> keyType;
|
||||
|
||||
@@ -78,14 +78,14 @@ public class SectionMapBuilder<MAP extends Map<K, V>, K, V>
|
||||
|
||||
public @NotNull ValueAdapter<K> buildKeyAdapter() {
|
||||
return new ValueAdapter<>(this.keyType)
|
||||
.parser((holder, type, data) -> {
|
||||
String source = holder.deserialize(String.class, data);
|
||||
return this.keyParser.handle(holder, source);
|
||||
})
|
||||
.serializer((holder, type, data) -> {
|
||||
String source = this.keySerializer.handle(holder, data);
|
||||
return holder.serialize(source);
|
||||
});
|
||||
.parser((holder, type, data) -> {
|
||||
String source = holder.deserialize(String.class, data);
|
||||
return this.keyParser.handle(holder, source);
|
||||
})
|
||||
.serializer((holder, type, data) -> {
|
||||
String source = this.keySerializer.handle(holder, data);
|
||||
return holder.serialize(source);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class SourceMapBuilder<MAP extends Map<K, V>, SOURCE, K, V>
|
||||
extends AbstractSourceBuilder<Map<K, V>, SOURCE, V, ConfiguredMap<K, V>, SourceMapBuilder<MAP, SOURCE, K, V>> {
|
||||
extends AbstractSourceBuilder<Map<K, V>, SOURCE, V, ConfiguredMap<K, V>, SourceMapBuilder<MAP, SOURCE, K, V>> {
|
||||
|
||||
protected final @NotNull ValueType<K> keyType;
|
||||
|
||||
@@ -74,14 +74,14 @@ public class SourceMapBuilder<MAP extends Map<K, V>, SOURCE, K, V>
|
||||
|
||||
public @NotNull ValueAdapter<K> buildKeyAdapter() {
|
||||
return new ValueAdapter<>(this.keyType)
|
||||
.parser((holder, type, data) -> {
|
||||
String source = holder.deserialize(String.class, data);
|
||||
return this.keyParser.handle(holder, source);
|
||||
})
|
||||
.serializer((holder, type, data) -> {
|
||||
String source = this.keySerializer.handle(holder, data);
|
||||
return holder.serialize(source);
|
||||
});
|
||||
.parser((holder, type, data) -> {
|
||||
String source = holder.deserialize(String.class, data);
|
||||
return this.keyParser.handle(holder, source);
|
||||
})
|
||||
.serializer((holder, type, data) -> {
|
||||
String source = this.keySerializer.handle(holder, data);
|
||||
return holder.serialize(source);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -38,8 +38,8 @@ public class ConfigValueBuilder<V> {
|
||||
}
|
||||
|
||||
public @NotNull SectionValueBuilder<V> fromSection(
|
||||
@NotNull ValueHandler<ConfigureSection, V> valueParser,
|
||||
@NotNull ValueHandler<V, ? extends Map<String, Object>> valueSerializer
|
||||
@NotNull ValueHandler<ConfigureSection, V> valueParser,
|
||||
@NotNull ValueHandler<V, ? extends Map<String, Object>> valueSerializer
|
||||
) {
|
||||
return new SectionValueBuilder<>(this.type, valueParser, valueSerializer);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SourceValueBuilder<S, V>
|
||||
extends AbstractSourceBuilder<V, S, V, ConfiguredValue<V>, SourceValueBuilder<S, V>> {
|
||||
extends AbstractSourceBuilder<V, S, V, ConfiguredValue<V>, SourceValueBuilder<S, V>> {
|
||||
|
||||
|
||||
public SourceValueBuilder(@NotNull ValueType<S> sourceType, @NotNull ValueType<V> valueType,
|
||||
|
||||
@@ -30,10 +30,10 @@ import java.util.function.Supplier;
|
||||
* @param <SELF> Self builder, for further implement support.
|
||||
*/
|
||||
public abstract class ConfigurationFactory<
|
||||
SOURCE extends ConfigureSource<?, ?, SOURCE>,
|
||||
HOLDER extends ConfigurationHolder<SOURCE>,
|
||||
SELF
|
||||
> {
|
||||
SOURCE extends ConfigureSource<?, ?, SOURCE>,
|
||||
HOLDER extends ConfigurationHolder<SOURCE>,
|
||||
SELF
|
||||
> {
|
||||
|
||||
protected @NotNull ValueAdapterRegistry adapters = new ValueAdapterRegistry();
|
||||
protected @NotNull ConfigurationOptionHolder options = new ConfigurationOptionHolder();
|
||||
|
||||
@@ -100,21 +100,21 @@ public class PathGenerator {
|
||||
*/
|
||||
public static String covertPathName(String name) {
|
||||
return name
|
||||
// Replace all uppercase letters with dashes
|
||||
.replaceAll("[A-Z]", "=$0")
|
||||
// If the first letter is also capitalized,
|
||||
// it will also be converted and the first dash will need to be removed
|
||||
.replaceAll("^=(.*)$", "$1")
|
||||
// Because the name may contain _, it needs to be treated a little differently
|
||||
.replaceAll("_=([A-Z])", "_$1")
|
||||
// The content that is not named in all caps is then converted
|
||||
.replaceAll("([a-z])=([A-Z])", "$1_$2")
|
||||
// Remove any extra horizontal lines
|
||||
.replace("=", "")
|
||||
// Replace the underscore with a dash
|
||||
.replace("_", "-")
|
||||
// Finally, convert it to all lowercase
|
||||
.toLowerCase();
|
||||
// Replace all uppercase letters with dashes
|
||||
.replaceAll("[A-Z]", "=$0")
|
||||
// If the first letter is also capitalized,
|
||||
// it will also be converted and the first dash will need to be removed
|
||||
.replaceAll("^=(.*)$", "$1")
|
||||
// Because the name may contain _, it needs to be treated a little differently
|
||||
.replaceAll("_=([A-Z])", "_$1")
|
||||
// The content that is not named in all caps is then converted
|
||||
.replaceAll("([a-z])=([A-Z])", "$1_$2")
|
||||
// Remove any extra horizontal lines
|
||||
.replace("=", "")
|
||||
// Replace the underscore with a dash
|
||||
.replace("_", "-")
|
||||
// Finally, convert it to all lowercase
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -477,7 +477,7 @@ public interface ConfigureSection {
|
||||
* @return The boolean if the path exists and is a boolean, otherwise false.
|
||||
*/
|
||||
default boolean getBoolean(@NotNull String path) {
|
||||
return getBoolean(path, false);
|
||||
return getBoolean(path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -509,7 +509,7 @@ public interface ConfigureSection {
|
||||
* @return The byte if the path exists and is a byte, otherwise 0.
|
||||
*/
|
||||
default @Nullable Byte getByte(@NotNull String path) {
|
||||
return getByte(path, (byte) 0);
|
||||
return getByte(path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -541,7 +541,7 @@ public interface ConfigureSection {
|
||||
* @return The short if the path exists and is a short, otherwise 0.
|
||||
*/
|
||||
default @Nullable Short getShort(@NotNull String path) {
|
||||
return getShort(path, (short) 0);
|
||||
return getShort(path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -573,7 +573,7 @@ public interface ConfigureSection {
|
||||
* @return The int if the path exists and is an int, otherwise 0.
|
||||
*/
|
||||
default @Nullable Integer getInt(@NotNull String path) {
|
||||
return getInt(path, 0);
|
||||
return getInt(path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -606,7 +606,7 @@ public interface ConfigureSection {
|
||||
* @return The long if the path exists and is a long, otherwise 0.
|
||||
*/
|
||||
default @Nullable Long getLong(@NotNull String path) {
|
||||
return getLong(path, 0L);
|
||||
return getLong(path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -638,7 +638,7 @@ public interface ConfigureSection {
|
||||
* @return The float if the path exists and is a float, otherwise 0.
|
||||
*/
|
||||
default @Nullable Float getFloat(@NotNull String path) {
|
||||
return getFloat(path, 0.0F);
|
||||
return getFloat(path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -670,7 +670,7 @@ public interface ConfigureSection {
|
||||
* @return The double if the path exists and is a double, otherwise 0.
|
||||
*/
|
||||
default @Nullable Double getDouble(@NotNull String path) {
|
||||
return getDouble(path, 0.0D);
|
||||
return getDouble(path, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -692,7 +692,7 @@ public interface ConfigureSection {
|
||||
* @return True if the value is present and is a char, false otherwise.
|
||||
*/
|
||||
default boolean isChar(@NotNull String path) {
|
||||
return isType(path, Boolean.class);
|
||||
return isType(path, Character.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -750,7 +750,7 @@ public interface ConfigureSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of values from the section
|
||||
* Get a list of values from current section
|
||||
* <p>
|
||||
* If the path does not exist, an empty list will be returned
|
||||
* <br>Any changes please use {@link #set(String, Object)} after changes
|
||||
@@ -765,7 +765,7 @@ public interface ConfigureSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of strings from the section
|
||||
* Get a list of strings from current section
|
||||
* <p> Limitations see {@link #getList(String, DataFunction)}
|
||||
*
|
||||
* @param path The path to get the list from
|
||||
@@ -776,7 +776,7 @@ public interface ConfigureSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of integer from the section
|
||||
* Get a list of integer from current section
|
||||
* <p> Limitations see {@link #getList(String, DataFunction)}
|
||||
*
|
||||
* @param path The path to get the list from
|
||||
@@ -787,7 +787,7 @@ public interface ConfigureSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of long from the section
|
||||
* Get a list of long from current section
|
||||
* <p> Limitations see {@link #getList(String, DataFunction)}
|
||||
*
|
||||
* @param path The path to get the list from
|
||||
@@ -798,7 +798,7 @@ public interface ConfigureSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of double from the section
|
||||
* Get a list of double from current section
|
||||
* <p> Limitations see {@link #getList(String, DataFunction)}
|
||||
*
|
||||
* @param path The path to get the list from
|
||||
@@ -809,7 +809,7 @@ public interface ConfigureSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of floats from the section
|
||||
* Get a list of floats from current section
|
||||
* <p> Limitations see {@link #getList(String, DataFunction)}
|
||||
*
|
||||
* @param path The path to get the list from
|
||||
@@ -820,7 +820,7 @@ public interface ConfigureSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of bytes from the section
|
||||
* Get a list of bytes from current section
|
||||
* <p> Limitations see {@link #getList(String, DataFunction)}
|
||||
*
|
||||
* @param path The path to get the list from
|
||||
@@ -831,7 +831,7 @@ public interface ConfigureSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of char from the section
|
||||
* Get a list of char from current section
|
||||
* <p> Limitations see {@link #getList(String, DataFunction)}
|
||||
*
|
||||
* @param path The path to get the list from
|
||||
@@ -842,7 +842,22 @@ public interface ConfigureSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specific type of collection from the section.
|
||||
* Get a list of {@link ConfigureSection} from current section
|
||||
*
|
||||
* @param path The path to get the list from
|
||||
* @return The list of {@link ConfigureSection}
|
||||
*/
|
||||
default @NotNull List<ConfigureSection> getSectionList(@NotNull String path) {
|
||||
return getList(path, obj -> {
|
||||
if (obj instanceof ConfigureSection) {
|
||||
return (ConfigureSection) obj;
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specific type of collection from current section.
|
||||
*
|
||||
* @param path The path to get the collection from
|
||||
* @param constructor The constructor of the collection
|
||||
@@ -858,7 +873,7 @@ public interface ConfigureSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specific type of steam from the section.
|
||||
* Get the specific type of steam from current section.
|
||||
*
|
||||
* @param path The path to get the stream from
|
||||
* @return The stream of values
|
||||
@@ -869,7 +884,7 @@ public interface ConfigureSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specific type of steam from the section.
|
||||
* Get the specific type of steam from current section.
|
||||
*
|
||||
* @param path The path to get the stream from
|
||||
* @param parser The function to parse the values
|
||||
@@ -886,9 +901,9 @@ public interface ConfigureSection {
|
||||
}
|
||||
|
||||
static <T, C extends Collection<T>> @NotNull C parseCollection(
|
||||
@Nullable List<?> data,
|
||||
@NotNull Supplier<C> constructor,
|
||||
@NotNull DataFunction<Object, T> parser
|
||||
@Nullable List<?> data,
|
||||
@NotNull Supplier<C> constructor,
|
||||
@NotNull DataFunction<Object, T> parser
|
||||
) {
|
||||
C values = constructor.get();
|
||||
if (data == null) return values;
|
||||
|
||||
@@ -17,9 +17,9 @@ import java.util.Set;
|
||||
* @see ConfigureSection
|
||||
*/
|
||||
public abstract class ConfigureSource<
|
||||
SECTION extends ConfigureSection, ORIGINAL,
|
||||
SELF extends ConfigureSource<SECTION, ORIGINAL, SELF>>
|
||||
implements ConfigureSection {
|
||||
SECTION extends ConfigureSection, ORIGINAL,
|
||||
SELF extends ConfigureSource<SECTION, ORIGINAL, SELF>>
|
||||
implements ConfigureSection {
|
||||
|
||||
protected final @NotNull ConfigurationHolder<? extends SELF> holder;
|
||||
protected long lastUpdateMillis;
|
||||
|
||||
@@ -135,8 +135,8 @@ public class ConfiguredMap<K, V> extends CachedConfigValue<Map<K, V>, V> impleme
|
||||
for (Map.Entry<K, V> entry : value.entrySet()) {
|
||||
try {
|
||||
data.put(
|
||||
keySerializer.serialize(holder(), keyType(), entry.getKey()),
|
||||
valueSerializer.serialize(holder(), valueType(), withValidated(entry.getValue()))
|
||||
keySerializer.serialize(holder(), keyType(), entry.getKey()),
|
||||
valueSerializer.serialize(holder(), valueType(), withValidated(entry.getValue()))
|
||||
);
|
||||
} catch (Exception e) {
|
||||
throwing(path + "." + entry.getKey(), e);
|
||||
|
||||
@@ -85,9 +85,9 @@ public class ConfiguredValue<V> extends CachedConfigValue<V, V> {
|
||||
|
||||
public static <V> ConfiguredValue<V> of(@NotNull ValueType<V> type, @NotNull Supplier<@Nullable V> defaultSupplier) {
|
||||
return of(
|
||||
new ValueManifest<>(type, defaultSupplier),
|
||||
(provider, t, data) -> provider.deserialize(type, data),
|
||||
(provider, t, value) -> provider.serialize(value)
|
||||
new ValueManifest<>(type, defaultSupplier),
|
||||
(provider, t, data) -> provider.deserialize(type, data),
|
||||
(provider, t, value) -> provider.serialize(value)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
//import java.util.LinkedList;
|
||||
//import java.util.List;
|
||||
//
|
||||
///**
|
||||
/// **
|
||||
// * @author Chris2018998
|
||||
// */
|
||||
//public class OffsetUtil {
|
||||
@@ -25,15 +25,15 @@
|
||||
// } catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//// try {
|
||||
//// unsafe = AccessController.doPrivileged((PrivilegedExceptionAction<Unsafe>) () -> {
|
||||
//// Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
//// theUnsafe.setAccessible(true);
|
||||
//// return (Unsafe) theUnsafe.get(null);
|
||||
//// });
|
||||
//// } catch (Throwable e) {
|
||||
//// System.err.println("Unable to load unsafe");
|
||||
//// }
|
||||
/// / try {
|
||||
/// / unsafe = AccessController.doPrivileged((PrivilegedExceptionAction<Unsafe>) () -> {
|
||||
/// / Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
/// / theUnsafe.setAccessible(true);
|
||||
/// / return (Unsafe) theUnsafe.get(null);
|
||||
/// / });
|
||||
/// / } catch (Throwable e) {
|
||||
/// / System.err.println("Unable to load unsafe");
|
||||
/// / }
|
||||
// }
|
||||
//
|
||||
// public static List<FieldOffset> getClassMemberOffset(Class<?> beanClass) {
|
||||
|
||||
+153
-10
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<properties>
|
||||
@@ -13,7 +13,11 @@
|
||||
<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>
|
||||
<maven.javadoc.skip>true</maven.javadoc.skip>
|
||||
<maven.deploy.skip>true</maven.deploy.skip>
|
||||
|
||||
<deps.mysql-driver.version>8.0.33</deps.mysql-driver.version>
|
||||
<log4j.version>2.25.0</log4j.version>
|
||||
</properties>
|
||||
<artifactId>configured-demo</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
@@ -24,38 +28,112 @@
|
||||
<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-commentable</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-feature-versioned</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-feature-validators</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-feature-kotlin</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-yaml</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-gson</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-sql</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>easysql-beecp</artifactId>
|
||||
<version>0.4.7</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${deps.mysql-driver.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-mongodb</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-hocon</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>${log4j.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>
|
||||
@@ -68,7 +146,72 @@
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceDirs>
|
||||
<source>src/main/java</source>
|
||||
<source>target/generated-sources/annotations</source>
|
||||
</sourceDirs>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<jvmTarget>1.8</jvmTarget>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-compile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>default-testCompile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>testCompile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -10,13 +10,13 @@ public interface DatabaseConfiguration extends Configuration {
|
||||
|
||||
@ConfigPath("driver")
|
||||
@HeaderComments({
|
||||
"数据库驱动配置,请根据数据库类型设置。",
|
||||
"- MySQL(旧): com.mysql.jdbc.Driver",
|
||||
"- MySQL(新): com.mysql.cj.jdbc.Driver",
|
||||
"- MariaDB(推荐): org.mariadb.jdbc.Driver",
|
||||
"数据库驱动配置,请根据数据库类型设置。",
|
||||
"- MySQL(旧): com.mysql.jdbc.Driver",
|
||||
"- MySQL(新): com.mysql.cj.jdbc.Driver",
|
||||
"- MariaDB(推荐): org.mariadb.jdbc.Driver",
|
||||
})
|
||||
ConfiguredValue<String> DRIVER_NAME = ConfiguredValue.of(
|
||||
String.class, "com.mysql.cj.jdbc.Driver"
|
||||
String.class, "com.mysql.cj.jdbc.Driver"
|
||||
);
|
||||
|
||||
ConfiguredValue<String> HOST = ConfiguredValue.of(String.class, "127.0.0.1");
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package cc.carm.lib.configuration.demo.tests;
|
||||
|
||||
import cc.carm.lib.configuration.demo.tests.conf.DemoConfiguration;
|
||||
import cc.carm.lib.configuration.demo.tests.conf.KotlinConfiguration;
|
||||
import cc.carm.lib.configuration.demo.tests.conf.RegistryConfig;
|
||||
import cc.carm.lib.configuration.demo.tests.model.UserRecord;
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -80,6 +82,22 @@ public class ConfigurationTest {
|
||||
|
||||
}
|
||||
|
||||
public static void testKotlin(ConfigurationHolder<?> provider) {
|
||||
provider.initialize(KotlinConfiguration.class);
|
||||
|
||||
System.out.println("> Test Kotlin value before:");
|
||||
System.out.println(KotlinConfiguration.INSTANCE.getLINKED_MAP().get());
|
||||
|
||||
LinkedHashMap<String, String> map = new LinkedHashMap<>();
|
||||
map.put("Language", "Kotlin");
|
||||
System.out.println("> Test Kotlin value -> " + map);
|
||||
KotlinConfiguration.INSTANCE.getLINKED_MAP().set(map);
|
||||
|
||||
System.out.println("> Test Kotlin value after:");
|
||||
System.out.println(KotlinConfiguration.INSTANCE.getLINKED_MAP().get());
|
||||
|
||||
}
|
||||
|
||||
public static void save(ConfigurationHolder<?> provider) {
|
||||
try {
|
||||
provider.save();
|
||||
|
||||
+24
-24
@@ -16,10 +16,10 @@ import java.util.UUID;
|
||||
@ConfigPath(root = true)
|
||||
@HeaderComments({"此处内容将显示在配置文件的最上方"})
|
||||
@FooterComments({
|
||||
"------------------------------------------------",
|
||||
"此处内容将显示在配置文件的最下方",
|
||||
"可用于显示版权信息等",
|
||||
"感谢您使用 https://github.com/CarmJos/configured !"
|
||||
"------------------------------------------------",
|
||||
"此处内容将显示在配置文件的最下方",
|
||||
"可用于显示版权信息等",
|
||||
"感谢您使用 https://github.com/CarmJos/configured !"
|
||||
})
|
||||
public interface DemoConfiguration extends Configuration {
|
||||
|
||||
@@ -38,30 +38,30 @@ public interface DemoConfiguration extends Configuration {
|
||||
@HeaderComments({"空值测试"})
|
||||
@InlineComment("空值Inline注释")
|
||||
ConfiguredMap<String, String> EMPTY = ConfiguredMap.builderOf(String.class, String.class)
|
||||
.asLinkedMap().fromString()
|
||||
.build();
|
||||
.asLinkedMap().fromString()
|
||||
.build();
|
||||
|
||||
@ConfigPath("registered_users") // 通过注解规定配置文件中的路径,若不进行注解则以变量名自动生成。
|
||||
@HeaderComments({"Section类型数据测试"}) // 通过注解给配置添加注释。
|
||||
@InlineComment("默认地注释会加到Section的首行末尾") // 通过注解给配置添加注释。
|
||||
ConfiguredList<UserRecord> ALLOWLISTS = ConfiguredList.builderOf(UserRecord.class).fromSection()
|
||||
.parse(UserRecord::deserialize).serialize(UserRecord::serialize)
|
||||
.defaults(UserRecord.CARM).build();
|
||||
.parse(UserRecord::deserialize).serialize(UserRecord::serialize)
|
||||
.defaults(UserRecord.CARM).build();
|
||||
|
||||
@HeaderComments({
|
||||
"------------------------------------------------",
|
||||
"[ID - ItemStack]对照表", "", "用于测试Map类型的解析与序列化保存"
|
||||
"------------------------------------------------",
|
||||
"[ID - ItemStack]对照表", "", "用于测试Map类型的解析与序列化保存"
|
||||
})
|
||||
@FooterComments("------------------------------------------------")
|
||||
ConfiguredMap<Integer, ItemStack> ITEMS = ConfiguredMap.builderOf(Integer.class, ItemStack.class)
|
||||
.asLinkedMap().fromSection()
|
||||
.parseKey(data -> Integer.parseInt(data))
|
||||
.parse(ItemStack::deserialize).serialize(ItemStack::serialize)
|
||||
.defaults(m -> {
|
||||
m.put(1, new ItemStack("stone", 64));
|
||||
m.put(2, new ItemStack("iron", 64, "铁锭", Arrays.asList("一些铁锭", "可以制造东西")));
|
||||
})
|
||||
.build();
|
||||
.asLinkedMap().fromSection()
|
||||
.parseKey(data -> Integer.parseInt(data))
|
||||
.parse(ItemStack::deserialize).serialize(ItemStack::serialize)
|
||||
.defaults(m -> {
|
||||
m.put(1, new ItemStack("stone", 64));
|
||||
m.put(2, new ItemStack("iron", 64, "铁锭", Arrays.asList("一些铁锭", "可以制造东西")));
|
||||
})
|
||||
.build();
|
||||
|
||||
|
||||
/**
|
||||
@@ -72,18 +72,18 @@ public interface DemoConfiguration extends Configuration {
|
||||
|
||||
@ConfigPath(value = "uuid-value", root = true)
|
||||
public static final ConfiguredValue<UUID> UUID_CONFIG_VALUE = ConfiguredValue
|
||||
.builderOf(UUID.class).fromString()
|
||||
.parse((holder, data) -> UUID.fromString(data))
|
||||
.build();
|
||||
.builderOf(UUID.class).fromString()
|
||||
.parse((holder, data) -> UUID.fromString(data))
|
||||
.build();
|
||||
|
||||
@HeaderComments({"内部类的内部类测试", "通过这种方式,您可以轻易实现多层次的配置文件结构"})
|
||||
@FooterComments({"-------------"})
|
||||
public interface That extends Configuration {
|
||||
|
||||
ConfiguredList<UUID> OPERATORS = ConfiguredList
|
||||
.builderOf(UUID.class).fromString()
|
||||
.parse(s -> Objects.requireNonNull(UUID.fromString(s)))
|
||||
.build();
|
||||
.builderOf(UUID.class).fromString()
|
||||
.parse(s -> Objects.requireNonNull(UUID.fromString(s)))
|
||||
.build();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package cc.carm.lib.configuration.demo.tests.conf
|
||||
|
||||
import cc.carm.lib.configuration.Configuration
|
||||
import cc.carm.lib.configuration.annotation.ConfigPath
|
||||
import cc.carm.lib.configuration.annotation.ConfigVersion
|
||||
import cc.carm.lib.configuration.kotlin.value.*
|
||||
|
||||
@ConfigPath(root = true)
|
||||
object KotlinConfiguration : Configuration {
|
||||
@ConfigVersion(1)
|
||||
val VERSION = valueFrom(Double::class) {
|
||||
defaults(1.0)
|
||||
}
|
||||
|
||||
val USER_LIST = listFrom(String::class) {
|
||||
defaults("Carm Jos")
|
||||
}
|
||||
|
||||
val NICKNAME = mapFrom(String::class, ::mutableMapOf) {
|
||||
defaultMap(mapOf("Carm Jos" to "Carm"))
|
||||
parse { v -> v }
|
||||
serialize { v -> v }
|
||||
}
|
||||
|
||||
val LINKED_MAP = linkedMapFrom(String::class) {
|
||||
parse { value ->
|
||||
value
|
||||
}
|
||||
serialize { v -> v }
|
||||
defaults("key", "value")
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,9 @@ public class RegistryConfig implements Configuration {
|
||||
@InlineComment(value = "用户名(匹配注释)", regex = "name") // 通过注解给配置添加注释。
|
||||
@InlineComment(value = "信息", regex = {"info.*", "info.game.*"}) // 通过注解给配置添加注释。
|
||||
public final ConfiguredValue<UserRecord> OWNER = ConfiguredValue.builderOf(UserRecord.class).fromSection()
|
||||
.defaults(new UserRecord("Carm", UUID.randomUUID()))
|
||||
.parse((holder, section) -> UserRecord.deserialize(section))
|
||||
.serialize((holder, data) -> data.serialize()).build();
|
||||
.defaults(new UserRecord("Carm", UUID.randomUUID()))
|
||||
.parse((holder, section) -> UserRecord.deserialize(section))
|
||||
.serialize((holder, data) -> data.serialize()).build();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -69,10 +69,10 @@ public class ItemStack {
|
||||
|
||||
public static ItemStack deserialize(ConfigureSection section) {
|
||||
return new ItemStack(
|
||||
section.getString("material"),
|
||||
section.getInt("amount", 1),
|
||||
section.getString("name"),
|
||||
section.getStringList("lore")
|
||||
section.getString("material"),
|
||||
section.getInt("amount", 1),
|
||||
section.getString("name"),
|
||||
section.getStringList("lore")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ public class UserRecord extends AbstractRecord {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TestUser{" +
|
||||
"name='" + name + '\'' +
|
||||
", uuid=" + uuid +
|
||||
'}';
|
||||
"name='" + name + '\'' +
|
||||
", uuid=" + uuid +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -1,4 +1,4 @@
|
||||
package config;
|
||||
package cc.carm.lib.configuration.tests.test;
|
||||
|
||||
import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
@@ -7,12 +7,12 @@ import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class JSONConfigTest {
|
||||
public class JSONConfigTests {
|
||||
|
||||
protected final ConfigurationHolder<?> holder = JSONConfigFactory
|
||||
.from(new File("target"), "config.json")
|
||||
.resourcePath("example.json")
|
||||
.build();
|
||||
.from(new File("target"), "config.json")
|
||||
.resourcePath("example.json")
|
||||
.build();
|
||||
|
||||
@Test
|
||||
public void onTest() {
|
||||
+11
-3
@@ -1,4 +1,4 @@
|
||||
package yaml.test;
|
||||
package cc.carm.lib.configuration.tests.test;
|
||||
|
||||
import cc.carm.lib.configuration.commentable.CommentableMeta;
|
||||
import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
|
||||
@@ -14,10 +14,10 @@ import java.util.Map;
|
||||
public class YamlTests {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
public void test() throws Exception {
|
||||
|
||||
ConfigurationHolder<YAMLSource> holder = YAMLConfigFactory.from("target/tests.yml")
|
||||
.resourcePath("configs/sample.yml").build();
|
||||
.resourcePath("configs/sample.yml").build();
|
||||
|
||||
Validators.activate(holder);
|
||||
|
||||
@@ -44,5 +44,13 @@ public class YamlTests {
|
||||
ConfigurationTest.save(holder);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKotlin() {
|
||||
ConfigurationHolder<YAMLSource> holder = YAMLConfigFactory.from("target/kotlin.yml").build();
|
||||
|
||||
ConfigurationTest.testKotlin(holder);
|
||||
|
||||
ConfigurationTest.save(holder);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package config;
|
||||
package cc.carm.lib.configuration.tests.test.mongodb;
|
||||
|
||||
import cc.carm.lib.configuration.Configuration;
|
||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue;
|
||||
+13
-13
@@ -1,4 +1,4 @@
|
||||
package config;
|
||||
package cc.carm.lib.configuration.tests.test.mongodb;
|
||||
|
||||
import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
|
||||
import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
@@ -28,22 +28,22 @@ public class MongoTest {
|
||||
gsonHolder.initialize(MongoConfig.class);
|
||||
|
||||
MongoClientSettings settings = MongoClientSettings.builder()
|
||||
.applyConnectionString(new ConnectionString(
|
||||
"mongodb://" + MongoConfig.HOST.resolve() + ":" + MongoConfig.PORT.resolve()
|
||||
))
|
||||
.credential(MongoCredential.createCredential(
|
||||
MongoConfig.USERNAME.resolve(), MongoConfig.DATABASE.resolve(),
|
||||
MongoConfig.PASSWORD.resolve().toCharArray()
|
||||
))
|
||||
.uuidRepresentation(UuidRepresentation.STANDARD)
|
||||
.build();
|
||||
.applyConnectionString(new ConnectionString(
|
||||
"mongodb://" + MongoConfig.HOST.resolve() + ":" + MongoConfig.PORT.resolve()
|
||||
))
|
||||
.credential(MongoCredential.createCredential(
|
||||
MongoConfig.USERNAME.resolve(), MongoConfig.DATABASE.resolve(),
|
||||
MongoConfig.PASSWORD.resolve().toCharArray()
|
||||
))
|
||||
.uuidRepresentation(UuidRepresentation.STANDARD)
|
||||
.build();
|
||||
MongoClient mongoClient = MongoClients.create(settings);
|
||||
MongoDatabase mongoDatabase = mongoClient.getDatabase(MongoConfig.DATABASE.resolve());
|
||||
|
||||
ConfigurationHolder<?> mongoHolder = MongoConfigFactory
|
||||
.from(mongoDatabase, "configs")
|
||||
.namespace("my_plugin")
|
||||
.build();
|
||||
.from(mongoDatabase, "configs")
|
||||
.namespace("my_plugin")
|
||||
.build();
|
||||
|
||||
// Test the configuration
|
||||
ConfigurationTest.testDemo(mongoHolder);
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
package config;
|
||||
package cc.carm.lib.configuration.tests.test.sql;
|
||||
|
||||
import cc.carm.lib.configuration.demo.DatabaseConfiguration;
|
||||
import cc.carm.lib.configuration.demo.tests.ConfigurationTest;
|
||||
@@ -33,9 +33,9 @@ public class SQLConfigTest {
|
||||
manager.setDebugMode(true);
|
||||
|
||||
ConfigurationHolder<?> holder = SQLConfigFactory.from(manager)
|
||||
.tableName("test_configs")
|
||||
.namespace("testing")
|
||||
.build();
|
||||
.tableName("test_configs")
|
||||
.namespace("testing")
|
||||
.build();
|
||||
|
||||
ConfigurationTest.testDemo(holder);
|
||||
ConfigurationTest.testInner(holder);
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="WARN" packages="config.SQLConfigTest">
|
||||
<Configuration status="WARN" packages="cc.carm.lib.configuration.tests">
|
||||
<Appenders>
|
||||
<console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg%n"/>
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
@@ -48,4 +48,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
+4
-4
@@ -42,12 +42,12 @@ public interface CommentableMeta {
|
||||
|
||||
static void register(@NotNull ConfigurationInitializer initializer) {
|
||||
initializer.registerAnnotation(
|
||||
HeaderComments.class, HEADER,
|
||||
a -> Arrays.asList(a.value())
|
||||
HeaderComments.class, HEADER,
|
||||
a -> Arrays.asList(a.value())
|
||||
);
|
||||
initializer.registerAnnotation(
|
||||
FooterComments.class, FOOTER,
|
||||
a -> Arrays.asList(a.value())
|
||||
FooterComments.class, FOOTER,
|
||||
a -> Arrays.asList(a.value())
|
||||
);
|
||||
initializer.registerAnnotation(InlineComment.class, INLINE, a -> {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
@@ -47,4 +47,4 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
</project>
|
||||
|
||||
+2
-2
@@ -9,8 +9,8 @@ import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public abstract class FileConfigFactory<SOURCE extends FileConfigSource<?, ?, SOURCE>,
|
||||
HOLDER extends ConfigurationHolder<SOURCE>, SELF extends FileConfigFactory<SOURCE, HOLDER, SELF>>
|
||||
extends ConfigurationFactory<SOURCE, HOLDER, SELF> {
|
||||
HOLDER extends ConfigurationHolder<SOURCE>, SELF extends FileConfigFactory<SOURCE, HOLDER, SELF>>
|
||||
extends ConfigurationFactory<SOURCE, HOLDER, SELF> {
|
||||
|
||||
|
||||
protected @NotNull File file;
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ import java.nio.file.Files;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class FileConfigSource<SECTION extends ConfigureSection, ORIGINAL, SELF extends FileConfigSource<SECTION, ORIGINAL, SELF>>
|
||||
extends ConfigureSource<SECTION, ORIGINAL, SELF> {
|
||||
extends ConfigureSource<SECTION, ORIGINAL, SELF> {
|
||||
|
||||
protected final @NotNull File file;
|
||||
protected final @Nullable String resourcePath;
|
||||
@@ -116,7 +116,7 @@ public abstract class FileConfigSource<SECTION extends ConfigureSection, ORIGINA
|
||||
}
|
||||
|
||||
protected void saveResource(@NotNull String resourcePath, boolean replace)
|
||||
throws IOException, IllegalArgumentException {
|
||||
throws IOException, IllegalArgumentException {
|
||||
Objects.requireNonNull(resourcePath, "ResourcePath cannot be null");
|
||||
if (resourcePath.isEmpty()) throw new IllegalArgumentException("ResourcePath cannot be empty");
|
||||
|
||||
|
||||
+1
-3
@@ -1,7 +1,5 @@
|
||||
package cc.carm.lib.configuration.source.option;
|
||||
|
||||
import cc.carm.lib.configuration.source.option.ConfigurationOption;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
@@ -11,7 +9,7 @@ public interface FileConfigOptions {
|
||||
* The charset of the file.
|
||||
*/
|
||||
ConfigurationOption<Charset> CHARSET = ConfigurationOption.of(StandardCharsets.UTF_8);
|
||||
|
||||
|
||||
/**
|
||||
* Whether to copy files from resource if exists.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
<?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.1.7</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.2.0</kotlin.version>
|
||||
</properties>
|
||||
|
||||
<artifactId>configured-feature-kotlin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>configured-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||
|
||||
<plugins>
|
||||
<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>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<jvmTarget>1.8</jvmTarget>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.dokka</groupId>
|
||||
<artifactId>dokka-maven-plugin</artifactId>
|
||||
<version>2.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>pre-site</phase>
|
||||
<goals>
|
||||
<goal>dokka</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>default-compile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>default-testCompile</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>testCompile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>testCompile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,29 @@
|
||||
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,107 @@
|
||||
package cc.carm.lib.configuration.kotlin.value
|
||||
|
||||
import cc.carm.lib.configuration.adapter.ValueType
|
||||
import cc.carm.lib.configuration.builder.map.SourceMapBuilder
|
||||
import cc.carm.lib.configuration.value.standard.ConfiguredMap
|
||||
import java.util.*
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
inline fun <S : Any, reified K, reified V> hashmapFrom(
|
||||
clazz: KClass<S>,
|
||||
block: SourceMapBuilder<HashMap<K, V>, S, K, V>.() -> Unit
|
||||
): ConfiguredMap<K, V> {
|
||||
return hashmapFrom(clazz.java, block)
|
||||
}
|
||||
|
||||
inline fun <S : Any, reified K, reified V> hashmapFrom(
|
||||
clazz: Class<S>,
|
||||
block: SourceMapBuilder<HashMap<K, V>, S, K, V>.() -> Unit
|
||||
): ConfiguredMap<K, V> {
|
||||
return hashmapFrom(ValueType.of(clazz), block)
|
||||
}
|
||||
|
||||
inline fun <S : Any, reified K, reified V> hashmapFrom(
|
||||
valueType: ValueType<S>,
|
||||
block: SourceMapBuilder<HashMap<K, V>, S, K, V>.() -> Unit
|
||||
): ConfiguredMap<K, V> {
|
||||
val mapCreator = ConfiguredMap.builderOf(K::class.java, V::class.java)
|
||||
val sourceValueBuilder: SourceMapBuilder<HashMap<K, V>, S, K, V> = mapCreator.asHashMap().from(valueType)
|
||||
return sourceValueBuilder.also(block).build()
|
||||
}
|
||||
|
||||
inline fun <S : Any, reified K, reified V> linkedMapFrom(
|
||||
clazz: KClass<S>,
|
||||
block: SourceMapBuilder<LinkedHashMap<K, V>, S, K, V>.() -> Unit
|
||||
): ConfiguredMap<K, V> {
|
||||
return linkedMapFrom(clazz.java, block)
|
||||
}
|
||||
|
||||
inline fun <S : Any, reified K, reified V> linkedMapFrom(
|
||||
clazz: Class<S>,
|
||||
block: SourceMapBuilder<LinkedHashMap<K, V>, S, K, V>.() -> Unit
|
||||
): ConfiguredMap<K, V> {
|
||||
return linkedMapFrom(ValueType.of(clazz), block)
|
||||
}
|
||||
|
||||
inline fun <S : Any, reified K, reified V> linkedMapFrom(
|
||||
valueType: ValueType<S>,
|
||||
block: SourceMapBuilder<LinkedHashMap<K, V>, S, K, V>.() -> Unit
|
||||
): ConfiguredMap<K, V> {
|
||||
val mapCreator = ConfiguredMap.builderOf(K::class.java, V::class.java)
|
||||
val sourceValueBuilder: SourceMapBuilder<LinkedHashMap<K, V>, S, K, V> = mapCreator.asLinkedMap().from(valueType)
|
||||
return sourceValueBuilder.also(block).build()
|
||||
}
|
||||
|
||||
inline fun <S : Any, reified K, reified V> treeMapFrom(
|
||||
clazz: KClass<S>,
|
||||
block: SourceMapBuilder<TreeMap<K, V>, S, K, V>.() -> Unit
|
||||
): ConfiguredMap<K, V> {
|
||||
return treeMapFrom(clazz.java, block)
|
||||
}
|
||||
|
||||
inline fun <S : Any, reified K, reified V> treeMapFrom(
|
||||
clazz: Class<S>,
|
||||
block: SourceMapBuilder<TreeMap<K, V>, S, K, V>.() -> Unit
|
||||
): ConfiguredMap<K, V> {
|
||||
return treeMapFrom(ValueType.of(clazz), block)
|
||||
}
|
||||
|
||||
inline fun <S : Any, reified K, reified V> treeMapFrom(
|
||||
valueType: ValueType<S>,
|
||||
block: SourceMapBuilder<TreeMap<K, V>, S, K, V>.() -> Unit
|
||||
): ConfiguredMap<K, V> {
|
||||
val mapCreator = ConfiguredMap.builderOf(K::class.java, V::class.java)
|
||||
val sourceValueBuilder: SourceMapBuilder<TreeMap<K, V>, S, K, V> = mapCreator.asTreeMap().from(valueType)
|
||||
return sourceValueBuilder.also(block).build()
|
||||
}
|
||||
|
||||
inline fun <reified MAP : Map<K, V>, S : Any, reified K, reified V> mapFrom(
|
||||
clazz: KClass<S>,
|
||||
noinline map: () -> MAP,
|
||||
block: SourceMapBuilder<MAP, S, K, V>.() -> Unit
|
||||
): ConfiguredMap<K, V> {
|
||||
return mapFrom(clazz.java, map, block)
|
||||
}
|
||||
|
||||
inline fun <reified MAP : Map<K, V>, S : Any, reified K, reified V> mapFrom(
|
||||
clazz: Class<S>,
|
||||
noinline map: () -> MAP,
|
||||
block: SourceMapBuilder<MAP, S, K, V>.() -> Unit
|
||||
): ConfiguredMap<K, V> {
|
||||
return mapFrom(ValueType.of(clazz), map, block)
|
||||
}
|
||||
|
||||
inline fun <reified MAP : Map<K, V>, S : Any, reified K, reified V> mapFrom(
|
||||
valueType: ValueType<S>,
|
||||
noinline map: () -> MAP,
|
||||
block: SourceMapBuilder<MAP, S, K, V>.() -> Unit
|
||||
): ConfiguredMap<K, V> {
|
||||
val mapCreator = ConfiguredMap.builderOf(K::class.java, V::class.java)
|
||||
val sourceValueBuilder: SourceMapBuilder<MAP, S, K, V> = mapCreator.constructor(map).from(valueType)
|
||||
return sourceValueBuilder.also(block).build()
|
||||
}
|
||||
|
||||
|
||||
fun <MAP : Map<K, V>, S, K, V> SourceMapBuilder<MAP, S, K, V>.defaultMap(map: MAP): SourceMapBuilder<MAP, S, K, V> {
|
||||
return defaults(map)
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package cc.carm.lib.configuration.kotlin.value
|
||||
|
||||
import cc.carm.lib.configuration.adapter.ValueType
|
||||
import cc.carm.lib.configuration.builder.value.SourceValueBuilder
|
||||
import cc.carm.lib.configuration.value.standard.ConfiguredValue
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
inline fun <S : Any, reified T> valueFrom(
|
||||
clazz: KClass<S>, block: (SourceValueBuilder<S, T>.() -> Unit)
|
||||
): ConfiguredValue<T> {
|
||||
return valueFrom(clazz.java, block)
|
||||
}
|
||||
|
||||
inline fun <S : Any, reified V> valueFrom(
|
||||
clazz: Class<S>, block: (SourceValueBuilder<S, V>.() -> Unit)
|
||||
): ConfiguredValue<V> {
|
||||
return valueFrom(ValueType.of(clazz), block)
|
||||
}
|
||||
|
||||
inline fun <S : Any, reified V> valueFrom(
|
||||
valueType: ValueType<S>, block: (SourceValueBuilder<S, V>.() -> Unit)
|
||||
): ConfiguredValue<V> {
|
||||
val configBuilder = ConfiguredValue.builderOf(V::class.java)
|
||||
val sourceValueBuilder: SourceValueBuilder<S, V> = if (valueType.rawType == String::class.java) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
configBuilder.fromString() as SourceValueBuilder<S, V>
|
||||
} else configBuilder.from(valueType)
|
||||
sourceValueBuilder.parse { holder, data ->
|
||||
holder.deserialize(V::class.java, data)
|
||||
}
|
||||
sourceValueBuilder.serialize { holder, data ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
holder.serialize(data) as? S
|
||||
}
|
||||
return sourceValueBuilder.also(block).build()
|
||||
}
|
||||
@@ -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>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<version>4.1.7</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>configured-feature-record</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<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,127 @@
|
||||
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.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)
|
||||
)
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
// 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) {
|
||||
}
|
||||
|
||||
|
||||
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>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
@@ -48,4 +48,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
+6
-1
@@ -74,7 +74,7 @@ public class ImmutableSection implements ConfigureSection {
|
||||
@Override
|
||||
public @Nullable ConfigureSection getSection(@NotNull String path) {
|
||||
ConfigureSection get = raw().getSection(path);
|
||||
if (get != null && !(get instanceof ImmutableSection)) {
|
||||
if (!(get instanceof ImmutableSection)) {
|
||||
return new ImmutableSection(this, get);
|
||||
}
|
||||
return get;
|
||||
@@ -350,6 +350,11 @@ public class ImmutableSection implements ConfigureSection {
|
||||
return raw().getCharList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<ConfigureSection> getSectionList(@NotNull String path) {
|
||||
return raw().getSectionList(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T, C extends Collection<T>> @NotNull C getCollection(@NotNull String path, @NotNull Supplier<C> constructor, @NotNull DataFunction<Object, T> parser) {
|
||||
return raw().getCollection(path, constructor, parser);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
@@ -57,4 +57,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
+5
-5
@@ -27,8 +27,8 @@ public class ConfiguredText<MSG, RECEIVER> extends ConfiguredValue<TextContents>
|
||||
|
||||
public static final ValueType<TextContents> TEXT_TYPE = ValueType.of(TextContents.class);
|
||||
public static final ValueAdapter<TextContents> TEXT_ADAPTER = new ValueAdapter<>(TEXT_TYPE,
|
||||
(h, t, d) -> d.serialize(),
|
||||
(h, t, d) -> TextContents.deserialize(d)
|
||||
(h, t, d) -> d.serialize(),
|
||||
(h, t, d) -> TextContents.deserialize(d)
|
||||
);
|
||||
|
||||
protected final @NotNull BiFunction<RECEIVER, String, String> parser;
|
||||
@@ -51,8 +51,8 @@ public class ConfiguredText<MSG, RECEIVER> extends ConfiguredValue<TextContents>
|
||||
|
||||
public PreparedText<MSG, RECEIVER> prepare(@NotNull Object... values) {
|
||||
return new PreparedText<MSG, RECEIVER>(resolve(), this.params)
|
||||
.parser(this.parser).compiler(this.compiler)
|
||||
.dispatcher(this.dispatcher).placeholders(values);
|
||||
.parser(this.parser).compiler(this.compiler)
|
||||
.dispatcher(this.dispatcher).placeholders(values);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +120,7 @@ public class ConfiguredText<MSG, RECEIVER> extends ConfiguredValue<TextContents>
|
||||
}
|
||||
|
||||
public abstract static class Builder<MSG, RECEIVER, SELF extends Builder<MSG, RECEIVER, SELF>>
|
||||
extends AbstractConfigBuilder<TextContents, TextContents, ConfiguredText<MSG, RECEIVER>, ConfigurationHolder<?>, SELF> {
|
||||
extends AbstractConfigBuilder<TextContents, TextContents, ConfiguredText<MSG, RECEIVER>, ConfigurationHolder<?>, SELF> {
|
||||
protected @NotNull TextContents.Builder defaultBuilder = TextContents.builder();
|
||||
protected @NotNull String[] params = new String[0];
|
||||
|
||||
|
||||
+16
-1
@@ -21,7 +21,7 @@ import java.util.function.Function;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEIVER, SELF>>
|
||||
implements Replaceable<RECEIVER, SELF>, Insertable<RECEIVER, SELF> {
|
||||
implements Replaceable<RECEIVER, SELF>, Insertable<RECEIVER, SELF> {
|
||||
|
||||
protected BiFunction<RECEIVER, String, String> parser = (receiver, value) -> value;
|
||||
protected String lineSeparator = System.lineSeparator();
|
||||
@@ -156,6 +156,11 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
|
||||
return self();
|
||||
}
|
||||
|
||||
public SELF paramReplacer(@NotNull ParamReplacer<RECEIVER> paramReplacer) {
|
||||
this.paramReplacer = paramReplacer;
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ContentInserter<RECEIVER>> inserters() {
|
||||
return this.inserters;
|
||||
@@ -246,6 +251,16 @@ public abstract class ContentHandler<RECEIVER, SELF extends ContentHandler<RECEI
|
||||
}
|
||||
}
|
||||
|
||||
public static String setPlaceholders(@NotNull String messages,
|
||||
@NotNull Map<String, Object> placeholders) {
|
||||
if (messages.isEmpty()) return messages;
|
||||
String parsed = messages;
|
||||
for (Map.Entry<String, Object> entry : placeholders.entrySet()) {
|
||||
parsed = parsed.replace(entry.getKey(), entry.getValue() == null ? "" : entry.getValue().toString());
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
|
||||
public static Map<String, Object> buildParams(@NotNull UnaryOperator<String> paramBuilder,
|
||||
@Nullable String[] params, @Nullable Object[] values) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
package cc.carm.lib.configuration.value.text.function;
|
||||
|
||||
import cc.carm.lib.configuration.value.text.data.TextContents;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class TextParser<RECEIVER, SELF extends TextParser<RECEIVER, SELF>>
|
||||
extends ContentHandler<RECEIVER, SELF> {
|
||||
extends ContentHandler<RECEIVER, SELF> {
|
||||
|
||||
public abstract TextContents texts();
|
||||
|
||||
|
||||
+3
-3
@@ -29,7 +29,7 @@ public class AppendLineInserter<RECEIVER> extends ContentInserter<RECEIVER> {
|
||||
* </ul>
|
||||
*/
|
||||
public static final @NotNull Pattern APPEND_PATTERN = Pattern.compile(
|
||||
"^(?:\\{(?<prefix>.*)})?#(?<id>.*)#(?:\\{(?<above>-?\\d+)(?:,(?<down>-?\\d+))?})?$"
|
||||
"^(?:\\{(?<prefix>.*)})?#(?<id>.*)#(?:\\{(?<above>-?\\d+)(?:,(?<down>-?\\d+))?})?$"
|
||||
);
|
||||
|
||||
public AppendLineInserter(int priority) {
|
||||
@@ -50,9 +50,9 @@ public class AppendLineInserter<RECEIVER> extends ContentInserter<RECEIVER> {
|
||||
|
||||
String prefix = Optional.ofNullable(matcher.group("prefix")).orElse("");
|
||||
int offsetAbove = Optional.ofNullable(matcher.group("above"))
|
||||
.map(Integer::parseInt).orElse(0);
|
||||
.map(Integer::parseInt).orElse(0);
|
||||
int offsetDown = Optional.ofNullable(matcher.group("down"))
|
||||
.map(Integer::parseInt).orElse(offsetAbove); // If offsetDown is not set, use offsetAbove
|
||||
.map(Integer::parseInt).orElse(offsetAbove); // If offsetDown is not set, use offsetAbove
|
||||
|
||||
List<String> contents = new ArrayList<>();
|
||||
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ public class OptionalLineInserter<RECEIVER> extends ContentInserter<RECEIVER> {
|
||||
* </ul>
|
||||
*/
|
||||
public static final @NotNull Pattern OPTIONAL_PATTERN = Pattern.compile(
|
||||
"^\\?\\[(?<id>.+)](?<content>.*)$"
|
||||
"^\\?\\[(?<id>.+)](?<content>.*)$"
|
||||
);
|
||||
|
||||
public OptionalLineInserter(int priority) {
|
||||
|
||||
+7
-7
@@ -12,9 +12,9 @@ import java.util.List;
|
||||
public class ConfigTest {
|
||||
|
||||
public static final String[] WEBSITES = new String[]{
|
||||
"https://carm.cc",
|
||||
"https://www.baidu.com",
|
||||
"https://www.google.com"
|
||||
"https://carm.cc",
|
||||
"https://www.baidu.com",
|
||||
"https://www.google.com"
|
||||
};
|
||||
|
||||
@Test
|
||||
@@ -27,10 +27,10 @@ public class ConfigTest {
|
||||
System.out.println("--------------------------");
|
||||
|
||||
List<String> str = AppMessages.WELCOME.prepare()
|
||||
.placeholders("Carm")
|
||||
.insert("guidance")
|
||||
.insert("websites", WEBSITES)
|
||||
.compile(System.out);
|
||||
.placeholders("Carm")
|
||||
.insert("guidance")
|
||||
.insert("websites", WEBSITES)
|
||||
.compile(System.out);
|
||||
|
||||
System.out.println("--------------------------");
|
||||
|
||||
|
||||
+9
-9
@@ -33,17 +33,17 @@ public class ParseTest {
|
||||
TextContents textContents = new TextContents(lines, optional);
|
||||
|
||||
PreparedText<String, PrintStream> msg = new PreparedText<String, PrintStream>(textContents)
|
||||
.dispatcher((p, s) -> s.forEach(p::println))
|
||||
.parser((p, s) -> s)
|
||||
.compiler((p, s) -> s)
|
||||
.replace( // Custom replacer, replace $UUID$ with Random UUID
|
||||
"$UUID$", () -> UUID.randomUUID().toString()
|
||||
);
|
||||
.dispatcher((p, s) -> s.forEach(p::println))
|
||||
.parser((p, s) -> s)
|
||||
.compiler((p, s) -> s)
|
||||
.replace( // Custom replacer, replace $UUID$ with Random UUID
|
||||
"$UUID$", () -> UUID.randomUUID().toString()
|
||||
);
|
||||
|
||||
msg.placeholder("name", "Carm")
|
||||
.insert("guidance")
|
||||
.insert("click")
|
||||
.insert("websites", "Baidu", "Bilibili", "Google");
|
||||
.insert("guidance")
|
||||
.insert("click")
|
||||
.insert("websites", "Baidu", "Bilibili", "Google");
|
||||
|
||||
|
||||
System.out.println("----------------------------");
|
||||
|
||||
+13
-13
@@ -7,22 +7,22 @@ import cc.carm.lib.configuration.annotation.ConfigPath;
|
||||
public interface AppMessages extends Configuration {
|
||||
|
||||
ConfiguredMsg WELCOME = ConfiguredMsg.builder()
|
||||
.defaults(
|
||||
"Hello, %(name)",
|
||||
"#more-creating#{1}",
|
||||
"This is a test message",
|
||||
"#guidance#",
|
||||
"{- }#websites#{0,1}",
|
||||
"Thanks for your reading!")
|
||||
.optional("guidance", "To get more information for %(name), see:")
|
||||
.params("name").build();
|
||||
.defaults(
|
||||
"Hello, %(name)",
|
||||
"#more-creating#{1}",
|
||||
"This is a test message",
|
||||
"#guidance#",
|
||||
"{- }#websites#{0,1}",
|
||||
"Thanks for your reading!")
|
||||
.optional("guidance", "To get more information for %(name), see:")
|
||||
.params("name").build();
|
||||
|
||||
ConfiguredMsg NO_PERMISSION = ConfiguredMsg.builder()
|
||||
.defaults("Sorry! But you don't have permissions to do this.")
|
||||
.build();
|
||||
.defaults("Sorry! But you don't have permissions to do this.")
|
||||
.build();
|
||||
|
||||
ConfiguredMsg NOT_AVAILABLE = ConfiguredMsg.builder()
|
||||
.defaults("Error! Service is not available now.", "Please contact your system manager.")
|
||||
.build();
|
||||
.defaults("Error! Service is not available now.", "Please contact your system manager.")
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
+5
-5
@@ -20,11 +20,11 @@ public class ConfiguredMsg extends ConfiguredText<String, PrintStream> {
|
||||
public ConfiguredMsg(@NotNull ValueManifest<TextContents, TextContents> manifest,
|
||||
@NotNull String[] params) {
|
||||
super(
|
||||
manifest,
|
||||
(p, s) -> s,
|
||||
(p, s) -> s,
|
||||
(p, s) -> s.forEach(p::println),
|
||||
params
|
||||
manifest,
|
||||
(p, s) -> s,
|
||||
(p, s) -> s,
|
||||
(p, s) -> s.forEach(p::println),
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
@@ -48,4 +48,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
@@ -48,4 +48,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<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.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.2.0</kotlin.version>
|
||||
</properties>
|
||||
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
<modules>
|
||||
<module>core</module>
|
||||
<module>features/section</module>
|
||||
@@ -24,7 +25,10 @@
|
||||
<module>features/versioned</module>
|
||||
<module>features/validators</module>
|
||||
<module>features/text</module>
|
||||
<module>features/kotlin</module>
|
||||
<module>features/record</module>
|
||||
|
||||
<module>providers/temp</module>
|
||||
<module>providers/yaml</module>
|
||||
<module>providers/gson</module>
|
||||
<module>providers/hocon</module>
|
||||
@@ -74,22 +78,21 @@
|
||||
|
||||
<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>
|
||||
<id>central</id>
|
||||
<url>https://repo1.maven.org/maven2/</url>
|
||||
</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>
|
||||
|
||||
<distributionManagement>
|
||||
@@ -126,7 +129,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.5.2</version>
|
||||
<version>3.5.3</version>
|
||||
<configuration>
|
||||
<useSystemClassLoader>false</useSystemClassLoader>
|
||||
</configuration>
|
||||
@@ -166,7 +169,6 @@
|
||||
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
@@ -276,11 +278,14 @@
|
||||
<plugin>
|
||||
<groupId>org.sonatype.central</groupId>
|
||||
<artifactId>central-publishing-maven-plugin</artifactId>
|
||||
<version>0.7.0</version>
|
||||
<version>0.8.0</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<publishingServerId>central</publishingServerId>
|
||||
<autoPublish>true</autoPublish>
|
||||
<excludeArtifacts>
|
||||
<excludeArtifact>configured-demo</excludeArtifact>
|
||||
</excludeArtifacts>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
@@ -301,4 +306,4 @@
|
||||
</profiles>
|
||||
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -1,8 +1,24 @@
|
||||
# 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
|
||||
|
||||
|
||||
+3
-10
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -41,17 +41,10 @@
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-demo</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.13.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -78,4 +71,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -17,11 +17,11 @@ import java.util.Objects;
|
||||
public class JSONSource extends FileConfigSource<SourcedSection, Map<String, Object>, JSONSource> {
|
||||
|
||||
public static final @NotNull Gson DEFAULT_GSON = new GsonBuilder()
|
||||
.serializeNulls().disableHtmlEscaping().setPrettyPrinting()
|
||||
.registerTypeAdapter(
|
||||
SourcedSection.class,
|
||||
(JsonSerializer<SourcedSection>) (src, t, c) -> c.serialize(src.data())
|
||||
).create();
|
||||
.serializeNulls().disableHtmlEscaping().setPrettyPrinting()
|
||||
.registerTypeAdapter(
|
||||
SourcedSection.class,
|
||||
(JsonSerializer<SourcedSection>) (src, t, c) -> c.serialize(src.data())
|
||||
).create();
|
||||
|
||||
protected final @NotNull Gson gson;
|
||||
protected @Nullable SourcedSection rootSection;
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
# configured-HOCON
|
||||
|
||||
HOCON file-based implementation, compatible with all Java environments.
|
||||
HOCON
|
||||
file-based
|
||||
implementation,
|
||||
compatible
|
||||
with
|
||||
all
|
||||
Java
|
||||
environments.
|
||||
|
||||
## Dependencies
|
||||
|
||||
|
||||
+2
-10
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
@@ -43,14 +43,6 @@
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-demo</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.typesafe</groupId>
|
||||
<artifactId>config</artifactId>
|
||||
@@ -82,4 +74,4 @@
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
+30
-27
@@ -9,15 +9,18 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
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
|
||||
extends FileConfigSource<SourcedSection, Map<String, Object>, HOCONSource> {
|
||||
extends FileConfigSource<SourcedSection, Map<String, Object>, HOCONSource> {
|
||||
protected @Nullable SourcedSection rootSection;
|
||||
|
||||
protected HOCONSource(
|
||||
@NotNull ConfigurationHolder<? extends HOCONSource> holder,
|
||||
@NotNull File file, @Nullable String resourcePath
|
||||
@NotNull ConfigurationHolder<? extends HOCONSource> holder,
|
||||
@NotNull File file, @Nullable String resourcePath
|
||||
) {
|
||||
super(holder, 0, file, resourcePath);
|
||||
|
||||
@@ -54,32 +57,32 @@ public class HOCONSource
|
||||
// accumulator: 将 Section 中的信息为 typesafe config 添加并返回
|
||||
// combiner: 合并两个配置文件
|
||||
Config config = this.getValues(true).entrySet().stream().reduce(
|
||||
ConfigFactory.empty(),
|
||||
(cfg, entry) -> {
|
||||
String key = entry.getKey(); // 源数据 key
|
||||
Object value = entry.getValue(); // 源数据 value
|
||||
ConfigFactory.empty(),
|
||||
(cfg, entry) -> {
|
||||
String key = entry.getKey(); // 源数据 key
|
||||
Object value = entry.getValue(); // 源数据 value
|
||||
|
||||
ConfigValue result; // 最终转换为 typesafe 的 ConfigValue 类型
|
||||
if (value == null || value instanceof Boolean || value instanceof String || value instanceof Number) {
|
||||
result = ConfigValueFactory.fromAnyRef(value); // 原始数据类型
|
||||
} else if (value instanceof Iterator) {
|
||||
result = ConfigValueFactory.fromIterable((Iterable<?>) value);
|
||||
} else if (value instanceof Map) {
|
||||
//noinspection unchecked
|
||||
result = ConfigValueFactory.fromMap((Map<String, ?>) value);
|
||||
} else {
|
||||
result = ConfigValueFactory.fromAnyRef(String.valueOf(value));
|
||||
}
|
||||
List<String> headerComments = HOCONSource.this.getHeaderComments(key); // 获取其注释
|
||||
result = result.withOrigin(result.origin().withComments(headerComments)); // 赋予其注释
|
||||
return cfg.withValue(key, result); // 将其添加到根 config 中
|
||||
},
|
||||
Config::withFallback
|
||||
ConfigValue result; // 最终转换为 typesafe 的 ConfigValue 类型
|
||||
if (value == null || value instanceof Boolean || value instanceof String || value instanceof Number) {
|
||||
result = ConfigValueFactory.fromAnyRef(value); // 原始数据类型
|
||||
} else if (value instanceof Iterator) {
|
||||
result = ConfigValueFactory.fromIterable((Iterable<?>) value);
|
||||
} else if (value instanceof Map) {
|
||||
//noinspection unchecked
|
||||
result = ConfigValueFactory.fromMap((Map<String, ?>) value);
|
||||
} else {
|
||||
result = ConfigValueFactory.fromAnyRef(String.valueOf(value));
|
||||
}
|
||||
List<String> headerComments = HOCONSource.this.getHeaderComments(key); // 获取其注释
|
||||
result = result.withOrigin(result.origin().withComments(headerComments)); // 赋予其注释
|
||||
return cfg.withValue(key, result); // 将其添加到根 config 中
|
||||
},
|
||||
Config::withFallback
|
||||
);
|
||||
return config.root().render(
|
||||
ConfigRenderOptions.defaults()
|
||||
.setJson(false)
|
||||
.setOriginComments(false)
|
||||
ConfigRenderOptions.defaults()
|
||||
.setJson(false)
|
||||
.setOriginComments(false)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ public interface SampleConfig extends Configuration {
|
||||
|
||||
@HeaderComments({"[ UUID >-----------------------------------", "A lot of UUIDs"})
|
||||
ConfiguredList<UUID> UUIDS = ConfiguredList.builderOf(UUID.class).fromString()
|
||||
.parse(UUID::fromString).serialize(UUID::toString)
|
||||
.defaults(
|
||||
UUID.fromString("00000000-0000-0000-0000-000000000000"),
|
||||
UUID.fromString("00000000-0000-0000-0000-000000000001")
|
||||
).build();
|
||||
.parse(UUID::fromString).serialize(UUID::toString)
|
||||
.defaults(
|
||||
UUID.fromString("00000000-0000-0000-0000-000000000000"),
|
||||
UUID.fromString("00000000-0000-0000-0000-000000000001")
|
||||
).build();
|
||||
|
||||
@ConfigPath("info") // Custom path
|
||||
interface INFO extends Configuration {
|
||||
|
||||
@@ -4,14 +4,14 @@ import cc.carm.lib.configuration.source.ConfigurationHolder;
|
||||
import cc.carm.lib.configuration.source.hocon.HOCONConfigFactory;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SampleTest {
|
||||
public class SampleTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
// 1. Make a configuration provider from a file.
|
||||
ConfigurationHolder<?> holder = HOCONConfigFactory.from("target/config.conf")
|
||||
.resourcePath("configs/sample.conf")
|
||||
.build();
|
||||
.resourcePath("configs/sample.conf")
|
||||
.build();
|
||||
|
||||
// 2. Initialize the configuration classes or instances.
|
||||
holder.initialize(SampleConfig.class);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
@@ -14,9 +14,7 @@
|
||||
<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>
|
||||
|
||||
<deps.mongodb.version>5.3.1</deps.mongodb.version>
|
||||
<log4j.version>2.24.3</log4j.version>
|
||||
<deps.mongodb.version>5.5.1</deps.mongodb.version>
|
||||
</properties>
|
||||
<artifactId>configured-mongodb</artifactId>
|
||||
|
||||
@@ -42,41 +40,6 @@
|
||||
<version>${deps.mongodb.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>${log4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-demo</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-gson</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -100,4 +63,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="WARN" packages="config.SQLConfigTest">
|
||||
<Appenders>
|
||||
<console name="Console" target="SYSTEM_OUT">
|
||||
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg%n"/>
|
||||
</console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="info">
|
||||
<filters>
|
||||
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL"/>
|
||||
<RegexFilter regex=".*\$\{[^}]*\}.*" onMatch="DENY" onMismatch="NEUTRAL"/>
|
||||
</filters>
|
||||
<AppenderRef ref="File"/>
|
||||
<appender-ref ref="Console"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
|
||||
+48
-15
@@ -1,8 +1,16 @@
|
||||
# configured-SQL
|
||||
|
||||
SQL database implementation, support for MySQL or MariaDB.
|
||||
SQL
|
||||
database
|
||||
implementation,
|
||||
support
|
||||
for
|
||||
MySQL
|
||||
or
|
||||
MariaDB.
|
||||
|
||||
## Table schema
|
||||
|
||||
```mysql
|
||||
CREATE TABLE IF NOT EXISTS conf
|
||||
(
|
||||
@@ -16,9 +24,11 @@ CREATE TABLE IF NOT EXISTS conf
|
||||
`version` MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, # 配置项的版本
|
||||
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, # 创建时间
|
||||
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`namespace`, `path`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4;
|
||||
PRIMARY KEY (`namespace`,
|
||||
`path`)
|
||||
)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4;
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
@@ -32,16 +42,30 @@ CREATE TABLE IF NOT EXISTS conf
|
||||
|
||||
<repository>
|
||||
<!-- Using Maven Central Repository for secure and stable updates, though synchronization might be needed. -->
|
||||
<id>maven</id>
|
||||
<name>Maven Central</name>
|
||||
<url>https://repo1.maven.org/maven2</url>
|
||||
<id>
|
||||
maven
|
||||
</id>
|
||||
<name>
|
||||
Maven
|
||||
Central
|
||||
</name>
|
||||
<url>
|
||||
https://repo1.maven.org/maven2
|
||||
</url>
|
||||
</repository>
|
||||
|
||||
<repository>
|
||||
<!-- Using GitHub dependencies for real-time updates, configuration required (recommended). -->
|
||||
<id>configured</id>
|
||||
<name>GitHub Packages</name>
|
||||
<url>https://maven.pkg.github.com/CarmJos/configured</url>
|
||||
<id>
|
||||
configured
|
||||
</id>
|
||||
<name>
|
||||
GitHub
|
||||
Packages
|
||||
</name>
|
||||
<url>
|
||||
https://maven.pkg.github.com/CarmJos/configured
|
||||
</url>
|
||||
</repository>
|
||||
|
||||
</repositories>
|
||||
@@ -53,10 +77,19 @@ CREATE TABLE IF NOT EXISTS conf
|
||||
<project>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>configured-sql</artifactId>
|
||||
<version>[LATEST RELEASE]</version>
|
||||
<scope>compile</scope>
|
||||
<groupId>
|
||||
cc.carm.lib
|
||||
</groupId>
|
||||
<artifactId>
|
||||
configured-sql
|
||||
</artifactId>
|
||||
<version>
|
||||
[LATEST
|
||||
RELEASE]
|
||||
</version>
|
||||
<scope>
|
||||
compile
|
||||
</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -80,4 +113,4 @@ repositories {
|
||||
dependencies {
|
||||
api "cc.carm.lib:configured-sql:[LATEST RELEASE]"
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
+3
-55
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<artifactId>configured-parent</artifactId>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.1.7</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<properties>
|
||||
@@ -14,9 +14,6 @@
|
||||
<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>
|
||||
|
||||
<deps.mysql-driver.version>8.0.33</deps.mysql-driver.version>
|
||||
<deps.log4j.version>2.24.3</deps.log4j.version>
|
||||
</properties>
|
||||
<artifactId>configured-sql</artifactId>
|
||||
|
||||
@@ -52,7 +49,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.12.1</version>
|
||||
<version>2.13.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -61,55 +58,6 @@
|
||||
<version>0.4.7</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cc.carm.lib</groupId>
|
||||
<artifactId>easysql-beecp</artifactId>
|
||||
<version>0.4.7</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-demo</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>${deps.log4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>${deps.log4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>${deps.log4j.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.parent.groupId}</groupId>
|
||||
<artifactId>configured-gson</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${deps.mysql-driver.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -133,4 +81,4 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
+9
-9
@@ -32,7 +32,7 @@ public class SQLConfigFactory extends ConfigurationFactory<SQLSource, Configurat
|
||||
}
|
||||
|
||||
protected static final @NotNull Gson DEFAULT_GSON = new GsonBuilder()
|
||||
.serializeNulls().disableHtmlEscaping().create();
|
||||
.serializeNulls().disableHtmlEscaping().create();
|
||||
|
||||
protected static final @NotNull BiConsumer<String, TableCreateBuilder> DEFAULT_TABLE_SCHEMA = (tableName, builder) -> {
|
||||
builder.addColumn("namespace", "VARCHAR(32) NOT NULL");
|
||||
@@ -48,17 +48,17 @@ public class SQLConfigFactory extends ConfigurationFactory<SQLSource, Configurat
|
||||
builder.addColumn("version", "MEDIUMINT UNSIGNED NOT NULL DEFAULT 0");
|
||||
|
||||
builder.addColumn(
|
||||
"create_time",
|
||||
"TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP"
|
||||
"create_time",
|
||||
"TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP"
|
||||
);
|
||||
builder.addColumn(
|
||||
"update_time",
|
||||
"TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
|
||||
"update_time",
|
||||
"TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"
|
||||
);
|
||||
|
||||
builder.setIndex(
|
||||
IndexType.PRIMARY_KEY, "pk_" + tableName.toLowerCase(),
|
||||
"namespace", "path"
|
||||
IndexType.PRIMARY_KEY, "pk_" + tableName.toLowerCase(),
|
||||
"namespace", "path"
|
||||
);
|
||||
builder.setTableSettings("ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
|
||||
};
|
||||
@@ -163,8 +163,8 @@ public class SQLConfigFactory extends ConfigurationFactory<SQLSource, Configurat
|
||||
|
||||
return new ConfigurationHolder<SQLSource>(this.adapters, this.options, this.metadata, this.initializer) {
|
||||
final SQLSource source = new SQLSource(
|
||||
this, System.currentTimeMillis(),
|
||||
gson, manager, resolvers, tableName, namespace
|
||||
this, System.currentTimeMillis(),
|
||||
gson, manager, resolvers, tableName, namespace
|
||||
);
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,6 +7,6 @@ public interface SQLOptions {
|
||||
/**
|
||||
* Whether to purge the configuration's in-database data when saving.
|
||||
*/
|
||||
ConfigurationOption<Boolean> PURGE = ConfigurationOption.of( true);
|
||||
ConfigurationOption<Boolean> PURGE = ConfigurationOption.of(true);
|
||||
|
||||
}
|
||||
|
||||
@@ -104,10 +104,10 @@ public class SQLSource extends ConfigureSource<SourcedSection, Map<String, Objec
|
||||
|
||||
int version = holder().metadata(path).get(VersionedMetaTypes.VERSION, 0);
|
||||
dataValues.add(new Object[]{
|
||||
namespace, path, time, version, typeID, data,
|
||||
Commentable.getInlineComment(holder(), path),
|
||||
gson.toJson(Commentable.getHeaderComments(holder(), path)),
|
||||
gson.toJson(Commentable.getFooterComments(holder(), path))
|
||||
namespace, path, time, version, typeID, data,
|
||||
Commentable.getInlineComment(holder(), path),
|
||||
gson.toJson(Commentable.getHeaderComments(holder(), path)),
|
||||
gson.toJson(Commentable.getFooterComments(holder(), path))
|
||||
});
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
@@ -118,18 +118,18 @@ public class SQLSource extends ConfigureSource<SourcedSection, Map<String, Objec
|
||||
purge();
|
||||
}
|
||||
this.table.createReplaceBatch()
|
||||
.setColumnNames(
|
||||
"namespace", "path", "update_time", "version", "type", "value",
|
||||
"inline_comment", "header_comments", "footer_comments"
|
||||
).setAllParams(dataValues).execute();
|
||||
.setColumnNames(
|
||||
"namespace", "path", "update_time", "version", "type", "value",
|
||||
"inline_comment", "header_comments", "footer_comments"
|
||||
).setAllParams(dataValues).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onReload() throws Exception {
|
||||
Map<String, Object> loaded = new LinkedHashMap<>();
|
||||
try (SQLQuery query = this.table.createQuery()
|
||||
.addCondition("namespace", namespace)
|
||||
.build().execute()) {
|
||||
.addCondition("namespace", namespace)
|
||||
.build().execute()) {
|
||||
ResultSet rs = query.getResultSet();
|
||||
while (rs.next()) {
|
||||
String path = rs.getString("path");
|
||||
@@ -161,9 +161,9 @@ public class SQLSource extends ConfigureSource<SourcedSection, Map<String, Objec
|
||||
|
||||
protected int typeIdOf(@NotNull Object value) {
|
||||
return this.resolvers.entrySet().stream()
|
||||
.filter(entry -> entry.getValue().isInstance(value))
|
||||
.findFirst().map(Map.Entry::getKey)
|
||||
.orElseThrow(() -> new IllegalStateException("No resolvers for value " + value.getClass().getName()));
|
||||
.filter(entry -> entry.getValue().isInstance(value))
|
||||
.findFirst().map(Map.Entry::getKey)
|
||||
.orElseThrow(() -> new IllegalStateException("No resolvers for value " + value.getClass().getName()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?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.1.7</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>
|
||||
|
||||
<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
|
||||
|
||||
YAML file-based implementation, compatible with all Java environments.
|
||||
YAML
|
||||
file-based
|
||||
implementation,
|
||||
compatible
|
||||
with
|
||||
all
|
||||
Java
|
||||
environments.
|
||||
|
||||
## Dependencies
|
||||
|
||||
@@ -61,4 +68,4 @@ repositories {
|
||||
dependencies {
|
||||
api "cc.carm.lib:configured-yaml:[LATEST RELEASE]"
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user