diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..6583cdf --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..230810d --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__antlr_antlr_2_7_7.xml b/.idea/libraries/Maven__antlr_antlr_2_7_7.xml new file mode 100644 index 0000000..b8d93d8 --- /dev/null +++ b/.idea/libraries/Maven__antlr_antlr_2_7_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml b/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml new file mode 100644 index 0000000..6fec8f4 --- /dev/null +++ b/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml b/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml new file mode 100644 index 0000000..9eb8596 --- /dev/null +++ b/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_classmate_1_3_4.xml b/.idea/libraries/Maven__com_fasterxml_classmate_1_3_4.xml new file mode 100644 index 0000000..33c30b4 --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_classmate_1_3_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_12_4.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_12_4.xml new file mode 100644 index 0000000..5351aad --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_12_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_13_4.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_13_4.xml new file mode 100644 index 0000000..50b4341 --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_13_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_9_0.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_9_0.xml new file mode 100644 index 0000000..06441f4 --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_12_4.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_12_4.xml new file mode 100644 index 0000000..b61928e --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_12_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_13_4.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_13_4.xml new file mode 100644 index 0000000..f876adb --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_13_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_9_9.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_9_9.xml new file mode 100644 index 0000000..55b3f7b --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_9_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_12_4.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_12_4.xml new file mode 100644 index 0000000..3088e4d --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_12_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_13_4_1.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_13_4_1.xml new file mode 100644 index 0000000..ed189fd --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_13_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_9_9.xml b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_9_9.xml new file mode 100644 index 0000000..b007cab --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_9_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_12_4.xml b/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_12_4.xml new file mode 100644 index 0000000..03661ab --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_12_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_9_9.xml b/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_9_9.xml new file mode 100644 index 0000000..7fc8036 --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_9_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_12_4.xml b/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_12_4.xml new file mode 100644 index 0000000..518a6c9 --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_12_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_9_9.xml b/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_9_9.xml new file mode 100644 index 0000000..23c806c --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_9_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_12_4.xml b/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_12_4.xml new file mode 100644 index 0000000..9c5251c --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_12_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_9_9.xml b/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_9_9.xml new file mode 100644 index 0000000..fe2eb1b --- /dev/null +++ b/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_9_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_code_findbugs_jsr305_3_0_2.xml b/.idea/libraries/Maven__com_google_code_findbugs_jsr305_3_0_2.xml new file mode 100644 index 0000000..1c380d0 --- /dev/null +++ b/.idea/libraries/Maven__com_google_code_findbugs_jsr305_3_0_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_code_gson_gson_2_8_6.xml b/.idea/libraries/Maven__com_google_code_gson_gson_2_8_6.xml new file mode 100644 index 0000000..82a9f20 --- /dev/null +++ b/.idea/libraries/Maven__com_google_code_gson_gson_2_8_6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_code_gson_gson_2_8_7.xml b/.idea/libraries/Maven__com_google_code_gson_gson_2_8_7.xml new file mode 100644 index 0000000..12484a2 --- /dev/null +++ b/.idea/libraries/Maven__com_google_code_gson_gson_2_8_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_code_gson_gson_2_9_0.xml b/.idea/libraries/Maven__com_google_code_gson_gson_2_9_0.xml new file mode 100644 index 0000000..e79354d --- /dev/null +++ b/.idea/libraries/Maven__com_google_code_gson_gson_2_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_errorprone_error_prone_annotations_2_11_0.xml b/.idea/libraries/Maven__com_google_errorprone_error_prone_annotations_2_11_0.xml new file mode 100644 index 0000000..4eb3ba5 --- /dev/null +++ b/.idea/libraries/Maven__com_google_errorprone_error_prone_annotations_2_11_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_guava_failureaccess_1_0_1.xml b/.idea/libraries/Maven__com_google_guava_failureaccess_1_0_1.xml new file mode 100644 index 0000000..36e948e --- /dev/null +++ b/.idea/libraries/Maven__com_google_guava_failureaccess_1_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_guava_guava_31_1_jre.xml b/.idea/libraries/Maven__com_google_guava_guava_31_1_jre.xml new file mode 100644 index 0000000..5757b3d --- /dev/null +++ b/.idea/libraries/Maven__com_google_guava_guava_31_1_jre.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml b/.idea/libraries/Maven__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml new file mode 100644 index 0000000..4e15702 --- /dev/null +++ b/.idea/libraries/Maven__com_google_guava_listenablefuture_9999_0_empty_to_avoid_conflict_with_guava.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_google_j2objc_j2objc_annotations_1_3.xml b/.idea/libraries/Maven__com_google_j2objc_j2objc_annotations_1_3.xml new file mode 100644 index 0000000..bacaa45 --- /dev/null +++ b/.idea/libraries/Maven__com_google_j2objc_j2objc_annotations_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_jayway_jsonpath_json_path_2_4_0.xml b/.idea/libraries/Maven__com_jayway_jsonpath_json_path_2_4_0.xml new file mode 100644 index 0000000..f19f6eb --- /dev/null +++ b/.idea/libraries/Maven__com_jayway_jsonpath_json_path_2_4_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_squareup_okhttp3_okhttp_4_10_0_RC1.xml b/.idea/libraries/Maven__com_squareup_okhttp3_okhttp_4_10_0_RC1.xml new file mode 100644 index 0000000..e266aa3 --- /dev/null +++ b/.idea/libraries/Maven__com_squareup_okhttp3_okhttp_4_10_0_RC1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_squareup_okio_okio_2_9_0.xml b/.idea/libraries/Maven__com_squareup_okio_okio_2_9_0.xml new file mode 100644 index 0000000..ec9ead3 --- /dev/null +++ b/.idea/libraries/Maven__com_squareup_okio_okio_2_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml b/.idea/libraries/Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml new file mode 100644 index 0000000..b8581a6 --- /dev/null +++ b/.idea/libraries/Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__com_zaxxer_HikariCP_3_2_0.xml b/.idea/libraries/Maven__com_zaxxer_HikariCP_3_2_0.xml new file mode 100644 index 0000000..8f760a2 --- /dev/null +++ b/.idea/libraries/Maven__com_zaxxer_HikariCP_3_2_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__commons_beanutils_commons_beanutils_1_9_4.xml b/.idea/libraries/Maven__commons_beanutils_commons_beanutils_1_9_4.xml new file mode 100644 index 0000000..84eb115 --- /dev/null +++ b/.idea/libraries/Maven__commons_beanutils_commons_beanutils_1_9_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__commons_codec_commons_codec_1_15.xml b/.idea/libraries/Maven__commons_codec_commons_codec_1_15.xml new file mode 100644 index 0000000..c88c2b7 --- /dev/null +++ b/.idea/libraries/Maven__commons_codec_commons_codec_1_15.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__commons_io_commons_io_2_11_0.xml b/.idea/libraries/Maven__commons_io_commons_io_2_11_0.xml new file mode 100644 index 0000000..f94fc5a --- /dev/null +++ b/.idea/libraries/Maven__commons_io_commons_io_2_11_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__commons_logging_commons_logging_1_2.xml b/.idea/libraries/Maven__commons_logging_commons_logging_1_2.xml new file mode 100644 index 0000000..eab40b3 --- /dev/null +++ b/.idea/libraries/Maven__commons_logging_commons_logging_1_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__io_github_openfeign_feign_core_10_12.xml b/.idea/libraries/Maven__io_github_openfeign_feign_core_10_12.xml new file mode 100644 index 0000000..e06dfc9 --- /dev/null +++ b/.idea/libraries/Maven__io_github_openfeign_feign_core_10_12.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__jakarta_annotation_jakarta_annotation_api_1_3_5.xml b/.idea/libraries/Maven__jakarta_annotation_jakarta_annotation_api_1_3_5.xml new file mode 100644 index 0000000..cba9dd2 --- /dev/null +++ b/.idea/libraries/Maven__jakarta_annotation_jakarta_annotation_api_1_3_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__javax_activation_javax_activation_api_1_2_0.xml b/.idea/libraries/Maven__javax_activation_javax_activation_api_1_2_0.xml new file mode 100644 index 0000000..ff49512 --- /dev/null +++ b/.idea/libraries/Maven__javax_activation_javax_activation_api_1_2_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__javax_annotation_javax_annotation_api_1_3_2.xml b/.idea/libraries/Maven__javax_annotation_javax_annotation_api_1_3_2.xml new file mode 100644 index 0000000..e74f3ab --- /dev/null +++ b/.idea/libraries/Maven__javax_annotation_javax_annotation_api_1_3_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__javax_persistence_javax_persistence_api_2_2.xml b/.idea/libraries/Maven__javax_persistence_javax_persistence_api_2_2.xml new file mode 100644 index 0000000..b7d39c6 --- /dev/null +++ b/.idea/libraries/Maven__javax_persistence_javax_persistence_api_2_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__javax_servlet_javax_servlet_api_3_1_0.xml b/.idea/libraries/Maven__javax_servlet_javax_servlet_api_3_1_0.xml new file mode 100644 index 0000000..c24f7e3 --- /dev/null +++ b/.idea/libraries/Maven__javax_servlet_javax_servlet_api_3_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__javax_servlet_javax_servlet_api_4_0_1.xml b/.idea/libraries/Maven__javax_servlet_javax_servlet_api_4_0_1.xml new file mode 100644 index 0000000..d05c196 --- /dev/null +++ b/.idea/libraries/Maven__javax_servlet_javax_servlet_api_4_0_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__javax_transaction_javax_transaction_api_1_3.xml b/.idea/libraries/Maven__javax_transaction_javax_transaction_api_1_3.xml new file mode 100644 index 0000000..8f5f3c6 --- /dev/null +++ b/.idea/libraries/Maven__javax_transaction_javax_transaction_api_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__javax_validation_validation_api_2_0_1_Final.xml b/.idea/libraries/Maven__javax_validation_validation_api_2_0_1_Final.xml new file mode 100644 index 0000000..6978c0b --- /dev/null +++ b/.idea/libraries/Maven__javax_validation_validation_api_2_0_1_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__javax_xml_bind_jaxb_api_2_3_1.xml b/.idea/libraries/Maven__javax_xml_bind_jaxb_api_2_3_1.xml new file mode 100644 index 0000000..059f88f --- /dev/null +++ b/.idea/libraries/Maven__javax_xml_bind_jaxb_api_2_3_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__junit_junit_4_11.xml b/.idea/libraries/Maven__junit_junit_4_11.xml new file mode 100644 index 0000000..f33320d --- /dev/null +++ b/.idea/libraries/Maven__junit_junit_4_11.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__junit_junit_4_12.xml b/.idea/libraries/Maven__junit_junit_4_12.xml new file mode 100644 index 0000000..d411041 --- /dev/null +++ b/.idea/libraries/Maven__junit_junit_4_12.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__junit_junit_4_13_2.xml b/.idea/libraries/Maven__junit_junit_4_13_2.xml new file mode 100644 index 0000000..606c352 --- /dev/null +++ b/.idea/libraries/Maven__junit_junit_4_13_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_9_3.xml b/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_9_3.xml new file mode 100644 index 0000000..183a430 --- /dev/null +++ b/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_9_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_9_5.xml b/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_9_5.xml new file mode 100644 index 0000000..51e5879 --- /dev/null +++ b/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_9_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_9_3.xml b/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_9_3.xml new file mode 100644 index 0000000..be4d19f --- /dev/null +++ b/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_9_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__net_minidev_accessors_smart_1_2.xml b/.idea/libraries/Maven__net_minidev_accessors_smart_1_2.xml new file mode 100644 index 0000000..b3d3858 --- /dev/null +++ b/.idea/libraries/Maven__net_minidev_accessors_smart_1_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__net_minidev_json_smart_2_3.xml b/.idea/libraries/Maven__net_minidev_json_smart_2_3.xml new file mode 100644 index 0000000..1083023 --- /dev/null +++ b/.idea/libraries/Maven__net_minidev_json_smart_2_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_axis_axis_1_4.xml b/.idea/libraries/Maven__org_apache_axis_axis_1_4.xml new file mode 100644 index 0000000..7698bdf --- /dev/null +++ b/.idea/libraries/Maven__org_apache_axis_axis_1_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_9.xml b/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_9.xml new file mode 100644 index 0000000..9050e00 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_directory_studio_org_apache_commons_codec_1_8.xml b/.idea/libraries/Maven__org_apache_directory_studio_org_apache_commons_codec_1_8.xml new file mode 100644 index 0000000..8cefdad --- /dev/null +++ b/.idea/libraries/Maven__org_apache_directory_studio_org_apache_commons_codec_1_8.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_11_2.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_11_2.xml new file mode 100644 index 0000000..fe93f54 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_11_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_16_0.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_16_0.xml new file mode 100644 index 0000000..d66bfac --- /dev/null +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_16_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_17_1.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_17_1.xml new file mode 100644 index 0000000..a54efd2 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_17_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_18_0.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_18_0.xml new file mode 100644 index 0000000..1d9652e --- /dev/null +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_18_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_core_2_16_0.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_core_2_16_0.xml new file mode 100644 index 0000000..2769f7e --- /dev/null +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_core_2_16_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_core_2_18_0.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_core_2_18_0.xml new file mode 100644 index 0000000..ef63c72 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_core_2_18_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_slf4j_impl_2_18_0.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_slf4j_impl_2_18_0.xml new file mode 100644 index 0000000..f55d8c5 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_slf4j_impl_2_18_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_11_2.xml b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_11_2.xml new file mode 100644 index 0000000..889bf4f --- /dev/null +++ b/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_11_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_maven_surefire_common_java5_2_19_1.xml b/.idea/libraries/Maven__org_apache_maven_surefire_common_java5_2_19_1.xml new file mode 100644 index 0000000..1319e01 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_maven_surefire_common_java5_2_19_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_maven_surefire_surefire_api_2_19_1.xml b/.idea/libraries/Maven__org_apache_maven_surefire_surefire_api_2_19_1.xml new file mode 100644 index 0000000..bb28dad --- /dev/null +++ b/.idea/libraries/Maven__org_apache_maven_surefire_surefire_api_2_19_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_21.xml b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_21.xml new file mode 100644 index 0000000..6d34a48 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_21.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_52.xml b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_52.xml new file mode 100644 index 0000000..241b61d --- /dev/null +++ b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_52.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_21.xml b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_21.xml new file mode 100644 index 0000000..4c5cd6a --- /dev/null +++ b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_21.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_52.xml b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_52.xml new file mode 100644 index 0000000..5fdce7c --- /dev/null +++ b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_52.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_21.xml b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_21.xml new file mode 100644 index 0000000..56e82d3 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_21.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_52.xml b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_52.xml new file mode 100644 index 0000000..74e5155 --- /dev/null +++ b/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_52.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_0_0.xml b/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_0_0.xml new file mode 100644 index 0000000..a82457d --- /dev/null +++ b/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_0_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_0.xml b/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_0.xml new file mode 100644 index 0000000..f854ab0 --- /dev/null +++ b/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_2.xml b/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_2.xml new file mode 100644 index 0000000..6ac1c42 --- /dev/null +++ b/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_aspectj_aspectjweaver_1_9_4.xml b/.idea/libraries/Maven__org_aspectj_aspectjweaver_1_9_4.xml new file mode 100644 index 0000000..d51ce49 --- /dev/null +++ b/.idea/libraries/Maven__org_aspectj_aspectjweaver_1_9_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_aspectj_aspectjweaver_1_9_7.xml b/.idea/libraries/Maven__org_aspectj_aspectjweaver_1_9_7.xml new file mode 100644 index 0000000..bbaf9a7 --- /dev/null +++ b/.idea/libraries/Maven__org_aspectj_aspectjweaver_1_9_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_assertj_assertj_core_3_11_1.xml b/.idea/libraries/Maven__org_assertj_assertj_core_3_11_1.xml new file mode 100644 index 0000000..4d16d46 --- /dev/null +++ b/.idea/libraries/Maven__org_assertj_assertj_core_3_11_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_checkerframework_checker_qual_3_12_0.xml b/.idea/libraries/Maven__org_checkerframework_checker_qual_3_12_0.xml new file mode 100644 index 0000000..1b2a35b --- /dev/null +++ b/.idea/libraries/Maven__org_checkerframework_checker_qual_3_12_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_dom4j_dom4j_2_1_1.xml b/.idea/libraries/Maven__org_dom4j_dom4j_2_1_1.xml new file mode 100644 index 0000000..6c8b371 --- /dev/null +++ b/.idea/libraries/Maven__org_dom4j_dom4j_2_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml new file mode 100644 index 0000000..f58bbc1 --- /dev/null +++ b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_library_1_3.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_library_1_3.xml new file mode 100644 index 0000000..78dbe45 --- /dev/null +++ b/.idea/libraries/Maven__org_hamcrest_hamcrest_library_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hibernate_common_hibernate_commons_annotations_5_0_4_Final.xml b/.idea/libraries/Maven__org_hibernate_common_hibernate_commons_annotations_5_0_4_Final.xml new file mode 100644 index 0000000..c4d0340 --- /dev/null +++ b/.idea/libraries/Maven__org_hibernate_common_hibernate_commons_annotations_5_0_4_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hibernate_hibernate_core_5_3_10_Final.xml b/.idea/libraries/Maven__org_hibernate_hibernate_core_5_3_10_Final.xml new file mode 100644 index 0000000..d826969 --- /dev/null +++ b/.idea/libraries/Maven__org_hibernate_hibernate_core_5_3_10_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_0_17_Final.xml b/.idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_0_17_Final.xml new file mode 100644 index 0000000..4025781 --- /dev/null +++ b/.idea/libraries/Maven__org_hibernate_validator_hibernate_validator_6_0_17_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_javassist_javassist_3_23_2_GA.xml b/.idea/libraries/Maven__org_javassist_javassist_3_23_2_GA.xml new file mode 100644 index 0000000..e4babf5 --- /dev/null +++ b/.idea/libraries/Maven__org_javassist_javassist_3_23_2_GA.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jboss_jandex_2_0_5_Final.xml b/.idea/libraries/Maven__org_jboss_jandex_2_0_5_Final.xml new file mode 100644 index 0000000..34e9ada --- /dev/null +++ b/.idea/libraries/Maven__org_jboss_jandex_2_0_5_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_3_2_Final.xml b/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_3_2_Final.xml new file mode 100644 index 0000000..5f7dd01 --- /dev/null +++ b/.idea/libraries/Maven__org_jboss_logging_jboss_logging_3_3_2_Final.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jdom_jdom_1_1.xml b/.idea/libraries/Maven__org_jdom_jdom_1_1.xml new file mode 100644 index 0000000..a6eefaf --- /dev/null +++ b/.idea/libraries/Maven__org_jdom_jdom_1_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jetbrains_annotations_13_0.xml b/.idea/libraries/Maven__org_jetbrains_annotations_13_0.xml new file mode 100644 index 0000000..e2c8297 --- /dev/null +++ b/.idea/libraries/Maven__org_jetbrains_annotations_13_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jetbrains_annotations_19_0_0.xml b/.idea/libraries/Maven__org_jetbrains_annotations_19_0_0.xml new file mode 100644 index 0000000..53f3d57 --- /dev/null +++ b/.idea/libraries/Maven__org_jetbrains_annotations_19_0_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jetbrains_annotations_22_0_0.xml b/.idea/libraries/Maven__org_jetbrains_annotations_22_0_0.xml new file mode 100644 index 0000000..f350de5 --- /dev/null +++ b/.idea/libraries/Maven__org_jetbrains_annotations_22_0_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jetbrains_annotations_23_0_0.xml b/.idea/libraries/Maven__org_jetbrains_annotations_23_0_0.xml new file mode 100644 index 0000000..b271e07 --- /dev/null +++ b/.idea/libraries/Maven__org_jetbrains_annotations_23_0_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_1_4_10.xml b/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_1_4_10.xml new file mode 100644 index 0000000..433f1d0 --- /dev/null +++ b/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_1_4_10.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_common_1_4_10.xml b/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_common_1_4_10.xml new file mode 100644 index 0000000..623e501 --- /dev/null +++ b/.idea/libraries/Maven__org_jetbrains_kotlin_kotlin_stdlib_common_1_4_10.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_7_2.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_7_2.xml new file mode 100644 index 0000000..a9a0266 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_9_0.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_9_0.xml new file mode 100644 index 0000000..07e0c34 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_7_2.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_7_2.xml new file mode 100644 index 0000000..2b9b506 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_8_2.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_8_2.xml new file mode 100644 index 0000000..8e50783 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_8_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_9_0.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_9_0.xml new file mode 100644 index 0000000..0796c40 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_7_2.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_7_2.xml new file mode 100644 index 0000000..636171a --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_9_0.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_9_0.xml new file mode 100644 index 0000000..0bca97c --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_7_2.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_7_2.xml new file mode 100644 index 0000000..380c9dd --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_9_0.xml b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_9_0.xml new file mode 100644 index 0000000..8c49f47 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_7_2.xml b/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_7_2.xml new file mode 100644 index 0000000..66260e6 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_8_2.xml b/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_8_2.xml new file mode 100644 index 0000000..181d095 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_8_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_9_0.xml b/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_9_0.xml new file mode 100644 index 0000000..86cd9a1 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_7_2.xml b/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_7_2.xml new file mode 100644 index 0000000..af6fc85 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_9_0.xml b/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_9_0.xml new file mode 100644 index 0000000..f0ef25d --- /dev/null +++ b/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_platform_junit_platform_launcher_1_7_2.xml b/.idea/libraries/Maven__org_junit_platform_junit_platform_launcher_1_7_2.xml new file mode 100644 index 0000000..adc2aac --- /dev/null +++ b/.idea/libraries/Maven__org_junit_platform_junit_platform_launcher_1_7_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_platform_junit_platform_launcher_1_9_0.xml b/.idea/libraries/Maven__org_junit_platform_junit_platform_launcher_1_9_0.xml new file mode 100644 index 0000000..fb5a0dc --- /dev/null +++ b/.idea/libraries/Maven__org_junit_platform_junit_platform_launcher_1_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_junit_platform_junit_platform_surefire_provider_1_1_0.xml b/.idea/libraries/Maven__org_junit_platform_junit_platform_surefire_provider_1_1_0.xml new file mode 100644 index 0000000..37cb0c2 --- /dev/null +++ b/.idea/libraries/Maven__org_junit_platform_junit_platform_surefire_provider_1_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_mockito_mockito_core_2_23_4.xml b/.idea/libraries/Maven__org_mockito_mockito_core_2_23_4.xml new file mode 100644 index 0000000..159204f --- /dev/null +++ b/.idea/libraries/Maven__org_mockito_mockito_core_2_23_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_objenesis_objenesis_2_6.xml b/.idea/libraries/Maven__org_objenesis_objenesis_2_6.xml new file mode 100644 index 0000000..af41e3b --- /dev/null +++ b/.idea/libraries/Maven__org_objenesis_objenesis_2_6.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml b/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml new file mode 100644 index 0000000..fbc1b16 --- /dev/null +++ b/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_ow2_asm_asm_5_0_4.xml b/.idea/libraries/Maven__org_ow2_asm_asm_5_0_4.xml new file mode 100644 index 0000000..0bf8cf2 --- /dev/null +++ b/.idea/libraries/Maven__org_ow2_asm_asm_5_0_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_projectlombok_lombok_1_18_8.xml b/.idea/libraries/Maven__org_projectlombok_lombok_1_18_8.xml new file mode 100644 index 0000000..9843fa4 --- /dev/null +++ b/.idea/libraries/Maven__org_projectlombok_lombok_1_18_8.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_skyscreamer_jsonassert_1_5_0.xml b/.idea/libraries/Maven__org_skyscreamer_jsonassert_1_5_0.xml new file mode 100644 index 0000000..c4c54d6 --- /dev/null +++ b/.idea/libraries/Maven__org_skyscreamer_jsonassert_1_5_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_26.xml b/.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_26.xml new file mode 100644 index 0000000..087b2a4 --- /dev/null +++ b/.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_26.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml new file mode 100644 index 0000000..20e8163 --- /dev/null +++ b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_25.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_26.xml b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_26.xml new file mode 100644 index 0000000..6545f77 --- /dev/null +++ b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_26.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_32.xml b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_32.xml new file mode 100644 index 0000000..e5a84fb --- /dev/null +++ b/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_32.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_slf4j_slf4j_api_2_0_0_alpha5.xml b/.idea/libraries/Maven__org_slf4j_slf4j_api_2_0_0_alpha5.xml new file mode 100644 index 0000000..ba4cb59 --- /dev/null +++ b/.idea/libraries/Maven__org_slf4j_slf4j_api_2_0_0_alpha5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_1_6_RELEASE.xml new file mode 100644 index 0000000..eee62a1 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_5_14.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_5_14.xml new file mode 100644 index 0000000..a528208 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_5_14.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_5_4.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_5_4.xml new file mode 100644 index 0000000..0a1945a --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_5_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_1_6_RELEASE.xml new file mode 100644 index 0000000..1b9e622 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_1_6_RELEASE.xml new file mode 100644 index 0000000..b51ea53 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_1_6_RELEASE.xml new file mode 100644 index 0000000..d523331 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_5_7.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_5_7.xml new file mode 100644 index 0000000..aca477a --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_aop_2_5_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_jpa_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_jpa_2_1_6_RELEASE.xml new file mode 100644 index 0000000..7c022e5 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_data_jpa_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_1_6_RELEASE.xml new file mode 100644 index 0000000..9913c94 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_jdbc_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_1_6_RELEASE.xml new file mode 100644 index 0000000..6a6e890 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_5_4.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_5_4.xml new file mode 100644 index 0000000..8014349 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_5_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_1_6_RELEASE.xml new file mode 100644 index 0000000..cda4eae --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_1_6_RELEASE.xml new file mode 100644 index 0000000..4f8a376 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_1_6_RELEASE.xml new file mode 100644 index 0000000..0799814 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_5_4.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_5_4.xml new file mode 100644 index 0000000..503acb7 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_5_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_1_6_RELEASE.xml new file mode 100644 index 0000000..1407ba5 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_5_4.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_5_4.xml new file mode 100644 index 0000000..230bb3c --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_5_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_1_6_RELEASE.xml new file mode 100644 index 0000000..283b404 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_5_14.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_5_14.xml new file mode 100644 index 0000000..c45122a --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_5_14.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_5_4.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_5_4.xml new file mode 100644 index 0000000..10114d4 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_5_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_1_6_RELEASE.xml b/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_1_6_RELEASE.xml new file mode 100644 index 0000000..9c97188 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_1_6_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_1_9_RELEASE.xml b/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_1_9_RELEASE.xml new file mode 100644 index 0000000..d4981b5 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_1_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_5_12.xml b/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_5_12.xml new file mode 100644 index 0000000..5186158 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_5_12.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_5_4.xml b/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_5_4.xml new file mode 100644 index 0000000..3c13af1 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_5_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_6_4.xml b/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_6_4.xml new file mode 100644 index 0000000..f6425b7 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_data_spring_data_commons_2_6_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_data_spring_data_jpa_2_1_9_RELEASE.xml b/.idea/libraries/Maven__org_springframework_data_spring_data_jpa_2_1_9_RELEASE.xml new file mode 100644 index 0000000..adedbf1 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_data_spring_data_jpa_2_1_9_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_aop_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_aop_5_1_8_RELEASE.xml new file mode 100644 index 0000000..c1a6cbf --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_aop_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_aop_5_3_13.xml b/.idea/libraries/Maven__org_springframework_spring_aop_5_3_13.xml new file mode 100644 index 0000000..a1d3f7e --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_aop_5_3_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_aop_5_3_9.xml b/.idea/libraries/Maven__org_springframework_spring_aop_5_3_9.xml new file mode 100644 index 0000000..06b191b --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_aop_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_aspects_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_aspects_5_1_8_RELEASE.xml new file mode 100644 index 0000000..419046e --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_aspects_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_beans_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_beans_5_1_8_RELEASE.xml new file mode 100644 index 0000000..d17293b --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_beans_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_beans_5_3_13.xml b/.idea/libraries/Maven__org_springframework_spring_beans_5_3_13.xml new file mode 100644 index 0000000..95086d7 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_beans_5_3_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_beans_5_3_22.xml b/.idea/libraries/Maven__org_springframework_spring_beans_5_3_22.xml new file mode 100644 index 0000000..bf03b58 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_beans_5_3_22.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_beans_5_3_9.xml b/.idea/libraries/Maven__org_springframework_spring_beans_5_3_9.xml new file mode 100644 index 0000000..c5bd2d3 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_beans_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_context_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_context_5_1_8_RELEASE.xml new file mode 100644 index 0000000..c68626e --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_context_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_context_5_3_13.xml b/.idea/libraries/Maven__org_springframework_spring_context_5_3_13.xml new file mode 100644 index 0000000..049f273 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_context_5_3_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_context_5_3_9.xml b/.idea/libraries/Maven__org_springframework_spring_context_5_3_9.xml new file mode 100644 index 0000000..4c2900a --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_context_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_core_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_core_5_1_8_RELEASE.xml new file mode 100644 index 0000000..8580e90 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_core_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_core_5_3_13.xml b/.idea/libraries/Maven__org_springframework_spring_core_5_3_13.xml new file mode 100644 index 0000000..86128a8 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_core_5_3_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_core_5_3_19.xml b/.idea/libraries/Maven__org_springframework_spring_core_5_3_19.xml new file mode 100644 index 0000000..3ca3639 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_core_5_3_19.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_core_5_3_22.xml b/.idea/libraries/Maven__org_springframework_spring_core_5_3_22.xml new file mode 100644 index 0000000..c97165c --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_core_5_3_22.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_core_5_3_9.xml b/.idea/libraries/Maven__org_springframework_spring_core_5_3_9.xml new file mode 100644 index 0000000..2529cbf --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_core_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_expression_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_expression_5_1_8_RELEASE.xml new file mode 100644 index 0000000..aae055d --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_expression_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_expression_5_3_13.xml b/.idea/libraries/Maven__org_springframework_spring_expression_5_3_13.xml new file mode 100644 index 0000000..99ae0af --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_expression_5_3_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_expression_5_3_9.xml b/.idea/libraries/Maven__org_springframework_spring_expression_5_3_9.xml new file mode 100644 index 0000000..dea9689 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_expression_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_jcl_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_jcl_5_1_8_RELEASE.xml new file mode 100644 index 0000000..1a99c90 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_jcl_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_13.xml b/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_13.xml new file mode 100644 index 0000000..dea8de9 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_13.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_19.xml b/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_19.xml new file mode 100644 index 0000000..d74ebf9 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_19.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_22.xml b/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_22.xml new file mode 100644 index 0000000..4a0ea86 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_22.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_9.xml b/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_9.xml new file mode 100644 index 0000000..feea851 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_jdbc_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_jdbc_5_1_8_RELEASE.xml new file mode 100644 index 0000000..5647436 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_jdbc_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_orm_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_orm_5_1_8_RELEASE.xml new file mode 100644 index 0000000..ed33859 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_orm_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_test_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_test_5_1_8_RELEASE.xml new file mode 100644 index 0000000..684e11b --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_test_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_test_5_3_22.xml b/.idea/libraries/Maven__org_springframework_spring_test_5_3_22.xml new file mode 100644 index 0000000..f37c501 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_test_5_3_22.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_test_5_3_9.xml b/.idea/libraries/Maven__org_springframework_spring_test_5_3_9.xml new file mode 100644 index 0000000..b90da2f --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_test_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_tx_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_tx_5_1_8_RELEASE.xml new file mode 100644 index 0000000..a1addd7 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_tx_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_web_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_web_5_1_8_RELEASE.xml new file mode 100644 index 0000000..1cbea8a --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_web_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_web_5_3_22.xml b/.idea/libraries/Maven__org_springframework_spring_web_5_3_22.xml new file mode 100644 index 0000000..759cb36 --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_web_5_3_22.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_web_5_3_9.xml b/.idea/libraries/Maven__org_springframework_spring_web_5_3_9.xml new file mode 100644 index 0000000..eeb831a --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_web_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_webmvc_5_1_8_RELEASE.xml b/.idea/libraries/Maven__org_springframework_spring_webmvc_5_1_8_RELEASE.xml new file mode 100644 index 0000000..8baea9b --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_webmvc_5_1_8_RELEASE.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_springframework_spring_webmvc_5_3_9.xml b/.idea/libraries/Maven__org_springframework_spring_webmvc_5_3_9.xml new file mode 100644 index 0000000..b4ee97b --- /dev/null +++ b/.idea/libraries/Maven__org_springframework_spring_webmvc_5_3_9.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_6_2.xml b/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_6_2.xml new file mode 100644 index 0000000..9f44657 --- /dev/null +++ b/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_6_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/Maven__org_yaml_snakeyaml_1_23.xml b/.idea/libraries/Maven__org_yaml_snakeyaml_1_23.xml new file mode 100644 index 0000000..7e63769 --- /dev/null +++ b/.idea/libraries/Maven__org_yaml_snakeyaml_1_23.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..70e18e8 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..d4a107b --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..797acea --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/utils.iml b/.idea/utils.iml new file mode 100644 index 0000000..7a796ae --- /dev/null +++ b/.idea/utils.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index cbb253a..b10e569 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,24 @@ # utils +工具集合 -utils \ No newline at end of file +# jpa +jpa工具 + +#myJs +js 常用函数 +js 常用功能封装 + +# okhttp3util +对okhttp3进行轻量级封装 + +# spring-util +spring工具类 引入后自动将自己注入到程序中 + +#test +测试工具 + +# util +个人编程过程中经常用的工具集合 + +# web +web编程工具 \ No newline at end of file diff --git a/cloud-util/cloud-util.iml b/cloud-util/cloud-util.iml new file mode 100644 index 0000000..af08d41 --- /dev/null +++ b/cloud-util/cloud-util.iml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cloud-util/pom.xml b/cloud-util/pom.xml new file mode 100644 index 0000000..1e34526 --- /dev/null +++ b/cloud-util/pom.xml @@ -0,0 +1,129 @@ + + + + 4.0.0 + + com.liuhuiyu + cloud-util + 2022.1.0 + cloud-util + cloud utils + http://www.liuhuiyu.com + + + UTF-8 + 1.8 + 1.8 + 2022.1.0 + 2.6.4 + 2.13.4.1 + 10.12 + 5.7.2 + + + + + io.github.openfeign + feign-core + ${feign-core.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson-databind.version} + + + org.springframework.data + spring-data-commons + ${spring-data-commons.version} + + + org.springframework + spring-beans + + + + + com.liuhuiyu + util + ${liuhuiyu.util.version} + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.data + spring-data-commons + + + + + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + test + + + org.junit.platform + junit-platform-launcher + 1.9.0 + test + + + com.liuhuiyu + test2 + 2022.1.0 + test + + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + diff --git a/cloud-util/src/main/java/com/liuhuiyu/cloud/feign/decoder/ResultFeignDecoder.java b/cloud-util/src/main/java/com/liuhuiyu/cloud/feign/decoder/ResultFeignDecoder.java new file mode 100644 index 0000000..040b545 --- /dev/null +++ b/cloud-util/src/main/java/com/liuhuiyu/cloud/feign/decoder/ResultFeignDecoder.java @@ -0,0 +1,105 @@ +package com.liuhuiyu.cloud.feign.decoder; + + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.google.gson.Gson; +import com.liuhuiyu.util.exception.LhyException; +import com.liuhuiyu.util.map.MapUtil; +import com.liuhuiyu.util.model.Result; +import feign.FeignException; +import feign.Response; +import feign.Util; +import feign.codec.DecodeException; +import feign.codec.Decoder; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-09-17 15:11 + */ +public class ResultFeignDecoder implements Decoder { + public static final String RESULT_DATA_FIELD_NAME = "data"; + public static final String PAGE_IMPL_CLASS_NAME = "org.springframework.data.domain.PageImpl"; + public static final String PAGE_IMPL_CONTENT_FIELD_NAME = "content"; + public static final String PAGE_IMPL_NUMBER_FIELD_NAME = "number"; + public static final String PAGE_IMPL_SIZE_FIELD_NAME = "size"; + public static final String PAGE_IMPL_TOTAL_ELEMENTS_FIELD_NAME = "totalElements"; + + @Override + public Object decode(Response response, Type type) throws IOException, FeignException { + + if (response.body() == null) { + throw new DecodeException(response.status(), "没有返回有效的数据", response.request()); + } + + final InputStreamReader reader = (InputStreamReader) response.body().asReader(Util.UTF_8); + String bodyStr = Util.toString(reader); + //对结果进行转换 + final Map map = MapUtil.mapOfJsonString(bodyStr); + Result result = Result.getResult(map); + //如果返回错误,且为内部错误,则直接抛出异常 + if (result.isSuccess()) { + // 获取接口接收类型 + JavaType javaType = TypeFactory.defaultInstance().constructType(type); + // 判断是否分页对象 + if (type.getTypeName().contains(PAGE_IMPL_CLASS_NAME)) { + // 获取分页泛型类型 + JavaType boundType = javaType.getBindings().getBoundType(0); + // 获取数据 + Object data = map.get(RESULT_DATA_FIELD_NAME); + // 结果集转Map + Map dataMap = MapUtil.mapObjectToStringKeyMap(data); + // 获取数据结果集 + List content = new ArrayList<>(); + if (dataMap.get(PAGE_IMPL_CONTENT_FIELD_NAME) instanceof Collection) { + Collection list = (Collection) dataMap.get(PAGE_IMPL_CONTENT_FIELD_NAME); + content.addAll(list); + } + else { + throw new LhyException("无法解析非List数据"); + } + // 数据转换 + List collect = content.stream().map(v -> { + try { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + String json = new Gson().toJson(v); + return objectMapper.readValue(json, boundType); + } + catch (JsonProcessingException e) { + throw new LhyException("无法解析List数据转换"); + } + }).collect(Collectors.toList()); + // 封装PageImpl + MapUtil mapUtil = new MapUtil(MapUtil.mapObjectToStringKeyMap(result.getData())); + int number = mapUtil.getIntegerValue(PAGE_IMPL_NUMBER_FIELD_NAME, 0); + int size = mapUtil.getIntegerValue(PAGE_IMPL_SIZE_FIELD_NAME, 0); + PageRequest pageable = PageRequest.of(number, size); + long totalElements = mapUtil.getLongValue(PAGE_IMPL_TOTAL_ELEMENTS_FIELD_NAME, 0L); + return new PageImpl<>(collect, pageable, totalElements); + } + // 其他类型转换 + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + return mapper.readValue(new Gson().toJson(result.getData()), javaType); + } + else { + throw new LhyException(result.getMsg()); + } + } +} diff --git a/cloud-util/src/main/java/com/liuhuiyu/cloud/feign/package-info.java b/cloud-util/src/main/java/com/liuhuiyu/cloud/feign/package-info.java new file mode 100644 index 0000000..6335646 --- /dev/null +++ b/cloud-util/src/main/java/com/liuhuiyu/cloud/feign/package-info.java @@ -0,0 +1,6 @@ +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-09-17 11:07 + */ +package com.liuhuiyu.cloud.feign; \ No newline at end of file diff --git a/cloud-util/src/main/java/com/liuhuiyu/cloud/package-info.java b/cloud-util/src/main/java/com/liuhuiyu/cloud/package-info.java new file mode 100644 index 0000000..fe9fbcd --- /dev/null +++ b/cloud-util/src/main/java/com/liuhuiyu/cloud/package-info.java @@ -0,0 +1,6 @@ +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-09-17 11:06 + */ +package com.liuhuiyu.cloud; \ No newline at end of file diff --git a/cloud-util/src/test/java/com/liuhuiyu/cloud/feign/decoder/ResultFeignDecoderTest.java b/cloud-util/src/test/java/com/liuhuiyu/cloud/feign/decoder/ResultFeignDecoderTest.java new file mode 100644 index 0000000..fdebadc --- /dev/null +++ b/cloud-util/src/test/java/com/liuhuiyu/cloud/feign/decoder/ResultFeignDecoderTest.java @@ -0,0 +1,19 @@ +package com.liuhuiyu.cloud.feign.decoder; + + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-11-16 19:49 + */ +class ResultFeignDecoderTest extends TestBase { + @Test + public void t1() { + ResultFeignDecoder resultFeignDecoder = new ResultFeignDecoder(); + final String name = resultFeignDecoder.getClass().getName(); + LOG.info("{}", name); + } +} \ No newline at end of file diff --git a/dto/dto.iml b/dto/dto.iml new file mode 100644 index 0000000..9f829c5 --- /dev/null +++ b/dto/dto.iml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dto/pom.xml b/dto/pom.xml new file mode 100644 index 0000000..a159dc5 --- /dev/null +++ b/dto/pom.xml @@ -0,0 +1,77 @@ + + + 4.0.0 + + com.liuhuiyu + dto + 2021.1.0 + + 2.6.4 + 8 + 8 + + + + + org.springframework.data + spring-data-commons + ${springdata.commons} + compile + + + org.springframework + spring-beans + + + + + com.google.code.gson + gson + 2.8.6 + + + com.liuhuiyu + test2 + 2022.1.0 + test + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + -Xdoclint:none + + + + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + \ No newline at end of file diff --git a/dto/src/main/java/com/liuhuiyu/dto/FromPrototype.java b/dto/src/main/java/com/liuhuiyu/dto/FromPrototype.java new file mode 100644 index 0000000..96a8d66 --- /dev/null +++ b/dto/src/main/java/com/liuhuiyu/dto/FromPrototype.java @@ -0,0 +1,43 @@ +package com.liuhuiyu.dto; + +import com.google.gson.Gson; + +/** + * 从原型创建(可以作为 深层Clone使用) + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-28 10:08 + */ +public interface FromPrototype { + /** + * 将当前信息转换为指定类型的信息(相同属性数据深层复制) + * + * @param classOfT 转换后类 + * @param 转换后的类型 + * @return T + * @author LiuHuiYu + * Created DateTime 2022-05-28 14:48 + */ + T fromPrototype(Class classOfT); + + /** + * 将当前信息转换为指定类型的信息(相同属性数据深层复制) + * + * @param classOfT 转换后的类 + * @param fromPrototype 可转换为json字符串的类型 + * @param 类 + * @return T 相同属性转换后新类 + * @author LiuHuiYu + * Created DateTime 2022-05-28 14:50 + */ + static T fromPrototype(Class classOfT, ISerializationJson fromPrototype) { + if (classOfT == null) { + throw new RuntimeException("类型不能为null"); + } + if (fromPrototype == null) { + throw new RuntimeException("要转换的数据不能为null"); + } + return new Gson().fromJson(fromPrototype.toJson(), classOfT); + } +} diff --git a/dto/src/main/java/com/liuhuiyu/dto/IDataChange.java b/dto/src/main/java/com/liuhuiyu/dto/IDataChange.java new file mode 100644 index 0000000..037a557 --- /dev/null +++ b/dto/src/main/java/com/liuhuiyu/dto/IDataChange.java @@ -0,0 +1,37 @@ +package com.liuhuiyu.dto; + +/** + * 数据更新接口 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-06-20 22:03 + */ +public interface IDataChange extends IOperating{ + + /** + * 是否是添加信息 + * + * @return boolean + * @author LiuHuiYu + * Created DateTime 2022-05-10 16:22 + */ + boolean isAdd(); + + /** + * 是否是修改信息 + * + * @return boolean + * @author LiuHuiYu + * Created DateTime 2022-05-10 16:22 + */ + boolean isUpdate(); + + /** + * 是否是删除信息 + * + * @return boolean + * @author LiuHuiYu + * Created DateTime 2022-05-10 16:22 + */ + boolean isDelete(); +} diff --git a/dto/src/main/java/com/liuhuiyu/dto/IFind.java b/dto/src/main/java/com/liuhuiyu/dto/IFind.java new file mode 100644 index 0000000..6638581 --- /dev/null +++ b/dto/src/main/java/com/liuhuiyu/dto/IFind.java @@ -0,0 +1,12 @@ +package com.liuhuiyu.dto; + +/** + * 查询接口 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-06-10 15:37 + */ +public interface IFind extends IOperating, IPaging { + +} diff --git a/dto/src/main/java/com/liuhuiyu/dto/IOperating.java b/dto/src/main/java/com/liuhuiyu/dto/IOperating.java new file mode 100644 index 0000000..9e5a63f --- /dev/null +++ b/dto/src/main/java/com/liuhuiyu/dto/IOperating.java @@ -0,0 +1,27 @@ +package com.liuhuiyu.dto; + +/** + * 操作接口 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-02 7:49 + */ +public interface IOperating{ + /** + * 获取操作信息 + * + * @return java.lang.String + * @author LiuHuiYu + * Created DateTime 2022-01-20 15:29 + */ + Operating getOperating(); + + /** + * 设置操作信息 + * + * @param operating 操作信息 + * @author LiuHuiYu + * Created DateTime 2022-01-20 15:29 + */ + void setOperating(Operating operating); +} diff --git a/dto/src/main/java/com/liuhuiyu/dto/IPaging.java b/dto/src/main/java/com/liuhuiyu/dto/IPaging.java new file mode 100644 index 0000000..fcde97b --- /dev/null +++ b/dto/src/main/java/com/liuhuiyu/dto/IPaging.java @@ -0,0 +1,38 @@ +package com.liuhuiyu.dto; + +/** + * 分页接口 + *
+ *     @ApiModelProperty("分页信息")
+ *     private Paging paging = new Paging();
+ *
+ *     @Override
+ *     public Paging getPaging() {
+ *         return paging;
+ *     }
+ *
+ *     @Override
+ *     public void setPaging(Paging paging) {
+ *         this.paging = paging;
+ *     }
+ * 
+ * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-01-12 10:22 + */ +public interface IPaging { + /** + * 获取分页信息 + * @author LiuHuiYu + * Created DateTime 2022-01-20 15:29 + * @return cc.rehome.zhanjiang.data_center_model.domain.Paging + */ + Paging getPaging(); + /** + * 设置分页信息 + * @author LiuHuiYu + * Created DateTime 2022-01-20 15:29 + * @param paging 分页信息 + */ + void setPaging(Paging paging); +} diff --git a/dto/src/main/java/com/liuhuiyu/dto/ISerializationJson.java b/dto/src/main/java/com/liuhuiyu/dto/ISerializationJson.java new file mode 100644 index 0000000..76f90bf --- /dev/null +++ b/dto/src/main/java/com/liuhuiyu/dto/ISerializationJson.java @@ -0,0 +1,19 @@ +package com.liuhuiyu.dto; + +import java.io.Serializable; + +/** + * 将当前类序列化成json字符串 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-28 10:15 + */ +public interface ISerializationJson extends Serializable { + /** + * 将当前类序列化成json字符串 + * @author LiuHuiYu + * Created DateTime 2022-01-20 15:30 + * @return java.lang.String + */ + String toJson(); +} \ No newline at end of file diff --git a/dto/src/main/java/com/liuhuiyu/dto/MasterDetailDto.java b/dto/src/main/java/com/liuhuiyu/dto/MasterDetailDto.java new file mode 100644 index 0000000..df9875f --- /dev/null +++ b/dto/src/main/java/com/liuhuiyu/dto/MasterDetailDto.java @@ -0,0 +1,56 @@ +package com.liuhuiyu.dto; + + +import com.google.gson.Gson; + +import java.util.List; + +/** + * 主从结构 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-12-01 4:53 + */ +public class MasterDetailDto implements FromPrototype, ISerializationJson { + /** + * 主表 + * Created DateTime 2022-12-01 9:50 + */ + private M master; + /** + * 从表 + * Created DateTime 2022-12-01 9:50 + */ + private List detail; + + public MasterDetailDto() { + } + + public M getMaster() { + return master; + } + + public void setMaster(M master) { + this.master = master; + } + + public List getDetail() { + return detail; + } + + public void setDetail(List detail) { + this.detail = detail; + } + + @Override + public String toJson() { + Gson gson = new Gson(); + return gson.toJson(this); + } + + @Override + public T fromPrototype(Class classOfT) { + return FromPrototype.fromPrototype(classOfT, this); + } +} diff --git a/dto/src/main/java/com/liuhuiyu/dto/Operating.java b/dto/src/main/java/com/liuhuiyu/dto/Operating.java new file mode 100644 index 0000000..355a811 --- /dev/null +++ b/dto/src/main/java/com/liuhuiyu/dto/Operating.java @@ -0,0 +1,124 @@ +package com.liuhuiyu.dto; + +import org.springframework.util.ObjectUtils; + +import java.util.Locale; + +/** + * 操作 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-02 7:49 + */ +public class Operating { + public static final String NONE = ""; + /** + * 操作人id + */ + private String operatorId; + /** + * 操作模式名称(用户自定义) + */ + private String modelName; + /** + * 记录行状态 + */ + private RowStatus rowStatus; + + public Operating() { + this.operatorId = NONE; + this.modelName = NONE; + this.rowStatus = RowStatus.U; + } + + public String getModelName() { + return modelName; + } + + public void setModelName(String modelName) { + this.modelName = modelName; + } + + /** + * 判定是否是指定模式 + * + * @param modelName 模式名称 + * @return boolean + * @author LiuHuiYu + * Created DateTime 2022-06-13 8:55 + */ + public boolean isModel(String modelName) { + return ObjectUtils.nullSafeEquals(this.modelName, modelName); + } + + public String getOperatorId() { + return operatorId; + } + + public void setOperatorId(String operatorId) { + this.operatorId = operatorId; + } + + public RowStatus getRowStatus() { + return rowStatus; + } + + public void setRowStatus(RowStatus rowStatus) { + this.rowStatus = rowStatus; + } + + /** + * 记录行状态 + * + * @author LiuHuiYu + * Created DateTime 2022-05-02 7:45 + */ + public enum RowStatus { + /** + * 添加 + */ + A, + /** + * 修改 + */ + E, + /** + * 删除 + */ + D, + /** + * 未知 + */ + U; + + RowStatus() { + } + + public boolean isAdd() { + return this.equals(A); + } + + public boolean isUpdate() { + return this.equals(E); + } + + public boolean isDelete() { + return this.equals(D); + } + + public boolean isUnknown() { + return this.equals(U); + } + + public static RowStatus fromString(String value) { + try { + return valueOf(value.toUpperCase(Locale.US)); + } + catch (Exception var2) { + throw new IllegalArgumentException(String.format("Invalid value '%s' for orders given! Has to be either 'A' 'E' 'D' 'U' (case insensitive).", value), var2); + } + } + } + +} diff --git a/dto/src/main/java/com/liuhuiyu/dto/Paging.java b/dto/src/main/java/com/liuhuiyu/dto/Paging.java new file mode 100644 index 0000000..b8b0b6f --- /dev/null +++ b/dto/src/main/java/com/liuhuiyu/dto/Paging.java @@ -0,0 +1,180 @@ +package com.liuhuiyu.dto; + +import org.springframework.data.domain.PageRequest; + +import java.util.ArrayList; +import java.util.List; + +/** + * 分页查询信息 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-12-20 16:13 + */ +public class Paging { + /** + * 当前页面索引(0开始) + */ + private int pageIndex; + /** + * 页面大小(0,表示不会有列表信息) + */ + private int pageSize; + /** + * 全部数据放入一个页面不分页 + */ + private boolean allInOne; + /** + * 排序 + */ + private List sort; + /** + * 第一页索引 + * Created DateTime 2022-05-28 14:55 + */ + public static final int FIRST_PAGE_INDEX = 0; + /** + * 默认页面大小 + * Created DateTime 2022-05-28 14:55 + */ + public static final int DEFAULT_PAGE_SIZE = 20; + /** + * 页面最小值 + * Created DateTime 2022-05-28 14:55 + */ + public static final int MIN_PAGE_SIZE = 0; + + /** + * 分页信息获取 + * + * @author LiuHuiYu + * Created DateTime 2022-05-28 14:55 + */ + public Paging() { + pageIndex = FIRST_PAGE_INDEX; + pageSize = DEFAULT_PAGE_SIZE; + this.sort = new ArrayList<>(); + } + + /** + * 获取页面索引 + * + * @return int + * @author LiuHuiYu + * Created DateTime 2022-05-28 14:55 + */ + public int getPageIndex() { + return pageIndex; + } + + /** + * 设置获取第几页信息 + * + * @param pageIndex 页面(0开始) + * @author LiuHuiYu + * Created DateTime 2022-05-28 14:54 + */ + public void setPageIndex(int pageIndex) { + this.pageIndex = Math.max(pageIndex, FIRST_PAGE_INDEX); + } + + /** + * 设置页面大小 + * + * @return int + * @author LiuHuiYu + * Created DateTime 2022-05-28 14:54 + */ + public int getPageSize() { + return pageSize; + } + + /** + * 设置页面大小 + * + * @param pageSize 页面大小 + * @author LiuHuiYu + * Created DateTime 2022-05-28 14:54 + */ + public void setPageSize(int pageSize) { + this.pageSize = pageSize < MIN_PAGE_SIZE ? DEFAULT_PAGE_SIZE : pageSize; + } + + /** + * 是否获取全部数据 + * + * @return boolean + * @author LiuHuiYu + * Created DateTime 2022-05-28 14:54 + */ + public boolean isAllInOne() { + return allInOne; + } + + /** + * 设置是否获取全部数据 + * + * @param allInOne 设置是否获取全部数据 + * @author LiuHuiYu + * Created DateTime 2022-05-28 14:53 + */ + public void setAllInOne(boolean allInOne) { + this.allInOne = allInOne; + } + + /** + * Pageable 实现 bean + * + * @return org.springframework.data.domain.PageRequest + * @author LiuHuiYu + * Created DateTime 2022-02-11 11:19 + */ + public PageRequest getPageRequest() { + return PageRequest.of(this.pageIndex, this.pageSize == 0 ? 1 : this.pageSize); + } + + /** + * 获取排序规则 + * + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2022-05-28 14:53 + */ + public List getSort() { + return sort; + } + + /** + * 设置排序 + * + * @param sort 排序 + * @author LiuHuiYu + * Created DateTime 2022-05-28 14:53 + */ + public void setSort(List sort) { + this.sort = sort; + } + + /** + * 获取起始数据NO(1开始) + * + * @return java.lang.Integer + * @author LiuHuiYu + * Created DateTime 2022-04-01 16:00 + */ + public Integer beginRowNo() { + return this.pageIndex * pageSize + 1; + } + + /** + * 获取结束数据NO(包含此NO的数据) + * + * @return java.lang.Integer + * @author LiuHuiYu + * Created DateTime 2022-04-01 16:01 + */ + public Integer endRowNo() { + return beginRowNo() + pageSize - 1; + } +} \ No newline at end of file diff --git a/dto/src/main/java/com/liuhuiyu/dto/Sort.java b/dto/src/main/java/com/liuhuiyu/dto/Sort.java new file mode 100644 index 0000000..5b8e739 --- /dev/null +++ b/dto/src/main/java/com/liuhuiyu/dto/Sort.java @@ -0,0 +1,101 @@ +package com.liuhuiyu.dto; + +import java.util.Locale; + +/** + * 排序规则 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-02 7:42 + */ +public class Sort { + private int index; + private String name; + private Direction direction; + + /** + * 初始化排序 + * + * @author LiuHuiYu + * Created DateTime 2022-05-28 15:04 + */ + public Sort() { + } + + /** + * 初始化排序 + * + * @param index 索引 + * @param name 字段名称 + * @param direction 排序方向 + * @author LiuHuiYu + * Created DateTime 2022-05-28 15:05 + */ + public Sort(int index, String name, Direction direction) { + this.index = index; + this.name = name; + this.direction = direction; + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Direction getDirection() { + return direction; + } + + public void setDirection(Direction direction) { + this.direction = direction; + } + + /** + * 排序方向 + * + * @author LiuHuiYu + * Created DateTime 2022-05-02 7:45 + */ + public enum Direction { + /** + * 顺序 + */ + ASC, + /** + * 倒序 + */ + DESC; + + Direction() { + } + + public boolean isAscending() { + return this.equals(ASC); + } + + public boolean isDescending() { + return this.equals(DESC); + } + + public static Direction fromString(String value) { + try { + return valueOf(value.toUpperCase(Locale.US)); + } + catch (Exception var2) { + return ASC; + } + } + } +} diff --git a/dto/src/test/java/com/liuhuiyu/dto/MasterDetailDtoTest.java b/dto/src/test/java/com/liuhuiyu/dto/MasterDetailDtoTest.java new file mode 100644 index 0000000..2b69fe6 --- /dev/null +++ b/dto/src/test/java/com/liuhuiyu/dto/MasterDetailDtoTest.java @@ -0,0 +1,22 @@ +package com.liuhuiyu.dto; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.stream.Collectors; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-12-01 9:51 + */ +class MasterDetailDtoTest extends TestBase { + @Test + public void create() { + MasterDetailDto dto = new MasterDetailDto<>(); + dto.setMaster("A01"); + dto.setDetail(Arrays.stream(new String[]{"B01", "B02", "B03"}).collect(Collectors.toList())); + LOG.info("{}:{}", dto.getMaster(), dto.getDetail()); + } +} \ No newline at end of file diff --git a/dto/src/test/java/com/liuhuiyu/dto/OperatingTest.java b/dto/src/test/java/com/liuhuiyu/dto/OperatingTest.java new file mode 100644 index 0000000..13cf246 --- /dev/null +++ b/dto/src/test/java/com/liuhuiyu/dto/OperatingTest.java @@ -0,0 +1,14 @@ +package com.liuhuiyu.dto; + + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-02 8:06 + */ +class OperatingTest { + public void create() { + Operating operating = new Operating(); + System.out.println(operating); + } +} \ No newline at end of file diff --git a/dto/src/test/java/com/liuhuiyu/dto/PagingTest.java b/dto/src/test/java/com/liuhuiyu/dto/PagingTest.java new file mode 100644 index 0000000..b499b5c --- /dev/null +++ b/dto/src/test/java/com/liuhuiyu/dto/PagingTest.java @@ -0,0 +1,29 @@ +package com.liuhuiyu.dto; + + +import java.util.ArrayList; +import java.util.List; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-28 14:57 + */ +public class PagingTest { + public void test() { + List list = new ArrayList<>(); + list.add(new Sort(0, "id", Sort.Direction.ASC)); + Sort sort = new Sort(); + sort.setIndex(1); + sort.setName("cname"); + sort.setDirection(Sort.Direction.DESC); + list.add(sort); + Paging paging = new Paging(); + paging.setAllInOne(true); + paging.setPageIndex(0); + paging.setPageSize(10); + paging.setSort(list); + paging.getSort().forEach(sortItem -> System.out.println("" + sortItem.getIndex() + "" + sortItem.getDirection())); + System.out.println(paging.getPageIndex()); + } +} \ No newline at end of file diff --git a/guava-utils/guava-utils.iml b/guava-utils/guava-utils.iml new file mode 100644 index 0000000..620acdc --- /dev/null +++ b/guava-utils/guava-utils.iml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/guava-utils/pom.xml b/guava-utils/pom.xml new file mode 100644 index 0000000..e1c9ed3 --- /dev/null +++ b/guava-utils/pom.xml @@ -0,0 +1,87 @@ + + + + 4.0.0 + + com.liuhuiyu + guava-utils + 1.0-SNAPSHOT + + guava-utils + + http://www.example.com + + + UTF-8 + 1.7 + 1.7 + + + + + com.google.guava + guava + 31.1-jre + + + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.18.0 + + + junit + junit + 4.13.2 + test + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + diff --git a/guava-utils/src/main/java/com/demo/App.java b/guava-utils/src/main/java/com/demo/App.java new file mode 100644 index 0000000..035be6e --- /dev/null +++ b/guava-utils/src/main/java/com/demo/App.java @@ -0,0 +1,13 @@ +package com.demo; + +/** + * Hello world! + * + */ +public class App +{ + public static void main( String[] args ) + { + System.out.println( "Hello World!" ); + } +} diff --git a/guava-utils/src/test/java/com/demo/AppTest.java b/guava-utils/src/test/java/com/demo/AppTest.java new file mode 100644 index 0000000..b146c7c --- /dev/null +++ b/guava-utils/src/test/java/com/demo/AppTest.java @@ -0,0 +1,20 @@ +package com.demo; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Unit test for simple App. + */ +public class AppTest +{ + /** + * Rigorous Test :-) + */ + @Test + public void shouldAnswerWithTrue() + { + assertTrue( true ); + } +} diff --git a/guava-utils/src/test/java/com/demo/util/StringsTest.java b/guava-utils/src/test/java/com/demo/util/StringsTest.java new file mode 100644 index 0000000..461ceae --- /dev/null +++ b/guava-utils/src/test/java/com/demo/util/StringsTest.java @@ -0,0 +1,40 @@ +package com.demo.util; + +import com.google.common.base.Strings; +import org.junit.Test; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-09-06 8:07 + */ +public class StringsTest extends TestBase { +// public static Logger LOG;// = LoggerFactory.getLogger(StringsTest.class); + +// @BeforeClass +// public static void setLogger() throws MalformedURLException { +// System.setProperty("log4j.configurationFile", "log4j2.xml"); +// LOG = LoggerFactory.getLogger(StringsTest.class); +// } + + @Test + public void commonPrefix() { + String a = "aaabbbccc"; + String b = "abc"; + final String s = Strings.commonPrefix(a, b); + LOG.info("公共前缀{};{}->{}", a, b, s); + } + + @Test + public void commonSuffix() { + String a = "aaabbbccc"; + String b = "abc"; + final String s = Strings.commonSuffix(a, b); + LOG.info("公共后缀{};{}->{}", a, b, s); + } + + @Override + protected String getConfigFileName() { + return "log4j2.xml"; + } +} diff --git a/guava-utils/src/test/java/com/demo/util/TestBase.java b/guava-utils/src/test/java/com/demo/util/TestBase.java new file mode 100644 index 0000000..038c549 --- /dev/null +++ b/guava-utils/src/test/java/com/demo/util/TestBase.java @@ -0,0 +1,25 @@ +package com.demo.util; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.Before; +import org.junit.BeforeClass; +import org.slf4j.LoggerFactory; + +import java.net.MalformedURLException; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-09-06 8:38 + */ +public abstract class TestBase { + protected static Logger LOG; +// @BeforeClass + @Before + public void setLogger() throws MalformedURLException { + System.setProperty("log4j.configurationFile", getConfigFileName()); + LOG = LogManager.getLogger(); + } + protected abstract String getConfigFileName(); +} diff --git a/guava-utils/src/test/resources/log4j2.xml b/guava-utils/src/test/resources/log4j2.xml new file mode 100644 index 0000000..79060e0 --- /dev/null +++ b/guava-utils/src/test/resources/log4j2.xml @@ -0,0 +1,99 @@ + + + + + + + third-api + /home/migu/portal-third-api/logs + 100 MB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jpa/jpa.iml b/jpa/jpa.iml new file mode 100644 index 0000000..f69a403 --- /dev/null +++ b/jpa/jpa.iml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jpa/pom.xml b/jpa/pom.xml new file mode 100644 index 0000000..137fab1 --- /dev/null +++ b/jpa/pom.xml @@ -0,0 +1,99 @@ + + + + 4.0.0 + + com.liuhuiyu + jpa + 2021.1.0 + + jpa + http://www.liuhuiyu.com + + + UTF-8 + 1.8 + 1.8 + 4.13.2 + 23.0.0 + 2021.1.0 + 2022.1.0 + 2.1.6.RELEASE + 2.18.0 + 31.1-jre + + + + org.springframework.boot + spring-boot-starter-data-jpa + ${spring.versions} + + + org.apache.logging.log4j + log4j-api + + + ch.qos.logback + logback-classic + + + org.apache.logging.log4j + log4j-to-slf4j + + + + + org.jetbrains + annotations + ${annotations.versions} + + + com.liuhuiyu + dto + ${com.liuhuiyu.dto.versions} + + + + org.apache.logging.log4j + log4j-core + ${log4j2.version} + compile + + + + + com.google.guava + guava + ${guava.version} + + + com.liuhuiyu + test2 + ${com.liuhuiyu.test.versions} + test + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + + + compile + + + jar-no-fork + + + + + + + + diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/BaseView.java b/jpa/src/main/java/com/liuhuiyu/jpa/BaseView.java new file mode 100644 index 0000000..171fffb --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/BaseView.java @@ -0,0 +1,525 @@ +package com.liuhuiyu.jpa; + +import javax.sql.DataSource; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.math.BigDecimal; +import java.sql.*; +import java.util.*; +import java.util.function.Consumer; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-03-22 9:12 + */ +public abstract class BaseView { + private final DataSource dataSource; + + public BaseView(DataSource dataSource) { + this.dataSource = dataSource; + } + + /** + * 连接获取 + * + * @param callFunctions 调用函数 + * @author LiuHuiYu + * Created DateTime 2021-03-25 10:42 + */ + protected void actionConnection(Consumer callFunctions) { + try (Connection connection = this.dataSource.getConnection()) { + callFunctions.accept(connection); + } + catch (SQLException throwable) { + throw new RuntimeException("获取连接异常。", throwable); + } + } + + /** + * 获取 PreparedStatement + * + * @param sql 基础语句 + * @param callFunctions 回调 + * @author LiuHuiYu + * Created DateTime 2021-03-25 10:45 + */ + protected void actionPreparedStatement(String sql, Consumer callFunctions) { + actionConnection((connection) -> { + try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + callFunctions.accept(preparedStatement); + } + catch (SQLException e) { + throw new RuntimeException(e); + } + }); + } + + /** + * 执行sql回调ResultSet + * + * @param sql 基础语句 + * @param parameterMap 参数Map + * @param callFunctions 回调 + * @author LiuHuiYu + * Created DateTime 2021-03-25 10:46 + */ + protected void fullResultSet(String sql, Map parameterMap, Consumer callFunctions) { + NamedParameterStatement namedParameterStatement = new NamedParameterStatement(sql); + this.actionPreparedStatement(namedParameterStatement.getSql(), preparedStatement -> { + if (parameterMap != null && parameterMap.size() > 0) { + namedParameterStatement.fillParameters(preparedStatement, parameterMap); + } + Log.i(namedParameterStatement.getSql()); + ResultSet resultSet; + try { + resultSet = preparedStatement.executeQuery(); + } + catch (SQLException throwable) { + throw new RuntimeException("执行sql语句异常。", throwable); + } + callFunctions.accept(resultSet); + }); + } + + + /** + * 对象列表获取 + * + * @param sql 基本语句 + * @param parameterMap 参数表 + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2021-03-22 14:05 + */ + protected List getResultList(String sql, Map parameterMap) { + return getResultList(sql, parameterMap, false); + } + + /** + * 对象列表获取 + * + * @param sql 基本语句 + * @param parameterMap 参数表 + * @param onlyFirst 仅第一行数据 + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2021-03-22 14:05 + */ + protected List getResultList(String sql, Map parameterMap, boolean onlyFirst) { + ArrayList resList = new ArrayList<>(); + this.fullResultSet(sql, parameterMap, (resultSet) -> { + try { + int columnCount = resultSet.getMetaData().getColumnCount(); + while (resultSet.next()) { + Object[] objs = new Object[columnCount]; + for (int i = 1; i <= columnCount; i++) { + objs[i - 1] = (resultSet.getObject(i)); + } + resList.add(objs); + if (onlyFirst) { + return; + } + } + } + catch (Exception ex) { + throw new RuntimeException(ex); + } + }); + return resList; + } + + /** + * 对象列表获取 + * + * @param sql 基本语句 + * @param parameterMap 参数表 + * @param onlyFirst 仅第一行数据 + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2021-03-22 14:05 + */ + protected List getResultListT(Class clazz, String sql, Map parameterMap, boolean onlyFirst) { + ArrayList resList = new ArrayList<>(); + this.fullResultSet(sql, parameterMap, (resultSet) -> { + try { + int columnCount = resultSet.getMetaData().getColumnCount(); +// ArrayList columnLabels=this.setColumnLabels(resultSet.getMetaData()); + while (resultSet.next()) { + while (resultSet.next()) { + final T t = rowToT(resultSet, clazz); + resList.add(t); + } + } + } + catch (Exception ex) { + throw new RuntimeException(ex); + } + }); + return resList; + } + + +// /** +// * 字段名称按照顺序设置 +// * +// * @author LiuHuiYu +// * Created DateTime 2023-07-28 17:26 +// */ +// private ArrayList setColumnLabels(ResultSetMetaData metaData) { +// ArrayList columnLabels; +// try { +// int count = metaData.getColumnCount(); +// columnLabels = new ArrayList<>(count); +// for (int i = 1; i <= count; i++) { +// columnLabels.add(metaData.getColumnLabel(i).toUpperCase()); +// } +// } +// catch (Exception ex) { +// throw new RuntimeException(ex); +// } +// return columnLabels; +// } + + /** + * 对象列表获取 + * + * @param b DaoOperator + * @param sql 基本语句 + * @param parameterMap 参数表 + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2021-03-22 14:04 + */ + protected List getResultList(DaoOperator b, String sql, Map parameterMap) { + List list = this.getResultList(sql, parameterMap); + List resList = new ArrayList<>(); + for (Object obj : list) { + resList.add(b.objectToT(obj)); + } + return resList; + } + + /** + * 返回第一行信息 + * + * @param b DaoOperator + * @param sql 执行语句 + * @param parameterMap 参数表 + * @return java.util.Optional + * @author LiuHuiYu + * Created DateTime 2021-03-22 14:02 + */ + protected Optional getFirstResult(DaoOperator b, String sql, Map parameterMap) { + List list = this.getResultList(sql, parameterMap, true); + if (list.size() == 0) { + return Optional.empty(); + } + else { + T t = b.objectToT(list.get(0)); + return Optional.of(t); + } + } + + /** + * 第一行第一列信息获取 + * + * @param sql 语句 + * @param parameterMap 参数表 + * @return java.util.Optional + * @author LiuHuiYu + * Created DateTime 2021-03-22 13:46 + */ + protected Optional getSingleResult(String sql, Map parameterMap) { + List list = this.getResultList(sql, parameterMap, true); + if (list.size() == 0 || list.get(0).length == 0) { + return Optional.empty(); + } + else { + return Optional.of(list.get(0)[0]); + } + } + + /** + * 快速 sql 查询 + * + * @param input 查询入参 + * @param sql 原始语句 + * @param whereFull 查询填充 + * @param b DaoOperator + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2022-01-12 10:16 + */ + protected List selectList(T input, String sql, WhereFull whereFull, DaoOperator b) { + Map parameterMap = new HashMap<>(1); + StringBuilder sqlBuilder = new StringBuilder(); + sqlBuilder.append(sql); + sqlBuilder.append(" WHERE(1=1)"); + whereFull.full(input, sqlBuilder, parameterMap); + return this.getResultList(b, sqlBuilder.toString(), parameterMap); + } + + /** + * 统计查询 + * + * @param input 查询入参 + * @param sql 原始语句 + * @param whereFull 查询填充 + * @return java.lang.Long + * @author LiuHuiYu + * Created DateTime 2022-01-12 10:48 + */ + protected Long selectCount(T input, String sql, WhereFull whereFull) { + StringBuilder sqlBuilder = new StringBuilder(sql); + sqlBuilder.append(" WHERE(1=1)"); + Map parameterMap = new HashMap<>(1); + whereFull.full(input, sqlBuilder, parameterMap); + final Optional singleResult = this.getSingleResult(sqlBuilder.toString(), parameterMap); + return singleResult.map(o -> ((BigDecimal) o).longValue()).orElse(0L); + } + + /** + * 返回第一行信息 + * + * @param input 查询条件 + * @param sql 原始语句 + * @param whereFull 条件生成 + * @param b 结果转化 + * @return java.util.Optional + * @author LiuHuiYu + * Created DateTime 2022-05-09 16:16 + */ + protected Optional getFirstResult(T input, String sql, WhereFull whereFull, DaoOperator b) { + List list = this.selectList(input, sql, whereFull, b); + if (list.size() == 0) { + return Optional.empty(); + } + else { + return Optional.of(list.get(0)); + } + } + + /** + * 统计查询 + * + * @param sql sql语句 + * @param parameterMap 参数 + * @return java.lang.Long + * @author LiuHuiYu + * Created DateTime 2022-02-15 16:54 + */ + protected Long selectCount(String sql, Map parameterMap) { + DaoOperator longDaoOperator = (o) -> { + Object obj = o.getClass().isArray() ? ((Object[]) o)[0] : o; + return obj instanceof Number ? ((Number) obj).longValue() : 0L; + }; + return getFirstResult(longDaoOperator, sql, parameterMap).orElse(0L); + } + + private T rowToT(ResultSet rs, Class clazz) { + T obj = null; + try { + obj = clazz.newInstance(); + final Field[] fields = obj.getClass().getDeclaredFields(); + for (Field field : fields) { + int mod = field.getModifiers(); + int columnIndex ; + try { + columnIndex = rs.findColumn(field.getName()); + } + catch (Exception igex) { + columnIndex = -1; + } + if (Modifier.isStatic(mod) || Modifier.isFinal(mod) || + columnIndex < 0) { + continue; + } + Object rowValue = rs.getObject(columnIndex + 1); + Object value = getValue(field, rowValue); + field.setAccessible(true); + field.set(obj, value); + } + } + catch (Exception e) { + e.printStackTrace(); + } + return obj; + } + + /** + * 将指定值转换为与类字段相同类型的值 + * + * @param field 字段 + * @param value 值 + * @return java.lang.Object + * @author LiuHuiYu + * Created DateTime 2023-07-28 16:19 + */ + private static Object getValue(Field field, Object value) { + if (value == null) { + return null; + } + if (field.getType().getName().equals(String.class.getName())) { + return value.toString(); + } + if (value instanceof BigDecimal) { + BigDecimal v = (BigDecimal) value; + if (field.getType().getName().equals(int.class.getName()) || + field.getType().getName().equals(Integer.class.getName())) { + return v.intValue(); + } + else if (field.getType().getName().equals(long.class.getName()) || + field.getType().getName().equals(Long.class.getName())) { + return v.longValue(); + } + else if (field.getType().getName().equals(float.class.getName()) || + field.getType().getName().equals(Float.class.getName())) { + return v.floatValue(); + } + else if (field.getType().getName().equals(double.class.getName()) || + field.getType().getName().equals(Double.class.getName())) { + return v.doubleValue(); + } + else if (field.getType().getName().equals(byte.class.getName()) || + field.getType().getName().equals(Byte.class.getName())) { + return v.byteValue(); + } + else if (field.getType().getName().equals(short.class.getName()) || + field.getType().getName().equals(Short.class.getName())) { + return v.shortValue(); + } + } + return value; + } + + /** + * 查询建造者 + * + * @author LiuHuiYu + * Created DateTime 2022-05-09 16:18 + */ + public class SelectBuilder { + private final String sql; + private final DaoOperator b; + + private Map parameterMap; + private T input; + private WhereFull whereFull; + + /** + * 建议 数量查询 使用 + * + * @param sql 原始语句 + * @author LiuHuiYu + * Created DateTime 2022-05-09 16:21 + */ + public SelectBuilder(String sql) { + this.b = null; + this.sql = sql; + } + + + /** + * 建议查询sql结果的时候使用 + * + * @param daoOperator 解析函数 + * @param sql 原生语句 + * @author LiuHuiYu + * Created DateTime 2022-05-09 16:22 + */ + public SelectBuilder(DaoOperator daoOperator, String sql) { + this.b = daoOperator; + this.sql = sql; + } + + /** + * 设置 参数列表 + * + * @param parameterMap 参数列表 + * @return com.liuhuiyu.jpa.BaseView.SelectBuilder + * @author LiuHuiYu + * Created DateTime 2022-05-09 15:51 + */ + public SelectBuilder parameterMap(Map parameterMap) { + if (this.input != null || this.whereFull != null) { + throw new RuntimeException("此方法与 whereFull 方法互斥不能同时使用"); + } + this.parameterMap = parameterMap; + return this; + } + + /** + * 设置条件查询解析 + * + * @param input 入参 + * @param whereFull 解析条件 + * @return com.liuhuiyu.jpa.BaseView.SelectBuilder + * @author LiuHuiYu + * Created DateTime 2022-05-09 15:51 + */ + public SelectBuilder whereFull(T input, WhereFull whereFull) { + if (this.parameterMap != null) { + throw new RuntimeException("此方法与 parameterMap 方法互斥不能同时使用"); + } + this.input = input; + this.whereFull = whereFull; + return this; + } + + /** + * 统计查询 + * + * @return java.lang.Long + * @author LiuHuiYu + * Created DateTime 2022-05-09 16:12 + */ + public Long buildCount() { + if (input == null) { + return selectCount(sql, parameterMap); + } + else { + return selectCount(input, sql, whereFull); + } + } + + /** + * 列表查询 + * + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2022-05-09 16:12 + */ + public List buildList() { + if (b == null) { + throw new NullPointerException("缺少转换函数"); + } + if (input == null) { + return getResultList(this.b, this.sql, this.parameterMap); + } + else { + return selectList(input, sql, whereFull, b); + } + } + + /** + * 第一条记录查询 + * + * @return java.util.Optional + * @author LiuHuiYu + * Created DateTime 2022-05-09 16:12 + */ + + public Optional buildFirst() { + if (b == null) { + throw new NullPointerException("缺少转换函数"); + } + if (input == null) { + return getFirstResult(this.b, this.sql, this.parameterMap); + } + else { + return getFirstResult(input, sql, whereFull, b); + } + } + } +} diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/DaoOperator.java b/jpa/src/main/java/com/liuhuiyu/jpa/DaoOperator.java new file mode 100644 index 0000000..145e8e0 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/DaoOperator.java @@ -0,0 +1,17 @@ +package com.liuhuiyu.jpa; + +/** + * 函数式(obj->T) + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-01-22 9:10 + */ +@FunctionalInterface +public interface DaoOperator { + /** + * Object 转换成 类型 T + * @param o Object + * @return T + */ + T objectToT(Object o); +} \ No newline at end of file diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/Log.java b/jpa/src/main/java/com/liuhuiyu/jpa/Log.java new file mode 100644 index 0000000..65e1714 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/Log.java @@ -0,0 +1,27 @@ +package com.liuhuiyu.jpa; + + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-07-31 16:54 + */ +public class Log { + private static final Logger LOG= LogManager.getLogger(Log.class); + public static boolean outLog = false; + + public static void i(String info) { + if (outLog) { + LOG.info(info); + } + } + + public static void d(String info) { + if (outLog) { + LOG.debug(info); + } + } +} diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/NamedParameterStatement.java b/jpa/src/main/java/com/liuhuiyu/jpa/NamedParameterStatement.java new file mode 100644 index 0000000..ee186f0 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/NamedParameterStatement.java @@ -0,0 +1,128 @@ +package com.liuhuiyu.jpa; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-03-22 11:01 + */ +public class NamedParameterStatement { + private final Map paramsMap = new HashMap<>(); + private String sql; + + public Map getParamsMap() { + return paramsMap; + } + + public String getSql() { + return this.sql; + } + + private void emptyMap() { + paramsMap.clear(); + } + + public NamedParameterStatement(String sql) { + this.sql = this.parseSql2(sql); + } + + /** + * 分析处理带命名参数的SQL语句。使用Map存储参数,然后将参数替换成? + * + * @param sql 基本语句 + * @author LiuHuiYu + * Created DateTime 2021-03-22 14:10 + */ + @Deprecated + private void parseSql(String sql) { + String regex = "((=[\\s+]|=):(\\w+))"; + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(sql); + emptyMap(); + int idx = 1; + while (m.find()) { + //参数名称可能有重复,使用序号来做Key + paramsMap.put(idx++, m.group(m.groupCount())); + } + this.sql = sql.replaceAll(regex, "=?"); + Log.i("分析前:" + sql); + Log.d("分析后:" + this.sql); + } + + private String parseSql2(String query) { + int length = query.length(); + StringBuilder parsedQuery = new StringBuilder(length); + boolean inSingleQuote = false; + boolean inDoubleQuote = false; + int index = 1; + + for (int i = 0; i < length; i++) { + char c = query.charAt(i); + if (inSingleQuote) { + if (c == '\'') { + inSingleQuote = false; + } + } + else if (inDoubleQuote) { + if (c == '"') { + inDoubleQuote = false; + } + } + else { + if (c == '\'') { + inSingleQuote = true; + } + else if (c == '"') { + inDoubleQuote = true; + } + else if (c == ':' && + i + 1 < length && + Character.isJavaIdentifierStart(query.charAt(i + 1))) { + int j = i + 2; + while (j < length && Character.isJavaIdentifierPart(query.charAt(j))) { + j++; + } + String name = query.substring(i + 1, j); + // 用问号替换参数 + c = '?'; + // 如果参数是跳过结尾 + i += name.length(); + this.paramsMap.put(index++, name); + } + } + parsedQuery.append(c); + } + return parsedQuery.toString(); + } + + /** + * 使用参数值Map,填充pStat + * + * @param pStat PreparedStatement + * @param pMap 命名参数的值表,其中的值可以比较所需的参数多。 + * @author LiuHuiYu + * Created DateTime 2021-03-22 14:10 + */ + public void fillParameters(PreparedStatement pStat, Map pMap) { + this.paramsMap.forEach((idKey, valueKey) -> { + if (pMap.containsKey(valueKey)) { + Object value = pMap.get(valueKey); + try { + pStat.setObject(idKey, value); + } + catch (SQLException throwables) { + throw new RuntimeException("填充参数出错,原因:", throwables); + } + } + else { + throw new RuntimeException("语句中参数‘" + valueKey + "’不存在列表中"); + } + }); + } +} diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/WhereFull.java b/jpa/src/main/java/com/liuhuiyu/jpa/WhereFull.java new file mode 100644 index 0000000..68c2b71 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/WhereFull.java @@ -0,0 +1,13 @@ +package com.liuhuiyu.jpa; + +import java.util.Map; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-01-12 10:13 + */ +@FunctionalInterface +public interface WhereFull { + void full(T v, StringBuilder sqlBuilder, Map parameterMap); +} diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/entity/IUniversallyUniqueIdentifier.java b/jpa/src/main/java/com/liuhuiyu/jpa/entity/IUniversallyUniqueIdentifier.java new file mode 100644 index 0000000..ccab87a --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/entity/IUniversallyUniqueIdentifier.java @@ -0,0 +1,16 @@ +package com.liuhuiyu.jpa.entity; + +/** + * 使用(32位长度id的接口) + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-11-19 14:40 + */ +public interface IUniversallyUniqueIdentifier { + /** + * UUID长度 + */ + int COLUMN_ID_MAX_LENGTH = 32; + +} diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/oracle/comment/Comment.java b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/comment/Comment.java new file mode 100644 index 0000000..299cc16 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/comment/Comment.java @@ -0,0 +1,18 @@ +package com.liuhuiyu.jpa.oracle.comment; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 数据库备注信息 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-11-19 11:35 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) +public @interface Comment { + String value() default ""; +} \ No newline at end of file diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/oracle/comment/CommentIntegrator.java b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/comment/CommentIntegrator.java new file mode 100644 index 0000000..e05d249 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/comment/CommentIntegrator.java @@ -0,0 +1,117 @@ +package com.liuhuiyu.jpa.oracle.comment; + +import org.hibernate.boot.Metadata; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.integrator.spi.Integrator; +import org.hibernate.mapping.PersistentClass; +import org.hibernate.mapping.Property; +import org.hibernate.service.spi.SessionFactoryServiceRegistry; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Field; +import java.util.Iterator; + +/** + * 注解集成 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-11-19 11:36 + */ +@Component +public class CommentIntegrator implements Integrator { + public static final CommentIntegrator INSTANCE = new CommentIntegrator(); + + public CommentIntegrator() { + super(); + } + + /** + * Perform comment integration. + * + * @param metadata The "compiled" representation of the mapping information + * @param sessionFactory The session factory being created + * @param serviceRegistry The session factory's service registry + */ + @Override + public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory, SessionFactoryServiceRegistry serviceRegistry) { + processComment(metadata); + } + + /** + * Not used. + * + * @param sessionFactoryImplementor The session factory being closed. + * @param sessionFactoryServiceRegistry That session factory's service registry + */ + @Override + public void disintegrate(SessionFactoryImplementor sessionFactoryImplementor, SessionFactoryServiceRegistry sessionFactoryServiceRegistry) { + } + + /** + * Process comment annotation. + * + * @param metadata process annotation of this {@code Metadata}. + */ + private void processComment(Metadata metadata) { + for (PersistentClass persistentClass : metadata.getEntityBindings()) { + // Process the Comment annotation is applied to Class + Class clz = persistentClass.getMappedClass(); + if (clz.isAnnotationPresent(Comment.class)) { + Comment comment = clz.getAnnotation(Comment.class); + persistentClass.getTable().setComment(comment.value()); + } + + // Process Comment annotations of identifier. + Property identifierProperty = persistentClass.getIdentifierProperty(); + if (identifierProperty != null) { + fieldComment(persistentClass, identifierProperty.getName()); + } + else { + org.hibernate.mapping.Component component = persistentClass.getIdentifierMapper(); + if (component != null) { + //noinspection unchecked + Iterator iterator = component.getPropertyIterator(); + while (iterator.hasNext()) { + fieldComment(persistentClass, iterator.next().getName()); + } + } + } + // Process fields with Comment annotation. + //noinspection unchecked + Iterator iterator = persistentClass.getPropertyIterator(); + while (iterator.hasNext()) { + fieldComment(persistentClass, iterator.next().getName()); + } + } + } + + /** + * Process @{code comment} annotation of field. + * + * @param persistentClass Hibernate {@code PersistentClass} + * @param columnName name of field + */ + private void fieldComment(PersistentClass persistentClass, String columnName) { + try { + Field field = persistentClass.getMappedClass().getDeclaredField(columnName); + if (field.isAnnotationPresent(Comment.class)) { + String comment = field.getAnnotation(Comment.class).value(); + String sqlColumnName = persistentClass.getProperty(columnName).getValue().getColumnIterator().next().getText(); +// Iterator columnIterator = persistentClass.getTable().getColumnIterator(); + Iterator columnIterator = persistentClass.getTable().getColumnIterator(); + while (columnIterator.hasNext()) { + final Object next = columnIterator.next(); + if (next instanceof org.hibernate.mapping.Column) { + org.hibernate.mapping.Column column = (org.hibernate.mapping.Column) next; + if (sqlColumnName.equalsIgnoreCase(column.getName())) { + column.setComment(comment); + break; + } + } + } + } + } + catch (NoSuchFieldException | SecurityException ignored) { + } + } +} \ No newline at end of file diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/oracle/comment/HibernateConfig.java b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/comment/HibernateConfig.java new file mode 100644 index 0000000..cfdbf37 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/comment/HibernateConfig.java @@ -0,0 +1,23 @@ +package com.liuhuiyu.jpa.oracle.comment; + +import org.hibernate.jpa.boot.spi.IntegratorProvider; +import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; +import org.springframework.stereotype.Component; + +import java.util.Collections; +import java.util.Map; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-11-19 12:01 + */ +@Component +public class HibernateConfig implements HibernatePropertiesCustomizer { + @Override + public void customize(Map hibernateProperties) { + hibernateProperties.put("hibernate.use_sql_comments", true); + hibernateProperties.put("hibernate.integrator_provider", + (IntegratorProvider) () -> Collections.singletonList(CommentIntegrator.INSTANCE)); + } +} diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/oracle/constant/IColumnConstant.java b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/constant/IColumnConstant.java new file mode 100644 index 0000000..8c96276 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/constant/IColumnConstant.java @@ -0,0 +1,25 @@ +package com.liuhuiyu.jpa.oracle.constant; + +import com.liuhuiyu.jpa.entity.IUniversallyUniqueIdentifier; + +/** + * 字段常量接口 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-01-28 15:16 + */ +public interface IColumnConstant extends IUniversallyUniqueIdentifier { + /** + * bool型字符串变量长度 + */ + int COLUMN_BOOL_CHAR_MAX_LENGTH = 1; + /** + * NVARCHAR2最大长度 + */ + int COLUMN_NVARCHAR2_MAX_LENGTH = 2000; + /** + * VARCHAR2最大长度 + */ + int COLUMN_VARCHAR2_MAX_LENGTH = 4000; +} diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/oracle/dao/OracleBaseView.java b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/dao/OracleBaseView.java new file mode 100644 index 0000000..052a0f7 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/dao/OracleBaseView.java @@ -0,0 +1,826 @@ +package com.liuhuiyu.jpa.oracle.dao; + +import com.google.common.base.Joiner; +import com.liuhuiyu.dto.IPaging; +import com.liuhuiyu.jpa.BaseView; +import com.liuhuiyu.jpa.DaoOperator; +import com.liuhuiyu.jpa.WhereFull; +import com.liuhuiyu.jpa.oracle.util.OracleDaoUtil; +import org.springframework.data.domain.PageImpl; +import org.springframework.util.StringUtils; + +import javax.sql.DataSource; +import java.util.*; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-02 8:15 + */ +public abstract class OracleBaseView extends BaseView { + public OracleBaseView(DataSource dataSource) { + super(dataSource); + } + + //region 查询 + + public static final String BLANK_BASE_WHERE = " "; + + /** + * 数量查询 + * + * @param t 条件 + * @param sql 原始语句 + * @param fullWhere 填充条件 + * @param 分页查询的条件 + * @return java.lang.Long + * @author LiuHuiYu + * Created DateTime 2022-02-21 16:24 + */ + protected Long count(T t, String sql, String baseWhere, WhereFull fullWhere) { + return count(t, sql, baseWhere, fullWhere, false); + } + + protected Long count(T t, String sql, String baseWhere, WhereFull fullWhere, boolean sqlPrototype) { + StringBuilder sqlBuilder = new StringBuilder(sql); + if (!sqlPrototype) { + OracleDaoUtil.countOracleSql(sqlBuilder); + } + sqlBuilder.append(SPACE).append(baseWhere); + Map parameterMap = new HashMap<>(0); + fullWhere.full(t, sqlBuilder, parameterMap); + return super.selectCount(sqlBuilder.toString(), parameterMap); + } + + + /** + * 获取分页列表数据 + * + * @param b 获取数据后的转换 + * @param t 获取条件 + * @param sql 基础查询语句 + * @param baseWhere 基础查询条件 + * @param order 排序 + * @param fullWhere 填充查询条件 + * @param 返回分页的数据类型 + * @param 分页查询的条件 + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2022-04-25 10:29 + */ + protected List pageList(DaoOperator b, T t, String sql, String baseWhere, String order, WhereFull fullWhere) { + if (!StringUtils.hasText(baseWhere) && !BLANK_BASE_WHERE.equals(baseWhere)) { + baseWhere = "WHERE(1=1)"; + } + Map parameterMap = new HashMap<>(0); + StringBuilder sqlBuilder = new StringBuilder(sql); + sqlBuilder.append(SPACE).append(baseWhere); + fullWhere.full(t, sqlBuilder, parameterMap); + sqlBuilder.append(SPACE).append(order); + OracleDaoUtil.paginationOracleSql(sqlBuilder, t.getPaging()); + return super.getResultList(b, sqlBuilder.toString(), parameterMap); + } + + public static final String SPACE = " "; + + /** + * 获取列表数据 + * + * @param b 获取数据后的转换 + * @param t 获取条件 + * @param sql 基础查询语句 + * @param baseWhere 基础查询条件(如果无条件此处使用 BLANK_BASE_WHERE) + * @param order 排序 + * @param fullWhere 填充查询条件 + * @param 返回分页的数据类型 + * @param 分页查询的条件 + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2022-04-25 10:29 + */ + protected List list(DaoOperator b, T t, String sql, String baseWhere, String order, WhereFull fullWhere) { + StringBuilder sqlBuilder = new StringBuilder(sql); + sqlBuilder.append(SPACE).append(baseWhere); + Map parameterMap = new HashMap<>(0); + fullWhere.full(t, sqlBuilder, parameterMap); + sqlBuilder.append(SPACE).append(order); + return super.getResultList(b, sqlBuilder.toString(), parameterMap); + } + + /** + * 分页数据查询 + * + * @param b 查询结果转换实例的实现 + * @param t 分页查询条件 + * @param sql 基础语句 + * @param baseWhere 基础查询(带where) + * @param order 排序(带 order by) + * @param fullWhere void fullWhere(T find, StringBuilder sqlBuilder, Map parameterMap) 实现 + * @param 返回分页的数据类型 + * @param 分页查询的条件 + * @return org.springframework.data.domain.PageImpl + * @author LiuHuiYu + * Created DateTime 2022-04-09 11:41 + */ + protected PageImpl page(DaoOperator b, T t, String sql, String baseWhere, String order, WhereFull fullWhere) { + return page(b, t, sql, null, baseWhere, order, fullWhere); + } + + /** + * 分页数据查询 + * + * @param b 查询结果转换实例的实现 + * @param t 分页查询条件 + * @param sql 基础语句 + * @param baseWhere 基础查询(带where) + * @param order 排序(带 order by) + * @param fullWhere void fullWhere(T find, StringBuilder sqlBuilder, Map parameterMap) 实现 + * @param 返回分页的数据类型 + * @param 分页查询的条件 + * @return org.springframework.data.domain.PageImpl + * @author LiuHuiYu + * Created DateTime 2022-04-09 11:41 + */ + protected PageImpl page(DaoOperator b, T t, String sql, String countSql, String baseWhere, String order, WhereFull fullWhere) { + Long total = this.count(t, StringUtils.hasText(countSql) ? countSql : sql, baseWhere, fullWhere, StringUtils.hasText(countSql)); + final List gatekeeperCarLogDtoList; + if (total == 0) { + gatekeeperCarLogDtoList = Collections.emptyList(); + } + else if (t.getPaging().isAllInOne()) { + gatekeeperCarLogDtoList = this.list(b, t, sql, baseWhere, order, fullWhere); + } + else if (t.getPaging().getPageSize() == 0) { + gatekeeperCarLogDtoList = Collections.emptyList(); + } + else { + //记录查询 + gatekeeperCarLogDtoList = pageList(b, t, sql, baseWhere, order, fullWhere); + } + return new PageImpl<>(gatekeeperCarLogDtoList, t.getPaging().getPageRequest(), total); + } + + protected Optional getFirstResult(DaoOperator b, T t, String sql, String baseWhere, String order, WhereFull fullWhere) { + StringBuilder sqlBuilder = new StringBuilder(sql); + sqlBuilder.append(SPACE).append(baseWhere); + Map parameterMap = new HashMap<>(0); + fullWhere.full(t, sqlBuilder, parameterMap); + sqlBuilder.append(SPACE).append(order); + final List resultList = super.getResultList(b, sqlBuilder.toString(), parameterMap); + if (resultList.size() == 0) { + return Optional.empty(); + } + else { + return Optional.of(resultList.get(0)); + } + } + //endregion + + //region 辅助功能 已经准备作废 + + /** + * 模糊匹配 like值 + * 建议构建继承SqlCommandPackage的类,使用SqlCommandPackage实现。 + * + * @param value 值 + * @return java.lang.String + * @author LiuHuiYu + * Created DateTime 2022-06-02 18:44 + */ + @Deprecated + protected static String likeValue(String value) { + return likeValue(value, true, true, true); + } + + /** + * like值 + * 建议构建继承SqlCommandPackage的类,使用SqlCommandPackage实现。 + * + * @param value 值 + * @param trim 去掉首尾空格 + * @param head 头部模糊匹配 + * @param tail 尾部模糊匹配 + * @return java.lang.String + * @author LiuHuiYu + * Created DateTime 2022-06-02 18:43 + */ + @Deprecated + protected static String likeValue(String value, Boolean trim, Boolean head, Boolean tail) { + return (head ? "%" : "") + (trim ? value.trim() : value) + (tail ? "%" : ""); + } + //endregion + + /** + * 分页查询建造者 + * + * @author LiuHuiYu + * Created DateTime 2022-05-02 8:33 + */ + public class PageImplBuilder { + private final DaoOperator b; + private final T t; + private final String sql; + private String countSql; + private final WhereFull fullWhere; + private String order; + private String baseWhere; + + public PageImplBuilder(DaoOperator b, T t, String sql, WhereFull fullWhere) { + this.b = b; + this.t = t; + this.sql = sql; + this.fullWhere = fullWhere; + this.order = ""; + this.baseWhere = " WHERE(1=1) "; + this.countSql = null; + } + + /** + * 设置独立的count查询语句 + * + * @param countSql count查询语句 + * @return com.liuhuiyu.jpa.oracle.dao.OracleBaseView.PageImplBuilder + * @author LiuHuiYu + * Created DateTime 2022-11-20 9:36 + */ + public PageImplBuilder setCountSql(String countSql) { + this.countSql = countSql; + return this; + } + + public PageImplBuilder order(String order) { + this.order = order; + return this; + } + + public PageImplBuilder baseWhere(String baseWhere) { + this.baseWhere = baseWhere; + return this; + } + + public PageImpl buildPage() { + return page(b, t, sql, countSql, baseWhere, order, fullWhere); + } + + public List buildList() { + return list(b, t, sql, baseWhere, order, fullWhere); + } + + public long buildCount() { + return count(t, StringUtils.hasText(countSql) ? countSql : sql, baseWhere, fullWhere, StringUtils.hasText(countSql)); + } + + public Optional buildFirstResult() { + return getFirstResult(b, t, sql, baseWhere, order, fullWhere); + } + } + + /** + * SQL原生封装 + * + * @author LiuHuiYu + * Created DateTime 2022-11-20 8:26 + */ + protected static abstract class SqlCommandPackage { + protected T findDto; + protected StringBuilder sqlBuilder; + protected Map parameterMap; + protected Joiner joiner = Joiner.on(",").skipNulls(); + + /** + * SQL原生封装 构建函数 + * + * @param findDto 查询条件 + * @param sqlBuilder sqlBuilder + * @param parameterMap 参数 + * @author LiuHuiYu + * Created DateTime 2022-11-20 8:27 + */ + public SqlCommandPackage(T findDto, StringBuilder sqlBuilder, Map parameterMap) { + this.findDto = findDto; + this.sqlBuilder = sqlBuilder; + this.parameterMap = parameterMap; + } + + /** + * 封装 in 条件 + * + * @param parameterName 参数名称头 + * @param fieldName 字段名称 + * @param data 查询的数据 + * @author LiuHuiYu + * Created DateTime 2022-11-20 8:28 + * @deprecated 使用 condition 方法进行操作 + */ + @Deprecated + protected

void inPackage(String parameterName, String fieldName, P[] data) { + inPackage(parameterName, fieldName, data, false, false); + } + + /** + * 封装 in 条件 + * + * @param parameterName 参数名称头 + * @param fieldName 字段名称 + * @param data 查询的数据 + * @param notIn 使用 not in + * @param isNull 包含空 OR(fieldName is null) + * @author LiuHuiYu + * Created DateTime 2022-11-20 8:28 + * @deprecated 使用 condition 方法进行操作 + */ + @Deprecated + protected

void inPackage(String parameterName, String fieldName, P[] data, Boolean notIn, Boolean isNull) { + if (data != null && data.length > 0) { + String[] names = new String[data.length]; + this.sqlBuilder.append("AND((").append(fieldName).append(notIn ? " NOT" : "").append(" IN("); + for (int i = 0; i < data.length; i++) { + names[i] = ":" + parameterName + i; + this.parameterMap.put(parameterName + i, data[i]); + } + this.sqlBuilder.append(joiner.join(names)).append("))"); + if (isNull) { + sqlBuilder.append("OR(").append(fieldName).append(" is null)"); + } + this.sqlBuilder.append(")"); + } + } + + + /** + * 封装 数据段互相包含(开区间 位置相同)条件 + * + * @param minParameterName 最小值参数名 + * @param maxParameterName 最大值参数名 + * @param minFieldName 最小值字段 + * @param maxFieldName 最大值字段 + * @param minValue 最小值 + * @param maxValue 最大值 + * @author LiuHuiYu + * Created DateTime 2022-12-01 10:23 + * @deprecated 使用 condition 方法进行操作 + */ + @Deprecated + protected

void inclusion(String minParameterName, String maxParameterName, String minFieldName, String maxFieldName, P minValue, P maxValue) { + this.sqlBuilder.append("and ("); + this.sqlBuilder.append("((").append(minFieldName).append(" < :").append(minParameterName).append(") and (") + .append(maxFieldName).append(" > :").append(minParameterName).append("))"); + this.sqlBuilder.append("or"); + this.sqlBuilder.append("((").append(minFieldName).append(" < :").append(maxParameterName).append(") and (") + .append(maxFieldName).append(" > :").append(maxParameterName).append("))"); + this.sqlBuilder.append("or"); + this.sqlBuilder.append("((").append(minFieldName).append(" >= :").append(minParameterName).append(") and (") + .append(maxFieldName).append(" <= :").append(maxParameterName).append("))"); + this.sqlBuilder.append(")"); + this.parameterMap.put(minParameterName, minValue); + this.parameterMap.put(maxParameterName, maxValue); + } + + /** + * 模糊匹配 like值 + * + * @param value 值 + * @author LiuHuiYu + * Created DateTime 2022-06-02 18:44 + * @deprecated 使用 condition 方法进行操作 + */ + @Deprecated + protected void likeValue(String parameterName, String fieldName, String value) { + likeValue(parameterName, fieldName, value, true, true, true); + } + + /** + * like值 + * + * @param value 值 + * @param trim 去掉首尾空格 + * @param head 头部模糊匹配 + * @param tail 尾部模糊匹配 + * @author LiuHuiYu + * Created DateTime 2022-06-02 18:43 + * @deprecated 使用 condition 方法进行操作 + */ + @Deprecated + protected void likeValue(String parameterName, String fieldName, String value, Boolean trim, Boolean head, Boolean tail) { + final String s = (head ? "%" : "") + (trim ? value.trim() : value) + (tail ? "%" : ""); + this.sqlBuilder.append("AND(").append(parameterName).append(" LIKE :").append(fieldName).append(")"); + this.parameterMap.put(fieldName, s); + } + + /** + * 命令封装 + * + * @author LiuHuiYu + * Created DateTime 2022-11-19 21:32 + */ + protected abstract void commandPackage(); + + /** + * 执行命令封装 + * @author LiuHuiYu + * Created DateTime 2023-05-06 11:42 + */ + public void runCommandPackage() { + this.commandPackage(); + if (this.conditionalDepth != 0) { + throw new RuntimeException("条件层级未闭锁,请检查是否所有的 begin 都有 对应的 end。"); + } + } + + /** + * 功能描述 + * + * @param minFieldName 最大值字段 + * @param maxFieldName 最小值字段 + * @return com.liuhuiyu.jpa.oracle.dao.OracleBaseView.SqlCommandPackage.Condition + * @author LiuHuiYu + * Created DateTime 2023-03-29 9:25 + */ + public Condition conditionAnd(String minFieldName, String maxFieldName) { + Condition f = new Condition<>(this); + f.minFieldName = minFieldName; + f.maxFieldName = maxFieldName; + f.condition = " AND "; + return f; + } + + /** + * 条件生成 + * + * @param fieldName 字段名称 + * @return com.liuhuiyu.jpa.oracle.dao.OracleBaseView.SqlCommandPackage.Condition + * @author LiuHuiYu + * Created DateTime 2023-02-23 23:56 + */ + public Condition conditionAnd(String fieldName) { + Condition f = new Condition<>(this); + f.fieldName = fieldName; + f.condition = " AND "; + return f; + } + + public Condition conditionOr(String minFieldName, String maxFieldName) { + Condition f = new Condition<>(this); + f.minFieldName = minFieldName; + f.maxFieldName = maxFieldName; + f.condition = " OR "; + return f; + } + + /** + * 条件生成 + * + * @param fieldName 字段名称 + * @return com.liuhuiyu.jpa.oracle.dao.OracleBaseView.SqlCommandPackage.Condition + * @author LiuHuiYu + * Created DateTime 2023-02-23 23:56 + */ + public Condition conditionOr(String fieldName) { + Condition f = new Condition<>(this); + f.fieldName = fieldName; + f.condition = " OR "; + return f; + } + + @Deprecated + public Condition conditionNone(String fieldName) { + Condition f = new Condition<>(this); + f.fieldName = fieldName; + f.condition = ""; + return f; + } + + int conditionalDepth = 0; + + public SqlCommandPackage conditionalBeginAnd() { + this.conditionalDepth++; + this.sqlBuilder.append("AND("); + return this; + } + + public Condition conditionalBeginAnd(String fieldName) { + this.conditionalDepth++; + this.sqlBuilder.append("AND("); + Condition f = new Condition<>(this); + f.fieldName = fieldName; + f.condition = ""; + return f; + } + + public Condition conditionalBeginAnd(String minFieldName, String maxFieldName) { + this.conditionalDepth++; + this.sqlBuilder.append("AND("); + Condition f = new Condition<>(this); + f.minFieldName = minFieldName; + f.maxFieldName = maxFieldName; + f.condition = ""; + return f; + } + + public SqlCommandPackage conditionalBeginOr() { + this.conditionalDepth++; + this.sqlBuilder.append("OR("); + return this; + } + + public Condition conditionalBeginOr(String fieldName) { + this.conditionalDepth++; + this.sqlBuilder.append("OR("); + Condition f = new Condition<>(this); + f.fieldName = fieldName; + f.condition = ""; + return f; + } + + public Condition conditionalBeginOr(String minFieldName, String maxFieldName) { + this.conditionalDepth++; + this.sqlBuilder.append("OR("); + Condition f = new Condition<>(this); + f.minFieldName = minFieldName; + f.maxFieldName = maxFieldName; + f.condition = ""; + return f; + } + + public SqlCommandPackage conditionalEnd() { + if (this.conditionalDepth <= 0) { + throw new RuntimeException("条件层级不能为负"); + } + this.conditionalDepth--; + this.sqlBuilder.append(")"); + return this; + } + + protected static class Condition { + final SqlCommandPackage sqlCommandPackage; + String fieldName; + String minFieldName; + String maxFieldName; + String condition; + + private void checkField() { + if (!StringUtils.hasText(fieldName)) { + throw new RuntimeException("未设定字段名称"); + } + } + + private void checkField2() { + if (!StringUtils.hasText(minFieldName) || !StringUtils.hasText(maxFieldName)) { + throw new RuntimeException("双字段名称设定不完整。"); + } + } + + private Condition(SqlCommandPackage sqlCommandPackage) { + this.sqlCommandPackage = sqlCommandPackage; + } + + /** + * like值 + * + * @param value 值 + * @param parameterName 参数名称 + * @author LiuHuiYu + * Created DateTime 2022-06-02 18:43 + */ + public SqlCommandPackage likeValue(String parameterName, String value) { + return likeValue(parameterName, value, true, true, true); + } + + /** + * like值 + * + * @param value 值 + * @param parameterName 参数名称 + * @param trim 去掉首尾空格 + * @param head 头部模糊匹配 + * @param tail 尾部模糊匹配 + * @author LiuHuiYu + * Created DateTime 2022-06-02 18:43 + */ + public SqlCommandPackage likeValue(String parameterName, String value, Boolean trim, Boolean head, Boolean tail) { + this.checkField(); + if (value == null) { + return this.sqlCommandPackage; + } + final String s = (head ? "%" : "") + (trim ? value.trim() : value) + (tail ? "%" : ""); + this.sqlCommandPackage.sqlBuilder.append(condition).append("(").append(this.fieldName).append(" LIKE :").append(parameterName).append(")"); + this.sqlCommandPackage.parameterMap.put(parameterName, s); + return this.sqlCommandPackage; + } + + /** + * 封装 in 条件 + * + * @param parameterName 参数名称头 + * @param data 查询的数据 + * @author LiuHuiYu + * Created DateTime 2022-11-20 8:28 + */ + public

SqlCommandPackage inPackage(String parameterName, P[] data) { + return inPackage(parameterName, data, false, false); + } + + /** + * 封装 in 条件 + * + * @param parameterName 参数名称头 + * @param data 查询的数据 + * @param notIn 使用 not in + * @param isNull 包含空 OR(fieldName is null) + * @author LiuHuiYu + * Created DateTime 2022-11-20 8:28 + */ + public

SqlCommandPackage inPackage(String parameterName, P[] data, Boolean notIn, Boolean isNull) { + this.checkField(); + if (data != null && data.length > 0) { + Joiner joiner = Joiner.on(",").skipNulls(); + String[] names = new String[data.length]; + this.sqlCommandPackage.sqlBuilder.append(condition).append("((").append(fieldName).append(notIn ? " NOT" : "").append(" IN("); + for (int i = 0; i < data.length; i++) { + names[i] = ":" + parameterName + i; + this.sqlCommandPackage.parameterMap.put(parameterName + i, data[i]); + } + this.sqlCommandPackage.sqlBuilder.append(joiner.join(names)).append("))"); + if (isNull) { + this.sqlCommandPackage.sqlBuilder.append("OR(").append(fieldName).append(" is null)"); + } + this.sqlCommandPackage.sqlBuilder.append(")"); + } + return this.sqlCommandPackage; + } + + public

SqlCommandPackage between(String beginParameterName, P beginValue, String endParameterName, P endValue) { + this.checkField(); + if (beginValue == null || endValue == null) { + return this.sqlCommandPackage; + } + this.sqlCommandPackage.sqlBuilder.append(condition) + .append("(").append(this.fieldName) + .append(" between :").append(beginParameterName) + .append(" and :") + .append(endParameterName) + .append(")"); + this.sqlCommandPackage.parameterMap.put(beginParameterName, beginValue); + this.sqlCommandPackage.parameterMap.put(endParameterName, endValue); + return this.sqlCommandPackage; + } + + /** + * 封装 数据段互相包含(开区间 位置相同)条件 + * + * @param minParameterName 最小值参数名 + * @param maxParameterName 最大值参数名 + * @param minValue 最小值 + * @param maxValue 最大值 + * @author LiuHuiYu + * Created DateTime 2022-12-01 10:23 + */ + public

SqlCommandPackage inclusion(String minParameterName, String maxParameterName, P minValue, P maxValue) { + this.checkField2(); + if (minValue == null || maxValue == null) { + return this.sqlCommandPackage; + } + this.sqlCommandPackage.sqlBuilder.append(condition).append(" ("); + this.sqlCommandPackage.sqlBuilder.append("((").append(minFieldName).append(" < :").append(minParameterName).append(") and (") + .append(maxFieldName).append(" > :").append(minParameterName).append("))"); + this.sqlCommandPackage.sqlBuilder.append("or"); + this.sqlCommandPackage.sqlBuilder.append("((").append(minFieldName).append(" < :").append(maxParameterName).append(") and (") + .append(maxFieldName).append(" > :").append(maxParameterName).append("))"); + this.sqlCommandPackage.sqlBuilder.append("or"); + this.sqlCommandPackage.sqlBuilder.append("((").append(minFieldName).append(" >= :").append(minParameterName).append(") and (") + .append(maxFieldName).append(" <= :").append(maxParameterName).append("))"); + this.sqlCommandPackage.sqlBuilder.append(")"); + this.sqlCommandPackage.parameterMap.put(minParameterName, minValue); + this.sqlCommandPackage.parameterMap.put(maxParameterName, maxValue); + return this.sqlCommandPackage; + } + + /** + * 等于 + * + * @param parameterName 参数名 + * @param value 值 + * @author LiuHuiYu + * Created DateTime 2023-02-23 23:51 + */ + public

SqlCommandPackage eq(String parameterName, P value) { + return this.generate("=", parameterName, value); + } + + /** + * <> 比较 + * + * @param parameterName 参数名称 + * @param value 值 + * @author LiuHuiYu + * Created DateTime 2023-03-25 9:23 + */ + public

SqlCommandPackage ne(String parameterName, P value) { + return this.generate("<>", parameterName, value); + } + + /** + * > 比较 + * + * @param parameterName 参数名称 + * @param value 值 + * @author LiuHuiYu + * Created DateTime 2023-03-25 9:23 + */ + public

SqlCommandPackage gt(String parameterName, P value) { + return this.generate(">", parameterName, value); + } + + /** + * < 比较 + * + * @param parameterName 参数名称 + * @param value 值 + * @author LiuHuiYu + * Created DateTime 2023-03-25 9:23 + */ + public

SqlCommandPackage lt(String parameterName, P value) { + return this.generate("<", parameterName, value); + } + + /** + * >= 比较 + * + * @param parameterName 参数名称 + * @param value 值 + * @author LiuHuiYu + * Created DateTime 2023-03-25 9:23 + */ + public

SqlCommandPackage ge(String parameterName, P value) { + return this.generate(">=", parameterName, value); + } + + /** + * <= 比较 + * + * @param parameterName 参数名称 + * @param value 值 + * @author LiuHuiYu + * Created DateTime 2023-03-25 9:23 + */ + public

SqlCommandPackage le(String parameterName, P value) { + return this.generate("<=", parameterName, value); + } + + /** + * 为 null + * + * @author LiuHuiYu + * Created DateTime 2023-03-25 9:23 + */ + public SqlCommandPackage isNull() { + this.checkField(); + this.sqlCommandPackage.sqlBuilder + .append(condition) + .append("(").append(this.fieldName) + .append(" is null )"); + return this.sqlCommandPackage; + } + + /** + * 为 null + * + * @author LiuHuiYu + * Created DateTime 2023-03-25 9:23 + */ + public SqlCommandPackage isNotNull() { + this.checkField(); + this.sqlCommandPackage.sqlBuilder + .append(condition) + .append("(").append(this.fieldName) + .append(" is not null )"); + return this.sqlCommandPackage; + } + + private

SqlCommandPackage generate(String operator, String parameterName, P value) { + this.checkField(); + if (value != null) { + this.sqlCommandPackage.sqlBuilder + .append(condition) + .append("(").append(this.fieldName) + .append(" ").append(operator) + .append(" :").append(parameterName).append(")"); + this.sqlCommandPackage.parameterMap.put(parameterName, value); + } + return this.sqlCommandPackage; + } + /* + * eq 就是 equal等于 +ne就是 not equal不等于 +gt 就是 greater than大于 +lt 就是 less than小于 +ge 就是 greater than or equal 大于等于 +le 就是 less than or equal 小于等于 +in 就是 in 包含(数组) +isNull 就是 等于null +*between 就是 在2个条件之间(包括边界值) +*like就是 模糊查询 + * */ + } + } +} diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/oracle/dao/OracleOrder.java b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/dao/OracleOrder.java new file mode 100644 index 0000000..061856d --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/dao/OracleOrder.java @@ -0,0 +1,70 @@ +package com.liuhuiyu.jpa.oracle.dao; + +import com.liuhuiyu.dto.Sort; +import org.springframework.util.StringUtils; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; + +/** + * oracle 排序生成 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-03-26 21:17 + */ +public class OracleOrder { + Map orderMap = new HashMap<>(); + String defOrder; + + /** + * 排序 + * + * @param defOrder 默认排序字段及排序 + * @author LiuHuiYu + * Created DateTime 2023-03-26 21:40 + */ + public OracleOrder(String defOrder) { + this.defOrder = defOrder; + } + + public OracleOrder(String field, Sort.Direction direction) { + this.defOrder = field + " " + direction; + } + + public OracleOrder addOrder(String key, String value) { + orderMap.put(key.toUpperCase(), value); + return this; + } + + public String getOrder(List sortList) { + StringBuilder orderBuilder = new StringBuilder(" ORDER BY "); + AtomicReference delimiter = new AtomicReference<>(""); + if (sortList != null && sortList.size() > 0) { + sortList.stream().sorted(Comparator.comparingInt(Sort::getIndex)) + .peek(v -> v.setName(v.getName().toUpperCase())) + .forEachOrdered(v -> { + if (orderMap.containsKey(v.getName())) { + orderBuilder + .append(delimiter) + .append(orderMap.get(v.getName())) + .append(" ") + .append(v.getDirection()); + delimiter.set(","); + } + }); + } + if (!StringUtils.hasText(delimiter.get())) { + if (StringUtils.hasText(this.defOrder)) { + orderBuilder.append(defOrder); + } + else { + return ""; + } + } + return orderBuilder.toString(); + } +} diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/oracle/entity/BaseAccountOperate.java b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/entity/BaseAccountOperate.java new file mode 100644 index 0000000..47ec3e0 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/entity/BaseAccountOperate.java @@ -0,0 +1,157 @@ +package com.liuhuiyu.jpa.oracle.entity; + +import com.liuhuiyu.dto.IDataChange; +import com.liuhuiyu.jpa.entity.IUniversallyUniqueIdentifier; +import com.liuhuiyu.jpa.oracle.comment.Comment; + +import javax.persistence.Column; +import javax.persistence.MappedSuperclass; +import java.sql.Timestamp; + +/** + * 账号操作基础类 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-12-07 17:03 + */ + +@MappedSuperclass +public abstract class BaseAccountOperate implements IUniversallyUniqueIdentifier { + + //region 添加修改删除 标准字段 + /** + * 创建时间 + */ + @Column(columnDefinition = " DATE default sysdate") + @Comment("创建时间") + private Timestamp createTime; + /** + * 创建人Id + */ + @Column(columnDefinition = " CHAR(" + COLUMN_ID_MAX_LENGTH + ")") + @Comment("创建人Id") + private String creatorId; + /** + * 更新时间 + */ + @Column(columnDefinition = " DATE default sysdate") + @Comment("更新时间") + private Timestamp updateTime; + /** + * 更新人Id + */ + @Column(columnDefinition = " CHAR(" + COLUMN_ID_MAX_LENGTH + ")") + @Comment("更新人Id") + private String updaterId; + /** + * 删除标记 + */ + @Column(columnDefinition = " CHAR(1) default '0'") + @Comment("删除标记(0:未删除;1:删除)") + private boolean deleteMark; + /** + * 删除时间 + */ + @Comment("删除时间") + private Timestamp deleteTime; + /** + * 删除人Id + */ + @Column(columnDefinition = " CHAR(" + COLUMN_ID_MAX_LENGTH + ")") + @Comment("删除人Id") + private String deleterId; + //endregion + + public Timestamp getCreateTime() { + return createTime; + } + + public void setCreateTime(Timestamp createTime) { + this.createTime = createTime; + } + + public String getCreatorId() { + return creatorId; + } + + public void setCreatorId(String creatorId) { + this.creatorId = creatorId; + } + + public Timestamp getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Timestamp updateTime) { + this.updateTime = updateTime; + } + + public String getUpdaterId() { + return updaterId; + } + + public void setUpdaterId(String updaterId) { + this.updaterId = updaterId; + } + + public boolean isDeleteMark() { + return deleteMark; + } + + public void setDeleteMark(boolean deleteMark) { + this.deleteMark = deleteMark; + } + + public Timestamp getDeleteTime() { + return deleteTime; + } + + public void setDeleteTime(Timestamp deleteTime) { + this.deleteTime = deleteTime; + } + + public String getDeleterId() { + return deleterId; + } + + public void setDeleterId(String deleterId) { + this.deleterId = deleterId; + } + + public void createOperate(String creatorId) { + this.createTime = new Timestamp(System.currentTimeMillis()); + this.creatorId = creatorId; + this.updateTime = new Timestamp(System.currentTimeMillis()); + this.updaterId = creatorId; + this.deleteMark = false; + this.deleterId = null; + this.deleteTime = null; + } + + public void createOperate(IDataChange operator) { + this.createOperate(operator.getOperating().getOperatorId()); + } + + public void updateOperate(String updaterId) { + this.updateTime = new Timestamp(System.currentTimeMillis()); + this.updaterId = updaterId; + this.deleteMark = false; + this.deleterId = null; + this.deleteTime = null; + } + + public void updateOperate(IDataChange operator) { + this.updateOperate(operator.getOperating().getOperatorId()); + } + + public void deleteOperate(String deleterId) { + this.deleteMark = true; + this.deleterId = deleterId; + this.deleteTime = new Timestamp(System.currentTimeMillis()); + } + + public void deleteOperate(IDataChange operator) { + this.deleteOperate(operator.getOperating().getOperatorId()); + } +} diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/oracle/package-info.java b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/package-info.java new file mode 100644 index 0000000..9cec26f --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/package-info.java @@ -0,0 +1,6 @@ +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-11-19 11:58 + */ +package com.liuhuiyu.jpa.oracle; \ No newline at end of file diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/oracle/util/DateBetween.java b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/util/DateBetween.java new file mode 100644 index 0000000..b745fd3 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/util/DateBetween.java @@ -0,0 +1,41 @@ +package com.liuhuiyu.jpa.oracle.util; + +import org.jetbrains.annotations.NotNull; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 时间范围结构 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * @deprecated 不需要那么麻烦了,直接使用 + * Created DateTime 2021-09-08 9:44 + */ +@Deprecated +public class DateBetween { + LocalDateTime startDateTime; + LocalDateTime endDateTime; + + public DateBetween(@NotNull LocalDateTime time1, @NotNull LocalDateTime time2) { + this.startDateTime = time1.isBefore(time2) ? time1 : time2; + this.endDateTime = time1.isAfter(time2) ? time1 : time2; + } + + public LocalDateTime getStartDateTime() { + return startDateTime; + } + + public LocalDateTime getEndDateTime() { + return endDateTime; + } + + public String oracleBetweenSql(String columnName) { + return "(" + columnName + " between to_date('" + + this.getStartDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + + "','yyyy-MM-dd hh24:mi:ss') and to_date('" + + this.getEndDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + + "','yyyy-MM-dd hh24:mi:ss'))"; + } +} diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/oracle/util/OracleDaoUtil.java b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/util/OracleDaoUtil.java new file mode 100644 index 0000000..5ba8486 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/oracle/util/OracleDaoUtil.java @@ -0,0 +1,91 @@ +package com.liuhuiyu.jpa.oracle.util; + +import com.liuhuiyu.dto.Paging; + +import java.util.Arrays; +import java.util.Locale; + +/** + * dao工具类 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-01-12 9:38 + */ +public class OracleDaoUtil { + /** + * oracle分页查询 + * + * @param sqlBuilder 原始sql + * @param paging 分页信息 + * @author LiuHuiYu + * Created DateTime 2022-01-12 9:39 + */ + public static void paginationOracleSql(StringBuilder sqlBuilder, Paging paging) { + String rowNumName; + for(int i=0;;i++){ + rowNumName = "rowno_" + i; + if(!sqlBuilder.toString().toLowerCase(Locale.ROOT).contains(rowNumName)){ + break; + } + } + sqlBuilder.insert(0, "SELECT * FROM (SELECT t_pagination.*, ROWNUM AS " + rowNumName + " FROM("); + sqlBuilder.append(") t_pagination WHERE ROWNUM <= ") + .append(paging.endRowNo()) + .append(") table_alias WHERE table_alias.") + .append(rowNumName) + .append(" >= ") + .append(paging.beginRowNo()); + } + + /** + * 将当前 sql查询语句转换成 统计数量的语句 + * 不支持复杂查询 + * + * @param sqlBuilder sql 字符串的 StringBuilder + * @author LiuHuiYu + * Created DateTime 2022-01-12 9:57 + */ + public static void countOracleSql(StringBuilder sqlBuilder) { + int index = sqlBuilder.toString().toLowerCase().indexOf(" from "); + sqlBuilder.replace(0, index, "select count(1)"); + } + + /** + * 将当前 sql查询语句转换成 统计数量的语句 + * 支持复杂查询(当前未开放,如果使用会出现错误) + * + * @param sqlBuilder sql 字符串的 StringBuilder + * @author LiuHuiYu + * @deprecated 未启用字符串分析 + * Created DateTime 2022-01-12 9:57 + */ + @Deprecated + public static void countOracleSql2(StringBuilder sqlBuilder) { + String fromString = " from "; + int f = 0; + int level = 0; + for (int i = 0; i < sqlBuilder.length(); i++) { + //字符串检测 + if (Arrays.asList('\'', '\"').contains(sqlBuilder.charAt(i))) { + throw new RuntimeException("当前解析无法解析包含字符串的sql语句"); + } + //包含检测 + if (sqlBuilder.charAt(i) == '(') { + level++; + } + else if (sqlBuilder.charAt(i) == ')') { + level--; + } + if (level < 0) { + throw new RuntimeException("输入的sql语句异常"); + } + +// if (f == fromString.length() && level == 0) { +// ; +// } + } + int index = sqlBuilder.toString().toLowerCase().indexOf(" from "); + sqlBuilder.replace(0, index, "select count(1)"); + } +} diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/util/DataBaseException.java b/jpa/src/main/java/com/liuhuiyu/jpa/util/DataBaseException.java new file mode 100644 index 0000000..827b190 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/util/DataBaseException.java @@ -0,0 +1,28 @@ +package com.liuhuiyu.jpa.util; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-08-11 10:27 + */ +public class DataBaseException extends RuntimeException { + + public DataBaseException() { + } + + public DataBaseException(String message) { + super(message); + } + + public DataBaseException(String message, Throwable cause) { + super(message, cause); + } + + public DataBaseException(Throwable cause) { + super(cause); + } + + public DataBaseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} \ No newline at end of file diff --git a/jpa/src/main/java/com/liuhuiyu/jpa/util/DataBaseUtil.java b/jpa/src/main/java/com/liuhuiyu/jpa/util/DataBaseUtil.java new file mode 100644 index 0000000..11fe94b --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/jpa/util/DataBaseUtil.java @@ -0,0 +1,31 @@ +package com.liuhuiyu.jpa.util; + +import java.io.BufferedReader; +import java.sql.Clob; +import java.sql.SQLException; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-08-11 9:59 + */ +public class DataBaseUtil { + public static String clobToString(Clob clob) throws SQLException { + // 得到流 + java.io.Reader is = clob.getCharacterStream(); + BufferedReader br = new BufferedReader(is); + StringBuilder sb = new StringBuilder(); + try { + String s = br.readLine(); + // 执行循环将字符串全部取出付值给StringBuffer由StringBuffer转成String + while (s != null) { + sb.append(s); + s = br.readLine(); + } + } + catch (Exception e) { + throw new DataBaseException(e); + } + return sb.toString(); + } +} diff --git a/jpa/src/main/java/com/liuhuiyu/view/ObjectArray.java b/jpa/src/main/java/com/liuhuiyu/view/ObjectArray.java new file mode 100644 index 0000000..5052267 --- /dev/null +++ b/jpa/src/main/java/com/liuhuiyu/view/ObjectArray.java @@ -0,0 +1,198 @@ +package com.liuhuiyu.view; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Clob; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.Locale; +import java.util.function.Function; + +/** + * 顺序获取对象序列 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-03-09 17:30 + */ +public class ObjectArray { + private final Object[] objects; + private int index = 0; + + public ObjectArray(Object obj) { + this.objects = (Object[]) obj; + } + + public void reset() { + this.index = 0; + } + + public Object get() { + if (this.index >= objects.length) { + throw new RuntimeException("当前要获取的数据数量" + (this.index + 1) + "超出了原始数据数量" + this.objects.length); + } + return objects[this.index++]; + } + + public String getString() { + return getString(""); + } + + public String getString(String defValue) { + return getT((obj) -> { + if (obj instanceof String) { + return (String) obj; + } + else if (obj instanceof Clob) { + Clob clob = (Clob) obj; + StringBuilder stringBuilder = new StringBuilder(); + try { + final long length = clob.length(); + int len = 1024; + for (long pos = 1; pos <= length; pos += len) { + len = (length - (pos-1)) >= len ? len : (int) (length - (pos-1)); + if (len > 0) { + stringBuilder.append(clob.getSubString(pos, len)); + } + else { + break; + } + } + } + catch (SQLException ignored) { + + } + return stringBuilder.toString(); + } + else { + return obj.toString(); + } + }, defValue); + } + + public Integer getInteger() { + return getInteger(0); + } + + public Integer getInteger(Integer defValue) { + return getT((obj) -> { + if (obj instanceof Number) { + return ((Number) obj).intValue(); + } + else { + return Integer.parseInt(obj.toString()); + } + }, defValue); + } + + public Long getLong() { + return getLong(0L); + } + + public Long getLong(Long defValue) { + return getT((obj) -> { + if (obj instanceof Number) { + return ((Number) obj).longValue(); + } + else { + return Long.parseLong(obj.toString()); + } + }, defValue); + } + + public Boolean getBoolean() { + return getBoolean(false); + } + + public Boolean getBoolean(Boolean defValue) { + return getT((obj) -> { + if (obj instanceof Boolean) { + return (Boolean) obj; + } + else if (obj instanceof Number) { + return ((Number) obj).intValue() == 1; + } + else if (obj instanceof String) { + String v = (String) obj; + return "y".equals(v.toLowerCase(Locale.ROOT)) || + "true".equals(v.toLowerCase(Locale.ROOT)) || + !"0".equals(v.toLowerCase(Locale.ROOT)); + } + else { + return Boolean.parseBoolean(obj.toString()); + } + }, defValue); + } + + public BigDecimal getBigDecimal() { + return getBigDecimal(new BigDecimal("0")); + } + + public BigDecimal getBigDecimal(BigDecimal defValue) { + return getT((obj) -> { + if (obj instanceof BigDecimal) { + return (BigDecimal) obj; + } + else if (obj instanceof Number) { + return new BigDecimal((obj).toString()); + } + else { + return new BigDecimal(obj.toString()); + } + }, defValue); + } + + + public Timestamp getTimestamp() { + return getTimestamp(Timestamp.valueOf(LocalDateTime.MIN)); + } + + public Timestamp getTimestamp(Timestamp defValue) { + return getT((obj) -> { + if (obj instanceof Timestamp) { + return (Timestamp) obj; + } + if ("oracle.sql.TIMESTAMP".equals(obj.getClass().getName())) { + return Timestamp.valueOf(obj.toString()); + } + else { + return defValue; + } + }, defValue); + } + + + public BigInteger getBigInteger() { + return getBigInteger(BigInteger.ZERO); + } + + public BigInteger getBigInteger(BigInteger defValue) { + return getT((obj) -> { + if (obj instanceof BigInteger) { + return (BigInteger) obj; + } + if (obj instanceof Number) { + return BigInteger.valueOf(((Number) obj).longValue()); + } + else { + return defValue; + } + }, defValue); + } + + private T getT(Function function, T defValue) { + Object obj = this.get(); + if (obj == null) { + return defValue; + } + else { + try { + return function.apply(obj); + } + catch (Exception ex) { + return defValue; + } + } + } +} diff --git a/jpa/src/main/resources/META-INF/spring.factories b/jpa/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..bed26c6 --- /dev/null +++ b/jpa/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.liuhuiyu.jpa.oracle.comment.CommentIntegrator,\ +com.liuhuiyu.jpa.oracle.comment.HibernateConfig +#com.liuhuiyu.jpa.BaseView diff --git a/jpa/src/test/java/com/liuhuiyu/AppTest.java b/jpa/src/test/java/com/liuhuiyu/AppTest.java new file mode 100644 index 0000000..9690d6b --- /dev/null +++ b/jpa/src/test/java/com/liuhuiyu/AppTest.java @@ -0,0 +1,51 @@ +package com.liuhuiyu; + +import com.liuhuiyu.jpa.DaoOperator; +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; + +import java.util.Collections; + + +/** + * Unit test for simple App. + */ +public class AppTest extends TestBase { + /** + * Rigorous Test :-) + */ + @Test + public void shouldAnswerWithTrue() { + Object obj = new Object[]{1, "abc"}; + Abc abc = new Abc(obj); + Abc def = objToClass(Abc::new, obj); + } + + private T objToClass(DaoOperator daoOperator, Object obj) { + return daoOperator.objectToT(obj); + } + + + static class Abc { + int index; + String name; + + public Abc(Object obj) { + Object[] objects = (Object[]) obj; + index = (int) objects[0]; + name = objects[1].toString(); + } + } + + @Test + public void out() { + LOG.info(String.join(";\n", Collections.nCopies(6, "{}")), 1, 2, 3, 4, 5, 6); + } + + @Test + public void sql() { + final String sql = "SELECT T.ID, T.AREA_ID, T.AREA_NAME, T.SITE_ID, T.SITE_NAME, T.PERSON_ID, T.ORIGINAL_PERSON_ID, T.PERSON_NAME, T.PERSON_PC_NO, T.COMPANY_NAME, T.FIRST_TIME, T.UPDATE_TIME, T.EXPIRATION_TIME" + + " FROM ZNAF_SITE_PERSON T"; + final String[] split = sql.split("[, ]"); + } +} \ No newline at end of file diff --git a/jpa/src/test/java/com/liuhuiyu/jpa/BaseViewTest.java b/jpa/src/test/java/com/liuhuiyu/jpa/BaseViewTest.java new file mode 100644 index 0000000..8960584 --- /dev/null +++ b/jpa/src/test/java/com/liuhuiyu/jpa/BaseViewTest.java @@ -0,0 +1,36 @@ +package com.liuhuiyu.jpa; + +import javax.sql.DataSource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-13 10:31 + */ +public class BaseViewTest extends BaseView { + public BaseViewTest(DataSource dataSource) { + super(dataSource); + } + + //region 封装测试 + public void test() { + Object inputObj = null; + String sql = ""; + Map parameterMap = new HashMap<>(); + final Long aLong = new SelectBuilder<>(sql).buildCount(); + final Optional o = new SelectBuilder<>((obj) -> obj, sql).buildFirst(); + final List objects = new SelectBuilder<>((obj) -> obj, sql) + .whereFull(inputObj, (inputO, sqlBuilder, map) -> { + }) + .buildList(); + final List objects1 = new SelectBuilder<>((obj) -> obj, sql) + .parameterMap(parameterMap) + .buildList(); + + } + //endregion +} \ No newline at end of file diff --git a/jpa/src/test/java/com/liuhuiyu/jpa/NamedParameterStatementTest.java b/jpa/src/test/java/com/liuhuiyu/jpa/NamedParameterStatementTest.java new file mode 100644 index 0000000..5f8585d --- /dev/null +++ b/jpa/src/test/java/com/liuhuiyu/jpa/NamedParameterStatementTest.java @@ -0,0 +1,113 @@ +package com.liuhuiyu.jpa; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-09-08 11:48 + */ +public class NamedParameterStatementTest { + private static final Logger LOG = LogManager.getLogger(NamedParameterStatementTest.class); + + @Test + public void s() { + Map paramsMap = new HashMap<>(); + String sql = "select count(1)\n" + + "from (SELECT t.ID,c.yzbh,t.RY_ZJHM,t.RY_XM,c.bmmc,t.RL_XSD,t.RL_ZPSJ,t.DZ_NAME,t.RL_IMG,t.RL_ZP_IMG_D,t.RL_ZP_IMG_X,\n" + + " row_number() over (partition by t.RYID order by RL_ZPSJ desc) rw\n" + + " FROM RL_YX_RLZP_LOG t\n" + + " left join RL_RY_KLOG c on t.ryk_id = c.id\n" + + " where (t.rl_zpsj between to_date('2021-09-07 00:00:00', 'yyyy-MM-dd HH24:mi:ss') and to_date('2021-09-08 23:59:59', 'yyyy-MM-dd HH24:mi:ss'))\n" + + " and (t.hk_8700_sjlx = '131668')\n" + + " and (t.RY_ZJHM LIKE :identificationNumber)) t\n" + + "where (t.rw = 1)"; + String regex = "((=[\\s+]|=|(LIKE)):(\\w+))"; + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(sql); +// paramsMap.clear(); + int idx = 1; + while (m.find()) { + //参数名称可能有重复,使用序号来做Key + paramsMap.put(idx++, m.group(m.groupCount())); + sql = sql.replace(m.group(), "?"); + } + LOG.info(sql); + LOG.info("{}", paramsMap.size()); +// sql = sql.replaceAll(regex, "=?"); +// log.info(sql); + } + + @Test + public void testParseSql2() { + String sql = "select count(1)\n" + + "from (SELECT t.ID,c.yzbh,t.RY_ZJHM,t.RY_XM,c.bmmc,t.RL_XSD,t.RL_ZPSJ,t.DZ_NAME,t.RL_IMG,t.RL_ZP_IMG_D,t.RL_ZP_IMG_X,\n" + + " row_number() over (partition by t.RYID order by RL_ZPSJ desc) rw\n" + + " FROM RL_YX_RLZP_LOG t\n" + + " left join RL_RY_KLOG c on t.ryk_id = c.id\n" + + " where (t.rl_zpsj between to_date('2021-09-07 00:00:00', 'yyyy-MM-dd HH24:mi:ss') and to_date('2021-09-08 23:59:59', 'yyyy-MM-dd HH24:mi:ss'))\n" + + " and (t.hk_8700_sjlx = ':ffff')\n" + + " and (t.RY_ZJHM LIKE :identificationNumber)) t\n" + + "where (t.rw = 1)"; + this.paramsMap = new HashMap<>(); + String outSql = parseSql2(sql); + LOG.info("sql={}", sql); + LOG.info("outSql={}", outSql); + LOG.info("paramsMap={}", paramsMap); + } + + private Map paramsMap; + + private String parseSql2(String query) { + int length = query.length(); + StringBuilder parsedQuery = new StringBuilder(length); + boolean inSingleQuote = false; + boolean inDoubleQuote = false; + int index = 1; + + for (int i = 0; i < length; i++) { + char c = query.charAt(i); + if (inSingleQuote) { + if (c == '\'') { + inSingleQuote = false; + } + } + else if (inDoubleQuote) { + if (c == '"') { + inDoubleQuote = false; + } + } + else { + if (c == '\'') { + inSingleQuote = true; + } + else if (c == '"') { + inDoubleQuote = true; + } + else if (c == ':' && + i + 1 < length && + Character.isJavaIdentifierStart(query.charAt(i + 1))) { + int j = i + 2; + while (j < length && Character.isJavaIdentifierPart(query.charAt(j))) { + j++; + } + String name = query.substring(i + 1, j); + c = '?'; // 用问号替换参数 + i += name.length(); // 如果参数是跳过结尾 + this.paramsMap.put(index++, name); + } + } + parsedQuery.append(c); + } + + return parsedQuery.toString(); + } +} \ No newline at end of file diff --git a/jpa/src/test/java/com/liuhuiyu/jpa/oracle/dao/OracleBaseViewDemo.java b/jpa/src/test/java/com/liuhuiyu/jpa/oracle/dao/OracleBaseViewDemo.java new file mode 100644 index 0000000..1bfabc2 --- /dev/null +++ b/jpa/src/test/java/com/liuhuiyu/jpa/oracle/dao/OracleBaseViewDemo.java @@ -0,0 +1,165 @@ +package com.liuhuiyu.jpa.oracle.dao; + +import com.liuhuiyu.dto.IPaging; +import org.springframework.data.domain.PageImpl; +import org.springframework.jdbc.datasource.AbstractDataSource; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; +import java.util.Map; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-02 8:56 + */ +public class OracleBaseViewDemo extends OracleBaseView { + + public static OracleBaseViewDemo getInstance() { + return new OracleBaseViewDemo(new AbstractDataSource() { + @Override + public Connection getConnection() throws SQLException { + throw new SQLException(""); + } + + @Override + public Connection getConnection(String username, String password) throws SQLException { + throw new SQLException(""); + } + }); + } + + public OracleBaseViewDemo(DataSource dataSource) { + super(dataSource); + } + + public List findList(IPaging pagingFind) { + return createPageImplBuilder(pagingFind).buildList(); + } + + public Object findOne(IPaging pagingFind) { + return createPageImplBuilder(pagingFind).buildFirstResult(); + } + + public PageImpl findPage(IPaging pagingFind) { + return new PageImplBuilder<>((o) -> new Object(), pagingFind, "SELECT * FROM AA T", this::fullWhere) + .setCountSql("SELECT count(0) FROM AA T") + .baseWhere("") + .order("").buildPage(); + } + + public PageImpl findPage2(IPaging pagingFind) { + return super.page((o) -> new Object(), pagingFind, "SELECT * FROM AA T", "WHERE(1=1)", "ORDER T.C", this::fullWhere); + } + + public PageImpl findPage3(IPaging pagingFind) { + return super.page((o) -> new Object(), pagingFind, "SELECT * FROM BB T", "WHERE(T.C=2)", "ORDER T.B", this::fullWhere); + } + + public Long findCount(IPaging pagingFind) { + return createPageImplBuilder(pagingFind).buildCount(); + } + + public Long findCount2(IPaging pagingFind) { + return super.count(pagingFind, "SELECT * from AA T", "WHERE(1=1)", this::fullWhere); + } + + public Long findCount3(IPaging pagingFind) { + return super.count(pagingFind, "SELECT * from AB T", "WHERE(2=2)", this::fullWhere); + } + + private PageImplBuilder createPageImplBuilder(IPaging pagingFind) { + return new PageImplBuilder<>((o) -> new Object(), pagingFind, "", this::fullWhere) + .baseWhere("") + .order(""); + } + + void fullWhere(IPaging pagingFind, StringBuilder sqlBuilder, Map parameterMap) { + OracleBaseViewTestSql oracleBaseViewTestSql = new OracleBaseViewTestSql(pagingFind, sqlBuilder, parameterMap); + oracleBaseViewTestSql.commandPackage(); + } + + static class OracleBaseViewTestSql extends SqlCommandPackage { + + /** + * SQL原生封装 构建函数 + * + * @param findDto 查询条件 + * @param sqlBuilder sqlBuilder + * @param parameterMap 参数 + * @author LiuHuiYu + * Created DateTime 2022-11-20 8:27 + */ + public OracleBaseViewTestSql(Object findDto, StringBuilder sqlBuilder, Map parameterMap) { + super(findDto, sqlBuilder, parameterMap); + } + + private void like0() { + super.conditionAnd("find0").likeValue("t.field0", "ab"); + } + + private void like1() { + super.conditionAnd("t.field1").likeValue("find1", "abc"); + } + + private void like2() { + super.conditionAnd("t.field2").likeValue("find2", "abcd", false, false, false); + } + + private void in0() { + super.conditionAnd("t.fieldInA").inPackage("inA", new String[]{"a"}); + super.conditionAnd("t.fieldInB").inPackage("inB", new String[]{"b"}); + //等效代码 + super.conditionAnd("t.fieldInB").inPackage("inB", new String[]{"a"}, false, false); + } + + private void in1() { + super.conditionAnd("t.fieldIn2").inPackage("in2", new String[]{"b"}, true, true); + } + + private void inclusion1() { + super.conditionAnd("t.min_value", "t.max_value").inclusion("minValue", "maxValue", 50, 100); + super.conditionAnd("t.min_value1", "t.max_value1").inclusion("minValue1", "maxValue1", 50, 100); + } + + private void inclusion2() { + super.conditionOr("t.min_v", "t.max_v").inclusion("minV", "maxV", 0.7, 1); + super.conditionOr("t.min_v1", "t.max_v1").inclusion("minV1", "maxV1", 0.7, 1); + } + + private void between() { + super.conditionAnd("t.A").between("vMin", 1, "vMax", 5); + } + + private void compare() { + super.conditionAnd("t.A").eq("v", 1) + .conditionAnd("t.B").ne("v", 1) + .conditionAnd("t.D").gt("v", 1) + .conditionAnd("t.C").ge("v", 1) + .conditionAnd("t.E").lt("v", 1) + .conditionAnd("t.F").le("v", 1) + .conditionOr("t.G").isNull() + .conditionOr("t.G1").isNull() + .conditionAnd("t.H").isNotNull() + .conditionalBeginAnd("T.I").isNull().conditionAnd("T.J").likeValue("j", "aaa") + .conditionalEnd() + .conditionalBeginOr("T.I").isNull().conditionOr("T.K").le("k", 99) + .conditionalEnd(); + } + + @Override + public void commandPackage() { + this.like0(); + this.like1(); + this.like2(); + this.in0(); + this.in1(); + this.inclusion1(); + this.inclusion2(); + this.between(); + this.compare(); + } + } +} \ No newline at end of file diff --git a/jpa/src/test/java/com/liuhuiyu/jpa/oracle/dao/OracleBaseViewTest.java b/jpa/src/test/java/com/liuhuiyu/jpa/oracle/dao/OracleBaseViewTest.java new file mode 100644 index 0000000..ebcc198 --- /dev/null +++ b/jpa/src/test/java/com/liuhuiyu/jpa/oracle/dao/OracleBaseViewTest.java @@ -0,0 +1,50 @@ +package com.liuhuiyu.jpa.oracle.dao; + +import com.liuhuiyu.dto.IPaging; +import com.liuhuiyu.dto.Paging; +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.PageImpl; + +import java.util.Collections; +import java.util.List; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-11-20 8:44 + */ +public class OracleBaseViewTest extends TestBase { + @BeforeEach + public void setup() { + throw new RuntimeException("此实例不能运行,需要数据库支持,仅作为演示使用。"); + } + + @Test + public void test() { + IPaging paging = new IPaging() { + @Override + public Paging getPaging() { + return null; + } + + @Override + public void setPaging(Paging paging) { + + } + }; + final OracleBaseViewDemo instance = OracleBaseViewDemo.getInstance(); + final Long count = instance.findCount(paging); + final Long count2 = instance.findCount2(paging); + final Long count3 = instance.findCount3(paging); + final List list = instance.findList(paging); + final Object one = instance.findOne(paging); + final PageImpl page = instance.findPage(paging); + final PageImpl page2 = instance.findPage2(paging); + final PageImpl page3 = instance.findPage3(paging); + + LOG.info(String.join("", Collections.nCopies(8, "{};\n")), count, count2, count3, list,one, page, page2, page3); + } + +} diff --git a/jpa/src/test/java/com/liuhuiyu/jpa/oracle/dao/OracleOrderTest.java b/jpa/src/test/java/com/liuhuiyu/jpa/oracle/dao/OracleOrderTest.java new file mode 100644 index 0000000..04b0f03 --- /dev/null +++ b/jpa/src/test/java/com/liuhuiyu/jpa/oracle/dao/OracleOrderTest.java @@ -0,0 +1,68 @@ +package com.liuhuiyu.jpa.oracle.dao; + +import com.liuhuiyu.dto.Sort; +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-03-26 21:41 + */ +class OracleOrderTest extends TestBase { + @DisplayName("排序测试") + @ParameterizedTest + @MethodSource("argumentsStream") + public void orderTest(String defOrder, Stream map, List sortList) { + OracleOrder oracleOrder = new OracleOrder(defOrder); + map.forEach(a -> { + oracleOrder.addOrder((String) a.get()[0], (String) a.get()[1]); + }); + final String order = oracleOrder.getOrder(sortList); + LOG.info(order); + } + + static Stream argumentsStream() { + return Stream.of( + Arguments.of("", Stream.of( + Arguments.of("A1", "t.a1"), + Arguments.of("a2", "t.a2"), + Arguments.of("a3", "t.a3") + ), Arrays.asList( + new Sort(10, "a1", Sort.Direction.ASC), + new Sort(2, "A3", Sort.Direction.DESC), + new Sort(3, "a7", Sort.Direction.ASC) + ) + ),Arguments.of("", Stream.of( + Arguments.of("a1", "t.a1"), + Arguments.of("a2", "t.a2"), + Arguments.of("a3", "t.a3") + ), Arrays.asList( + new Sort(10, "a11", Sort.Direction.ASC), + new Sort(2, "a13", Sort.Direction.DESC), + new Sort(3, "a7", Sort.Direction.ASC) + ) + ),Arguments.of("t.a8 DESC", Stream.of( + Arguments.of("a1", "t.a1"), + Arguments.of("a2", "t.a2"), + Arguments.of("a3", "t.a3") + ), Arrays.asList( + new Sort(10, "a11", Sort.Direction.ASC), + new Sort(2, "a13", Sort.Direction.DESC), + new Sort(3, "a7", Sort.Direction.ASC) + ) + ) + ); + } + +} \ No newline at end of file diff --git a/jpa/src/test/java/com/liuhuiyu/view/ObjectArrayTest.java b/jpa/src/test/java/com/liuhuiyu/view/ObjectArrayTest.java new file mode 100644 index 0000000..70fa8dc --- /dev/null +++ b/jpa/src/test/java/com/liuhuiyu/view/ObjectArrayTest.java @@ -0,0 +1,65 @@ +package com.liuhuiyu.view; + + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Test; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-04-02 8:19 + */ + +public class ObjectArrayTest { + private static final Logger LOG= LogManager.getLogger(ObjectArrayTest.class); + + @Test + public void get() { + Object object = new Object[]{1, 30_000_000_000L, "bbbb", true}; + ObjectArray objectArray = new ObjectArray(object); + LOG.info("原始:i={};l={},s={},b={}", 1, 30_000_000_000L, "bbbb", true); + int i = objectArray.getInteger(); + Long l = objectArray.getLong(); + String s = objectArray.getString(); + boolean b = objectArray.getBoolean(); + LOG.info("i l s b;i={};l={},s={},b={}", i, l, s, b); + objectArray.reset(); + b = objectArray.getBoolean(true); + i = objectArray.getInteger(18); + l = objectArray.getLong(100L); + s = objectArray.getString("NONE"); + LOG.info("b i l s i={};l={},s={},b={}", i, l, s, b); + objectArray.reset(); + s = objectArray.getString("NONE"); + b = objectArray.getBoolean(true); + i = objectArray.getInteger(18); + l = objectArray.getLong(100L); + LOG.info("s b i l i={};l={},s={},b={}", i, l, s, b); + objectArray.reset(); + s = objectArray.getString("NONE"); + i = objectArray.getInteger(18); + b = objectArray.getBoolean(true); + l = objectArray.getLong(100L); + LOG.info("s i b l i={};l={},s={},b={}", i, l, s, b); + } + + @Test + public void get2() { + int r1 = 1_000_000_000; + Object object = new Object[]{1, 30_000_000_000L, "bbbb", true}; + ObjectArray objectArray = new ObjectArray(object); + int i = 0; + Long l = 0L; + String s = ""; + boolean b = false; + for (int r = 0; r <= r1; r++) { + objectArray.reset(); + i = objectArray.getInteger(); + l = objectArray.getLong(); + s = objectArray.getString(); + b = objectArray.getBoolean(); + } + LOG.info("s i b l i={};l={},s={},b={}", i, l, s, b); + } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/core.iml b/model/liuhuiyu-core/core.iml new file mode 100644 index 0000000..2310917 --- /dev/null +++ b/model/liuhuiyu-core/core.iml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/model/liuhuiyu-core/pom.xml b/model/liuhuiyu-core/pom.xml new file mode 100644 index 0000000..617b676 --- /dev/null +++ b/model/liuhuiyu-core/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + core + liuhuiyu-tool-core + 2023.0.1 + 无依赖工具包 + + com.liuhuiyu + liuhuiyu-tool-parent + 2023.0.1 + + + 8 + 8 + UTF-8 + 1.8.0 + + + + + com.liuhuiyu + liuhuiyu-test + 2023.0.1 + test + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + -Xdoclint:none + + + + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + \ No newline at end of file diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeData.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeData.java new file mode 100644 index 0000000..7993f80 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeData.java @@ -0,0 +1,159 @@ +package com.liuhuiyu.core.data.change; + +import java.util.Locale; + +/** + * 变更数据模型 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-07 12:38 + */ +public class ChangeData { + T data; + T oldData; + DataStatus dataStatus; + String changeModel; + + /** + * 变更数据模型 + * + * @param data 数据信息 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:07 + */ + public ChangeData(T data) { + this(null, data, null, null); + } + + /** + * 变更数据模型 + * + * @param data 数据信息 + * @param dataStatus 数据状态 + * @param changeModel 数据模式 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:07 + */ + public ChangeData(T data, DataStatus dataStatus, String changeModel) { + this(null, data, dataStatus, changeModel); + } + + /** + * 变更数据模型 + * + * @param data 数据信息 + * @param dataStatus 数据状态 + * @param changeModel 数据模式 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:07 + */ + public ChangeData(T oldData, T data, DataStatus dataStatus, String changeModel) { + this.oldData = oldData; + this.data = data; + this.dataStatus = dataStatus == null ? DataStatus.U : dataStatus; + this.changeModel = changeModel == null ? "" : changeModel; + } + + /** + * 获取数据 + * + * @return T + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:07 + */ + public T getData() { + return data; + } + + public T getOldData() { + return oldData; + } + + /** + * 获取数据状态 + * + * @return com.liuhuiyu.core.data.change.ChangeData.DataStatus + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:07 + */ + public DataStatus getDataStatus() { + return dataStatus; + } + + /** + * 获取更新模式 + * + * @return java.lang.String + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:07 + */ + public String getChangeModel() { + return changeModel; + } + + /** + * 是指定的更新模式 + * + * @param changeModel 更新模式名称 + * @return boolean + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:06 + */ + public boolean isChangeModel(String changeModel) { + return this.changeModel.equals(changeModel); + } + + /** + * 记录行状态 + * + * @author LiuHuiYu + * Created DateTime 2022-05-02 7:45 + */ + public enum DataStatus { + /** + * 添加 + */ + A, + /** + * 修改 + */ + E, + /** + * 删除 + */ + D, + /** + * 未知 + */ + U; + + DataStatus() { + } + + public boolean isAdd() { + return this.equals(A); + } + + public boolean isUpdate() { + return this.equals(E); + } + + public boolean isDelete() { + return this.equals(D); + } + + public boolean isUnknown() { + return this.equals(U); + } + + public static DataStatus fromString(String value) { + try { + return valueOf(value.toUpperCase(Locale.US)); + } + catch (Exception var2) { + throw new IllegalArgumentException(String.format("Invalid value '%s' for orders given! Has to be either 'A' 'E' 'D' 'U' (case insensitive).", value), var2); + } + } + } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeNotice.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeNotice.java new file mode 100644 index 0000000..35b04e7 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeNotice.java @@ -0,0 +1,84 @@ +package com.liuhuiyu.core.data.change; + +import com.liuhuiyu.core.thread.ThreadPoolExecutorBuilder; +import com.liuhuiyu.core.util.IgnoredException; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; + +/** + * 更新通知 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-07 14:13 + */ +public class ChangeNotice { + private final Object sender; + final ExecutorService executorService; + private final Map> noticeMap = new HashMap<>(0); + + public ChangeNotice(Object sender) { + this.sender = sender; + this.executorService = ThreadPoolExecutorBuilder.create().builder(); + } + + /** + * 注册 + * + * @param iChangeNotice 注册的对象 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:05 + */ + public void reg(IChangeNotice iChangeNotice) { + this.noticeMap.put(iChangeNotice.getKey(), iChangeNotice); + } + + /** + * 注销通知 + * + * @param iChangeNotice 注销的对象 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:05 + */ + public void unReg(IChangeNotice iChangeNotice) { + this.noticeMap.remove(iChangeNotice.getKey()); + } + + /** + * 数据更新通知 + * + * @param data 变更的数据 + * @param dataStatus 变更数据的状态 + * @param changeModel 更新模式 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:04 + */ + public void changeNotice(T data, ChangeData.DataStatus dataStatus, String changeModel) { + this.noticeMap.forEach((key, item) -> IgnoredException.run(() -> this.executorService.execute(() -> item.changeNotice(sender, new ChangeData<>(data, dataStatus, changeModel))))); + } + + /** + * 数据更新通知 + * + * @param data 变更的数据 + * @param dataStatus 变更数据的状态 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:04 + */ + public void changeNotice(T data, ChangeData.DataStatus dataStatus) { + this.changeNotice(data, dataStatus, null); + } + + /** + * 数据更新通知 + * + * @param data 变更的数据 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:03 + */ + public void changeNotice(T data) { + this.changeNotice(data, null, null); + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeNoticeBaseImpl.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeNoticeBaseImpl.java new file mode 100644 index 0000000..da1819d --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeNoticeBaseImpl.java @@ -0,0 +1,48 @@ +package com.liuhuiyu.core.data.change; + +import java.util.function.Consumer; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-23 14:16 + */ +public class ChangeNoticeBaseImpl implements IChangeNotice { + private final String key; + private final Consumer> consumer; + + public ChangeNoticeBaseImpl(String key, Consumer> consumer) { + this.key = key; + this.consumer = consumer; + } + + @Override + public String getKey() { + return this.key; + } + + @Override + public void changeNotice(Object sender, ChangeData changeData) { + if (this.consumer != null) { + this.consumer.accept(new Data<>(sender, changeData)); + } + } + + public static class Data { + Object sender; + ChangeData changeData; + + public Data(Object sender, ChangeData changeData) { + this.sender = sender; + this.changeData = changeData; + } + + public Object getSender() { + return sender; + } + + public ChangeData getChangeData() { + return changeData; + } + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeNoticeManage.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeNoticeManage.java new file mode 100644 index 0000000..6c7b492 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeNoticeManage.java @@ -0,0 +1,40 @@ +package com.liuhuiyu.core.data.change; + +/** + * 更新数据管理 + * 不建议使用 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-07 12:45 + */ +@Deprecated +public class ChangeNoticeManage { + + private final ChangeNotice changeNotice; + + public ChangeNoticeManage(ChangeNotice changeNotice) { + this.changeNotice = changeNotice; + } + + /** + * 注册 + * + * @param iChangeNotice 注册的对象 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:05 + */ + public void reg(IChangeNotice iChangeNotice) { + this.changeNotice.reg(iChangeNotice); + } + + /** + * 注销通知 + * + * @param iChangeNotice 注销的对象 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:05 + */ + public void unReg(IChangeNotice iChangeNotice) { + this.changeNotice.unReg(iChangeNotice); + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeNoticeVectorImpl.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeNoticeVectorImpl.java new file mode 100644 index 0000000..85a975a --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/ChangeNoticeVectorImpl.java @@ -0,0 +1,59 @@ +package com.liuhuiyu.core.data.change; + +import java.util.Vector; +import java.util.function.Consumer; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-23 14:29 + */ +public class ChangeNoticeVectorImpl implements IChangeNotice { + private final String key; + private final Consumer> consumer; + Vector> vector; + + public ChangeNoticeVectorImpl(String key, Consumer> consumer) { + this.vector = new Vector<>(0); + this.key = key; + this.consumer = consumer; + } + + private void run() { + synchronized (this) { + while (this.vector.size() > 0) { + this.consumer.accept(this.vector.get(0)); + this.vector.remove(0); + } + } + } + + @Override + public String getKey() { + return this.key; + } + + @Override + public void changeNotice(Object sender, ChangeData changeData) { + this.vector.add(new Data<>(sender, changeData)); + this.run(); + } + + public static class Data { + Object sender; + ChangeData changeData; + + public Data(Object sender, ChangeData changeData) { + this.sender = sender; + this.changeData = changeData; + } + + public Object getSender() { + return sender; + } + + public ChangeData getChangeData() { + return changeData; + } + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/IChangeNotice.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/IChangeNotice.java new file mode 100644 index 0000000..b7a319e --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/IChangeNotice.java @@ -0,0 +1,25 @@ +package com.liuhuiyu.core.data.change; + +/** + * 数据变更通知接口 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-07 12:36 + */ +public interface IChangeNotice { + /** + * 注册key + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:02 + * @return java.lang.String + */ + String getKey(); + /** + * 功能描述 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:02 + * @param sender 消息发送者 + * @param changeData 更新的数据信息 + */ + void changeNotice(Object sender,ChangeData changeData); +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/IChangeNoticeReg.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/IChangeNoticeReg.java new file mode 100644 index 0000000..8470166 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/IChangeNoticeReg.java @@ -0,0 +1,12 @@ +package com.liuhuiyu.core.data.change; + +/** + * 数据变更通知注册 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-03-14 22:00 + */ +public interface IChangeNoticeReg { + void changeNoticeReg(IChangeNotice iChangeNotice); +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/package-info.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/package-info.java new file mode 100644 index 0000000..04b8705 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/change/package-info.java @@ -0,0 +1,9 @@ +/** + * 数据变更通知 + * [接口] + * [实现类] + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-07 12:34 + */ +package com.liuhuiyu.core.data.change; \ No newline at end of file diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionConsumerBaseImpl.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionConsumerBaseImpl.java new file mode 100644 index 0000000..334402a --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionConsumerBaseImpl.java @@ -0,0 +1,39 @@ +package com.liuhuiyu.core.data.collection; + +import com.liuhuiyu.core.thread.ThreadPoolExecutorBuilder; + +import java.util.concurrent.ExecutorService; +import java.util.function.Consumer; + +/** + * 基础采集数据消费者(无序) + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-03-30 21:04 + */ +public class CollectionConsumerBaseImpl implements ICollectionConsumer { + private final String key; + private final Consumer> consumer; + private ExecutorService executorService; + public CollectionConsumerBaseImpl(String key, Consumer> consumer) { + this.key = key; + this.consumer = consumer; + this.executorService = ThreadPoolExecutorBuilder.create().threadName("ConsumerBase").builder(); + } + + public void setExecutorService(ExecutorService executorService) { + this.executorService = executorService; + } + + @Override + public String getKey() { + return this.key; + } + + @Override + public void collectionNotice(Object sender, CollectionData changeData) { + if (this.consumer != null) { + this.executorService.execute(() -> this.consumer.accept(new CollectionConsumerData<>(sender, changeData))); + } + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionConsumerData.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionConsumerData.java new file mode 100644 index 0000000..923f68b --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionConsumerData.java @@ -0,0 +1,26 @@ +package com.liuhuiyu.core.data.collection; + +/** + * 采集消费数据 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-03-31 8:01 + */ +public class CollectionConsumerData { + Object sender; + CollectionData collectionData; + + public CollectionConsumerData(Object sender, CollectionData collectionData) { + this.sender = sender; + this.collectionData = collectionData; + } + + public Object getSender() { + return sender; + } + + public CollectionData getCollectionData() { + return collectionData; + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionConsumerVectorImpl.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionConsumerVectorImpl.java new file mode 100644 index 0000000..6f1df0c --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionConsumerVectorImpl.java @@ -0,0 +1,56 @@ +package com.liuhuiyu.core.data.collection; + +import com.liuhuiyu.core.thread.ThreadPoolExecutorBuilder; + +import java.util.Vector; +import java.util.concurrent.ExecutorService; +import java.util.function.Consumer; + +/** + * 采集数据消费者(有序) + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-03-30 21:10 + */ +public class CollectionConsumerVectorImpl implements ICollectionConsumer { + private final String key; + private final Consumer> consumer; + Vector> vector; + private ExecutorService executorService; + + public CollectionConsumerVectorImpl(String key, Consumer> consumer) { + this.vector = new Vector<>(0); + this.key = key; + this.consumer = consumer; + this.executorService = ThreadPoolExecutorBuilder.create().threadName("ConsumerVector").builder(); + } + + public void setExecutorService(ExecutorService executorService) { + this.executorService = executorService; + } + + private void run() { + synchronized (this) { + while (this.vector.size() > 0) { + this.consumer.accept(this.vector.get(0)); + this.vector.remove(0); + } + } + } + + @Override + public String getKey() { + return this.key; + } + + @Override + public void collectionNotice(Object sender, CollectionData changeData) { + if (this.consumer != null) { + this.executorService.execute(() -> { + this.vector.add(new CollectionConsumerData<>(sender, changeData)); + this.run(); + }); + } + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionData.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionData.java new file mode 100644 index 0000000..b3be987 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionData.java @@ -0,0 +1,38 @@ +package com.liuhuiyu.core.data.collection; + +/** + * 采集到的数据 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-03-30 20:45 + */ +public class CollectionData { + T data; + String collectionModel; + + public CollectionData(T data, String collectionModel) { + this.data = data; + this.collectionModel = collectionModel; + } + + public T getData() { + return data; + } + + public String getCollectionModel() { + return collectionModel; + } + + /** + * 采集的模式 + * + * @param modelName 更新模式名称 + * @return boolean + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:06 + */ + public boolean isCollectionModel(String modelName) { + return this.collectionModel != null && this.collectionModel.equals(modelName); + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionNotice.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionNotice.java new file mode 100644 index 0000000..8730757 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/CollectionNotice.java @@ -0,0 +1,79 @@ +package com.liuhuiyu.core.data.collection; + +import com.liuhuiyu.core.thread.ThreadPoolExecutorBuilder; +import com.liuhuiyu.core.util.IgnoredException; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; + +/** + * 数据采集通知 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-03-30 20:50 + */ +public class CollectionNotice implements ICollectionNoticeReg { + private final Object sender; + private ExecutorService executorService; + private final Map> noticeMap = new HashMap<>(0); + + public CollectionNotice(Object sender) { + this.sender = sender; + this.executorService = ThreadPoolExecutorBuilder.create().threadName("CollectionNotice").builder(); + } + + public void setExecutorService(ExecutorService executorService) { + this.executorService = executorService; + } + + /** + * 注册 + * + * @param collectionConsumer 注册的对象 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:05 + */ + @Override + public void collectionNoticeReg(ICollectionConsumer collectionConsumer) { + this.noticeMap.put(collectionConsumer.getKey(), collectionConsumer); + } + + /** + * 注销通知 + * + * @param key 注销key + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:05 + */ + @Override + public void collectionNoticeUnReg(String key) { + this.noticeMap.remove(key); + } + + /** + * 数据采集通知 + * + * @param data 采集的数据 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:03 + */ + public void collectionNotice(T data) { + this.collectionNotice(data, ""); + } + + /** + * 数据采集通知 + * + * @param data 采集的数据 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:03 + */ + public void collectionNotice(T data, String modelName) { + synchronized (this) { + CollectionData collectionData = new CollectionData<>(data, modelName); + this.noticeMap.forEach((key, item) -> IgnoredException.run(() -> this.executorService.execute(() -> item.collectionNotice(sender, collectionData)))); + } + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/ICollectionConsumer.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/ICollectionConsumer.java new file mode 100644 index 0000000..ada5f2e --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/ICollectionConsumer.java @@ -0,0 +1,29 @@ +package com.liuhuiyu.core.data.collection; + +/** + * 采集数据消费者接口 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-03-30 20:53 + */ +public interface ICollectionConsumer { + /** + * 注册key + * + * @return java.lang.String + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:02 + */ + String getKey(); + + /** + * 采集通知 + * + * @param sender 消息发送者 + * @param changeData 更新的数据信息 + * @author LiuHuiYu + * Created DateTime 2023-02-07 14:02 + */ + void collectionNotice(Object sender, CollectionData changeData); +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/ICollectionNoticeReg.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/ICollectionNoticeReg.java new file mode 100644 index 0000000..a37383c --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/ICollectionNoticeReg.java @@ -0,0 +1,28 @@ +package com.liuhuiyu.core.data.collection; + +/** + * 数据采集通知注册 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-03-30 20:44 + */ +public interface ICollectionNoticeReg { + /** + * 消费者注册 + * + * @param collectionConsumer 消费者注册 + * @author LiuHuiYu + * Created DateTime 2023-03-31 8:24 + */ + void collectionNoticeReg(ICollectionConsumer collectionConsumer); + + /** + * 消费者注销 + * + * @param collectionConsumerKey 消费者Key + * @author LiuHuiYu + * Created DateTime 2023-03-31 8:24 + */ + void collectionNoticeUnReg(String collectionConsumerKey); +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/package-info.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/package-info.java new file mode 100644 index 0000000..81df216 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/collection/package-info.java @@ -0,0 +1,9 @@ +/** + * 信息采集 + * 发起端 提交要采集的信息,收集采集的数据 + * 接收端 提交采集的信息 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-26 11:00 + */ +package com.liuhuiyu.core.data.collection; \ No newline at end of file diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/package-info.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/package-info.java new file mode 100644 index 0000000..a7a1607 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/package-info.java @@ -0,0 +1,7 @@ +/** + * notice + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-07 12:32 + */ +package com.liuhuiyu.core.data; \ No newline at end of file diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/structure/Pageable.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/structure/Pageable.java new file mode 100644 index 0000000..cd8c734 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/structure/Pageable.java @@ -0,0 +1,10 @@ +package com.liuhuiyu.core.data.structure; + +/** + * 可分页信息 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-04-20 15:56 + */ +public class Pageable { +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/structure/Paging.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/structure/Paging.java new file mode 100644 index 0000000..1ed114a --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/data/structure/Paging.java @@ -0,0 +1,13 @@ +package com.liuhuiyu.core.data.structure; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-04-20 15:49 + */ +public class Paging { + private final List content = new ArrayList(); +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/design/patterns/package-info.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/design/patterns/package-info.java new file mode 100644 index 0000000..1f8eef9 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/design/patterns/package-info.java @@ -0,0 +1,8 @@ +/** + * 设计模式 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-04-07 17:08 + */ +package com.liuhuiyu.core.design.patterns; \ No newline at end of file diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/design/patterns/strategy/StrategyRouter.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/design/patterns/strategy/StrategyRouter.java new file mode 100644 index 0000000..2addbb6 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/design/patterns/strategy/StrategyRouter.java @@ -0,0 +1,54 @@ +package com.liuhuiyu.core.design.patterns.strategy; + +import java.util.function.Function; + +/** + * 策略路由器 + * + * @param

路由参数 + * @param 路由结果 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-04-07 17:11 + */ +public abstract class StrategyRouter { + + public StrategyRouter() { + this.abstractInit(); + } + + private Function strategyMapper; + + /** + * 类初始化时注册分发策略 Mapper + */ + private void abstractInit() { + //获取到StrategyMapper接口的实现 + strategyMapper = registerStrategyMapper(); + if (strategyMapper == null) { + throw new NullPointerException("未找到策略分发者"); + } + } + + /** + * 执行策略 + * + * @param param 入参 + * @return 返回值 + */ + public R runStrategy(P param) { + //调用实现StrategyMapper接口的匿名类的get方法,此时get方法会根据入参,返回对应的策略执行者,再调用approve方法 + return strategyMapper.apply(param); + } + + /** + * 分发策略的具体实现 + * + * @return 策略映射器 + */ + public abstract Function registerStrategyMapper(); + + public Function getStrategyMapper() { + return strategyMapper; + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/lang/function_interface/RunnableException.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/lang/function_interface/RunnableException.java new file mode 100644 index 0000000..44a88f2 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/lang/function_interface/RunnableException.java @@ -0,0 +1,18 @@ +package com.liuhuiyu.core.lang.function_interface; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-08-03 9:08 + */ +@FunctionalInterface +public interface RunnableException { + /** + * 执行函数 + * + * @throws Exception 异常 + * @author LiuHuiYu + * Created DateTime 2023-08-03 9:21 + */ + void run() throws Exception; +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/lang/function_interface/SupplierException.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/lang/function_interface/SupplierException.java new file mode 100644 index 0000000..1bd7641 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/lang/function_interface/SupplierException.java @@ -0,0 +1,20 @@ +package com.liuhuiyu.core.lang.function_interface; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-08-03 9:11 + */ +@FunctionalInterface +public interface SupplierException { + + /** + * 获取函数接口数据 + * + * @return T 实体 + * @throws Exception 异常信息 + * Created DateTime 2023-08-03 9:20 + * @author LiuHuiYu + */ + T get() throws Exception; +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/lang/id/NanoId.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/lang/id/NanoId.java new file mode 100644 index 0000000..73c6567 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/lang/id/NanoId.java @@ -0,0 +1,99 @@ +package com.liuhuiyu.core.lang.id; + +import java.security.SecureRandom; +import java.util.Random; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-01-04 16:01 + */ +public class NanoId { + /** + * 默认随机数生成器,使用{@link SecureRandom}确保健壮性 + */ + private static final SecureRandom DEFAULT_NUMBER_GENERATOR = new SecureRandom(); + + /** + * 默认随机字母表,使用URL安全的Base64字符 + */ + public static final char[] NUMBER_UPPERCASE_LETTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); + public static final char[] NUMBER = "0123456789".toCharArray(); + public static final char[] UPPERCASE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); + public static final char[] LOWERCASE_LETTERS = "abcdefghijklmnopqrstuvwxyz".toCharArray(); + private static final char[] DEFAULT_ALPHABET = NUMBER_UPPERCASE_LETTERS; + + /** + * 默认长度 + */ + public static final int DEFAULT_SIZE = 16; + + /** + * 生成伪随机的NanoId字符串,长度为默认的{@link #DEFAULT_SIZE},使用密码安全的伪随机生成器 + * + * @return 伪随机的NanoId字符串 + */ + public static String randomNanoId() { + return randomNanoId(DEFAULT_SIZE); + } + + /** + * 生成伪随机的NanoId字符串 + * + * @param size ID长度 + * @return 伪随机的NanoId字符串 + */ + public static String randomNanoId(int size) { + return randomNanoId(null, null, size); + } + + /** + * 生成伪随机的NanoId字符串 + * + * @param alphabet 随机字母表 + * @param size ID长度 + * @return 伪随机的NanoId字符串 + */ + public static String randomNanoId(char[] alphabet, int size) { + return randomNanoId(null, alphabet, size); + } + + /** + * 生成伪随机的NanoId字符串 + * + * @param random 随机数生成器 + * @param alphabet 随机字母表 + * @param size ID长度 + * @return 伪随机的NanoId字符串 + */ + public static String randomNanoId(Random random, char[] alphabet, int size) { + if (size <= 0) { + throw new IllegalArgumentException("Size must be greater than zero."); + } + if (random == null) { + random = DEFAULT_NUMBER_GENERATOR; + } + if (alphabet == null) { + alphabet = DEFAULT_ALPHABET; + } + if (alphabet.length == 0 || alphabet.length >= 256) { + throw new IllegalArgumentException("Alphabet must contain between 1 and 255 symbols."); + } + final int mask = (2 << (int) Math.floor(Math.log(alphabet.length - 1) / Math.log(2))) - 1; + final int step = (int) Math.ceil(1.6 * mask * size / alphabet.length); + final StringBuilder idBuilder = new StringBuilder(); + while (true) { + final byte[] bytes = new byte[step]; + random.nextBytes(bytes); + for (int i = 0; i < step; i++) { + final int alphabetIndex = bytes[i] & mask; + if (alphabetIndex < alphabet.length) { + idBuilder.append(alphabet[alphabetIndex]); + if (idBuilder.length() == size) { + return idBuilder.toString(); + } + } + } + } + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/lang/id/SnowflakeId.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/lang/id/SnowflakeId.java new file mode 100644 index 0000000..4e781c8 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/lang/id/SnowflakeId.java @@ -0,0 +1,194 @@ +package com.liuhuiyu.core.lang.id; + +import com.liuhuiyu.core.util.Assert; + +import java.sql.Timestamp; + +/** + * 雪花算法生成Id(默认支持69年id生成)可通过自定义生成更广范围的id + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-01-16 16:11 + */ +public class SnowflakeId { + /** + * 开始时间截 LocalDateTime.of(2023,1,1,0,0) + */ + public static final long INITIALIZE_THE_TIMESTAMP = 1_672_502_400_000L; + + /** + * 机器id所占的位数 + */ + public static final long WORKER_ID_BITS = 5L; + + /** + * 数据标识id所占的位数 + */ + public static final long DATACENTER_ID_BITS = 5L; + + /** + * 序列在id中占的位数 + */ + public static final long SEQUENCE_BITS = 12L; + /** + * 时间戳左移最大位数 + * Created DateTime 2023-01-17 10:07 + */ + public static final long MAX_TIMESTAMP_LEFT_SHIFT = 22L; + private final long initializeTheTimestamp; + + /** + * 机器ID向左移12位 + */ + private final long workerIdShift; + + /** + * 数据标识id向左移17位(12+5) + */ + private final long datacenterIdShift; + + /** + * 时间截向左移22位(5+5+12) + */ + private final long timestampLeftShift; + + /** + * 生成序列的掩码,根据 sequenceBits 生成 (0b(sequenceBits)1) + */ + private final long sequenceMask; + + /** + * 工作机器ID(0~31) + */ + private final long workerId; + + /** + * 数据中心ID(0~31) + */ + private final long datacenterId; + + /** + * 毫秒内序列(0~4095) + */ + private long sequence = 0L; + + /** + * 上次生成ID的时间截 + */ + private long lastTimestamp = -1L; + + /** + * 构造函数 + * + * @param workerId 工作ID (0~31) + * @param datacenterId 数据中心ID (0~31) + */ + public SnowflakeId(long workerId, long datacenterId) { + this(INITIALIZE_THE_TIMESTAMP, WORKER_ID_BITS, DATACENTER_ID_BITS, SEQUENCE_BITS, workerId, datacenterId); + } + + /** + * 自定义初始化构造函数 + * + * @param initializeTheTimestamp 初始化时间 + * @param workerIdBits 工作ID位数(bit) + * @param datacenterIdBits 数据中心ID位数(bit) + * @param sequenceBits 序列占用的位数(bit) + * @param workerId 工作ID(0~2^workerIdBits-1) + * @param datacenterId 数据中心ID(0~2^datacenterIdBits-1) + * @author LiuHuiYu + * Created DateTime 2023-01-17 9:30 + */ + public SnowflakeId(Timestamp initializeTheTimestamp, long workerIdBits, long datacenterIdBits, long sequenceBits, long workerId, long datacenterId) { + this(initializeTheTimestamp.getTime(), workerIdBits, datacenterIdBits, sequenceBits, workerId, datacenterId); + } + + /** + * 自定义初始化构造函数 + * + * @param initializeTheTimestamp 初始化时间戳 + * @param workerIdBits 工作ID位数(bit) + * @param datacenterIdBits 数据中心ID位数(bit) + * @param sequenceBits 序列占用的位数(bit) + * @param workerId 工作ID(0~2^workerIdBits-1) + * @param datacenterId 数据中心ID(0~2^datacenterIdBits-1) + * @author LiuHuiYu + * Created DateTime 2023-01-17 9:30 + */ + public SnowflakeId(long initializeTheTimestamp, long workerIdBits, long datacenterIdBits, long sequenceBits, long workerId, long datacenterId) { + final long maxWorkerId = ~(-1L << workerIdBits); + final long maxDatacenterId = ~(-1L << datacenterIdBits); + Assert.assertTrue(initializeTheTimestamp >= 0, new IllegalArgumentException("初始化时间戳 不能小于 0")); + Assert.assertTrue(workerIdBits > 0, new IllegalArgumentException("工作ID位数 不能小于 0")); + Assert.assertTrue(datacenterIdBits > 0, new IllegalArgumentException("数据中心ID位数 %d 不能小于 0")); + Assert.assertTrue(sequenceBits > 0, new IllegalArgumentException("序列占用的位数 %d 不能小于 0")); + Assert.assertTrue(workerId <= maxWorkerId && workerId >= 0, new IllegalArgumentException(String.format("工作ID 不能大于 %d 不能小于 0", maxWorkerId))); + Assert.assertTrue(datacenterId <= maxWorkerId && datacenterId >= 0, new IllegalArgumentException(String.format("数据中心ID 不能大于 %d 不能小于 0", maxDatacenterId))); + this.initializeTheTimestamp = initializeTheTimestamp; + this.sequenceMask = ~(-1L << sequenceBits); + this.workerIdShift = sequenceBits; + this.datacenterIdShift = sequenceBits + workerIdBits; + this.timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; + Assert.assertTrue(this.timestampLeftShift <= MAX_TIMESTAMP_LEFT_SHIFT, new IllegalArgumentException(String.format("工作ID位数(bit)+数据中心ID位数(bit)+序列占用的位数(bit) 不能大于 %d", MAX_TIMESTAMP_LEFT_SHIFT))); + this.workerId = workerId; + this.datacenterId = datacenterId; + } + + /** + * 获得下一个ID (该方法是线程安全的) + * + * @return SnowflakeId + */ + public synchronized long nextId() { + long timestamp = timeGen(); + //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常 + Assert.assertTrue(timestamp >= lastTimestamp, new RuntimeException(String.format("时钟倒退。拒绝生成 id %d 毫秒", lastTimestamp - timestamp))); + + //如果是同一时间生成的,则进行毫秒内序列 + if (lastTimestamp == timestamp) { + sequence = (sequence + 1) & sequenceMask; + //毫秒内序列溢出 + if (sequence == 0) { + //阻塞到下一个毫秒,获得新的时间戳 + timestamp = tilNextMillis(lastTimestamp); + } + } + //时间戳改变,毫秒内序列重置 + else { + sequence = 0L; + } + + //上次生成ID的时间截 + lastTimestamp = timestamp; + + //移位并通过或运算拼到一起组成64位的ID + return ((timestamp - initializeTheTimestamp) << timestampLeftShift) + | (datacenterId << datacenterIdShift) + | (workerId << workerIdShift) + | sequence; + } + + /** + * 阻塞到下一个毫秒,直到获得新的时间戳 + * + * @param lastTimestamp 上次生成ID的时间截 + * @return 当前时间戳 + */ + protected long tilNextMillis(long lastTimestamp) { + long timestamp = timeGen(); + while (timestamp <= lastTimestamp) { + timestamp = timeGen(); + } + return timestamp; + } + + /** + * 返回以毫秒为单位的当前时间 + * + * @return 当前时间(毫秒) + */ + protected long timeGen() { + return System.currentTimeMillis(); + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/net/Ping.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/net/Ping.java new file mode 100644 index 0000000..484c37d --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/net/Ping.java @@ -0,0 +1,94 @@ +package com.liuhuiyu.core.net; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.InetAddress; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-01-10 16:36 + */ +public class Ping { + /** + * ping 指定地址 + * + * @param ipAddress 地址 + * @return boolean + * @author LiuHuiYu + * Created DateTime 2023-01-10 17:08 + */ + public static boolean ping(String ipAddress) { + //超时应该在3钞以上 + int timeOut = 3000; + try { + return InetAddress.getByName(ipAddress).isReachable(timeOut); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * 使用windows命令 ping 指定地址 + * + * @param ipAddress 地址 + * @param pingTimes ping次数 + * @param timeOut 超时时间 + * @return boolean + * @author LiuHuiYu + * Created DateTime 2023-01-10 17:09 + */ + public static boolean windowsPing(String ipAddress, int pingTimes, int timeOut) { + // 将要执行的ping命令,此命令是windows格式的命令 + Runtime r = Runtime.getRuntime(); + String pingCommand = "ping " + ipAddress + " -n " + pingTimes + " -w " + timeOut; + // 执行命令并获取输出 + Process p; + try { + p = r.exec(pingCommand); + } + catch (IOException e) { + throw new RuntimeException(e); + } + if (p == null) { + return false; + } + try (BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()))) { + int connectedCount = 0; + String line; + while ((line = in.readLine()) != null) { + connectedCount += getCheckResult(line); + } // 如果出现类似=23ms TTL=62这样的字样,出现的次数=测试次数则返回真 + return connectedCount == pingTimes; + } + catch (Exception ex) { + ex.printStackTrace(); // 出现异常则返回假 + return false; + } + } + + + /** + * 若line含有=18ms TTL=16字样,说明已经ping通,返回1,否則返回0. + * Created DateTime 2023-01-10 16:51 + */ + public static final String REGEX = "(\\d+ms)(\\s+)(TTL=\\d+)"; + + /** + * 返回信息检测 + * + * @param line 返回信息 + * @return int + * @author LiuHuiYu + * Created DateTime 2023-01-10 16:53 + */ + private static int getCheckResult(String line) { + Pattern pattern = Pattern.compile(REGEX, Pattern.CASE_INSENSITIVE); + Matcher matcher = pattern.matcher(line); + return matcher.find() ? 1 : 0; + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/package-info.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/package-info.java new file mode 100644 index 0000000..344658c --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/package-info.java @@ -0,0 +1,6 @@ +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-01-04 16:00 + */ +package com.liuhuiyu.core; \ No newline at end of file diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/thread/EasyThreadFactory.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/thread/EasyThreadFactory.java new file mode 100644 index 0000000..1380c7e --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/thread/EasyThreadFactory.java @@ -0,0 +1,45 @@ +package com.liuhuiyu.core.thread; + +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * 简易线程工厂 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-22 22:45 + */ +public class EasyThreadFactory implements ThreadFactory { + private static final AtomicInteger poolNumber = new AtomicInteger(1); + private final ThreadGroup group; + private final AtomicInteger threadNumber = new AtomicInteger(1); + private final String namePrefix; + + public EasyThreadFactory() { + this(""); + } + + public EasyThreadFactory(String namePrefix) { + SecurityManager s = System.getSecurityManager(); + group = (s != null) ? s.getThreadGroup() : + Thread.currentThread().getThreadGroup(); + if (namePrefix == null || namePrefix.trim().length() == 0) { + this.namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-"; + } + else { + this.namePrefix = namePrefix; + } + } + + public Thread newThread(Runnable r) { + Thread t = new Thread(group, r, + namePrefix + threadNumber.getAndIncrement(), + 0); + if (t.isDaemon()) + t.setDaemon(false); + if (t.getPriority() != Thread.NORM_PRIORITY) + t.setPriority(Thread.NORM_PRIORITY); + return t; + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/thread/ThreadPoolExecutorBuilder.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/thread/ThreadPoolExecutorBuilder.java new file mode 100644 index 0000000..356176c --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/thread/ThreadPoolExecutorBuilder.java @@ -0,0 +1,100 @@ +package com.liuhuiyu.core.thread; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-22 22:23 + */ +public class ThreadPoolExecutorBuilder { + + /** + * 参数初始化(初始化cpu数量) + * Created DateTime 2021-07-17 10:31 + */ + private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); + + /** + * 初始化线程数量(2-4) + * Created DateTime 2021-07-17 10:51 + */ + private int corePoolSize = Math.max(2, Math.min(CPU_COUNT - 1, 4)); + + /** + * 线程池大小(cpu * 2 +1) + * Created DateTime 2021-07-17 10:51 + */ + private int maxPoolSize = CPU_COUNT * 2 + 1; + + /** + * 线程空闲后的存活时长(30秒) + * Created DateTime 2021-07-17 10:52 + */ + private int keepAliveSeconds = 30; + private String threadName = "taskExecutor-"; + + public static ThreadPoolExecutorBuilder create() { + return new ThreadPoolExecutorBuilder(); + } + + /** + * 核心线程数量大小 + * + * @param corePoolSize 核心线程数量大小 + * @return com.liuhuiyu.util.thread.ThreadUtil.ExecutorBuilder + * @author LiuHuiYu + * Created DateTime 2021-07-17 10:28 + */ + public ThreadPoolExecutorBuilder corePoolSize(int corePoolSize) { + this.corePoolSize = corePoolSize; + return this; + } + + /** + * 线程池最大容纳线程数 + * + * @param maxPoolSize 线程池最大容纳线程数 + * @return com.liuhuiyu.util.thread.ThreadUtil.ExecutorBuilder + * @author LiuHuiYu + * Created DateTime 2021-07-17 10:28 + */ + public ThreadPoolExecutorBuilder maxPoolSize(int maxPoolSize) { + this.maxPoolSize = maxPoolSize; + return this; + } + + /** + * 线程空闲后的存活时长 + * + * @param keepAliveSeconds 线程空闲后的存活时长 + * @return com.liuhuiyu.util.thread.ThreadUtil.ExecutorBuilder + * @author LiuHuiYu + * Created DateTime 2021-07-17 10:27 + */ + public ThreadPoolExecutorBuilder keepAliveSeconds(int keepAliveSeconds) { + this.keepAliveSeconds = keepAliveSeconds; + return this; + } + + /** + * 线程名称 + * + * @param threadName 线程名称 + * @return com.liuhuiyu.util.thread.ThreadUtil.ExecutorBuilder + * @author LiuHuiYu + * Created DateTime 2021-07-17 10:27 + */ + public ThreadPoolExecutorBuilder threadName(String threadName) { + this.threadName = threadName; + return this; + } + + public ExecutorService builder() { + EasyThreadFactory easyThreadFactory = new EasyThreadFactory(threadName); + return new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveSeconds, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), easyThreadFactory); + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/time/TimePeriod.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/time/TimePeriod.java new file mode 100644 index 0000000..2dfda89 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/time/TimePeriod.java @@ -0,0 +1,130 @@ +package com.liuhuiyu.core.time; + +import java.sql.Timestamp; + +/** + * 时间段信息 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-28 15:54 + */ +public class TimePeriod { + final Timestamp beginTime; + final Timestamp endTime; + + private TimePeriod(Timestamp beginTime, Timestamp endTime) { + if (beginTime == null || endTime == null) { + this.beginTime = null; + this.endTime = null; + } + else { + this.beginTime = beginTime.before(endTime) ? beginTime : endTime; + this.endTime = beginTime.after(endTime) ? beginTime : endTime; + } + } + + /** + * 使用开始结束时间字符串创建 + * + * @param beginTime 开始时间(字符串) + * @param endTime 结束时间(字符串) + * @return com.liuhuiyu.core.time.TimePeriod + * @author LiuHuiYu + * Created DateTime 2023-01-13 10:03 + */ + public static TimePeriod stringCreate(String beginTime, String endTime) { + Timestamp b = TimestampUtil.beginTime(beginTime); + Timestamp e = TimestampUtil.beginTime(endTime); + if (b == null || e == null) { + return new TimePeriod(null, null); + } + else { + if (b.before(e)) { + return new TimePeriod(b, TimestampUtil.endTime(endTime)); + } + else { + return new TimePeriod(e, TimestampUtil.endTime(beginTime)); + } + } + } + + /** + * 使用开始结束时间Timestamp串创建 + * + * @param beginTime 开始时间(Timestamp) + * @param endTime 结束时间(Timestamp) + * @return com.liuhuiyu.core.time.TimePeriod + * @author LiuHuiYu + * Created DateTime 2023-01-13 10:03 + */ + public static TimePeriod timestampCreate(Timestamp beginTime, Timestamp endTime) { + return new TimePeriod(beginTime, endTime); + } + + /** + * 时间点在当前时间段内部(不包含边界) + * + * @param timestamp 检测时间点 + * @return boolean + * @author LiuHuiYu + * Created DateTime 2022-11-29 10:49 + */ + public boolean isInTimePeriod(Timestamp timestamp) { + return beginTime.before(timestamp) && endTime.after(timestamp); + } + + /** + * 两个时间段是否交错(任何一个无效,都会返回不交错) + * + * @param timePeriod 时间段 + * @return boolean + * @author LiuHuiYu + * Created DateTime 2023-02-25 11:10 + */ + public boolean isTimeStaggered(TimePeriod timePeriod) { + if (!timePeriod.isValidTime() || !this.isValidTime()) { + return false; + } + if (this.beginTime.equals(timePeriod.getBeginTime()) && this.endTime.equals(timePeriod.getEndTime())) { + return true; + } + return this.isInTimePeriod(timePeriod.beginTime) || + this.isInTimePeriod(timePeriod.endTime) || + timePeriod.isInTimePeriod(this.beginTime) || + timePeriod.isInTimePeriod(this.endTime); + } + + /** + * 获取开始时间 + * + * @return java.sql.Timestamp + * @author LiuHuiYu + * Created DateTime 2023-01-13 10:03 + */ + public Timestamp getBeginTime() { + return beginTime; + } + + /** + * 获取结束时间 + * + * @return java.sql.Timestamp + * @author LiuHuiYu + * Created DateTime 2023-01-13 10:03 + */ + public Timestamp getEndTime() { + return endTime; + } + + /** + * 判断时间段是否有效 + * + * @return boolean + * @author LiuHuiYu + * Created DateTime 2023-01-13 10:02 + */ + public boolean isValidTime() { + return beginTime != null; + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/time/TimestampUtil.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/time/TimestampUtil.java new file mode 100644 index 0000000..427a0c5 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/time/TimestampUtil.java @@ -0,0 +1,94 @@ +package com.liuhuiyu.core.time; + +import java.sql.Timestamp; +import java.text.SimpleDateFormat; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-28 15:55 + */ +public class TimestampUtil { + public static final String FORMAT_YEAR_MONTH_DAY = "yyyy-MM-dd"; + public static final String FORMAT_YEAR_MONTH_DAY_HOUR = "yyyy-MM-dd HH"; + public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE = "yyyy-MM-dd HH:mm"; + public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss"; + + /** + * 转换成开始时间 + * + * @param value 字符串 + * @return java.sql.Timestamp + * @author LiuHuiYu + * Created DateTime 2022-01-06 15:38 + */ + public static Timestamp beginTime(String value) { + try { + String tempV = value; + if (tempV.length() == FORMAT_YEAR_MONTH_DAY.length()) { + tempV += " 00:00:00"; + } + else if (tempV.length() == FORMAT_YEAR_MONTH_DAY_HOUR.length()) { + tempV += ":00:00"; + } + else if (tempV.length() == FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE.length()) { + tempV += ":00"; + } + return Timestamp.valueOf(tempV); + } + catch (Exception e) { + return null; + } + } + + /** + * 转换成结束时间 + * + * @param value 字符串 + * @return java.sql.Timestamp + * @author LiuHuiYu + * Created DateTime 2022-01-06 15:38 + */ + public static Timestamp endTime(String value) { + try { + String tempV = value; + if (tempV.length() == FORMAT_YEAR_MONTH_DAY.length()) { + tempV += " 23:59:59.999"; + } + else if (tempV.length() == FORMAT_YEAR_MONTH_DAY_HOUR.length()) { + tempV += ":59:59.999"; + } + else if (tempV.length() == FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE.length()) { + tempV += ":59.999"; + } + else if (tempV.length() == FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND.length()) { + tempV += ".999"; + } + return Timestamp.valueOf(tempV); + } + catch (Exception e) { + return null; + } + } + + /** + * 可以转换为 Timestamp 的字符串 + * + * @param value 字符串 + * @return boolean + * @author LiuHuiYu + * Created DateTime 2022-01-06 15:37 + */ + public static boolean isTimestampString(String value) { + return endTime(value) != null; + } + + public static String toString(Timestamp timestamp, String format) { + try { + return new SimpleDateFormat(format).format(timestamp); + } + catch (Exception ex) { + return ""; + } + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/Assert.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/Assert.java new file mode 100644 index 0000000..28f1f4f --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/Assert.java @@ -0,0 +1,113 @@ +package com.liuhuiyu.core.util; + +import java.util.function.Function; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-01-17 11:10 + */ +public abstract class Assert { + static Function exceptionProxy; + + private static RuntimeException throwEx(String message) { + if (exceptionProxy == null) { + return new RuntimeException(message); + } + else { + return exceptionProxy.apply(message); + } + } + + /** + * 接受到异常信息后的异常抛出处理 + * + * @param proxy 接受到异常信息后的代理。 + * @author LiuHuiYu + * Created DateTime 2021-12-10 14:43 + */ + public static void exceptionProxy(Function proxy) { + exceptionProxy = proxy; + } + + //region assertTrue + + public static void assertTrue(boolean value, RuntimeException exception) { + if (!value) { + throw exception; + } + } + + public static void assertTrue(boolean value, String message) { + assertTrue(value, throwEx(message)); + } + //endregion + + //region assertFalse + + public static void assertFalse(boolean value, String message) { + assertTrue(!value, message); + } + + public static void assertFalse(boolean value, RuntimeException exception) { + assertTrue(!value, exception); + } + //endregion + + //region assertNotNull + + public static void assertNotNull(Object object, RuntimeException exception) { + assertTrue(object != null, exception); + } + + /** + * 对象为空则抛出异常 + * + * @param object 对象 + * @param message 对象 + */ + public static void assertNotNull(Object object, String message) { + assertTrue(object != null, message); + } + + + //endregion + + //region assertNull + + /** + * 对象不为空则抛出异常 + * + * @param object 对象 + * @param exception 对象 + */ + public static void assertNull(Object object, RuntimeException exception) { + assertTrue(object == null, exception); + } + + /** + * 对象不为空则抛出异常 + * + * @param object 对象 + * @param message 消息 + */ + public static void assertNull(Object object, String message) { + assertTrue(object == null, message); + } + //endregion + + //region 字符串长度 + + public static void assertLen(String value, int min, int max, String message) { + assertNotNull(value, message + "未设定"); + assertTrue( + (min <= 0 || value.length() >= min) && + (max < 0 || value.length() <= max), message + "(长度范围[" + min + "-" + max + "])"); + } + + public static void assertLen(String value, int min, int max, RuntimeException exception) { + assertNotNull(value, exception); + assertTrue(value.length() >= min && value.length() <= max, exception); + } + //endregion +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/IfRun.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/IfRun.java new file mode 100644 index 0000000..576ab0a --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/IfRun.java @@ -0,0 +1,201 @@ +package com.liuhuiyu.core.util; + +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * @param 输入 + * @param 输出 + * Created DateTime 2023-01-27 10:23 + * @author LiuHuiYu + * @version v1.0.0.0 + */ +public class IfRun { + private final T t; + + @SuppressWarnings("all") + private Optional resOptional; + + //region 初始化函数 + + private IfRun(T t) { + this.t = t; + } + + public static IfRun create() { + return new IfRun<>(null); + } + + /** + * 链式多条件执行并返回结果,如果都没有执行将返回默认 + * + * @param t 输出参数 + * @param 输出参数 + * @param 输出参数 + * @return com.liuhuiyu.core.util.IfRun + * @author LiuHuiYu + * Created DateTime 2023-01-27 10:31 + */ + public static IfRun create(T t) { + return new IfRun<>(t); + } + //endregion + + //region 条件执行 + + public IfRun elseIf(boolean b, Function f) { + if (isAllowExecution(b)) { + this.resOptional = Optional.ofNullable(f.apply(t)); + } + return this; + } + + /** + * 添加执行 + * + * @param b 判断是否执行 + * @param supplier 要执行的函数 + * @return com.liuhuiyu.util.list.IfRun + * @author LiuHuiYu + * Created DateTime 2022-05-21 16:17 + */ + public IfRun elseIf(Boolean b, Supplier supplier) { + if (this.isAllowExecution(b)) { + this.resOptional = Optional.ofNullable(supplier.get()); + } + return this; + } + + public IfRun elseIf(Boolean b, Runnable execution) { + if (this.isAllowExecution(b)) { + execution.run(); + this.resOptional = Optional.empty(); + } + return this; + } + + /** + * 如果上面任何一个条件都不满足就返回指定值 + * + * @param b 判断是否执行 + * @param r 赋予的值 + * @return com.liuhuiyu.core.util.IfRun + * @author LiuHuiYu + * Created DateTime 2023-01-27 11:28 + * @deprecated 此方法会在代码编写过程中因编码错误引发故障。 + */ + @Deprecated + public IfRun elseIf(Boolean b, R r) { + if (this.isAllowExecution(b)) { + this.resOptional = Optional.ofNullable(r); + } + return this; + } + //endregion + + //region 结果获取或者处理 + + /** + * 获取执行后的信息 + * + * @return java.util.Optional + * @author LiuHuiYu + * Created DateTime 2023-01-27 11:11 + */ + public Optional getOptionalResults() { + return this.isAlreadyExecution() ? this.resOptional : Optional.empty(); + } + + /** + * 没有返回结构将抛出异常 + * + * @param exceptionSupplier 将返回要抛出的异常的供应商 + * @param 将返回要抛出的异常的供应商 + * @return R + * @author LiuHuiYu + * Created DateTime 2022-06-06 16:51 + */ + public R orElseThrow(Supplier exceptionSupplier) throws X { + if (this.isAlreadyExecution()) { + return this.resOptional.orElse(null); + } + else { + throw exceptionSupplier.get(); + } + } + + /** + * 如果上面任何一个条件都不满足就返回指定值 + * + * @param r 指定值 + * @return R + * @author LiuHuiYu + * Created DateTime 2023-01-24 13:56 + */ + public R orElse(R r) { + if (this.isAlreadyExecution()) { + return this.resOptional.orElse(null); + } + else { + return r; + } + } + + public R orElse(Function f) { + if (this.isAlreadyExecution()) { + return this.resOptional.orElse(null); + } + else { + return f.apply(t); + } + } + + /** + * 添加执行 + * + * @param supplier 要执行的函数 + * @return com.liuhuiyu.util.list.IfRun + * @author LiuHuiYu + * Created DateTime 2022-05-21 16:17 + */ + public R orElse(Supplier supplier) { + if (this.isAlreadyExecution()) { + return this.resOptional.orElse(null); + } + else { + return supplier.get(); + } + } + + public void orElse(Runnable execution) { + if (!this.isAlreadyExecution()) { + execution.run(); + } + } + //endregion + + /** + * 允许执行方法(之前没有任何可用的执行方法) + * + * @param b 执行条件 + * @return boolean + * @author LiuHuiYu + * Created DateTime 2023-01-24 14:09 + */ + private boolean isAllowExecution(Boolean b) { + return b && !isAlreadyExecution(); + } + + /** + * 已经有执行的函数了 + * + * @return boolean + * @author LiuHuiYu + * Created DateTime 2023-01-24 14:10 + */ + @SuppressWarnings("all") + private boolean isAlreadyExecution() { + return null != this.resOptional; + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/IgnoredException.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/IgnoredException.java new file mode 100644 index 0000000..9f747f5 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/IgnoredException.java @@ -0,0 +1,84 @@ +package com.liuhuiyu.core.util; + +import com.liuhuiyu.core.lang.function_interface.RunnableException; +import com.liuhuiyu.core.lang.function_interface.SupplierException; + +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * 执行中出现异常,忽略不报错并且继续执行(多用于循环体中可忽略的循环执行) + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-05 9:53 + */ +public class IgnoredException { + /** + * 执行中出现异常,忽略不报错并且继续执行(多用于循环体中可忽略的循环执行) + * + * @param execution 要执行的 Runnable + * @author LiuHuiYu + * Created DateTime 2023-02-22 21:37 + */ + public static void run(RunnableException execution) { + try { + execution.run(); + } + catch (Exception ignored) { + } + } + + /** + * 执行中出现异常,忽略不报错并且继续执行(多用于循环体中可忽略的循环执行) + * + * @param execution 要执行的 Runnable + * @param exceptionFunction 异常出现要执行的 Consumer + * @author LiuHuiYu + * Created DateTime 2023-02-22 21:37 + */ + public static void run(RunnableException execution, Consumer exceptionFunction) { + try { + execution.run(); + } + catch (Exception ex) { + exceptionFunction.accept(ex); + } + } + + /** + * 执行中出现异常,返回默认值 + * + * @param supplier 要执行的 Supplier + * @param def 默认值 + * @return T + * @author LiuHuiYu + * Created DateTime 2023-02-22 21:38 + */ + public static T get(SupplierException supplier, T def) { + try { + return supplier.get(); + } + catch (Exception ex) { + return def; + } + } + + /** + * 执行中出现异常,返回默认值 + * + * @param supplier 要执行的 Supplier + * @param exceptionFunction 异常的时候执行 + * @return T + * @author LiuHuiYu + * Created DateTime 2023-02-22 21:38 + */ + public static T get(SupplierException supplier, Function exceptionFunction) { + try { + return supplier.get(); + } + catch (Exception ex) { + return exceptionFunction.apply(ex); + } + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/proxy/DynamicProxy.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/proxy/DynamicProxy.java new file mode 100644 index 0000000..fe9ae44 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/proxy/DynamicProxy.java @@ -0,0 +1,57 @@ +package com.liuhuiyu.core.util.proxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-04-07 8:40 + */ +public class DynamicProxy implements InvocationHandler { + private Object target; + + public DynamicProxy(Object target, Runnable beforeMethodInvocation, Runnable afterMethodInvocation) { + this.target = target; + this.afterMethodInvocation = afterMethodInvocation; + this.beforeMethodInvocation = beforeMethodInvocation; + } + + Runnable beforeMethodInvocation; + Runnable afterMethodInvocation; + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (beforeMethodInvocation != null) { + beforeMethodInvocation.run(); + } + Object result = method.invoke(target, args); + if (afterMethodInvocation != null) { + afterMethodInvocation.run(); + } + return result; + } + + public static T proxy(T v) { + return proxy(v, () -> { + }, () -> { + }); + } + + public static T proxy(T v, Runnable beforeMethodInvocation, Runnable afterMethodInvocation) { + DynamicProxy dynamicProxy = new DynamicProxy(v, beforeMethodInvocation, afterMethodInvocation); + ClassLoader classLoader = v.getClass().getClassLoader(); + //获取类实现的接口 + Class[] interfaces = v.getClass().getInterfaces(); + //创建代理对象 + return (T) Proxy.newProxyInstance(classLoader, interfaces, dynamicProxy); + } + public Object getInstance(Class cls){ + MethodProxy invocationHandler = new MethodProxy(); + Object newProxyInstance = Proxy.newProxyInstance( + cls.getClassLoader(), + new Class[] { cls }, + invocationHandler); + return (Object)newProxyInstance; + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/proxy/Invoker.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/proxy/Invoker.java new file mode 100644 index 0000000..44ceaaa --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/proxy/Invoker.java @@ -0,0 +1,19 @@ +package com.liuhuiyu.core.util.proxy; + +import java.lang.reflect.Proxy; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-04-07 8:55 + */ +public class Invoker { + public Object getInstance(Class cls){ + MethodProxy invocationHandler = new MethodProxy(); + Object newProxyInstance = Proxy.newProxyInstance( + cls.getClassLoader(), + new Class[] { cls }, + invocationHandler); + return (Object)newProxyInstance; + } +} diff --git a/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/proxy/MethodProxy.java b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/proxy/MethodProxy.java new file mode 100644 index 0000000..84e1f82 --- /dev/null +++ b/model/liuhuiyu-core/src/main/java/com/liuhuiyu/core/util/proxy/MethodProxy.java @@ -0,0 +1,41 @@ +package com.liuhuiyu.core.util.proxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-04-07 8:56 + */ +public class MethodProxy implements InvocationHandler { + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + //如果传进来是一个已实现的具体类(本次演示略过此逻辑) + if (Object.class.equals(method.getDeclaringClass())) { + try { + return method.invoke(this, args); + } catch (Throwable t) { + t.printStackTrace(); + } + //如果传进来的是一个接口(核心) + } else { + return run(method, args); + } + return null; + } + + /** + * 实现接口的核心方法 + * @param method + * @param args + * @return + */ + public Object run(Method method,Object[] args){ + //TODO + //如远程http调用 + //如远程方法调用(rmi) + //.... + return "method call success!"; + } +} diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/data/change/ChangeNoticeManageTest.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/data/change/ChangeNoticeManageTest.java new file mode 100644 index 0000000..63c048c --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/data/change/ChangeNoticeManageTest.java @@ -0,0 +1,213 @@ +package com.liuhuiyu.core.data.change; + +import com.liuhuiyu.core.util.IgnoredException; +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; + +import java.util.Random; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-07 14:34 + */ +class ChangeNoticeManageTest extends TestBase { + public static final int STOP_TIME = 1000; + + @Test + public void test() throws InterruptedException { + Aa1 aa1 = new Aa1("aa"); + +// A a = new A(10); + new B(aa1); + Random random = new Random(); + int max = 1000; + for (int i = 0; i < max; i++) { +// a.setAa1Id(random.nextInt(9), random.nextInt(100)); + aa1.setId(random.nextInt(100), i); +// aa1.setId(0); + } + Thread.sleep(STOP_TIME * max); + } + + + static class Aa1 { + public void regMan(IChangeNotice iChangeNotice) { + this.changeNoticeMan.reg(iChangeNotice); + } +// public void regCar(IChangeNotice iChangeNotice) { +// this.changeNoticeCar.reg(iChangeNotice); +// } + + // private final ChangeNoticeManage changeNoticeManage; +// private final ChangeNotice changeNoticeCar; + private final ChangeNotice changeNoticeMan; + +// public ChangeNoticeManage getChangeNoticeManage() { +// return this.changeNoticeManage; +// } + + String name; + Integer id; + + public Aa1(String name) { + this.name = name; +// this.changeNoticeCar = new ChangeNotice<>(this); + this.changeNoticeMan = new ChangeNotice<>(this); +// this.changeNoticeManage = new ChangeNoticeManage<>(changeNotice); + } + + public void setId(Integer id, int i) { + LOG.info("设置{}[{}]的值为{}", name, i, id); + this.id = id; + this.changeNoticeMan.changeNotice(id); + } + + public String getName() { + return this.name; + } + } + + /** + * 我是通知接受者 + * + * @author LiuHuiYu + * Created DateTime 2023-02-16 18:56 + */ + static class B { + Bb bb; + Bb1 bb1; + + public B(Aa1 a) { + bb = new Bb(); + bb1 = new Bb1(); + a.regMan(bb1); + } + + private void ss() { + } + + class Bb implements IChangeNotice { + @Override + public String getKey() { + return "VBb"; + } + + @Override + public void changeNotice(Object sender, ChangeData changeData) { + Aa1 a = (Aa1) sender; + LOG.info("开始{}:{}数据变更:{}", getKey(), a.getName(), changeData.data); + try { + Thread.sleep(STOP_TIME); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + LOG.info("结束{}:{}数据变更:{}", getKey(), a.getName(), changeData.data); + ss(); + } + } + + static class Bb1 implements IChangeNotice { + @Override + public String getKey() { + return "VBc"; + } + + @Override + public void changeNotice(Object sender, ChangeData changeData) { + IgnoredException.run(() -> { + Aa1 a = (Aa1) sender; + LOG.info("开始{}:{}数据变更:{}", getKey(), a.getName(), changeData.data); + try { + Thread.sleep(STOP_TIME); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + LOG.info("结束{}:{}数据变更:{}", getKey(), a.getName(), changeData.data); +// throw new OutOfMemoryError(""); + }, (ex) -> LOG.error("我是异常信息", ex)); + } + } + } + + + /** + * 我是通知接受者 + * + * @author LiuHuiYu + * Created DateTime 2023-02-16 18:56 + */ + static class Ka { + Bb bb; + Bb1 bb1; + + public Ka(Aa1 a) { + bb = new Bb(); + bb1 = new Bb1(); + a.regMan(bb1); + } + + private void ss() { + } + + class Bb implements IChangeNotice { + @Override + public String getKey() { + return "VBb"; + } + + @Override + public void changeNotice(Object sender, ChangeData changeData) { + Aa1 a = (Aa1) sender; + LOG.info("{}:{}数据变更:{}", getKey(), a.getName(), changeData.data); + ss(); + } + } + + static class Bb1 implements IChangeNotice { + @Override + public String getKey() { + return "VBb"; + } + + @Override + public void changeNotice(Object sender, ChangeData changeData) { + IgnoredException.run(() -> { + Aa1 a = (Aa1) sender; + LOG.info("{}:{}数据变更:{}", getKey(), a.getName(), 16 / changeData.data); +// throw new OutOfMemoryError(""); + }, (ex) -> LOG.error("我是异常信息", ex)); + } + } + } +// +// /** +// * 我是通知接受者 +// * +// * @author LiuHuiYu +// * Created DateTime 2023-02-16 18:56 +// */ +// static class B2 { +// Bb bb; +// +// public B2(A a) { +// bb = new Bb(); +// a.reg(bb); +// } +// +// static class Bb implements IChangeNotice { +// @Override +// public String getKey() { +// return "VBb2"; +// } +// +// @Override +// public void changeNotice(Object sender, ChangeData changeData) { +// Aa1 a = (Aa1) sender; +// LOG.info("{}:{}数据变更:{}",getKey(), a.getName(), changeData.data); +// } +// } +// } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/data/change/ChangeNoticeVectorImplTest.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/data/change/ChangeNoticeVectorImplTest.java new file mode 100644 index 0000000..9418b45 --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/data/change/ChangeNoticeVectorImplTest.java @@ -0,0 +1,80 @@ +package com.liuhuiyu.core.data.change; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; + +import java.util.Random; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-23 14:38 + */ +class ChangeNoticeVectorImplTest extends TestBase { + @Test + public void test() throws InterruptedException { + Aa1 aa1 = new Aa1("aa1"); + Random random = new Random(); + ChangeNoticeVectorImpl changeNoticeVector = new ChangeNoticeVectorImpl<>("aaa", (b) -> { + try { + Thread.sleep(1000); + LOG.info("{}:ChangeNoticeVectorImpl:{}",b.getSender(), b.getChangeData().data); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + }); + ChangeNoticeBaseImpl changeNoticeBase = new ChangeNoticeBaseImpl<>("bbb", (b) -> { + try { + Thread.sleep(1000); + LOG.info("{}:ChangeNoticeVectorImpl:{}",b.getSender(), b.getChangeData().data); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + }); + + ChangeNoticeBaseImpl changeNoticeBase2 = new ChangeNoticeBaseImpl<>("ccc",this::aaaa); + aa1.regMan(changeNoticeVector); + aa1.regMan(changeNoticeBase); + aa1.regMan(changeNoticeBase2); + for (int i = 0; i < 15; i++) { + aa1.setId(random.nextInt(), i); + } + Thread.sleep(100_000); + } + + private void aaaa(ChangeNoticeBaseImpl.Data data) { + LOG.info("{};{};{}",data.getChangeData().getData(),data.getChangeData().getDataStatus(),data.getChangeData().getChangeModel()); + } + + + static class Aa1 { + public void regMan(IChangeNotice iChangeNotice) { + this.changeNoticeMan.reg(iChangeNotice); + } + + // private final ChangeNoticeManage changeNoticeManage; +// private final ChangeNotice changeNoticeCar; + private final ChangeNotice changeNoticeMan; + + + String name; + Integer id; + + public Aa1(String name) { + this.name = name; + this.changeNoticeMan = new ChangeNotice<>(this); + } + + public void setId(Integer id, int i) { + LOG.info("设置{}[{}]的值为{}", name, i, id); + this.id = id; + this.changeNoticeMan.changeNotice(id, ChangeData.DataStatus.U,"ssssssssss"); + } + + public String getName() { + return this.name; + } + } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/data/collection/CollectionNoticeTest.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/data/collection/CollectionNoticeTest.java new file mode 100644 index 0000000..aab0f9b --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/data/collection/CollectionNoticeTest.java @@ -0,0 +1,81 @@ +package com.liuhuiyu.core.data.collection; + +import com.liuhuiyu.core.thread.ThreadPoolExecutorBuilder; +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-03-31 7:51 + */ +class CollectionNoticeTest extends TestBase { + @Test + public void test() throws InterruptedException { + Aa1 aa1 = new Aa1("Ak1"); + CollectionConsumerBaseImpl baseConsumer1 = new CollectionConsumerBaseImpl<>("C1", (data) -> this.outPrint("C1", data, 1000)); + baseConsumer1.setExecutorService(ThreadPoolExecutorBuilder.create().threadName("C1-").builder()); + CollectionConsumerBaseImpl baseConsumer2 = new CollectionConsumerBaseImpl<>("C2", (data) -> this.outPrint("C2", data, 100)); + baseConsumer2.setExecutorService(ThreadPoolExecutorBuilder.create().threadName("C2-").builder()); + CollectionConsumerVectorImpl vectorConsumer1 = new CollectionConsumerVectorImpl<>("V1", (data) -> this.outPrint("V1", data, 1000)); + vectorConsumer1.setExecutorService(ThreadPoolExecutorBuilder.create().threadName("V1-").builder()); + CollectionConsumerVectorImpl vectorConsumer2 = new CollectionConsumerVectorImpl<>("V2", (data) -> this.outPrint("V2", data, 1200)); + vectorConsumer2.setExecutorService(ThreadPoolExecutorBuilder.create().threadName("V2-").builder()); + aa1.collectionNoticeReg(baseConsumer1); + aa1.collectionNoticeReg(baseConsumer2); + aa1.collectionNoticeReg(vectorConsumer1); + aa1.collectionNoticeReg(vectorConsumer2); +// Random random = new Random(); + for (int i = 0; i < 15; i++) { + aa1.setId(i, i); + } + Thread.sleep(100_000); + } + + private void outPrint(String name, CollectionConsumerData data, long time) { + try { + Thread.sleep(time); + } + catch (InterruptedException e) { + throw new RuntimeException(e); + } + LOG.info("{}->{};{};{};{}",data.getSender(), name, data.getCollectionData().getData(), data.getCollectionData().getCollectionModel(),data.getCollectionData().isCollectionModel("abc")); + } + + static class Aa1 implements ICollectionNoticeReg { + + // private final ChangeNoticeManage changeNoticeManage; +// private final ChangeNotice changeNoticeCar; + private final CollectionNotice collectionNotice; + + @Override + public void collectionNoticeReg(ICollectionConsumer iCollectionConsumer) { + this.collectionNotice.collectionNoticeReg(iCollectionConsumer); + } + + @Override + public void collectionNoticeUnReg(String collectionConsumerKey) { + this.collectionNotice.collectionNoticeUnReg(collectionConsumerKey); + } + + + String name; + Integer id; + + public Aa1(String name) { + this.name = name; + this.collectionNotice = new CollectionNotice<>(this); + } + + public void setId(Integer id, int i) { + LOG.info("设置{}[{}]的值为{}", name, i, id); + this.id = id; + this.collectionNotice.collectionNotice(id); + } + + public String getName() { + return this.name; + } + + } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/demo/design/patterns/InterpreterPattern.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/demo/design/patterns/InterpreterPattern.java new file mode 100644 index 0000000..57bd2ad --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/demo/design/patterns/InterpreterPattern.java @@ -0,0 +1,87 @@ +package com.liuhuiyu.core.demo.design.patterns; + +import org.junit.jupiter.api.Test; + +/** + * 解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-04-07 20:56 + */ +public class InterpreterPattern { + public interface Expression { + public boolean interpret(String context); + } + + public class TerminalExpression implements Expression { + + private String data; + + public TerminalExpression(String data) { + this.data = data; + } + + @Override + public boolean interpret(String context) { + return context.contains(data); + } + } + + public class OrExpression implements Expression { + + private Expression expr1 = null; + private Expression expr2 = null; + + public OrExpression(Expression expr1, Expression expr2) { + this.expr1 = expr1; + this.expr2 = expr2; + } + + @Override + public boolean interpret(String context) { + return expr1.interpret(context) || expr2.interpret(context); + } + } + + public class AndExpression implements Expression { + + private Expression expr1 = null; + private Expression expr2 = null; + + public AndExpression(Expression expr1, Expression expr2) { + this.expr1 = expr1; + this.expr2 = expr2; + } + + @Override + public boolean interpret(String context) { + return expr1.interpret(context) && expr2.interpret(context); + } + } + + + //规则:Robert 和 John 是男性 + public Expression getMaleExpression() { + Expression robert = new TerminalExpression("Robert"); + Expression john = new TerminalExpression("John"); + return new OrExpression(robert, john); + } + + //规则:Julie 是一个已婚的女性 + public Expression getMarriedWomanExpression() { + Expression julie = new TerminalExpression("Julie"); + Expression married = new TerminalExpression("Married"); + return new AndExpression(julie, married); + } + + @Test + public void test() { + Expression isMale = getMaleExpression(); + Expression isMarriedWoman = getMarriedWomanExpression(); + + System.out.println("John is male? " + isMale.interpret("John")); + System.out.println("Julie is a married women? " + + isMarriedWoman.interpret("Married Julie")); + } +} diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/design/patterns/strategy/StrategyRouterTest.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/design/patterns/strategy/StrategyRouterTest.java new file mode 100644 index 0000000..641a3a4 --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/design/patterns/strategy/StrategyRouterTest.java @@ -0,0 +1,81 @@ +package com.liuhuiyu.core.design.patterns.strategy; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; + +import java.util.function.Function; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-04-07 17:19 + */ +class StrategyRouterTest extends TestBase { + @Test + public void t1() { + S1 s = new S1(); + S2 s2 = new S2(); + + LOG.info("执行:s2.runStrategy(true)"); + s2.runStrategy(true); + LOG.info("执行:s2.runStrategy(false)"); + s2.runStrategy(false); + LOG.info("执行:s.runStrategy(true)"); + s.runStrategy(true); + LOG.info("执行:s.runStrategy(false)"); + s.runStrategy(false); + StrategyRouter f = new StrategyRouter() { + @Override + public Function registerStrategyMapper() { + return (param) -> { + if (param) { + LOG.info("执行了 New:true"); + return /*(Function)*/ s2.runStrategy(param); + } + else { + LOG.info("执行了 New:false"); + return s.runStrategy(param); + } + }; + } + }; + LOG.info("执行:new StrategyRouter(true)"); + f.runStrategy(true); + LOG.info("执行:new StrategyRouter(false)"); + f.runStrategy(false); + super.printObjectJson(f.getStrategyMapper()); + } + + static class S1 extends StrategyRouter { + @Override + public Function registerStrategyMapper() { + return param -> { + + if (param) { + LOG.info("执行了S1:true"); + return null; + } + else { + LOG.info("执行了S1:false"); + new S2().runStrategy(param); + } + return null; + }; + } + } + + static class S2 extends StrategyRouter { + @Override + public Function registerStrategyMapper() { + return param -> { + if (param) { + LOG.info("执行了S2:true"); + } + else { + LOG.info("执行了S2:false"); + } + return null; + }; + } + } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/lang/id/NanoIdTest.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/lang/id/NanoIdTest.java new file mode 100644 index 0000000..827f071 --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/lang/id/NanoIdTest.java @@ -0,0 +1,46 @@ +package com.liuhuiyu.core.lang.id; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-01-04 16:17 + */ +class NanoIdTest extends TestBase { + @Test + public void id() { + int i = 100; + for (int i1 = 0; i1 < i; i1++) { + final String s = NanoId.randomNanoId(30); + LOG.info("{}", s); + } + } + + @Test + public void id1() { + int i = 100; + for (int i1 = 0; i1 < i; i1++) { + final String s = NanoId.randomNanoId(NanoId.NUMBER, 30); + LOG.info("{}", s); + } + } + + @Test + public void id2() { + int i = 100; + for (int i1 = 0; i1 < i; i1++) { + final String s = NanoId.randomNanoId(NanoId.LOWERCASE_LETTERS,30); + LOG.info("{}", s); + } + } + @Test + public void id3() { + int i = 100; + for (int i1 = 0; i1 < i; i1++) { + final String s = NanoId.randomNanoId(NanoId.UPPERCASE_LETTERS,30); + LOG.info("{}", s); + } + } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/lang/id/SnowflakeIdTest.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/lang/id/SnowflakeIdTest.java new file mode 100644 index 0000000..ae1587a --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/lang/id/SnowflakeIdTest.java @@ -0,0 +1,53 @@ +package com.liuhuiyu.core.lang.id; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; + +import java.sql.Timestamp; +import java.time.LocalDateTime; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-01-16 16:11 + */ +class SnowflakeIdTest extends TestBase { + @Test + public void create() { + SnowflakeId idWorker = new SnowflakeId(0, 0); + long[] ids = new long[40_000]; + for (int i = ids.length - 1; i >= 0; i--) { + ids[i] = idWorker.nextId(); + } + for (long id : ids) { + LOG.info("{};{}", Long.toBinaryString(id), id); + } + } + + @Test + public void create2() { + LocalDateTime localDateTime = LocalDateTime.of(2023, 1, 1, 0, 0, 0, 0); + Timestamp init = Timestamp.valueOf(localDateTime); + SnowflakeId idWorker = new SnowflakeId(init, SnowflakeId.WORKER_ID_BITS, SnowflakeId.DATACENTER_ID_BITS, SnowflakeId.SEQUENCE_BITS, 0, 0); + long[] ids = new long[40_000]; + for (int i = ids.length - 1; i >= 0; i--) { + ids[i] = idWorker.nextId(); + } + for (long id : ids) { + LOG.info("{};{}", Long.toBinaryString(id), id); + } + } + + @Test + public void maxDate() { + LocalDateTime localDateTime = LocalDateTime.of(2023, 1, 1, 0, 0, 0, 0); + Timestamp init = Timestamp.valueOf(localDateTime); + Timestamp timestamp = new Timestamp(Long.parseLong("0", 2)); + Timestamp timestamp2 = new Timestamp(Long.parseLong("11111111111111111111111111111111111111111", 2)); + long l = timestamp.getTime(); + LOG.info("{};{};{}", Long.toBinaryString(init.getTime()), init.getTime(), init); + LOG.info("{};{};{}", Long.toBinaryString(l), l, timestamp); + LOG.info("{};{};{}", Long.toBinaryString(timestamp2.getTime()), timestamp2.getTime(), timestamp2); + LOG.info("{};{}", Long.toBinaryString(Long.MAX_VALUE), Long.MAX_VALUE); + } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/net/PingTest.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/net/PingTest.java new file mode 100644 index 0000000..52f94cf --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/net/PingTest.java @@ -0,0 +1,38 @@ +package com.liuhuiyu.core.net; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-01-10 16:38 + */ +class PingTest extends TestBase { + + @DisplayName("ping ip") + @ParameterizedTest() + @MethodSource("ipGenerator") + public void ping(String ipAddress) throws Exception { + final boolean ping = Ping.ping(ipAddress); + LOG.info("ping:{} {}", ipAddress, ping); + final boolean ping2 = Ping.windowsPing(ipAddress, 5, 5000); + LOG.info("windows ping:{} {}", ipAddress, ping2); + } + + static Stream ipGenerator() { + List list = new ArrayList<>(); + list.add("127.0.0.1"); + list.add("128.0.0.1"); + return list.stream(); + } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/time/TimePeriodTest.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/time/TimePeriodTest.java new file mode 100644 index 0000000..a63cfa7 --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/time/TimePeriodTest.java @@ -0,0 +1,91 @@ +package com.liuhuiyu.core.time; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-01-13 10:12 + */ +class TimePeriodTest extends TestBase { + @DisplayName("时间段测试") + @ParameterizedTest() + @MethodSource("stringTimeGenerator") + public void stringTimePeriod(StringTime data) { + final TimePeriod timePeriod = TimePeriod.stringCreate(data.beginTime, data.endTime); + if (timePeriod.isValidTime()) { + LOG.info("开始时间:{};结束时间:{};时间点{}在时间范围之{}", timePeriod.getBeginTime(), timePeriod.getEndTime(), data.middleTime, timePeriod.isInTimePeriod(data.middleTime) ? "内" : "外"); + } + else { + LOG.info("无法对{}/{}进行日期转换", data.beginTime, data.endTime); + } + } + + @DisplayName("时间段测试") + @ParameterizedTest() + @MethodSource("stringTimeGenerator") + public void timestampCreate(StringTime data) { + Timestamp beginTime = TimestampUtil.beginTime(data.beginTime); + Timestamp endTime = TimestampUtil.beginTime(data.endTime); + final TimePeriod timePeriod = TimePeriod.timestampCreate(beginTime, endTime); + if (timePeriod.isValidTime()) { + LOG.info("开始时间:{};结束时间:{};时间点{}在时间范围之{}", timePeriod.getBeginTime(), timePeriod.getEndTime(), data.middleTime, timePeriod.isInTimePeriod(data.middleTime) ? "内" : "外"); + } + else { + LOG.info("无法对{}/{}进行日期转换", data.beginTime, data.endTime); + } + } + + @DisplayName("时间段交错测试") + @ParameterizedTest() + @MethodSource("argumentGenerator") + public void t(String beg01, String end01, String beg02, String end02, String info) { + TimePeriod timePeriod1 = TimePeriod.stringCreate(beg01, end01); + TimePeriod timePeriod2 = TimePeriod.stringCreate(beg02, end02); + LOG.info("{}:{}", timePeriod1.isTimeStaggered(timePeriod2), info); + } + + static class StringTime { + String beginTime; + String endTime; + Timestamp middleTime; + + public StringTime(String beginTime, String endTime, String middleTime) { + this.beginTime = beginTime; + this.endTime = endTime; + this.middleTime = Timestamp.valueOf(middleTime); + } + } + + static Stream stringTimeGenerator() { + List list = new ArrayList<>(); + list.add(new StringTime("2022-1-1 13:11", "2022-1-1 12:11", "2022-01-01 12:17:00")); + list.add(new StringTime("2022-01-01 13:11", "2022-01-01 12:1", "2022-01-01 12:17:00")); + list.add(new StringTime("2022-01-01 13:11", "2022-01-01 12:01", "2022-01-01 12:17:00")); + list.add(new StringTime("2022-01-01 13:11", "2022-01-01 12:01", "2022-01-01 13:17:00")); + list.add(new StringTime("2022-01-01 13:11", "2022-01-01 12:01", "2022-01-01 12:01:00")); + list.add(new StringTime("2022-01-01 13:11", "2022-01-01 12:01", "2022-01-01 13:11:00")); + return list.stream(); + } + + static Stream argumentGenerator() { + return Stream.of( + Arguments.of("2022-01-01 13:11", "2022-01-01 12:11", "2022-01-01 13:11", "2022-01-01 12:11", "相同时间点"), + Arguments.of("2022-01-01 13:11", "2022-01-01 12:01", "2022-01-01 12:17:00", "", "有无效数据"), + Arguments.of("2022-01-01 13:11", "", "2022-01-01 12:01", "2022-01-01 12:17:00", "有无效数据"), + Arguments.of("2022-01-01 13:11", "2022-01-01 12:01", "2022-01-01 12:11", "2022-01-01 11:01", "交错"), + Arguments.of("2022-01-01 13:11", "2022-01-01 12:01", "2022-01-01 12:11", "2022-01-01 12:12", "交错"), + Arguments.of("2022-01-01 13:11", "2022-01-01 12:01", "2022-01-01 10:11", "2022-01-01 14:01", "交错"), + Arguments.of("2022-01-01 13:11", "2022-01-01 12:01", "2022-01-02 13:11", "2022-01-02 12:01", "不交错") + ); + } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/time/TimestampUtilTest.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/time/TimestampUtilTest.java new file mode 100644 index 0000000..c5d4f70 --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/time/TimestampUtilTest.java @@ -0,0 +1,17 @@ +package com.liuhuiyu.core.time; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-01-13 10:32 + */ +class TimestampUtilTest extends TestBase { + @Test + public void test() { + final boolean timestampString = TimestampUtil.isTimestampString(""); + LOG.info("{}", timestampString); + } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/util/AssertTest.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/util/AssertTest.java new file mode 100644 index 0000000..bf73f46 --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/util/AssertTest.java @@ -0,0 +1,47 @@ +package com.liuhuiyu.core.util; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-01-17 15:09 + */ +class AssertTest extends TestBase { + @DisplayName("断言测试") + @ParameterizedTest() + @MethodSource("dataGenerator") + public void test(Object obj) { + Assert.exceptionProxy(RuntimeException::new); + if (obj instanceof Boolean) { + Assert.assertTrue((Boolean) obj, "obj!=true"); + Assert.assertFalse((Boolean) obj, new RuntimeException("obj==true")); + } + else if (obj instanceof Integer) { + Assert.assertFalse((Integer) obj > 1, "obj > 1"); + } + else if (obj instanceof String) { + Assert.assertLen((String) obj, 5, 10, "长度错误。"); + Assert.assertLen((String) obj, 15, 20, new RuntimeException("长度错误。")); + } + Assert.assertNull(obj, "obj!=null"); + Assert.assertNull(obj, new RuntimeException("obj!=null")); + Assert.assertNotNull(obj, "obj==null"); + } + + static Stream dataGenerator() { + List objects = new ArrayList<>(); + objects.add("1"); + objects.add(null); + objects.add(true); + objects.add(1); + return objects.stream(); + } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/util/IfRunTest.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/util/IfRunTest.java new file mode 100644 index 0000000..ba8c2af --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/util/IfRunTest.java @@ -0,0 +1,66 @@ +package com.liuhuiyu.core.util; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-01-27 11:55 + */ +class IfRunTest extends TestBase { + @DisplayName("测试条件执行") + @ParameterizedTest() + @MethodSource("argumentsGenerator") + public void test(Object obj) { + LOG.info("输入值:{}", obj); + Object value = "".equals(obj) ? null : obj; + IfRun ifRun = "".equals(obj) ? IfRun.create() : IfRun.create(value); + IfRun ifRun1 = ifRun +// .elseIf(value instanceof Integer, "Integer") + .elseIf(value instanceof Long, () -> "Long") + .elseIf(value instanceof String, (v) -> "String[" + v + "]") + .elseIf(value instanceof Character, () -> LOG.info("char")); + final Object v0 = ifRun1.getOptionalResults(); + final Object v1 = ifRun1.orElse("指定值"); + final Object v2 = ifRun1.orElse(() -> "Supplier"); + final Object v3 = ifRun1.orElse((a) -> "Function->" + a); + ifRun.orElse(() -> LOG.info("Runnable")); + LOG.info("{},{},{},{}", v0, v1, v2, v3); + final Object v4 = ifRun.orElseThrow(() -> new RuntimeException("异常")); + LOG.info("{}", v4); + } + + @Test + public void test2() { + String info = "a"; + final Object o = IfRun.create() + .elseIf(false, () -> this.ff(info+"1")) +// .elseIf(false, this.ff(info+"2")) + .orElse(() -> "执行else"); + LOG.info("{}",o); + } + + private String ff(String info) { + LOG.info("执行了ff"); + return info; + } + + public static Stream argumentsGenerator() { + return Stream.of( + Arguments.arguments(1), + Arguments.arguments("a"), + Arguments.arguments(true), + Arguments.arguments(0L), + Arguments.arguments('c'), + Arguments.arguments(""), + Arguments.arguments(100L) + ); + } +} \ No newline at end of file diff --git a/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/util/IgnoredExceptionTest.java b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/util/IgnoredExceptionTest.java new file mode 100644 index 0000000..e2a98c4 --- /dev/null +++ b/model/liuhuiyu-core/src/test/java/com/liuhuiyu/core/util/IgnoredExceptionTest.java @@ -0,0 +1,55 @@ +package com.liuhuiyu.core.util; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-02-05 9:55 + */ +class IgnoredExceptionTest extends TestBase { + + @DisplayName("openId解绑") + @ParameterizedTest(name = "[{index}] {0}") + @MethodSource("argumentsProvider") + public void run(Integer value) { + IgnoredException.run(() -> { + if (value > 10) { + throw new RuntimeException("数字过大"); + } + LOG.info("输入的数字为:{}", value); + }, (ex) -> LOG.info("{}:{}", ex.getMessage(), value)); + } + + @DisplayName("忽略异常获取默认值") + @ParameterizedTest() + @MethodSource("argumentsProvider") + public void get(Integer value) { + int v = value > 10 ? -1 : 0; + final Integer integer = IgnoredException.get(() -> { + if (value > 10) { + throw new Exception(""); + } + Assert.assertTrue(value > 5, ""); + return value; + }, v); + LOG.info("{}->{}", value, integer); + } + + static Stream argumentsProvider() { + return Stream.of( + Arguments.arguments(1), + Arguments.arguments(3), + Arguments.arguments(16), + Arguments.arguments(7), + Arguments.arguments(15) + ); + } + +} \ No newline at end of file diff --git a/model/liuhuiyu-json/.gitignore b/model/liuhuiyu-json/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/model/liuhuiyu-json/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/model/liuhuiyu-json/pom.xml b/model/liuhuiyu-json/pom.xml new file mode 100644 index 0000000..b9d3e45 --- /dev/null +++ b/model/liuhuiyu-json/pom.xml @@ -0,0 +1,69 @@ + + 4.0.0 + + com.liuhuiyu + liuhuiyu-tool-parent + 2023.0.1 + + + liuhuiyu-json + jar + + liuhuiyu-json + http://maven.apache.org + + + UTF-8 + 8 + 8 + 2.8.7 + + + + + com.google.code.gson + gson + ${gson.version} + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + + + compile + + + jar-no-fork + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + -Xdoclint:none + + + + + + + diff --git a/model/liuhuiyu-json/src/main/java/com/liuhuiyu/json/map/MapUtil.java b/model/liuhuiyu-json/src/main/java/com/liuhuiyu/json/map/MapUtil.java new file mode 100644 index 0000000..72aefea --- /dev/null +++ b/model/liuhuiyu-json/src/main/java/com/liuhuiyu/json/map/MapUtil.java @@ -0,0 +1,596 @@ +package com.liuhuiyu.json.map; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.*; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-01-20 14:53 + */ +public class MapUtil { + + boolean throwException = false; + + public boolean isThrowException() { + return throwException; + } + + public void setThrowException(boolean throwException) { + this.throwException = throwException; + } + + //region 静态方法 + + /** + * Map对象转换成对象 + * + * @param obj Map对象 + * @return java.util.Map 对象 + * @author LiuHuiYu + * Created DateTime 2023-04-20 16:32 + */ + public static Map mapObjectToStringKeyMap(Object obj) { + if (obj == null) { + return null; + } + else if (obj instanceof Map) { + Map map = (Map) obj; + Map resMap = new HashMap<>(map.size()); + map.forEach((k, v) -> resMap.put(k.toString(), v)); + return resMap; + } + else { + return new HashMap<>(0); + } + } + + private Object getMapObjectValue(Map map, String key) { + return getMapObjectValue(map, key, null); + } + + private Object getMapObjectValue(Map map, String key, Object defValue) { + return map.getOrDefault(key, defValue); + } + + public static String getMapStringValue(Map map, String key) { + return getMapStringValue(map, key, ""); + } + + /** + * 获取字符串(如果key 不存在返回 “”) + * + * @param map map + * @param key key + * @param defValue 默认值 + * @return java.lang.String 字符串 + * @author LiuHuiYu + * Created DateTime 2023-04-20 16:33 + */ + public static String getMapStringValue(Map map, String key, String defValue) { + if (map.containsKey(key)) { + Object obj = map.get(key); + return obj == null ? defValue : obj.toString(); + } + else { + return defValue; + } + } + + public static Integer getMapIntegerValue(Map map, String key) { + return getMapIntegerValue(map, key, 0); + } + + public static Integer getMapIntegerValue(Map map, String key, Integer defValue) { + Object obj = map.getOrDefault(key, defValue); + if (obj == null) { + return defValue; + } + else if (obj instanceof Number) { + return ((Number) obj).intValue(); + } + else { + String value = obj.toString(); + try { + return Integer.parseInt(value); + } + catch (NumberFormatException ex) { + return defValue; + } + } + } + + public static Float getMapFloatValue(Map map, String key) { + return getMapFloatValue(map, key, 0F); + } + + public static Float getMapFloatValue(Map map, String key, Float defValue) { + Object obj = map.getOrDefault(key, defValue); + if (obj == null) { + return defValue; + } + else if (obj instanceof Number) { + return ((Number) obj).floatValue(); + } + else { + String value = obj.toString(); + try { + return Float.parseFloat(value); + } + catch (NumberFormatException ex) { + return defValue; + } + } + } + + public static Long getMapLongValue(Map map, String key) { + return getMapLongValue(map, key, 0L); + } + + public static Long getMapLongValue(Map map, String key, Long defValue) { + Object obj = map.getOrDefault(key, defValue); + if (obj == null) { + return defValue; + } + else if (obj instanceof Number) { + return ((Number) obj).longValue(); + } + else { + String value = obj.toString(); + try { + return Long.parseLong(value); + } + catch (NumberFormatException ex) { + return defValue; + } + } + } + + public static Boolean getMapBooleanValue(Map map, String key) { + return getMapBooleanValue(map, key, false); + } + + public static Boolean getMapBooleanValue(Map map, String key, boolean defValue) { + Object obj = map.getOrDefault(key, defValue); + if (obj == null) { + return defValue; + } + else if (obj instanceof Boolean) { + return (Boolean) obj; + } + try { + return Boolean.parseBoolean(obj.toString()); + } + catch (Exception ex) { + return defValue; + } + } + + /** + * 将 map 中的 可转化为 int 的数字转化为 int + * + * @param resultMap map + * @return 修正后的map + */ + public static Map mapNumberToInt(Map resultMap) { + Map res = new HashMap<>(resultMap.size()); + for (Object keyObj : resultMap.keySet()) { + String key = keyObj.toString(); + if (resultMap.get(key) instanceof Double) { + Double value = (Double) resultMap.get(key); + if (value.intValue() == value) { + res.put(key, ((Double) resultMap.get(key)).intValue()); + } + else { + res.put(key, resultMap.get(key)); + } + } + else if (resultMap.get(key) instanceof List) { + res.put(key, listNumberToInt((List) resultMap.get(key))); + } + else if (resultMap.get(key) instanceof Map) { + res.put(key, mapNumberToInt((Map) resultMap.get(key))); + } + else { + res.put(key, resultMap.get(key)); + } + } + return res; + } + + /** + * 将 list 中的 可转化为 int 的数字转化为 int + * + * @param list list + * @return 修正后的list + */ + public static List listNumberToInt(List list) { + List res = new ArrayList<>(list.size()); + for (Object o : list) { + if (o instanceof Number) { + Double value = (Double) o; + if (value.intValue() == value) { + Object v = value.intValue(); + res.add(v); + } + else { + res.add(value); + } + } + else if (o instanceof Map) { + res.add(mapNumberToInt((Map) o)); + } + else if (o instanceof List) { + res.add(listNumberToInt((List) o)); + } + else { + res.add(o); + } + } + return res; + } + + + //endregion + public static Map mapOfJsonString(String jsonString) { + try { + Map resultMap = new Gson().fromJson(jsonString, new TypeToken>() { + }.getType()); + return mapDoubleToInt(resultMap); + } + catch (JsonSyntaxException e) { + throw new RuntimeException("无法解析成Map格式数据"); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * 将Map序列化成指定类 + * + * @param map map + * @param classOfT T.class + * @param 得到的类 + * @return T + * @author LiuHuiYu + * Created DateTime 2022-01-22 16:42 + */ + public static T fromMap(Map map, Class classOfT) { + String json = new Gson().toJson(map); + return new Gson().fromJson(json, classOfT); + } + + /** + * 功能描述 + * + * @param map map + * @param classOfT T.class + * @param typeAdapter typeAdapter + * @param 得到的类 + * @return T + * @author LiuHuiYu + * Created DateTime 2023-04-20 16:34 + */ + public static T fromMap(Map map, Class classOfT, GsonAdapter[] typeAdapter) { + GsonBuilder gsonBuilder = new GsonBuilder(); + for (GsonAdapter gsonAdapter : typeAdapter) { + gsonBuilder.registerTypeAdapter(gsonAdapter.type, gsonAdapter.typeAdapter); + } + Gson gson = gsonBuilder.create(); + String json = gson.toJson(map); + return new Gson().fromJson(json, classOfT); + } + + public static class GsonAdapter { + Type type; + Object typeAdapter; + + public GsonAdapter(Type type, Object typeAdapter) { + this.type = type; + this.typeAdapter = typeAdapter; + } + } + + public static Map mapDoubleToInt(Map resultMap) { + Map res = new HashMap<>(resultMap.size()); + for (Object keyObj : resultMap.keySet()) { + String key = keyObj.toString(); + if (resultMap.get(key) instanceof Double) { + Double value = (Double) resultMap.get(key); + if (value.intValue() == value) { + res.put(key, ((Double) resultMap.get(key)).intValue()); + } + else { + res.put(key, resultMap.get(key)); + } + } + else if (resultMap.get(key) instanceof List) { + res.put(key, listDoubleToInt((List) resultMap.get(key))); + } + else if (resultMap.get(key) instanceof Map) { + res.put(key, mapDoubleToInt((Map) resultMap.get(key))); + } + else { + res.put(key, resultMap.get(key)); + } + } + return res; + } + + public static List listDoubleToInt(List list) { + List res = new ArrayList<>(list.size()); + for (Object o : list) { + if (o instanceof Number) { + Double value = (Double) o; + if (value.intValue() == value) { + Object v = value.intValue(); + res.add(v); + } + else { + res.add(value); + } + } + else if (o instanceof Map) { + res.add(mapDoubleToInt((Map) o)); + } + else if (o instanceof List) { + res.add(listDoubleToInt((List) o)); + } + else { + res.add(o); + } + } + return res; + } + + public static MapUtil ofJsonString(String jsonString) { + Map map = mapOfJsonString(jsonString); + return new MapUtil(map); + } + + private final Map map; + + public MapUtil(Map map) { + this.map = map; + } + + public String getStringValue(String key) { + return getMapStringValue(this.map, key); + } + + public String getStringValue(String key, String defValue) { + return getMapStringValue(this.map, key, defValue); + } + + public Integer getIntegerValue(String key) { + return getMapIntegerValue(map, key); + } + + public Integer getIntegerValue(String key, Integer defValue) { + return getMapIntegerValue(map, key, defValue); + } + + public Float getFloatValue(String key) { + return getMapFloatValue(map, key); + } + + public Float getFloatValue(String key, Float defValue) { + return getMapFloatValue(map, key, defValue); + } + + public Long getLongValue(String key) { + return getMapLongValue(map, key); + } + + public Long getLongValue(String key, Long defValue) { + return getMapLongValue(map, key, defValue); + } + + public Object getObjectValue(String key) { + return getMapObjectValue(map, key); + } + + public Object getObjectValue(String key, Object defValue) { + return getMapObjectValue(map, key, defValue); + } + + public T getValue(String key, T defValue) { + Object obj = map.getOrDefault(key, defValue); + if (obj.getClass().equals(defValue.getClass())) { + return (T) obj; + } + else if (throwException) { + throw new RuntimeException("类型转换失败。"); + } + else { + return defValue; + } + } + + public Boolean getBooleanValue(String key) { + return getMapBooleanValue(map, key); + } + + public Boolean getBooleanValue(String key, boolean defValue) { + return getMapBooleanValue(map, key, defValue); + } + + public Timestamp getTimestampValue(String key) { + return getTimestampValue(key, Timestamp.valueOf(LocalDateTime.now())); + } + + public Timestamp getTimestampValue(String key, Timestamp defValue) { + Object obj = map.get(key); + if (obj == null) { + return defValue; + } + else if (obj instanceof Timestamp) { + return (Timestamp) obj; + } + else if (obj instanceof Number) { + return new Timestamp(((Number) obj).longValue()); + } + else if (obj instanceof String) { + try { + return Timestamp.valueOf((String) obj); + } + catch (Exception ex) { + return defValue; + } + } + else { + return defValue; + } + } + + public BigDecimal getBigDecimal(String key) { + return getBigDecimal(key, BigDecimal.ZERO); + } + + public BigDecimal getBigDecimal(String key, BigDecimal defValue) { + Object obj = map.get(key); + if (obj == null) { + return defValue; + } + else if (obj instanceof Double) { + return BigDecimal.valueOf((Double) obj); + } + else if (obj instanceof Long) { + return BigDecimal.valueOf((Long) obj); + } + else if (obj instanceof Number) { + return BigDecimal.valueOf(((Number) obj).doubleValue()); + } + else if (obj instanceof String) { + try { + return new BigDecimal((String) obj); + } + catch (Exception ex) { + return defValue; + } + } + else { + return defValue; + } + } + + public T getValue(String key, Function function) { + return function.apply(map.getOrDefault(key, null)); + } + + public List getListValue(String key, Function function) { + Function> function2 = (obj) -> new ResInfo<>(true, function.apply(obj)); + return getCollectionValueAllowJudgment(key, function2, () -> new ArrayList<>(0)); + } + + public List getListMapValue(String key, Function, T> function) { + Function> function2 = (obj) -> { + Map map = MapUtil.mapObjectToStringKeyMap(obj); + return new ResInfo<>(true, function.apply(map)); + }; + return getCollectionValueAllowJudgment(key, function2, () -> new ArrayList<>(0)); + } + + /** + * Collection获取(List;Set) + * + * @param key 键值 + * @param function 转换 + * @param initializeCollection 初始化 Collection + * @param T + * @param R + * @return R 集合 + * @author LiuHuiYu + * Created DateTime 2021-08-06 9:50 + */ + public > R getCollectionValue(String key, Function function, Supplier initializeCollection) { + Function> function2 = (obj) -> new ResInfo<>(true, function.apply(obj)); + return getCollectionValueAllowJudgment(key, function2, initializeCollection); + } + + /** + * Collection获取(List;Set) + * + * @param key 键值 + * @param function 转换 + * @param initializeCollection 初始化 Collection + * @param R + * @param T + * @return R 集合对象 + * @author LiuHuiYu + * Created DateTime 2021-08-06 9:50 + */ + public > R getCollectionValueAllowJudgment(String key, Function> function, Supplier initializeCollection) { + R resList = initializeCollection.get(); + if (this.map.containsKey(key)) { + Object obj = this.map.get(key); + if (obj instanceof Collection) { + Collection list = (Collection) obj; + list.forEach(item -> { + ResInfo resInfo = function.apply(item); + if (resInfo.res) { + resList.add(resInfo.resData); + } + }); + return resList; + } + else if (this.throwException) { + throw new RuntimeException("无法解析非List数据"); + } + else { + return resList; + } + } + else if (this.throwException) { + throw new RuntimeException("不存在的键值。"); + } + else { + return resList; + } + } + + public Map getMap(String key) { + return getMap(key, new HashMap<>(0)); + } + + public Map getMap(String key, Map defValue) { + Object obj = map.get(key); + if (obj == null) { + return defValue; + } + else { + try { + return mapObjectToStringKeyMap(obj); + } + catch (Exception ignored) { + return defValue; + } + } + } + + public static class ResInfo { + Boolean res; + T resData; + + public ResInfo(Boolean res, T resData) { + this.res = res; + this.resData = resData; + } + } + + public static T cloneObj(T a, Class classOfT) { + String json = new Gson().toJson(a); + return new Gson().fromJson(json, classOfT); + } +} diff --git a/model/liuhuiyu-test/.gitignore b/model/liuhuiyu-test/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/model/liuhuiyu-test/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/model/liuhuiyu-test/pom.xml b/model/liuhuiyu-test/pom.xml new file mode 100644 index 0000000..82f4536 --- /dev/null +++ b/model/liuhuiyu-test/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + liuhuiyu-test + liuhuiyu-tool-test + 2023.0.1 + 测试基础包 + jar + + com.liuhuiyu + liuhuiyu-tool-parent + 2023.0.1 + + + UTF-8 + 5.9.0 + 2.18.0 + 2.9.0 + + + + + org.junit.jupiter + junit-jupiter + ${junit.version} + compile + + + org.apache.logging.log4j + log4j-core + ${log4j2.version} + compile + + + com.google.code.gson + gson + ${gson.version} + compile + + + diff --git a/model/liuhuiyu-test/src/main/java/com/liuhuiyu/test/TestBase.java b/model/liuhuiyu-test/src/main/java/com/liuhuiyu/test/TestBase.java new file mode 100644 index 0000000..82f4bef --- /dev/null +++ b/model/liuhuiyu-test/src/main/java/com/liuhuiyu/test/TestBase.java @@ -0,0 +1,57 @@ +package com.liuhuiyu.test; + +import com.google.gson.Gson; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.config.Configurator; +import org.junit.jupiter.api.BeforeAll; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-04-19 14:10 + */ +public abstract class TestBase { + protected static Logger LOG; + + @BeforeAll + public static void initializeLogger() { + LOG = LogManager.getLogger(); + Configurator.setLevel(LOG, Level.DEBUG); + } + + /** + * 初始化 Logger + * + * @author LiuHuiYu + * Created DateTime 2022-09-08 11:18 + */ + protected void setLoggerValue(final Class clazz, Level level) { + LOG = LogManager.getLogger(clazz); + Configurator.setLevel(LOG, level); + } + + /** + * 初始化 Logger + * + * @param level 级别 + * @author LiuHuiYu + * Created DateTime 2022-09-08 11:18 + */ + protected void setLoggerValue(Level level) { + LOG = LogManager.getLogger(); + org.apache.logging.log4j.core.config.Configurator.setLevel(LOG, level); + } + + /** + * 打印Object序列化到json的信息 + * + * @param obj 打印的对象 + * @author LiuHuiYu + * Created DateTime 2022-09-08 11:21 + */ + protected void printObjectJson(Object obj) { + LOG.info(new Gson().toJson(obj)); + } +} diff --git a/model/liuhuiyu-test/src/test/java/com/liuhuiyu/AppTest.java b/model/liuhuiyu-test/src/test/java/com/liuhuiyu/AppTest.java new file mode 100644 index 0000000..4248285 --- /dev/null +++ b/model/liuhuiyu-test/src/test/java/com/liuhuiyu/AppTest.java @@ -0,0 +1,55 @@ +package com.liuhuiyu; + +import com.liuhuiyu.test.TestBase; +import org.apache.logging.log4j.Level; +import org.junit.jupiter.api.Test; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +/** + * Unit test for simple App. + */ +public class AppTest extends TestBase { + @Test + public void t1() { + super.setLoggerValue(Level.ALL); + LOG.trace("s"); + LOG.debug("s"); + LOG.info("s"); + LOG.warn("s"); + LOG.error("s"); + LOG.fatal("s"); + super.setLoggerValue(Level.INFO); + LOG.trace("s1"); + LOG.debug("s1"); + LOG.info("s1"); + LOG.warn("s1"); + LOG.error("s1"); + LOG.fatal("s1"); + super.setLoggerValue(this.getClass(),Level.WARN); + LOG.trace("s2"); + LOG.debug("s2"); + LOG.info("s2"); + LOG.warn("s2"); + LOG.error("s2"); + LOG.fatal("s2"); + super.setLoggerValue(this.getClass(),Level.ERROR); + LOG.trace("s3"); + LOG.debug("s3"); + LOG.info("s3"); + LOG.warn("s3"); + LOG.error("s3"); + LOG.fatal("s3"); + } + + @Test + public void t2() { + String s = "24:0"; + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("H:m"); + LocalTime t1 = LocalTime.parse(s, formatter); + t1 = t1.plusNanos(-1); + LOG.info(t1); + this.printObjectJson(t1); + } +} diff --git a/model/liuhuiyu-test/src/test/java/com/liuhuiyu/test/TestBaseTest.java b/model/liuhuiyu-test/src/test/java/com/liuhuiyu/test/TestBaseTest.java new file mode 100644 index 0000000..7dbc440 --- /dev/null +++ b/model/liuhuiyu-test/src/test/java/com/liuhuiyu/test/TestBaseTest.java @@ -0,0 +1,12 @@ +package com.liuhuiyu.test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2023-04-19 14:15 + */ +class TestBaseTest { + +} \ No newline at end of file diff --git a/model/liuhuiyu-tool-parent.iml b/model/liuhuiyu-tool-parent.iml new file mode 100644 index 0000000..7a796ae --- /dev/null +++ b/model/liuhuiyu-tool-parent.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/model/pom.xml b/model/pom.xml new file mode 100644 index 0000000..128a8ed --- /dev/null +++ b/model/pom.xml @@ -0,0 +1,116 @@ + + + 4.0.0 + + pom + + com.liuhuiyu + liuhuiyu-tool-parent + 2023.0.1 + liuhuiyu-tool-parent + liuhuiyu工具箱 + https://github.com/liuhuiyu2004/utils + + liuhuiyu-test + liuhuiyu-core + liuhuiyu-json + + + + UTF-8 + UTF-8 + + 8 + + + + + + + + Github Issue + https://github.com/liuhuiyu2004/utils/issues + + + + + Mulan Permissive Software License,Version 2 + https://license.coscl.org.cn/MulanPSL2 + + + + + liuhuiyu + liuhuiyu2004@outlook.com + http://liuhuiyu.com + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${compile.version} + ${compile.version} + UTF-8 + -Xlint:unchecked + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.4.0 + + + package + + jar + + + + + + + + + + release + + + oss + https://oss.sonatype.org/content/repositories/snapshots/ + + + oss + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + oss + package + + jar-no-fork + + + + + + + + + + \ No newline at end of file diff --git a/myJs/js/demo.js b/myJs/js/demo.js new file mode 100644 index 0000000..e6ccb00 --- /dev/null +++ b/myJs/js/demo.js @@ -0,0 +1,3 @@ +//分页 +let paging=new ProgPaging({}); +paging.showPage(10,5,6); \ No newline at end of file diff --git a/myJs/js/progFunction.js b/myJs/js/progFunction.js new file mode 100644 index 0000000..4b15cde --- /dev/null +++ b/myJs/js/progFunction.js @@ -0,0 +1,391 @@ +/** + * 程序通用函数 + * @type {{assignObj: (function(*=, *=): *), exitFullScreen: progFunction.exitFullScreen, isFullScreen: (function(): boolean), getMaxZIndex: (function(): any), fullScreen: progFunction.fullScreen}} + */ +progFunction = { + /** + * 功能描述 + * @author LiuHuiYu + * Created DateTime 2021-03-15 9:00 + * @param url + * @param data + * @param backFunction {success,error,complete}回调函数 + * @return + */ + ajax: function (url, data, backFunction) { + if (typeof (backFunction.beforeSend) === "undefined") { + backFunction.beforeSend = function (xhr) { + xhr.setRequestHeader("Authorization", "Basic " + btoa("test:test")); + }; + } + $.ajax({ + type: "POST", + url: url, + dataType: "json", + async: true, + data: data, + traditional: true, + beforeSend: function (xhr) { + backFunction.beforeSend(xhr); + }, + success: function (res) { + if (res.success) { + progFunction.runFunc(backFunction.success, res.data); + } + else { + // debugger; + progFunction.runFunc(backFunction.error, res.msg); + } + }, + error: function (res) { + // debugger; + progFunction.runFunc(backFunction.error, "错误码:" + res.status); + }, + complete: function () { + progFunction.runFunc(backFunction.complete); + } + }); + }, + runFunc: function (runFunction, v1, v2, v3, v4, v5) { + if (typeof (runFunction) === "function") { + runFunction(v1, v2, v3, v4, v5); + } + }, + /** + * 进入全屏 + */ + fullScreen: function () { + try { + let docElm = document.documentElement; + //W3C + if (docElm.requestFullscreen) { + docElm.requestFullscreen(); + } + //FireFox + else if (docElm.mozRequestFullScreen) { + docElm.mozRequestFullScreen(); + } + //Chrome等 + else if (docElm.webkitRequestFullScreen) { + docElm.webkitRequestFullScreen(); + } + //IE11 + else if (docElm.msRequestFullscreen) { + docElm.msRequestFullscreen(); + } + } catch (error) { + console.error("执行全屏失败:", error); + } + }, + /** + * 节点全屏 + * @author LiuHuiYu + * Created DateTime 2021-03-05 15:01 + * @param element 元素 + * @return + */ + launchFullScreen: function (element) { + if (element.requestFullscreen) { + element.requestFullscreen(); + } + else if (element.mozRequestFullScreen) { + element.mozRequestFullScreen();//火狐 + } + else if (element.msRequestFullscreen) { + element.msRequestFullscreen();//ie浏览器 + document.getElementById("fullScreen").style.height = window.screen.height + "px"; + document.getElementById("fullScreen").style.width = document.documentElement.clientWidth + "px"; + } + else if (element.webkitRequestFullscreen) { + element.webkitRequestFullScreen();//谷歌浏览器 + } + }, + /** + * 退出全屏 + */ + exitFullScreen: function () { + if (document.exitFullscreen) { + document.exitFullscreen(); + } + else if (document.mozCancelFullScreen) { + document.mozCancelFullScreen(); + } + else if (document.webkitCancelFullScreen) { + document.webkitCancelFullScreen(); + } + else if (document.msExitFullscreen) { + document.msExitFullscreen(); + } + }, + /** + * 当前是否全屏 + * @returns {boolean, undefined}ie11检测不到是否全屏 + */ + isFullScreen: function () { + if (document.fullscreen !== undefined) { + return document.fullscreen; + } + else if (document.mozFullScreen !== undefined) { + return document.mozFullScreen; + } + else if (document.webkitIsFullScreen !== undefined) { + return document.webkitIsFullScreen; + } + else if (document.webkitFullScreen !== undefined) { + return document.webkitFullScreen; + } + else if (document.msFullScreen !== undefined) { + return document.msFullScreen; + } + else { + return undefined; + } + }, + /** + * 最大的 zIndex 获取 + * @returns {number} + */ + getMaxZIndex: function () { + return Math.max.apply(null, + $.map($('body *'), function (e) { + if ($(e).css('position') !== 'static') + return parseInt($(e).css('z-index')) || -1; + })); + }, + /** + * 对象合并 + * @param target 原始对象 + * @param sources 加入的合并数据 + * @returns {*} + */ + assignObj: function (target, sources) { + let obj = target; + if (typeof target != 'object' || typeof sources == 'function') { + if (typeof target == 'function' && typeof sources != 'function') { + return target; + } + return sources; + } + if (typeof sources != 'object') { + return target; + } + for (let key in sources) { + if (sources.hasOwnProperty(key)) { + // 如果target也存在 那就再次合并 + obj[key] = target.hasOwnProperty(key) ? progFunction.assignObj(target[key], sources[key]) : sources[key]; + } + } + return obj; + }, + /** + * 深层复制 + * @author LiuHuiYu + * Created DateTime 2021-03-03 10:22 + * @param obj + * @return + */ + clone: function (obj) { + let o; + if (typeof obj == "object") { + if (obj === null) { + o = null; + } + else { + if (obj instanceof Array) { + o = []; + for (let i = 0, len = obj.length; i < len; i++) { + o.push(progFunction.clone(obj[i])); + } + } + else { + o = {}; + for (let j in obj) { + if (obj.hasOwnProperty(j)) { + o[j] = progFunction.clone(obj[j]); + } + } + } + } + } + else { + o = obj; + } + return o; + }, + stringIsEmpty: function (obj) { + return typeof (obj) == "string" && obj.trim() === ""; + }, + stringIsNotEmpty: function (obj) { + return typeof (obj) == "string" && obj.trim() !== ""; + }, + /** + * 默认赋值 + * @author LiuHuiYu + * Created DateTime 2021-03-16 9:56 + * @param inputValue 传入值 + * @param defValue 默认返回值(null) + * @param allowNull 允许null + * @return + */ + defaultValue: function (inputValue, defValue, allowNull) { + if (allowNull === undefined) { + allowNull = false; + } + if (inputValue === undefined || (inputValue === null && !allowNull)) { + if (defValue === undefined) { + return null; + } + return defValue; + } + return inputValue; + }, + /** + * 是否是ie浏览器 + * @returns {boolean} + * @constructor + */ + isIE: function () { + return (!!window.ActiveXObject || "ActiveXObject" in window); + }, + /** + * 遍历循环map + * @author LiuHuiYu + * Created DateTime 2021-03-06 15:07 + * @param map 循环map + * @param func(value,key) 对象操作 + * @return 是否结束循环 + */ + forMap: function (map, func) { + for (let key in map) { + if (map.hasOwnProperty(key)) { + let res = func(map[key], key); + if (res === true) { + break; + } + } + } + }, + /** + * 遍历循环 array(反向循环) + * @author LiuHuiYu + * Created DateTime 2021-03-08 11:12 + * @param array 数组 + * @param func 便利函数返回true 结束循环 + * @return boolean 是否终止循环跳出 + */ + forArray: function (array, func) { + let isBreak = false; + for (let index = array.length - 1; index >= 0; index--) { + isBreak = func(array[index], index); + if (isBreak === true) { + break; + } + } + return isBreak; + }, + formatDate: function (date, fmt) { + if (/(y+)/.test(fmt)) { + fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); + } + let o = { + 'M+': date.getMonth() + 1, + 'd+': date.getDate(), + 'h+': date.getHours(), + 'm+': date.getMinutes(), + 's+': date.getSeconds() + }; + for (let k in o) { + let t = new RegExp('(' + k + ')'); + if (t.test(fmt)) { + let str = o[k] + ''; + fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str)); + } + } + + function padLeftZero(str) { + return ('00' + str).substr(str.length) + } + + return fmt; + }, + formatTimestamp: function (timestamp, fmt) { + let date = new Date(timestamp); + return progFunction.formatDate(date, fmt) + }, + /** + * 获取随机数 + * @author LiuHuiYu + * Created DateTime 2021-03-18 15:02 + * @param start 最小数 + * @param end 最大数 + * @param fixed 是整数 + * @return + */ + getRandom: function (start, end, fixed) { + if (fixed === undefined) { + fixed = 0; + } + let differ = end - start + let random = Math.random() + return (start + differ * random).toFixed(fixed) + }, + /** + * 消息管理 + * @author LiuHuiYu + * Created DateTime 2021-04-29 16:07 + * @param null + * @return null + */ + messageQueueManagement: { + /** + * 创建消息管理 + * @author LiuHuiYu + * Created DateTime 2021-04-29 16:07 + * @param props {backFunction} + * @return null + */ + create: function (props) { + let baseProps = {backFunction: null}; + let nowProps = progFunction.assignObj(baseProps, props); + let mqList = []; + + function newInfo(info) { + let newV = { + id: "mq" + performance.now() + "_" + Math.floor(Math.random() * 100000000), + info: info, + } + mqList.push(newV); + change("D", message); + return newV; + } + + function removeInfo(message) { + for (let i = mqList.length - 1; i >= 0; i--) { + if (mqList[i].id === message.id) { + mqList.splice(i, 1); + change("D", message); + return; + } + } + } + + function change(type, data) { + if (nowProps.backFunction) { + nowProps.backFunction(type, data); + } + } + + return { + putInfo: function (info) { + return newInfo(info); + }, + removeInfo: function (message) { + removeInfo(message) + }, + getList: function () { + return mqList; + } + }; + } + }, +} \ No newline at end of file diff --git a/myJs/js/progLoading.js b/myJs/js/progLoading.js new file mode 100644 index 0000000..1bdb60a --- /dev/null +++ b/myJs/js/progLoading.js @@ -0,0 +1,156 @@ +// +// 需要 progFunction.js 支持 +// + +/** + * 数据加载蒙版 + * @param property + * @constructor + */ +function ProgLoading(property) { + let baseProperty = { + style: { + masking: { + 'width': '100%', + 'height': '100%', + 'top': '0', + 'left': '0', + 'position': 'absolute', + 'text-align': 'center', + 'background-color': '#00000077', + }, + box: { + 'background-color': '#000161', + 'color': '#00ffd5', + 'top': '50%', + 'left': '50%', + 'position': 'absolute', + 'transform': 'translate(-50%, -50%)', + 'padding': '20px 50px', + }, + }, + class: { + masking_class: [], + masking_style: {}, + box_class: [], + box_style: {}, + }, + info: { + div: null, + content: "数据加载中......", + }, + }; + let div;//蒙版 + let box;//对话框 + let autoClose = false; + let nowShowState = false; + initProgLoading(property); + + /** + * 参数合并初始化 + * @param property + */ + function initProgLoading(property) { + console.log('参数初始化'); + if (typeof (property) === "string") { + //字符串的话就作为信息传入处理 + property = {info: {content: property,}} + } + progFunction.assignObj(baseProperty, property); + } + + /** + * 添加class + * @param item + * @param classList + */ + function addClass(item, classList) { + for (let i = 0, len = classList.length; i < len; i++) { + item.classList.add(classList[i]); + } + } + + /** + * 添加样式 + * @param item + * @param styles + */ + function addStyle(item, styles) { + for (let key in styles) { + if (styles.hasOwnProperty(key)) { + item.style[key] = styles[key]; + } + } + } + + /** + * 显示loading + * @param property + */ + this.show = function (property) { + initProgLoading(property); + if (div === undefined) { + let nowZIndex = progFunction.getMaxZIndex() + 100; + div = document.createElement("div"); + div.style['z-index'] = nowZIndex; + if (autoClose) { + let _this = this; + div.onclick = _this.close; + } + } + else { + //样式 class 清理 + } + //region 蒙版样式设定 + if (baseProperty.class.masking_class.length > 0) { + addClass(div, baseProperty.class.masking_class); + addStyle(div, baseProperty.class.masking_style); + } + else { + addStyle(div, baseProperty.style.masking); + } + //endregion + if (box === undefined) { + box = document.createElement("div"); + div.appendChild(box); + } + //region box样式设定 + if (baseProperty.class.box_class.length > 0) { + addClass(box, baseProperty.class.box_class); + addStyle(box, baseProperty.class.box_style); + } + else { + addStyle(box, baseProperty.style.box); + } + box.innerHTML = baseProperty.info.content; + document.body.append(div); + nowShowState = true; + return this; + } + this.close = function () { + if (div !== undefined && nowShowState) { + nowShowState = false; + document.body.removeChild(div); + } + } + /** + * 显示信息到时间自动关闭 + * @author LiuHuiYu + * Created DateTime 2021-02-18 10:36 + * @param property 参数 + * @param time 显示时间(毫秒) + * @return + */ + this.showInfo = function (property, time) { + autoClose = true; + if (time === undefined) { + time = 3000; + } + this.show(property); + let _this = this; + setTimeout(function () { + _this.close(); + }, time); + return this; + } +} \ No newline at end of file diff --git a/myJs/js/progPaging.js b/myJs/js/progPaging.js new file mode 100644 index 0000000..27095b8 --- /dev/null +++ b/myJs/js/progPaging.js @@ -0,0 +1,154 @@ +/** + * 分页功能 + * @author LiuHuiYu + * Created DateTime 2021-02-07 10:09 + * @param property {showFirstPage,showLastPage,parentDiv,outerDiv,outPage,goPageEvent} + * @return + */ +function ProgPaging(property) { + let baseProperty = { + /** + * 显示首页 + */ + showFirstPage: true, + /** + * 显示末页 + */ + showLastPage: true, + /** + * 分页上级节点(如果没有默认是body) + */ + parentDiv: null, + /** + * 分页Dom + */ + outerDiv: null, + /** + * 输出函数 + * 参数(页面索引,是否是当前页,是否是首页,是否是末页) + */ + outPage: setPage, + /** + * 跳转事件函数 + */ + goPageEvent: goPage, + }; + Object.assign(baseProperty, property); + + /** + * 设置更新分页页面 + * @param index 当前索引 + * @param isNowPage 是否是当前页面 + * @param isFirst 是否是第一页 + * @param isLast 是否是最后一页 + */ + function setPage(index, isNowPage, isFirst, isLast) { + let li = document.createElement("li"); + if (!isNowPage) { + (function (index) { + //监听点击事件 object比如google地图中的Maker对象 + li.addEventListener("click", function () { + baseProperty.goPageEvent(index); //调用方法 + }); + })(index); + } + if (isNowPage) { + li.innerHTML = '(' + (index + 1) + ')'; + } + else if (isFirst) { + li.innerHTML = '首页'; + } + else if (isLast) { + li.innerHTML = '末页'; + } + else { + li.innerHTML = (index + 1); + } + + baseProperty.outerDiv.appendChild(li); + } + + function goPage(index) { + console.info("跳转" + index); + } + + /** + * 功能描述 + * @author LiuHuiYu + * Created DateTime 2021-02-07 10:15 + * @param countPageNum 总页数 + * @param nowPageIndex 当前页索引(0开始) + * @param showPageNum 显示页面数量(最少显示3页) + * @param property 更新设定参数 + * @return + */ + this.showPage = function page(countPageNum, nowPageIndex, showPageNum, property) { + Object.assign(baseProperty, property); + + //region 异常数据处理 + if (countPageNum <= 1) { + //不显示 + return; + } + if (showPageNum < 3) { + showPageNum = 3; + } + //页面异常数据处理 + if (nowPageIndex < 0) { + nowPageIndex = 0; + } + else if (nowPageIndex > countPageNum - 1) { + nowPageIndex = countPageNum - 1 + } + if (showPageNum > countPageNum) { + showPageNum = countPageNum; + } + //endregion + //显示页面的中间位置//取丢弃小数部分,保留整数部分 + let halfAmount = Math.ceil((showPageNum - 1) / 2); + let amendmentsNum = (showPageNum + 1) % 2; + let frontNumber, afterNumber; + //当前页面位置判断。 + if (nowPageIndex <= halfAmount) { + frontNumber = nowPageIndex; + afterNumber = showPageNum - 1 - frontNumber; + } + else if ((countPageNum - nowPageIndex - 1) <= halfAmount) { + afterNumber = countPageNum - nowPageIndex - 1; + frontNumber = showPageNum - 1 - afterNumber; + } + else { + if (countPageNum / 2 > nowPageIndex) { + frontNumber = halfAmount + amendmentsNum; + afterNumber = showPageNum - 1 - frontNumber; + } + else { + afterNumber = halfAmount + amendmentsNum; + frontNumber = showPageNum - 1 - afterNumber; + } + } + + if (baseProperty.parentDiv == null) { + baseProperty.parentDiv = document.createElement("div"); + document.body.append(baseProperty.parentDiv); + } + if (baseProperty.outerDiv == null) { + baseProperty.outerDiv = document.createElement("lu"); + baseProperty.parentDiv.appendChild(baseProperty.outerDiv); + } + baseProperty.outerDiv.innerHTML = ''; + if ((nowPageIndex - frontNumber) > 0) { + setPage(0, (nowPageIndex === 0), true, false); + } + for (let i = frontNumber; i > 0; i--) { + setPage(nowPageIndex - i, false, false, false); + } + setPage(nowPageIndex, true, false, false); + for (let i = 0; i < afterNumber; i++) { + setPage(nowPageIndex + i + 1, false, false, false); + } + if ((nowPageIndex + afterNumber) < countPageNum - 1) { + setPage(countPageNum - 1, (nowPageIndex === (countPageNum - 1)), false, true); + } + } +} diff --git a/myJs/myJs.iml b/myJs/myJs.iml new file mode 100644 index 0000000..80cc739 --- /dev/null +++ b/myJs/myJs.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/okhttp3util/okhttp3util.iml b/okhttp3util/okhttp3util.iml new file mode 100644 index 0000000..c47cdcd --- /dev/null +++ b/okhttp3util/okhttp3util.iml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/okhttp3util/pom.xml b/okhttp3util/pom.xml new file mode 100644 index 0000000..29276c8 --- /dev/null +++ b/okhttp3util/pom.xml @@ -0,0 +1,141 @@ + + + 4.0.0 + + com.liuhuiyu + okhttp3util + 2021.2.2 + jar + + + UTF-8 + 1.8 + 1.8 + 4.10.0-RC1 + 2.17.1 + + + + + org.junit.jupiter + junit-jupiter-api + 5.8.2 + test + + + org.apache.logging.log4j + log4j-api + ${log4j2.version} + test + + + org.slf4j + slf4j-api + 2.0.0-alpha5 + test + + + + + + + + + + + + + + + + + com.squareup.okhttp3 + okhttp + + ${okhttp.version} + + + com.google.code.gson + gson + 2.8.6 + + + + + + + + + + + + + + org.apache.commons + commons-lang3 + 3.9 + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + 1.3.70 + + + compile + process-sources + + compile + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-resources + process-resources + + copy-resources + + + ${project.build.outputDirectory} + + + src/main/java + + **/*.java + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/okhttp3util/src/main/java/com/liuhuiyu/okhttp/OkHttpException.java b/okhttp3util/src/main/java/com/liuhuiyu/okhttp/OkHttpException.java new file mode 100644 index 0000000..76a630a --- /dev/null +++ b/okhttp3util/src/main/java/com/liuhuiyu/okhttp/OkHttpException.java @@ -0,0 +1,12 @@ +package com.liuhuiyu.okhttp; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-01-09 17:30 + */ +public class OkHttpException extends RuntimeException{ + public OkHttpException(String message) { + super(message); + } +} diff --git a/okhttp3util/src/main/java/com/liuhuiyu/okhttp/OkHttpUtil.java b/okhttp3util/src/main/java/com/liuhuiyu/okhttp/OkHttpUtil.java new file mode 100644 index 0000000..2e56720 --- /dev/null +++ b/okhttp3util/src/main/java/com/liuhuiyu/okhttp/OkHttpUtil.java @@ -0,0 +1,609 @@ +package com.liuhuiyu.okhttp; + +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; +import com.google.gson.reflect.TypeToken; +import okhttp3.*; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; + +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.util.*; +import java.util.concurrent.TimeUnit; + +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.SecureRandom; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Collection; +import java.util.function.Supplier; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +/** + * 早期编写的比较过时,现在都在使用 OkHttpUtil2 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-01-09 15:06 + */ +public class OkHttpUtil { + private final OkHttpClient.Builder client; +// private final Request.Builder builder; + /** + * 保存body中的form-data、x-www-form-urlencoded 信息 + * Created DateTime 2021-03-29 22:00 + */ +// private final Map bodyMap; + private final List bodyMap; + /** + * 保存params信息 + * Created DateTime 2021-03-29 21:58 + */ + private final Map paramMap; + private final List headerList; + private String method; + private String bodyString = ""; + private Object tag; + public static final String MEDIA_TYPE_APPLICATION_JSON_UTF_8 = "application/json;charset=utf-8"; + public static final int CONNECT_TIMEOUT = 15; + public static final int READ_TIMEOUT = 15; + public static final int WRITE_TIMEOUT = 15; + + private OkHttpUtil(int connectTimeout, int readTimeout, int writeTimeout) { + this.client = new OkHttpClient.Builder() + .retryOnConnectionFailure(true) + .connectTimeout(connectTimeout, TimeUnit.SECONDS) + .readTimeout(readTimeout, TimeUnit.SECONDS) + .writeTimeout(writeTimeout, TimeUnit.SECONDS) + .connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)); + //.build(); + this.paramMap = new HashMap<>(0); +// this.bodyMap = new HashMap<>(0); + this.bodyMap = new ArrayList<>(0); + this.headerList = new ArrayList<>(); + this.method = ""; + } +// public void https(){ +// this.client.hostnameVerifier(new HostnameVerifier() { +// @Override +// public boolean verify(String hostname, SSLSession session) { +// return true; +// } +// }).sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager); +// } + + /** + * 创建实例 + * + * @return 实例 + */ + public static OkHttpUtil create() { + return create(CONNECT_TIMEOUT, READ_TIMEOUT, WRITE_TIMEOUT); + } + + /** + * 创建实例 + * + * @param connectTimeout 连接超时 + * @param readTimeout 读取超时 + * @param writeTimeout 写入超时 + * @return com.liuhuiyu.okhttp.OkHttpUtil + * @author LiuHuiYu + * Created DateTime 2021-03-30 9:39 + */ + public static OkHttpUtil create(int connectTimeout, int readTimeout, int writeTimeout) { + return new OkHttpUtil(connectTimeout, readTimeout, writeTimeout); + } + + public void setMethod(String value) { + this.method = value == null ? "" : value.trim(); + } + + public void setBodyString(String bodyString) { + this.bodyString = bodyString; + } + + public void setTag(Object tag) { + this.tag = tag; + } + + /** + * 添加 body + * + * @param key 键值 + * @param value 数值 + * @return OkHttpUtil + */ + public OkHttpUtil addBody(String key, String value) { + this.bodyMap.add(new String[]{key, value}); +// this.bodyMap.put(key, value); + return this; + } + + /** + * 添加uri参数 + * + * @param key 键值 + * @param value 数值 + * @return OkHttpUtil + */ + public OkHttpUtil addQueryParameter(String key, String value) { + this.paramMap.put(key, value); + return this; + } + + /** + * 添加Header + * + * @param key 键值 + * @param value 数值 + * @return OkHttpUtil + */ + public OkHttpUtil addHeader(String key, String value) { + this.headerList.add(new String[]{key, value}); + return this; + } + + /** + * 加入认证 + * + * @param username 认证账号 + * @param password 认证密码 + * @return OkHttpUtil + */ + public OkHttpUtil headerAuthorizationByBasicAuth(String username, String password) { + String base64AppMsg; + String appMsg = username + ":" + password; + base64AppMsg = Base64.getEncoder().encodeToString(appMsg.getBytes(StandardCharsets.UTF_8)); + return this.addHeader("Authorization", "Basic " + base64AppMsg); + } + + public OkHttpUtil headerAuthorizationByBearerToken(String token) { + return this.addHeader("Authorization", "Bearer " + token); + } + + //region 生成基本数据 + private HttpUrl getHttpUrl(String url) { + HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder(); + this.paramMap.forEach(urlBuilder::addQueryParameter); + return urlBuilder.build(); + } + + private RequestBody getRequestBody() { + RequestBody body; + if (this.bodyMap.size() > 0) { +// if ("".equals(this.method)) { + FormBody.Builder bodyBuilder = new FormBody.Builder(); +// this.bodyMap.forEach(bodyBuilder::add); + this.bodyMap.forEach((infos) -> bodyBuilder.add(infos[0], infos[1])); + body = bodyBuilder.build(); +// bodyBuilder.add("a", "1"); +// } +// else { +// Gson gson = new Gson(); +// String jsonData = gson.toJson(bodyMap); +// body = RequestBody.create(jsonData, MediaType.parse(this.method)); +// } + } + else if (StringUtils.isNotBlank(this.bodyString)) { + MediaType mediaType = MediaType.parse(this.method); +// body = RequestBody.create(MediaType.parse(this.method),this.bodyString); + body = RequestBody.create(mediaType, this.bodyString); + } + else { + body = new FormBody.Builder().build(); + } + return body; + } + + private void addHeader(Request.Builder builder) { + this.headerList.forEach(keyValue -> builder.addHeader(keyValue[0], keyValue[1])); + } + + private void addTag(Request.Builder builder) { + if (this.tag != null) { + builder.tag(this.tag); + } + } + //endregion + //region post申请 + + /** + * 执行 post + * + * @param url 地址 + * @return Response + */ + public Response executePost(String url) { + try { + HttpUrl httpUrl = this.getHttpUrl(url); + RequestBody body = this.getRequestBody(); + + Request.Builder builder = new Request.Builder(); + this.addHeader(builder); + this.addTag(builder); + builder.post(body); + builder.url(httpUrl); + /* builder.method(this.method,body); */ + Request request = builder.build(); + return this.client.build().newCall(request).execute(); + } + catch (IOException e) { + throw new OkHttpException(e.getMessage()); + } + } + + public String executePostToString(String url) { + try (Response response = this.executePost(url)) { + return Objects.requireNonNull(response.body()).string(); + } + catch (IOException e) { + throw new OkHttpException(e.getMessage()); + } + } + + public Map executePostToMap(String url) { + String strJson = this.executePostToString(url); + return getStringObjectMap(strJson); + } + + public List executePostToList(String url) { + return executeList(() -> this.executePostToString(url)); + } + //endregion + + //region get申请 + + /** + * @param url 地址 + * @return Response + */ + public Response executeGet(String url) { + try { + HttpUrl httpUrl = this.getHttpUrl(url); + Request.Builder builder = new Request.Builder(); + this.addHeader(builder); + this.addTag(builder); + builder.get(); + builder.url(httpUrl); + Request request = builder.build(); + return this.client.build().newCall(request).execute(); + } + catch (IOException e) { + throw new OkHttpException(e.getMessage()); + } + } + + public String executeGetToString(String url) { + String resData; + try (Response response = this.executeGet(url)) { + resData = Objects.requireNonNull(response.body()).string(); + } + catch (IOException e) { + throw new OkHttpException(e.getMessage()); + } + return resData; + } + + public Map executeGetToMap(String url) { + return executeMap(() -> this.executeGetToString(url)); + } + + public List executeGetList(String url) { + return executeList(() -> this.executeGetToString(url)); + } + //endregion + + //region put申请 + + /** + * @param url 地址 + * @return Response + */ + public Response executePut(String url) { + try { + HttpUrl httpUrl = this.getHttpUrl(url); + RequestBody body = this.getRequestBody(); + + Request.Builder builder = new Request.Builder(); + this.addHeader(builder); + this.addTag(builder); + builder.put(body); + builder.url(httpUrl); + Request request = builder.build(); + return this.client.build().newCall(request).execute(); + } + catch (IOException e) { + throw new OkHttpException(e.getMessage()); + } + + } + + public String executePutToString(String url) { + try (Response response = this.executePut(url)) { + return Objects.requireNonNull(response.body()).string(); + } + catch (IOException e) { + throw new OkHttpException(e.getMessage()); + } + } + + public Map executePutToMap(String url) { + String strJson = this.executePutToString(url); + return getStringObjectMap(strJson); + } + + public List executePutList(String url) { + return executeList(() -> this.executePutToString(url)); + } + //endregion + + //region webSocket + public static WebSocket webSocket(String url, WebSocketListener webSocketListener) { + OkHttpClient client = new OkHttpClient.Builder().retryOnConnectionFailure(true).build(); + Request request = new Request.Builder().url(url).build(); + client.dispatcher().cancelAll();//清理一次 + + return client.newWebSocket(request, webSocketListener); + } + //endregion + + /** + * 使用函数式将String转换成Map + * + * @param supplier 数据获取函数式 + * @return java.util.Map + * @author LiuHuiYu + * Created DateTime 2021-04-16 9:08 + */ + private static Map executeMap(Supplier supplier) { + String strJson = supplier.get(); + return getStringObjectMap(strJson); + } + + /** + * 使用函数式将String转换成List + * + * @param supplier 数据获取函数式 + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2021-04-16 9:09 + */ + private static List executeList(Supplier supplier) { + String strJson = supplier.get(); + return getStringObjectList(strJson); + } + + /** + * 将json字符串转换成Map + * + * @param strJson json字符串 + * @return java.util.Map + * @author LiuHuiYu + * Created DateTime 2021-03-30 9:04 + */ + @NotNull + public static Map getStringObjectMap(String strJson) { + try { + if (strJson == null) { + return new HashMap<>(0); + } + Gson gson = new Gson(); + Map resultMap = gson.fromJson(strJson, new TypeToken>() { + }.getType()); + if(resultMap==null){ + return new HashMap<>(0); + } + return mapDoubleToInt(resultMap); + } + catch (JsonSyntaxException e) { + throw new OkHttpException(e.getMessage()); + } + } + + public static List getStringObjectList(String strJson) { + try { + Gson gson = new Gson(); + List resultList = gson.fromJson(strJson, new TypeToken>() { + }.getType()); + return listDoubleToInt(resultList); + } + catch (JsonSyntaxException e) { + throw new OkHttpException(e.getMessage()); + } + } + + public static Map mapDoubleToInt(Map resultMap) { + Map res = new HashMap<>(resultMap.size()); + for (Object keyObj : resultMap.keySet()) { + String key = keyObj.toString(); + if (resultMap.get(key) instanceof Double) { + Double value = (Double) resultMap.get(key); + if (value.intValue() == value) { + res.put(key, ((Double) resultMap.get(key)).intValue()); + } + else { + res.put(key, resultMap.get(key)); + } + } + else if (resultMap.get(key) instanceof List) { + res.put(key, listDoubleToInt((List) resultMap.get(key))); + } + else if (resultMap.get(key) instanceof Map) { + res.put(key, mapDoubleToInt((Map) resultMap.get(key))); + } + else { + res.put(key, resultMap.get(key)); + } + } + return res; + } + + public static List listDoubleToInt(List list) { + List res = new ArrayList<>(list.size()); + for (Object o : list) { + if (o instanceof Number) { + Double value = (Double) o; + if (value.intValue() == value) { + Object v = value.intValue(); + res.add(v); + } + else { + res.add(value); + } + } + else if (o instanceof Map) { + res.add(mapDoubleToInt((Map) o)); + } + else if (o instanceof List) { + res.add(listDoubleToInt((List) o)); + } + else { + res.add(o); + } + } + return res; + } + + //region https支持 + private MyTrustManager mMyTrustManager; + + public OkHttpUtil https() { + this.client.sslSocketFactory(createSSLSocketFactory(), mMyTrustManager) + .hostnameVerifier(new TrustAllHostnameVerifier()); + return this; + } + + private SSLSocketFactory createSSLSocketFactory() { + SSLSocketFactory ssfFactory = null; + try { + mMyTrustManager = new MyTrustManager(); + SSLContext sc = SSLContext.getInstance("TLS"); + sc.init(null, new TrustManager[]{mMyTrustManager}, new SecureRandom()); + ssfFactory = sc.getSocketFactory(); + } + catch (Exception ignored) { + ignored.printStackTrace(); + } + + return ssfFactory; + } + + //实现X509TrustManager接口 + public static class MyTrustManager implements X509TrustManager { + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + } + + //实现HostnameVerifier接口 + private static class TrustAllHostnameVerifier implements HostnameVerifier { + @Override + public boolean verify(String hostname, SSLSession session) { + return true; + } + } + + /** + * 对外提供的获取支持自签名的okhttp客户端 + * + * @param certificate 自签名证书的输入流 + * @return 支持自签名的客户端 + */ + public OkHttpClient getTrusClient(InputStream certificate) { + X509TrustManager trustManager; + SSLSocketFactory sslSocketFactory; + try { + trustManager = trustManagerForCertificates(certificate); + SSLContext sslContext = SSLContext.getInstance("TLS"); + //使用构建出的trustManger初始化SSLContext对象 + sslContext.init(null, new TrustManager[]{trustManager}, null); + //获得sslSocketFactory对象 + sslSocketFactory = sslContext.getSocketFactory(); + } + catch (GeneralSecurityException e) { + throw new RuntimeException(e); + } + return new OkHttpClient.Builder() + .sslSocketFactory(sslSocketFactory, trustManager) + .build(); + } + + /** + * 获去信任自签证书的trustManager + * + * @param in 自签证书输入流 + * @return 信任自签证书的trustManager + * @throws GeneralSecurityException + */ + private X509TrustManager trustManagerForCertificates(InputStream in) + throws GeneralSecurityException { + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); + //通过证书工厂得到自签证书对象集合 + Collection certificates = certificateFactory.generateCertificates(in); + if (certificates.isEmpty()) { + throw new IllegalArgumentException("expected non-empty set of trusted certificates"); + } + //为证书设置一个keyStore + char[] password = "password".toCharArray(); // Any password will work. + KeyStore keyStore = newEmptyKeyStore(password); + int index = 0; + //将证书放入keystore中 + for (Certificate certificate : certificates) { + String certificateAlias = Integer.toString(index++); + keyStore.setCertificateEntry(certificateAlias, certificate); + } + // Use it to build an X509 trust manager. + //使用包含自签证书信息的keyStore去构建一个X509TrustManager + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance( + KeyManagerFactory.getDefaultAlgorithm()); + keyManagerFactory.init(keyStore, password); + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( + TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(keyStore); + TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); + if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) { + throw new IllegalStateException("Unexpected default trust managers:" + + Arrays.toString(trustManagers)); + } + return (X509TrustManager) trustManagers[0]; + } + + private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException { + try { + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + InputStream in = null; // By convention, 'null' creates an empty key store. + keyStore.load(null, password); + return keyStore; + } + catch (IOException e) { + throw new AssertionError(e); + } + } + //endregion + +} diff --git a/okhttp3util/src/main/java/com/liuhuiyu/okhttp/OkHttpUtil2.java b/okhttp3util/src/main/java/com/liuhuiyu/okhttp/OkHttpUtil2.java new file mode 100644 index 0000000..753e6b8 --- /dev/null +++ b/okhttp3util/src/main/java/com/liuhuiyu/okhttp/OkHttpUtil2.java @@ -0,0 +1,419 @@ +package com.liuhuiyu.okhttp; + +import com.liuhuiyu.okhttp.functional_interface.OnFailure; +import com.liuhuiyu.okhttp.functional_interface.OnResponse; +import com.liuhuiyu.okhttp.utils.ArrangeTransformUtil; +import okhttp3.*; +import okhttp3.internal.http.HttpMethod; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +/** + * OkHttpUtil升级版 + * 尽量完整封装各个类 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-07-06 10:05 + */ +public class OkHttpUtil2 { + public static final String MEDIA_TYPE_APPLICATION_JSON_UTF_8 = "application/json;charset=utf-8"; + public static final String MEDIA_TYPE_APPLICATION_JSON = "application/json"; + + private final OkHttpClient.Builder client; + private final Request.Builder request; + private final HttpUrl.Builder httpUrl; + private final FormBody.Builder bodyBuilder; + private MultipartBody.Builder multipartBody; + private MethodModel methodModel; + private RequestBody requestBody; + + /** + * 提供已经包装的OkHttp3原型 + * + * @return com.liuhuiyu.okhttp.OkHttpUtil2.OkHttpPrimeval + * @author LiuHuiYu + * Created DateTime 2021-09-18 16:31 + */ + public OkHttpPrimeval getOkHttpPrimeval() { + return new OkHttpPrimeval(); + } + + class OkHttpPrimeval { + public OkHttpClient.Builder getOkHttpClientBuilder() { + return client; + } + + public Request.Builder getRequestBuilder() { + return request; + } + + public HttpUrl.Builder getHttpUrlBuilder() { + return httpUrl; + } + + public FormBody.Builder getBodyBuilderBuilder() { + return bodyBuilder; + } + + public MethodModel getMethodModel() { + return methodModel; + } + + public RequestBody getRequestBody() { + return requestBody; + } + } + + public static OkHttpUtil2 create(String url) { + return new OkHttpUtil2(url); + } + + private OkHttpUtil2(String url) { + this.httpUrl = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder(); + this.request = new Request.Builder(); + this.client = new OkHttpClient.Builder(); + this.bodyBuilder = new FormBody.Builder(); + this.methodModel = MethodModel.GET; + } + + /** + * 连接超时 + * + * @param seconds 秒 + * @return com.liuhuiyu.okhttp.OkHttpUtil2 + * @author LiuHuiYu + * Created DateTime 2021-12-03 14:07 + */ + public OkHttpUtil2 connectTimeout(int seconds) { + this.client.connectTimeout(seconds, TimeUnit.SECONDS); + return this; + } + + /** + * 读取超时 + * + * @param seconds 秒 + * @return com.liuhuiyu.okhttp.OkHttpUtil2 + * @author LiuHuiYu + * Created DateTime 2021-12-03 14:07 + */ + public OkHttpUtil2 readTimeout(int seconds) { + this.readTimeout=seconds; + this.client.readTimeout(seconds, TimeUnit.SECONDS); + return this; + } + int readTimeout; + + /** + * 写入超时 + * + * @param seconds 秒 + * @return com.liuhuiyu.okhttp.OkHttpUtil2 + * @author LiuHuiYu + * Created DateTime 2021-12-03 14:07 + */ + public OkHttpUtil2 writeTimeout(int seconds) { + this.client.writeTimeout(seconds, TimeUnit.SECONDS); + return this; + } + + + /** + * 添加地址参数 + * + * @param name 键值 + * @param value 值 + * @return com.liuhuiyu.okhttp.OkHttpUtil2 + * @author LiuHuiYu + * Created DateTime 2021-07-06 10:20 + */ + public OkHttpUtil2 addQueryParameter(String name, String value) { + this.httpUrl.addQueryParameter(name, value); + return this; + } + + /** + * 添加body参数 + * + * @param name 参数名称 + * @param value 参数值 + * @return com.liuhuiyu.okhttp.OkHttpUtil2 + * @author LiuHuiYu + * Created DateTime 2021-07-06 11:06 + */ + public OkHttpUtil2 addBody(String name, String value) { + this.bodyBuilder.add(name, value); + this.post(); + return this; + } + + /** + * 添加form + * + * @param name 名称 + * @param value 值 + * @return com.liuhuiyu.okhttp.OkHttpUtil2 + * @author LiuHuiYu + * Created DateTime 2021-11-30 14:05 + */ + public OkHttpUtil2 addFormDataPart(String name, String value) { + //传递键值对参数 + if (multipartBody == null) { + this.multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM); + } + this.multipartBody.addFormDataPart(name, value); + this.post(); + return this; + } + + /** + * 添加formData + * + * @param name 名称 + * @param filename 文件名 + * @param body RequestBody + * @return com.liuhuiyu.okhttp.OkHttpUtil2 + * @author LiuHuiYu + * Created DateTime 2021-11-30 14:07 + */ + public OkHttpUtil2 addFormDataPart(String name, String filename, RequestBody body) { + if (multipartBody == null) { + this.multipartBody = new MultipartBody.Builder().setType(MultipartBody.FORM); + } + this.multipartBody.addFormDataPart(name, filename, body); + this.post(); + return this; + } + + /** + * 字符串设置Body + * + * @param bodyString body字符串 + * @param method MediaType + * @return com.liuhuiyu.okhttp.OkHttpUtil2 + * @throws IllegalArgumentException 参数不能设置成空 + * @author LiuHuiYu + * Created DateTime 2021-09-18 16:25 + */ + public OkHttpUtil2 setBody(String bodyString, String method) { + if (bodyString == null || method == null) { + throw new IllegalArgumentException("参数不能为空"); + } + else { + this.requestBody = RequestBody.create(bodyString, MediaType.parse(method)); + this.post(); + } + return this; + } + + /** + * 模式 + * + * @author LiuHuiYu + * Created DateTime 2021-07-06 10:33 + */ + public enum MethodModel { + /** + * get方法 + * Created DateTime 2021-07-06 10:40 + */ + GET, + /** + * post方法 + * Created DateTime 2021-07-06 10:40 + */ + POST, + /** + * delete方法 + * Created DateTime 2021-07-06 10:40 + */ + DELETE, + /** + * put方法 + * Created DateTime 2021-07-06 10:40 + */ + PUT, + /** + * patch方法 + * Created DateTime 2021-07-06 10:40 + */ + PATCH, + /** + * head方法 + * Created DateTime 2021-07-06 10:40 + */ + HEAD, + ; + + public String getName() { + return this.name(); + } + + void builder(Request.Builder builder, RequestBody requestBody) { + if (HttpMethod.permitsRequestBody(this.name())) { + builder.method(this.getName(), requestBody); + } + else { + builder.method(this.name(), null); + } + } + } + + //region 执行模式设定 + + /** + * 设定执行模式 + * + * @param methodModel GET, POST, DELETE, PUT, PATCH, HEAD + * @return com.liuhuiyu.okhttp.OkHttpUtil2 + * @author LiuHuiYu + * Created DateTime 2021-09-18 10:52 + */ + public OkHttpUtil2 setMethodModel(OkHttpUtil2.MethodModel methodModel) { + this.methodModel = methodModel; + return this; + } + + /** + * get模式 + * + * @return com.liuhuiyu.okhttp.OkHttpUtil2 + * @author LiuHuiYu + * Created DateTime 2021-09-18 10:54 + */ + public OkHttpUtil2 get() { + this.methodModel = MethodModel.GET; + return this; + } + + /** + * post模式 + * + * @return com.liuhuiyu.okhttp.OkHttpUtil2 + * @author LiuHuiYu + * Created DateTime 2021-09-18 10:54 + */ + public OkHttpUtil2 post() { + this.methodModel = MethodModel.POST; + return this; + } + //endregion + + //region 执行查询 + + /** + * 执行查询 + * + * @return okhttp3.Response + * @author LiuHuiYu + * Created DateTime 2021-09-18 16:56 + */ + public Response execute() { + this.request.url(httpUrl.build()); + if (this.multipartBody != null) { + this.request.post(this.multipartBody.build()); + } + OkHttpClient client = this.getOkHttpClient(); + Request request = this.request.build(); + try { + return client.newCall(request).execute(); + } + catch (IOException e) { + throw new RuntimeException(e); + } + } + + public String executeToString() { + try { + String resData; + try (Response response = this.execute()) { + resData=Objects.requireNonNull(response.body()).string(); + } + return resData; + } + catch (IOException e) { + throw new OkHttpException(e.getMessage()); + } + } + + public Map executeToMap() { + return ArrangeTransformUtil.executeMap(this::executeToString); + } + + //endregion + + //region 异步执行 + + /** + * 异步执行提交 + * + * @param onResponse 返回信息 + * @param onFailure 异常 + * @author LiuHuiYu + * Created DateTime 2021-09-18 16:21 + */ + public void asynchronousExecute(OnResponse onResponse, OnFailure onFailure) { + this.request.url(httpUrl.build()); + OkHttpClient client = getOkHttpClient(); + Request request = this.request.build(); + Callback callback = new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + if (onFailure != null) { + onFailure.onFailure(call, e); + } + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { + if (onResponse != null) { + onResponse.onResponse(call, response); + } + } + }; + client.newCall(request).enqueue(callback); + } + + private OkHttpClient getOkHttpClient() { + OkHttpClient client = this.client.build(); + if (this.requestBody == null) { + this.requestBody = this.bodyBuilder.build(); + } + this.methodModel.builder(this.request, this.requestBody); + return client; + } + + /** + * 异步执行返回 String + * + * @param consumer String消费 + * @param onFailure 异常 + * @author LiuHuiYu + * Created DateTime 2021-09-18 16:21 + */ + public void asynchronousExecuteToString(Consumer consumer, OnFailure onFailure) { + this.asynchronousExecute((call, response) -> { + String str = Objects.requireNonNull(response.body()).string(); + response.close(); + consumer.accept(str); + }, onFailure); + } + + /** + * 异步执行返回 Map + * + * @param consumer Map消费 + * @param onFailure 异常 + * @author LiuHuiYu + * Created DateTime 2021-09-18 16:21 + */ + public void asynchronousExecuteToMap(Consumer> consumer, OnFailure onFailure) { + asynchronousExecuteToString((str) -> consumer.accept(ArrangeTransformUtil.executeMap(() -> str)), onFailure); + } + //endregion +} diff --git a/okhttp3util/src/main/java/com/liuhuiyu/okhttp/WebSocketManager.java b/okhttp3util/src/main/java/com/liuhuiyu/okhttp/WebSocketManager.java new file mode 100644 index 0000000..ce01b23 --- /dev/null +++ b/okhttp3util/src/main/java/com/liuhuiyu/okhttp/WebSocketManager.java @@ -0,0 +1,177 @@ +package com.liuhuiyu.okhttp; + +import com.google.gson.Gson; +import okhttp3.Response; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; +import okio.ByteString; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-03-31 17:33 + */ +public final class WebSocketManager { + boolean err = false; + boolean run = false; + + /** + * 功能描述 + * + * @param url 地址 + * @param webSocketListener 监听反馈 + * @return com.liuhuiyu.okhttp.WebSocketManager + * @author LiuHuiYu + * Created DateTime 2021-04-01 8:20 + */ + public static WebSocketManager create(String url, WebSocketListener webSocketListener) { + return new WebSocketManager(url, webSocketListener); + } + + String url; + WebSocketListener webSocketListener; + WebSocket webSocket; + int restartMaxNum = 5; + int restartNum = 0; + + private WebSocketManager(String url, WebSocketListener webSocketListener) { + this.url = url; + this.webSocketListener = webSocketListener; + } + + /** + * 设定最多重新启动的次数 + * @author LiuHuiYu + * Created DateTime 2021-04-01 9:36 + * @param num 次数 + */ + public void setRestartMaxNum(int num) { + this.restartMaxNum = Math.max(num, 0); + } + + public boolean start() { + if (!run) { + this.restartNum = 0; + this.run(this.url); + return true; + } + else { + return false; + } + } + public boolean stop() { + if (run) { + this.webSocket.close(0, "主动关闭"); + return true; + } + else { + return false; + } + } + + /** + * 消息发送 + * + * @param message 消息 + * @author LiuHuiYu + * Created DateTime 2021-04-01 9:30 + */ + public void send(String message) { + if (this.run) { + this.webSocket.send(message); + } + } + + /** + * 对象发送 + * + * @param jsonObject json对象 + * @author LiuHuiYu + * Created DateTime 2021-04-01 9:32 + */ + public void sendJson(Object jsonObject) { + Gson gson = new Gson(); + String json = gson.toJson(jsonObject); + this.send(json); + } + + private void restart(){ + if(this.restartMaxNum==0 || this.restartNum + * @author LiuHuiYu + * Created DateTime 2021-04-16 9:08 + */ + public static Map executeMap(Supplier supplier) { + String strJson = supplier.get(); + return getStringObjectMap(strJson); + } + + /** + * 将json字符串转换成Map + * + * @param strJson json字符串 + * @return java.util.Map + * @author LiuHuiYu + * Created DateTime 2021-03-30 9:04 + */ + @NotNull + public static Map getStringObjectMap(String strJson) { + try { + Gson gson = new Gson(); + Map resultMap = gson.fromJson(strJson, new TypeToken>() { + }.getType()); + if (resultMap == null) { + return new HashMap<>(); + } + else { + return mapDoubleToInt(resultMap); + } + } + catch (JsonSyntaxException e) { + throw new OkHttpException("Json'" + strJson + "'解析异常:" + e.getMessage()); + } + } + + public static Map mapDoubleToInt(Map resultMap) { + Map res = new HashMap<>(resultMap.size()); + for (Object keyObj : resultMap.keySet()) { + String key = keyObj.toString(); + if (resultMap.get(key) instanceof Double) { + Double value = (Double) resultMap.get(key); + if (value.intValue() == value) { + res.put(key, ((Double) resultMap.get(key)).intValue()); + } + else { + res.put(key, resultMap.get(key)); + } + } + else if (resultMap.get(key) instanceof List) { + res.put(key, listDoubleToInt((List) resultMap.get(key))); + } + else if (resultMap.get(key) instanceof Map) { + res.put(key, mapDoubleToInt((Map) resultMap.get(key))); + } + else { + res.put(key, resultMap.get(key)); + } + } + return res; + } + + public static List listDoubleToInt(List list) { + List res = new ArrayList<>(list.size()); + for (Object o : list) { + if (o instanceof Number) { + Double value = (Double) o; + if (value.intValue() == value) { + Object v = value.intValue(); + res.add(v); + } + else { + res.add(value); + } + } + else if (o instanceof Map) { + res.add(mapDoubleToInt((Map) o)); + } + else if (o instanceof List) { + res.add(listDoubleToInt((List) o)); + } + else { + res.add(o); + } + } + return res; + } +} diff --git a/okhttp3util/src/test/java/com/liuhuiyu/okhttp/OkHttpTest.java b/okhttp3util/src/test/java/com/liuhuiyu/okhttp/OkHttpTest.java new file mode 100644 index 0000000..34fd2e5 --- /dev/null +++ b/okhttp3util/src/test/java/com/liuhuiyu/okhttp/OkHttpTest.java @@ -0,0 +1,42 @@ +package com.liuhuiyu.okhttp; + +import com.liuhuiyu.okhttp.functional_interface.OnFailure; +import com.liuhuiyu.okhttp.functional_interface.OnResponse; +import okhttp3.*; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; + +import java.io.IOException; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-09-18 10:32 + */ +//@Log4j2 +public class OkHttpTest { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(OkHttpTest.class); + @Test + public void getAsynchronousInteraction() throws InterruptedException { + log.info("测试异步"); + OkHttpClient okHttpClient = new OkHttpClient(); + Request build = new Request.Builder().url("https://blog.csdn.net/QasimCyrus").build(); + OnFailure onFailure = (call, e) -> { + }; + OnResponse onResponse = (call, response) -> { + }; + Callback callback = new Callback() { + @Override + public void onFailure(@NotNull Call call, @NotNull IOException e) { + onFailure.onFailure(call, e); + } + + @Override + public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException { + onResponse.onResponse(call, response); + } + }; + okHttpClient.newCall(build).enqueue(callback); + Thread.sleep(100000); + } +} diff --git a/okhttp3util/src/test/java/com/liuhuiyu/okhttp/OkHttpUtil2Test.java b/okhttp3util/src/test/java/com/liuhuiyu/okhttp/OkHttpUtil2Test.java new file mode 100644 index 0000000..0dfea25 --- /dev/null +++ b/okhttp3util/src/test/java/com/liuhuiyu/okhttp/OkHttpUtil2Test.java @@ -0,0 +1,175 @@ +package com.liuhuiyu.okhttp; + +import com.google.gson.Gson; +import com.liuhuiyu.okhttp.utils.ArrangeTransformUtilTest; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-07-06 10:44 + */ +public class OkHttpUtil2Test { + // private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(OkHttpUtil2Test.class); + private final static Logger LOG = LogManager.getLogger(OkHttpUtil2Test.class); + + public void getOkHttpPrimeval() { + String url = "http://127.0.0.1:9999/api/get/test"; + OkHttpUtil2 okHttpUtil2 = OkHttpUtil2.create(url); + OkHttpUtil2.OkHttpPrimeval okHttpPrimeval = okHttpUtil2.getOkHttpPrimeval(); + LOG.info("OkHttpClient.Builder:{}", okHttpPrimeval.getOkHttpClientBuilder()); + LOG.info("BodyBuilder.Builder:{}", okHttpPrimeval.getBodyBuilderBuilder()); + LOG.info("HttpUrl.Builder:{}", okHttpPrimeval.getHttpUrlBuilder()); + LOG.info("Request.Builder:{}", okHttpPrimeval.getRequestBuilder()); + LOG.info("MethodModel:{}", okHttpPrimeval.getMethodModel()); + LOG.info("RequestBody:{}", okHttpPrimeval.getRequestBody()); + } + + @Test + public void getNoParameters() { + String url = "http://127.0.0.1:9999/api/get/test"; + String s = OkHttpUtil2.create(url).get().executeToString(); + LOG.info(s); + String s2 = OkHttpUtil2.create(url) + .setMethodModel(OkHttpUtil2.MethodModel.GET) + .executeToString(); + LOG.info(s2); + } + + @Test + public void getParameters() { + String url = "http://127.0.0.1:9999/api/get/test_p"; + String parameter = "轻微隐患"; + String parameterName = "p1"; + String s = OkHttpUtil2.create(url) + .addQueryParameter(parameterName, parameter) + .executeToString(); + Map map = OkHttpUtil2.create(url) + .addQueryParameter(parameterName, parameter) + .executeToMap(); + LOG.info(s); + LOG.info("map:{}", map); + } + + @Test + public void asynchronousExecute() { + String url = "http://127.0.0.1:9999/api/get/test"; + AtomicBoolean b = new AtomicBoolean(true); + OkHttpUtil2.create(url).get().asynchronousExecute((call, response) -> { + LOG.info("测试"); + b.set(false); + }, (call, e) -> LOG.error(e)); + LOG.info("异步"); + while (b.get()) { + LOG.info("等待结束"); + } + } + + @Test + public void asynchronousExecuteToString() { + String url = "http://127.0.0.1:9999/api/get/test"; + AtomicBoolean b = new AtomicBoolean(true); + OkHttpUtil2.create(url).get().asynchronousExecuteToString((str) -> { + LOG.info(str); + b.set(false); + }, (call, e) -> LOG.error("", e)); + LOG.info("异步"); + while (b.get()) { + LOG.info("等待结束"); + } + } + + @Test + public void asynchronousExecuteToMap() { + String url = "http://127.0.0.1:9999/api/get/test"; + AtomicBoolean b = new AtomicBoolean(true); + OkHttpUtil2 + .create(url) + .get() + .asynchronousExecuteToMap((map) -> { + LOG.info("map:{}", map); + b.set(false); + }, (call, e) -> LOG.error(e)); + LOG.info("异步"); + while (b.get()) { + LOG.info("等待结束"); + } + } + + @Test + public void postNoParameters() { + String url = "http://127.0.0.1:9999/api/post/test"; + String s = OkHttpUtil2.create(url) + .post() + .executeToString(); + LOG.info(s); + } + + @Test + public void postParameters() { + String url = "http://127.0.0.1:9999/api/post/test_p"; + String parameter = "轻微隐患"; + String parameterName = "p1"; + String s = OkHttpUtil2.create(url) + .addQueryParameter(parameterName, parameter) + .addBody(parameterName, parameter + "body传入") + .post() + .executeToString(); + LOG.info(s); + Map map = OkHttpUtil2.create(url) + .post() + .addQueryParameter(parameterName, parameter + "url传入") + .addBody(parameterName, parameter) + .executeToMap(); + LOG.info("map:{}", map); + } + + @Test + public void postStringBody() { + final String GET_TOKEN_URL = "https://safety-vsmapi.geg.com.cn/WebService.asmx/GetToken"; + final String CONTRACTOR_PERSONNEL_INFORMATION_URL = "https://safety-vsmapi.geg.com.cn/WebService.asmx/GetDataRequest"; + String strJson = "{\"userName\":\"zhAdmin\",\"userPwd\":\"zh@2021\"}"; + String method = "application/json"; + Map map = OkHttpUtil2 + .create(GET_TOKEN_URL) + .setBody(strJson, method) + .post() + .executeToMap(); + LOG.info(map); + String token = map.get("token").toString(); + String cardNo = "440421198903088237"; + String findJson = getJson(token, cardNo); + Map map2 = OkHttpUtil2 + .create(CONTRACTOR_PERSONNEL_INFORMATION_URL) + .setBody(findJson, method) + .post() + .executeToMap(); + LOG.info("map2:{}", map2); + } + + private String getJson(String token, String cardNo) { + //region 结构编码 + Map map = new HashMap<>(); + map.put("token", token); + map.put("dataType", "C_VENUSER"); + map.put("company", "ZHP"); + map.put("pageSize", 1000); + Map dataMap = new HashMap<>(); + dataMap.put("code", ""); + dataMap.put("name", ""); + dataMap.put("idcards", cardNo); + dataMap.put("suCode", ""); + dataMap.put("mobile", ""); + dataMap.put("suName", ""); + map.put("data", dataMap); + //endregion + Gson gson = new Gson(); + return gson.toJson(map); + } +} \ No newline at end of file diff --git a/okhttp3util/src/test/java/com/liuhuiyu/okhttp/OkHttpUtilTest.java b/okhttp3util/src/test/java/com/liuhuiyu/okhttp/OkHttpUtilTest.java new file mode 100644 index 0000000..6d94cc2 --- /dev/null +++ b/okhttp3util/src/test/java/com/liuhuiyu/okhttp/OkHttpUtilTest.java @@ -0,0 +1,293 @@ +package com.liuhuiyu.okhttp; + +import com.liuhuiyu.okhttp.utils.ArrangeTransformUtilTest; +import okhttp3.Response; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; +import okio.ByteString; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CountDownLatch; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-01-12 19:11 + */ +public class OkHttpUtilTest { + private final static Logger LOG = LogManager.getLogger(ArrangeTransformUtilTest.class); + + //region get测试 + private String getUrl(String url) { + return "http://192.168.2.7:8006" + url; + } + + @Test + public void testGetForLogin() { + String url = getUrl("/Authentication/Login"); + OkHttpUtil okHttpUtil = OkHttpUtil.create(); + okHttpUtil.addQueryParameter("userid", "ZH_Admin"); + okHttpUtil.addQueryParameter("password", "UmVob21lLnpocHNAMjAyMA=="); + Response res = okHttpUtil.executeGet(url); + String resString = okHttpUtil.executeGetToString(url); + Map resMap = okHttpUtil.executeGetToMap(url); + LOG.info(resMap); + } + + @Test + public void testTime() { + for (int i = 0; i < 100; i++) { + testGetForLogin(); + } + } + + private String getToken() { + String url = getUrl("/Authentication/Login"); + OkHttpUtil okHttpUtil = OkHttpUtil.create(); + okHttpUtil.addQueryParameter("userid", "ZH_Admin"); + okHttpUtil.addQueryParameter("password", "UmVob21lLnpocHNAMjAyMA=="); + Map resMap = okHttpUtil.executeGetToMap(url); + return resMap.get("token").toString(); + } + + @Test + public void testGet02() { + String url = getUrl("/U_RS_BASICINFO/GetUserInfoByManID"); + String token = getToken(); + OkHttpUtil okHttpUtil = OkHttpUtil.create(); + okHttpUtil.headerAuthorizationByBearerToken(token); + okHttpUtil.headerAuthorizationByBearerToken(token); + Response res = okHttpUtil.executeGet(url); + String resString = okHttpUtil.executeGetToString(url); + Map resMap = okHttpUtil.executeGetToMap(url); + LOG.info(res); + LOG.info(resString); + LOG.info(resMap); + } + + @Test + public void testGet03() { + String url = getUrl("/U_RS_BASICINFO/GetTreeUser"); + String token = getToken(); + OkHttpUtil okHttpUtil = OkHttpUtil.create(); + okHttpUtil.addQueryParameter("dc", "ZH"); + okHttpUtil.headerAuthorizationByBearerToken(token); + okHttpUtil.headerAuthorizationByBearerToken(token); + Response res = okHttpUtil.executeGet(url); + String resString = okHttpUtil.executeGetToString(url); + Map resMap = okHttpUtil.executeGetToMap(url); + } + + //endregion + @Test + public void test() { + Map m1 = new HashMap<>(); + Map m2 = new HashMap<>(); + Map m3 = new HashMap<>(); + List list1 = new ArrayList<>(); + list1.add(1.0); + list1.add(2.0); + list1.add(3.0); + list1.add(4.1); + list1.add(5.0); + m3.put("m3_1", list1); + m3.put("m3_2", 2.0); + m3.put("m3_3", 3.0); + m2.put("m2_1", m3); + m2.put("m2_2", 5.0); + m2.put("m2_3", 6.1); + m1.put("m1_1", m2); + m1.put("m1_2", 4.0); + m1.put("m1_3", 1.1); + Map map = OkHttpUtil.mapDoubleToInt(m1); + + } + + @Test + public void testHeadGet() { + String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiWkhfQWRtaW4iLCJleHAiOjE2MTI2MzM4MzAsImlzcyI6Imh0dHA6Ly8xOTIuMTY4LjIuNzo4MDA2IiwiYXVkIjoiaHR0cDovLzE5Mi4xNjguMi43OjgwMDYifQ.E6R3ei7UyUK3UnLAKbbLj9vIO9frdUtekT1UD4hHB6A"; + String url = "http://192.168.2.7:8006/U_SYSTREE/GetUserTreeStr"; + Map map = OkHttpUtil.create().headerAuthorizationByBearerToken(token).addQueryParameter("dc", "ZH").executeGetToMap(url); + if (Integer.parseInt(map.get("code").toString()) == 200) { + System.out.println(map.get("data")); + } + else { + System.out.println(map); + } + } + + @Test + public void testPut01() { + String url = "http://192.168.2.7:8006/YJYAJX/QYSX"; + String token = this.getToken(); + String id = "b7af1ab0-0719-4e3e-93f0-c81dba07e9cb"; + OkHttpUtil okHttpUtil = OkHttpUtil.create(); + okHttpUtil.addQueryParameter("id", id); + okHttpUtil.headerAuthorizationByBearerToken(token); + Response response = okHttpUtil.executePut(url); + Map map = okHttpUtil.executePutToMap(url); + /* + { + "code": 200, + "msg": "", + "id": "b7af1ab0-0719-4e3e-93f0-c81dba07e9cb", + "JSR": "管理员", + "JSSJ": "2021-03-26 10:35:25" + } + */ + } + + @Test + public void testPut02() { + String token = this.getToken(); + String url = "http://192.168.2.7:8006/YJYAJX/UpDate"; + Map queryParameter = new HashMap<>(5); + queryParameter.put("id", "aa30fe55-746c-45a1-8bc1-ef91cd7566c9"); + queryParameter.put("yjyaid", "96f3065d-8006-4758-a784-b12f147594b6"); + queryParameter.put("title", "2021年122号台风天鸽应急预案"); + queryParameter.put("type", "防风"); + queryParameter.put("dz", "200002"); + OkHttpUtil okHttpUtil = OkHttpUtil.create(); + okHttpUtil.headerAuthorizationByBearerToken(token); + for (String key : queryParameter.keySet()) { + okHttpUtil.addBody(key, queryParameter.get(key)); + } + okHttpUtil.setMethod(OkHttpUtil.MEDIA_TYPE_APPLICATION_JSON_UTF_8); + Response response = okHttpUtil.executePut(url); + Map map = okHttpUtil.executePutToMap(url); + } + + static CountDownLatch countDownLatch = new CountDownLatch(1); + + @Test + public void testWebSocket() throws InterruptedException { + String url = "ws://localhost:8111/ws1"; + WebSocketListener webSocketListener = new WebSocketListener() { + @Override + public void onClosed(@NotNull WebSocket webSocket, int code, @NotNull String reason) { + super.onClosed(webSocket, code, reason); + } + + @Override + public void onClosing(@NotNull WebSocket webSocket, int code, @NotNull String reason) { + super.onClosing(webSocket, code, reason); + } + + @Override + public void onFailure(@NotNull WebSocket webSocket, @NotNull Throwable t, @Nullable Response response) { + super.onFailure(webSocket, t, response); + } + + @Override + public void onMessage(@NotNull WebSocket webSocket, @NotNull String text) { + super.onMessage(webSocket, text); + } + + @Override + public void onMessage(@NotNull WebSocket webSocket, @NotNull ByteString bytes) { + super.onMessage(webSocket, bytes); + } + + @Override + public void onOpen(@NotNull WebSocket webSocket, @NotNull Response response) { + super.onOpen(webSocket, response); + } + }; + OkHttpUtil.webSocket(url, webSocketListener); + countDownLatch.await(); + } + + @Test + public void testHttps() { + String url = "http://10.0.21.227/WebService.asmx/GetToken"; + OkHttpUtil okHttpUtil = OkHttpUtil.create(); + okHttpUtil.setMethod("application/json"); + okHttpUtil.addBody("userName", "zhAdmin"); + okHttpUtil.addBody("userPwd", "zh@2021"); + okHttpUtil.https(); + Map map = okHttpUtil.executePostToMap(url); + String token = map.get("token").toString(); + String url2 = "https://safety-vsmapi.geg.com.cn/WebService.asmx/GetDataRequest"; + OkHttpUtil okHttpUtil2 = OkHttpUtil.create(); + okHttpUtil2.setMethod("application/json"); + String[] names = {"", "巫中建"};//"巫中建"; + String name = names[0];//"巫中建"; + String[] ids = {"", "51162119900401647X", "510231197208103576", "511621"}; + String idCards = ids[3];//""510231197208103576"; + String pageSize = "5"; + okHttpUtil2.setBodyString("{\n" + + " \"token\":\"" + token + "\",\n" + + " \"dataType\":\"C_VENUSER\",\n" + + " \"company\":\"ZHP\",\n" + + " \"pageSize\":" + pageSize + ",\n" + + " \"data\":{" + + " \"code\":\"\"," + + " \"name\":\"" + name + "\"," + + " \"idcards\":\"" + idCards + "\"," + + " \"suCode\":\"\"," + + " \"mobile\":\"\"," + + " \"suName\":\"\"" + + " }\n" + + "}\n"); +// String info=okHttpUtil.executePostToString(url); + Map map2 = okHttpUtil2.executePostToMap(url2); + + } + + @Test + public void testHttpsGet() { + String url = "https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13614600169"; + OkHttpUtil okHttpUtil = OkHttpUtil.create(); +// okHttpUtil.https(); + String info = okHttpUtil.executeGetToString(url); + } + + @Test + public void testHttpsGet2() { + String url = "https://127.0.0.1:8125/api/v1.0/system/authentication/login_do"; + Map queryParameter = new HashMap<>(2); + String account = "ZH_AF_Admin"; + String password = "UmVob21lLnpoYWZAMjEwNg=="; + queryParameter.put("account", account); + queryParameter.put("password", password); + OkHttpUtil okHttpUtil = OkHttpUtil.create(); + for (String key : queryParameter.keySet()) { + okHttpUtil.addQueryParameter(key, queryParameter.get(key)); + } + okHttpUtil.https(); + Map map = okHttpUtil.executeGetToMap(url); + } + + @Test + public void testFor() { + int num = 100_000; + int n = 0; + long m = 0; + for (int k = 0; k <= 50; k++) { + for (int j = 0; j <= 10_000; j++) { + n = 0; + for (int i = 0; i <= num; i++) { + n += i * 2 - 1; + m++; + } + } + } + System.out.println(m + "," + n); + } + + @Test + public void testVoid() { + String id = "f592b1eac6fb4d1091041bf1dab89aa2"; + String url = "http://10.19.0.114:8354/partnerRequest/hik8700/queryHls.shtml"; + String str = OkHttpUtil.create().addQueryParameter("indexCode", id).executeGetToString(url); + } + +} \ No newline at end of file diff --git a/okhttp3util/src/test/java/com/liuhuiyu/okhttp/OkHttpUtilTestKt.kt b/okhttp3util/src/test/java/com/liuhuiyu/okhttp/OkHttpUtilTestKt.kt new file mode 100644 index 0000000..16bf94c --- /dev/null +++ b/okhttp3util/src/test/java/com/liuhuiyu/okhttp/OkHttpUtilTestKt.kt @@ -0,0 +1,75 @@ +//package com.liuhuiyu.okhttp +// +//import org.junit.Test +// +///** +// * @author LiuHuiYu +// * @version v1.0.0.0 +// * Created DateTime 2021-04-01 10:00 +// */ +//class OkHttpUtilTestKt { +// @Test +// fun test01() { +// print("this is my first Kotlin.\n") +// } +// +// private fun getUrl(url: String): String { +// return "http://192.168.2.7:8006$url" +// } +// +// @Test +// fun testGetForLogin() { +// val url: String = this.getUrl("/Authentication/Login") +// val okHttpUtil = OkHttpUtil.create() +// okHttpUtil.addQueryParameter("userid", "ZH_Admin") +// okHttpUtil.addQueryParameter("password", "UmVob21lLnpocHNAMjAyMA==") +// val res = okHttpUtil.executeGet(url) +// val resString = okHttpUtil.executeGetToString(url) +// val resMap = okHttpUtil.executeGetToMap(url) +// } +// +// @Test +// fun testTime() { +// for (i in 0..99) { +// testGetForLogin() +// } +// } +// +// private fun getToken(): String { +// val url = getUrl("/Authentication/Login") +// val okHttpUtil = OkHttpUtil.create() +// okHttpUtil.addQueryParameter("userid", "ZH_Admin") +// okHttpUtil.addQueryParameter("password", "UmVob21lLnpocHNAMjAyMA==") +// val resMap = okHttpUtil.executeGetToMap(url) +// return resMap["token"].toString() +// } +// +// @Test +// fun testGet02() { +// val url = getUrl("/U_RS_BASICINFO/GetUserInfoByManID") +// val token = getToken() +// val okHttpUtil = OkHttpUtil.create() +// okHttpUtil.headerAuthorizationByBearerToken(token) +// okHttpUtil.headerAuthorizationByBearerToken(token) +// val res = okHttpUtil.executeGet(url) +// val resString = okHttpUtil.executeGetToString(url) +// val resMap = okHttpUtil.executeGetToMap(url) +// } +// +// @Test +// fun testFor() { +// val num = 100000 +// var n = 0 +// var m: Long = 0 +// for (k in 0..50) { +// for (j in 0..10000) { +// n = 0 +// for (i in 0..num) { +// n += i * 2 - 1 +// m++ +// } +// } +// } +// println("$m,$n") +// } +//} \ No newline at end of file diff --git a/okhttp3util/src/test/java/com/liuhuiyu/okhttp/utils/ArrangeTransformUtilTest.java b/okhttp3util/src/test/java/com/liuhuiyu/okhttp/utils/ArrangeTransformUtilTest.java new file mode 100644 index 0000000..bc21348 --- /dev/null +++ b/okhttp3util/src/test/java/com/liuhuiyu/okhttp/utils/ArrangeTransformUtilTest.java @@ -0,0 +1,24 @@ +package com.liuhuiyu.okhttp.utils; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Test; + +import java.util.Map; + + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-10-13 14:03 + */ +public class ArrangeTransformUtilTest { + private final static Logger LOG = LogManager.getLogger(ArrangeTransformUtilTest.class); + + @Test + public void getStringObjectMap() { + String json = "a32132131"; + Map map = ArrangeTransformUtil.getStringObjectMap(json); + LOG.info("map={}", map); + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..b5368fc --- /dev/null +++ b/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 2.1.3.RELEASE + + + com.springcloud + utils + 1.0.0 + utils + pom + Demo project for Spring Boot + + + 1.8 + Greenwich.RELEASE + + + + cloud-util + dto + guava-utils + jpa + model + okhttp3util + spring-util + test + test2 + util + web + web-service-util + + + diff --git a/spring-util/pom.xml b/spring-util/pom.xml new file mode 100644 index 0000000..62877d9 --- /dev/null +++ b/spring-util/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + + com.liuhuiyu + spring-util + 2021.1.0 + jar + + liuhuiyu-spring-util + spring个人工具类 + https://github.com/liuhuiyu2004/utils + + + UTF-8 + 8 + 8 + 2.16.0 + 2.5.7 + 5.3.13 + 22.0.0 + + + + + org.springframework.boot + spring-boot-starter-parent + ${spring-boot.version} + + + + + + org.jetbrains + annotations + ${org.jetbrains.annotations.version} + + + org.springframework + spring-context + ${spring-context.version} + + + org.springframework.boot + spring-boot-starter-aop + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter + + + + + + + + + + org.apache.logging.log4j + log4j-core + ${log4j2.version} + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + + + compile + + + jar-no-fork + + + + + + + + \ No newline at end of file diff --git a/spring-util/spring-util.iml b/spring-util/spring-util.iml new file mode 100644 index 0000000..c53acfe --- /dev/null +++ b/spring-util/spring-util.iml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-util/src/main/java/com/liuhuiyu/spring_util/SpringUtil.java b/spring-util/src/main/java/com/liuhuiyu/spring_util/SpringUtil.java new file mode 100644 index 0000000..64ae059 --- /dev/null +++ b/spring-util/src/main/java/com/liuhuiyu/spring_util/SpringUtil.java @@ -0,0 +1,74 @@ +package com.liuhuiyu.spring_util; + +import com.liuhuiyu.spring_util.run_timer.TimerUtil; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * 在初始化的时候加入 @Bean public SpringUtil springUtilBean(){ return new SpringUtil(); } + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2020-06-24 14:55 + */ +public class SpringUtil implements ApplicationContextAware { + private static final Logger LOG = LogManager.getLogger(TimerUtil.class); + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException { + if (SpringUtil.applicationContext == null) { + SpringUtil.applicationContext = applicationContext; + } + LOG.info("===ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext=%1$s==={}", SpringUtil.applicationContext); + LOG.info("--------------------------------------------------------------"); + } + + /** + * 获取applicationContext + * @author LiuHuiYu + * Created DateTime 2021-12-15 9:26 + * @return org.springframework.context.ApplicationContext + */ + public static ApplicationContext getApplicationContext() { + return applicationContext; + } + + /** + * 通过name获取 Bean. + * @author LiuHuiYu + * Created DateTime 2021-12-15 9:26 + * @param name bean名称 + * @return java.lang.Object + */ + public static @NotNull Object getBean(String name) { + return getApplicationContext().getBean(name); + } + + /** + * 通过class获取Bean. + * @author LiuHuiYu + * Created DateTime 2021-12-15 9:27 + * @param clazz 类.class + * @return T + */ + public static @NotNull T getBean(Class clazz) { + return getApplicationContext().getBean(clazz); + } + + /** + * 通过name,以及Clazz返回指定的Bean + * + * @param name 名称 + * @param clazz 类class + * @param 类 + * @return 类实例 + */ + public static @NotNull T getBean(String name, Class clazz) { + return getApplicationContext().getBean(name, clazz); + } +} diff --git a/spring-util/src/main/java/com/liuhuiyu/spring_util/run_timer/RunTimeAspect.java b/spring-util/src/main/java/com/liuhuiyu/spring_util/run_timer/RunTimeAspect.java new file mode 100644 index 0000000..dfb91cf --- /dev/null +++ b/spring-util/src/main/java/com/liuhuiyu/spring_util/run_timer/RunTimeAspect.java @@ -0,0 +1,21 @@ +package com.liuhuiyu.spring_util.run_timer; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-03-02 11:56 + */ +@Aspect +@Component +public class RunTimeAspect { + @Around(value = "@annotation(timer)") + public Object logAround(ProceedingJoinPoint pjp, RunTimer timer) throws Throwable { + TimerUtil tu = new TimerUtil(); + return tu.runTime(pjp, timer); + } +} diff --git a/spring-util/src/main/java/com/liuhuiyu/spring_util/run_timer/RunTimer.java b/spring-util/src/main/java/com/liuhuiyu/spring_util/run_timer/RunTimer.java new file mode 100644 index 0000000..618daea --- /dev/null +++ b/spring-util/src/main/java/com/liuhuiyu/spring_util/run_timer/RunTimer.java @@ -0,0 +1,15 @@ +package com.liuhuiyu.spring_util.run_timer; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * 运行时间注解 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-03-02 11:22 + */ +@Retention(RetentionPolicy.RUNTIME) +public @interface RunTimer { + String explain() default ""; +} diff --git a/spring-util/src/main/java/com/liuhuiyu/spring_util/run_timer/TimerUtil.java b/spring-util/src/main/java/com/liuhuiyu/spring_util/run_timer/TimerUtil.java new file mode 100644 index 0000000..ed83089 --- /dev/null +++ b/spring-util/src/main/java/com/liuhuiyu/spring_util/run_timer/TimerUtil.java @@ -0,0 +1,69 @@ +package com.liuhuiyu.spring_util.run_timer; + + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.Signature; +import org.aspectj.lang.reflect.MethodSignature; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-03-02 11:23 + */ +public class TimerUtil { + private static final Logger LOG = LogManager.getLogger(TimerUtil.class); + public void runTime(Method m, Object obj) throws InvocationTargetException, IllegalAccessException { + long start = System.currentTimeMillis(); + m.invoke(obj); + long end = System.currentTimeMillis(); + LOG.info("{}执行时间:{}", m.getName(), (end - start)); + } + + public Object runTime(ProceedingJoinPoint pjp, RunTimer runTimer) throws Throwable { + Signature sig = pjp.getSignature(); + MethodSignature msig;// = null; + if (!(sig instanceof MethodSignature)) { + throw new IllegalArgumentException("该注解只能用于方法"); + } + msig = (MethodSignature) sig; + Object target = pjp.getTarget(); + Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes()); + + long start = System.currentTimeMillis(); + Object res = pjp.proceed(); + long end = System.currentTimeMillis(); + + LOG.info("{}.{} {}执行时间:{}", currentMethod.getDeclaringClass().getName(), currentMethod.getName(), runTimer.explain(), (end - start)); + return res; + } + + public void getTime() { + // 获取当前类型名字 + String className = Thread.currentThread().getStackTrace()[2].getClassName(); + System.out.println("current className(expected): " + className); + try { + Class c = Class.forName(className); + Object obj = c.newInstance(); + Method[] methods = c.getDeclaredMethods(); + for (Method m : methods) { + // 判断该方法是否包含Timer注解 + if (m.isAnnotationPresent(RunTimer.class)) { + m.setAccessible(true); + long start = System.currentTimeMillis(); + // 执行该方法 + m.invoke(obj); + long end = System.currentTimeMillis(); + System.out.println(m.getName() + "() time consumed: " + (end - start) + "\\\\n"); + } + } + } + catch (ReflectiveOperationException e) { + LOG.error(e.toString()); + } + } +} diff --git a/spring-util/src/main/resources/META-INF/spring.factories b/spring-util/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000..04be253 --- /dev/null +++ b/spring-util/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.liuhuiyu.spring_util.SpringUtil,\ +com.liuhuiyu.spring_util.run_timer.RunTimeAspect \ No newline at end of file diff --git a/test/pom.xml b/test/pom.xml new file mode 100644 index 0000000..c6c51e3 --- /dev/null +++ b/test/pom.xml @@ -0,0 +1,111 @@ + + + + 4.0.0 + + com.liuhuiyu + test + 2021.1.0 + jar + + 测试基础类 + + http://www.liuhuiyu.com + + + UTF-8 + 1.8 + 1.8 + + + + + + + + + + + org.projectlombok + lombok + 1.18.8 + compile + + + org.springframework.boot + spring-boot-starter-test + 2.1.6.RELEASE + + + org.springframework.boot + spring-boot-starter-data-jpa + 2.1.6.RELEASE + + + + org.springframework.boot + spring-boot-starter-web + 2.1.6.RELEASE + + + + + org.jetbrains + annotations + 19.0.0 + + + com.google.code.gson + gson + 2.8.7 + + + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + diff --git a/test/src/main/java/com/liuhuiyu/test/BaseControllerTest.java b/test/src/main/java/com/liuhuiyu/test/BaseControllerTest.java new file mode 100644 index 0000000..6c5f409 --- /dev/null +++ b/test/src/main/java/com/liuhuiyu/test/BaseControllerTest.java @@ -0,0 +1,119 @@ +package com.liuhuiyu.test; + +import lombok.SneakyThrows; +import lombok.extern.log4j.Log4j2; +import org.jetbrains.annotations.NotNull; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.ResultHandler; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.function.Consumer; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2020-07-21 9:26 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc//网站测试 +@Log4j2 +public class BaseControllerTest { + @Autowired + protected WebApplicationContext wac; + + protected MockMvc mvc; + + @Before() + public void setup() { + mvc = MockMvcBuilders.webAppContextSetup(wac).build(); + } + + protected void printHtml(@NotNull ResultActions resultActions) throws UnsupportedEncodingException { + this.responseInfo(resultActions); + this.printInfo("html信息"); + log.info(resultActions.andReturn().getResponse().getContentAsString()); + this.printInfo("html end"); + } + + String characterEncoding = "UTF-8"; + + public void setCharacterEncoding(String characterEncoding) { + this.characterEncoding = characterEncoding; + } + + protected void printJsonResult(@NotNull ResultActions resultActions) throws Exception { + this.responseInfo(resultActions); + this.printInfo("json信息"); +// log.info(resultActions.andReturn().getResponse().getContentAsString()); + resultActions.andReturn().getResponse().setCharacterEncoding(this.characterEncoding); + ResultHandler handler = result -> { + log.info(result.getResponse().getContentAsString()); + }; + resultActions.andDo(handler); + + + this.printInfo("json end"); + } + + /** + * 显示Response信息 + * Created DateTime 2021-02-23 9:10 + * + * @param resultActions ResultActions + * @author LiuHuiYu + */ + private void responseInfo(@NotNull ResultActions resultActions) throws UnsupportedEncodingException { + String json = resultActions.andReturn().getResponse().getContentAsString(); + int size = json.getBytes().length; + this.printInfo("访问地址"); + log.info("{}{}", resultActions.andReturn().getRequest().getLocalAddr(), resultActions.andReturn().getRequest().getRequestURI()); + this.printInfo("参数信息"); + for (String key : resultActions.andReturn().getRequest().getParameterMap().keySet()) { + log.info("{}:{}", key, resultActions.andReturn().getRequest().getParameterMap().get(key)); + } + this.printInfo("字节Byte:" + size); + this.printInfo("流量bit:" + (size * 8)); + } + + protected void printInfo(String info) { + log.info("/******************************* " + info + " *******************************/"); + } + + @SneakyThrows + protected MockHttpSession adminLoginSession(String adminAttribute, Object value) { + return setSession((session) -> session.setAttribute(adminAttribute, value)); + } + + @SneakyThrows + protected MockHttpSession userLoginSession(String userAttribute, Object value) { + return setSession((session) -> session.setAttribute(userAttribute, value)); + } + + /** + * session设定; + * session.setAttribute(“admin”,admin);//对session进行登陆设置 + * Created DateTime 2021-02-23 9:19 + * + * @param consumer session + * @author LiuHuiYu + */ + @SneakyThrows + protected MockHttpSession setSession(Consumer consumer) { + MockHttpSession session = new MockHttpSession(); + consumer.accept(session); + return session; + } +} \ No newline at end of file diff --git a/test/src/main/java/com/liuhuiyu/test/BaseServiceTest.java b/test/src/main/java/com/liuhuiyu/test/BaseServiceTest.java new file mode 100644 index 0000000..84c2bc1 --- /dev/null +++ b/test/src/main/java/com/liuhuiyu/test/BaseServiceTest.java @@ -0,0 +1,73 @@ +package com.liuhuiyu.test; + +import com.google.gson.Gson; +import lombok.extern.log4j.Log4j2; +import org.jetbrains.annotations.NotNull; +import org.junit.After; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.domain.Page; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.List; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2020-07-06 10:43 + */ +@RunWith(SpringRunner.class) +@SpringBootTest +@Log4j2 +public abstract class BaseServiceTest { + + @Before + public void login() { + + } + + @After + public void after() { + + } + + protected void printList(@NotNull List list) { + for (Object obj : list) { + log.info(obj.toString()); + } + log.info("size = " + list.size()); + } + + protected void printObject(Object obj) { + if (obj == null) { + log.info("Obj=null"); + } + else { + log.info(obj.toString()); + } + } + + protected void printPageImpl(@NotNull Page pageImpl) { + log.info("总记录数:" + pageImpl.getTotalElements()); + log.info("当前页号索引:" + pageImpl.getNumber()); + + log.info("每页数据:" + pageImpl.getSize()); + + log.info("当前页记录数:" + pageImpl.getNumberOfElements()); + log.info("当前页号:" + (pageImpl.getNumber() + 1)); + + log.info("总页数:" + pageImpl.getTotalPages()); + printList(pageImpl.getContent()); + } + + protected void printJson(Object obj) { + if (obj == null) { + log.info("Obj=null"); + } + else { + log.info(new Gson().toJson(obj)); + } + } +} + diff --git a/test/src/test/java/com/liuhuiyu/test/AppTest.java b/test/src/test/java/com/liuhuiyu/test/AppTest.java new file mode 100644 index 0000000..e3d1e61 --- /dev/null +++ b/test/src/test/java/com/liuhuiyu/test/AppTest.java @@ -0,0 +1,20 @@ +package com.liuhuiyu.test; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Unit test for simple App. + */ +public class AppTest +{ + /** + * Rigorous Test :-) + */ + @Test + public void shouldAnswerWithTrue() + { + assertTrue( true ); + } +} diff --git a/test/test.iml b/test/test.iml new file mode 100644 index 0000000..60434e7 --- /dev/null +++ b/test/test.iml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test2/pom.xml b/test2/pom.xml new file mode 100644 index 0000000..dca9ab4 --- /dev/null +++ b/test2/pom.xml @@ -0,0 +1,123 @@ + + + + 4.0.0 + com.liuhuiyu + test2 + 2022.1.0 + jar + + test2 + + + UTF-8 + 1.8 + 1.8 + 5.9.0 + 2.18.0 + 2.9.0 + 23.0.0 + 2.5.14 + 2.5.12 + 5.3.22 + + + + + org.junit.jupiter + junit-jupiter + ${junit.version} + compile + + + org.apache.logging.log4j + log4j-core + ${log4j2.version} + compile + + + + com.google.code.gson + gson + ${gson.version} + compile + + + javax.servlet + javax.servlet-api + 3.1.0 + compile + + + org.springframework.boot + spring-boot-test + ${spring-boot-test.version} + compile + + + org.springframework + spring-beans + + + org.springframework + spring-context + + + org.springframework + spring-core + + + + + org.springframework.data + spring-data-commons + ${springdata.commons.version} + compile + + + org.slf4j + slf4j-api + + + org.springframework + spring-beans + + + org.springframework + spring-core + + + + + org.jetbrains + annotations + ${annotations.version} + compile + + + org.springframework + spring-core + ${org.springframework.version} + compile + + + org.springframework + spring-test + ${org.springframework.version} + compile + + + org.springframework + spring-beans + ${org.springframework.version} + compile + + + org.springframework + spring-web + ${org.springframework.version} + compile + + + diff --git a/test2/src/main/java/com/liuhuiyu/test/BaseControllerTest.java b/test2/src/main/java/com/liuhuiyu/test/BaseControllerTest.java new file mode 100644 index 0000000..0ca3af7 --- /dev/null +++ b/test2/src/main/java/com/liuhuiyu/test/BaseControllerTest.java @@ -0,0 +1,116 @@ +package com.liuhuiyu.test; + +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.BeforeEach; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.ResultHandler; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; + +import java.io.UnsupportedEncodingException; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2020-07-21 9:26 + */ +@SpringBootTest +public abstract class BaseControllerTest extends TestBase { + @Autowired + protected WebApplicationContext wac; + + protected MockMvc mvc; + + @BeforeEach + public void setup() { + mvc = MockMvcBuilders.webAppContextSetup(wac).build(); + } + + protected void printHtml(@NotNull ResultActions resultActions) throws UnsupportedEncodingException { + this.responseInfo(resultActions); + this.printInfo("html信息"); + LOG.info(resultActions.andReturn().getResponse().getContentAsString()); + this.printInfo("html end"); + } + + String characterEncoding = "UTF-8"; + + public void setCharacterEncoding(String characterEncoding) { + this.characterEncoding = characterEncoding; + } + + protected void printJsonResult(@NotNull ResultActions resultActions) throws Exception { + this.responseInfo(resultActions); + this.printInfo("json信息"); + resultActions.andReturn().getResponse().setCharacterEncoding(this.characterEncoding); + ResultHandler handler = result -> { + LOG.info(result.getResponse().getContentAsString()); + }; + resultActions.andDo(handler); + + + this.printInfo("json end"); + } + + /** + * 显示Response信息 + * Created DateTime 2021-02-23 9:10 + * + * @param resultActions ResultActions + * @author LiuHuiYu + */ + private void responseInfo(@NotNull ResultActions resultActions) throws UnsupportedEncodingException { + String json = resultActions.andReturn().getResponse().getContentAsString(); + int size = json.getBytes().length; + this.printInfo("访问地址"); + LOG.info("{}{}", resultActions.andReturn().getRequest().getLocalAddr(), resultActions.andReturn().getRequest().getRequestURI()); + this.printInfo("参数信息"); + for (String key : resultActions.andReturn().getRequest().getParameterMap().keySet()) { + LOG.info("{}:{}", key, resultActions.andReturn().getRequest().getParameterMap().get(key)); + } + this.printInfo("字节Byte:" + size); + this.printInfo("流量bit:" + (size * 8)); + } + + protected void printInfo(String info) { + LOG.info("/******************************* " + info + " *******************************/"); + } + + protected MockHttpSession adminLoginSession(String adminAttribute, Object value) { + return setSession((session) -> session.setAttribute(adminAttribute, value)); + } + + protected MockHttpSession userLoginSession(String userAttribute, Object value) { + return setSession((session) -> session.setAttribute(userAttribute, value)); + } + + /** + * session设定; + * session.setAttribute(“admin”,admin);//对session进行登陆设置 + * Created DateTime 2021-02-23 9:19 + * + * @param consumer session + * @author LiuHuiYu + */ + protected MockHttpSession setSession(Consumer consumer) { + MockHttpSession session = new MockHttpSession(); + consumer.accept(session); + return session; + } + + protected String getResultJson(@NotNull ResultActions resultActions) throws Exception { + AtomicReference s = new AtomicReference<>(); + resultActions.andReturn().getResponse().setCharacterEncoding("UTF-8"); + ResultHandler handler = (result) -> { + s.set(result.getResponse().getContentAsString()); + }; + resultActions.andDo(handler); + return s.get(); + } +} \ No newline at end of file diff --git a/test2/src/main/java/com/liuhuiyu/test/BaseServiceTest.java b/test2/src/main/java/com/liuhuiyu/test/BaseServiceTest.java new file mode 100644 index 0000000..83a195b --- /dev/null +++ b/test2/src/main/java/com/liuhuiyu/test/BaseServiceTest.java @@ -0,0 +1,69 @@ +package com.liuhuiyu.test; + +import com.google.gson.Gson; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.domain.Page; + +import java.util.List; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-09-08 15:44 + */ +@SpringBootTest +public abstract class BaseServiceTest extends TestBase{ + + @BeforeEach + public void login() { + + } + + @AfterEach + public void after() { + + } + + protected void printList(@NotNull List list) { + for (Object obj : list) { + LOG.info(obj.toString()); + } + LOG.info("size = " + list.size()); + } + + protected void printObject(Object obj) { + if (obj == null) { + LOG.info("Obj=null"); + } + else { + LOG.info(obj.toString()); + } + } + + protected void printPageImpl(@NotNull Page pageImpl) { + LOG.info("总记录数:" + pageImpl.getTotalElements()); + LOG.info("当前页号索引:" + pageImpl.getNumber()); + + LOG.info("每页数据:" + pageImpl.getSize()); + + LOG.info("当前页记录数:" + pageImpl.getNumberOfElements()); + LOG.info("当前页号:" + (pageImpl.getNumber() + 1)); + + LOG.info("总页数:" + pageImpl.getTotalPages()); + printList(pageImpl.getContent()); + } + + protected void printJson(Object obj) { + if (obj == null) { + LOG.info("Obj=null"); + } + else { + LOG.info(new Gson().toJson(obj)); + } + } +} + + diff --git a/test2/src/main/java/com/liuhuiyu/test/TestBase.java b/test2/src/main/java/com/liuhuiyu/test/TestBase.java new file mode 100644 index 0000000..d91c9fa --- /dev/null +++ b/test2/src/main/java/com/liuhuiyu/test/TestBase.java @@ -0,0 +1,56 @@ +package com.liuhuiyu.test; + +import com.google.gson.Gson; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.config.Configurator; +import org.junit.jupiter.api.BeforeAll; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-09-08 11:17 + */ +public abstract class TestBase { + protected static Logger LOG; + + @BeforeAll + public static void initializeLogger() { + LOG = LogManager.getLogger(); + Configurator.setLevel(LOG, Level.DEBUG); + } + + /** + * 初始化 Logger + * + * @author LiuHuiYu + * Created DateTime 2022-09-08 11:18 + */ + protected void setLoggerValue(final Class clazz, Level level) { + LOG = LogManager.getLogger(clazz); + Configurator.setLevel(LOG, level); + } + + /** + * 初始化 Logger + * + * @author LiuHuiYu + * Created DateTime 2022-09-08 11:18 + */ + protected void setLoggerValue(Level level) { + LOG = LogManager.getLogger(); + org.apache.logging.log4j.core.config.Configurator.setLevel(LOG, level); + } + + /** + * 打印Object序列化到json的信息 + * + * @param obj 打印的对象 + * @author LiuHuiYu + * Created DateTime 2022-09-08 11:21 + */ + protected void printObjectJson(Object obj) { + LOG.info(new Gson().toJson(obj)); + } +} diff --git a/test2/src/main/main.iml b/test2/src/main/main.iml new file mode 100644 index 0000000..908ad4f --- /dev/null +++ b/test2/src/main/main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/test2/src/main/resources/log4j2d.xml b/test2/src/main/resources/log4j2d.xml new file mode 100644 index 0000000..79060e0 --- /dev/null +++ b/test2/src/main/resources/log4j2d.xml @@ -0,0 +1,99 @@ + + + + + + + third-api + /home/migu/portal-third-api/logs + 100 MB + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test2/src/test/java/com/liuhuiyu/test/TestBaseTest.java b/test2/src/test/java/com/liuhuiyu/test/TestBaseTest.java new file mode 100644 index 0000000..be179f0 --- /dev/null +++ b/test2/src/test/java/com/liuhuiyu/test/TestBaseTest.java @@ -0,0 +1,33 @@ +package com.liuhuiyu.test; + +import org.apache.logging.log4j.Level; +import org.junit.jupiter.api.Test; + +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-09-08 11:36 + */ +public class TestBaseTest extends TestBase{ + @Test + public void t1(){ + super.setLoggerValue(Level.ALL); + LOG.trace("s"); + LOG.debug("s"); + LOG.info("s"); + LOG.warn("s"); + LOG.error("s"); + LOG.fatal("s"); + } + @Test + public void t2(){ + String s="24:0"; + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("H:m"); + LocalTime t1=LocalTime.parse(s, formatter); + t1=t1.plusNanos(-1); + LOG.info(t1); + } +} diff --git a/test2/test2.iml b/test2/test2.iml new file mode 100644 index 0000000..2aea17f --- /dev/null +++ b/test2/test2.iml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/util/README.md b/util/README.md new file mode 100644 index 0000000..72cf543 --- /dev/null +++ b/util/README.md @@ -0,0 +1,41 @@ +# util 简介 +My util, Common tools collection +工具集合类 +# 包说明 +|包|说明| +|---|---| +|asserts|断言| +|constant.enums|常量枚举| +|exception|异常| +|spring|spring工具| +|web|web工具| +#导入方法 +1.将项目maven打jar包 +Maven->Util->生命周期->package +2.在要引用的项目中建立lib文件夹 +3.复制jar包到lib文件夹 +4.在pom.xml中 +dependencies 标签中加入 +~~~ + + com.liuhuiyu + util + 1.0-SNAPSHOT + system + ${project.basedir}/lib/util-1.0-SNAPSHOT.jar + +~~~ +build 标签中加入 +~~~ + + + lib + /BOOT-INF/lib/ + + **/*.jar + + + +~~~ +本地仓库安装 +mvn install:install-file -Dfile=util-1.0.0.jar -DgroupId=com.liuhuiyu -DartifactId=util -Dversion=1.0-SNAPSHOT -Dpackaging=jar diff --git a/util/pom.xml b/util/pom.xml new file mode 100644 index 0000000..762d2d6 --- /dev/null +++ b/util/pom.xml @@ -0,0 +1,195 @@ + + + + 4.0.0 + + com.liuhuiyu + util + 2022.1.0 + jar + + liuhuiyu-util + 个人工具类 + https://github.com/liuhuiyu2004/util + + + org.springframework.boot + spring-boot-starter-parent + 2.5.4 + + + + + + + MIT License + https://github.com/everitoken/evt4j/blob/master/LICENSE + repo + + + + https://github.com/liuhuiyu2004/util + scm:git:git@github.com:liuhuiyu2004/util + scm:git:git@github.com:liuhuiyu2004/util + + + + liuhuiyu + liuhuiyu2004@outlook.com + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + UTF-8 + 1.8 + 1.8 + 2.18.0 + + + + org.junit.platform + junit-platform-surefire-provider + 1.1.0 + test + + + org.junit.jupiter + junit-jupiter-api + 5.8.2 + test + + + com.liuhuiyu + test2 + 2022.1.0 + test + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter + + + + + + org.springframework.data + spring-data-commons + + + + org.jetbrains + annotations + 19.0.0 + + + + org.apache.directory.studio + org.apache.commons.codec + 1.8 + + + commons-codec + commons-codec + 1.15 + + + org.apache.commons + commons-io + 1.3.2 + + + commons-io + commons-io + 2.11.0 + + + com.google.code.gson + gson + 2.9.0 + + + + + + + + + + + + commons-beanutils + commons-beanutils + 1.9.4 + + + commons-collections + commons-collections + + + + + + org.apache.logging.log4j + log4j-core + ${log4j2.version} + compile + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + + + compile + + + jar-no-fork + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + -Xdoclint:none + + + + + + + diff --git a/util/src/main/java/com/liuhuiyu/util/ObjectUtil.java b/util/src/main/java/com/liuhuiyu/util/ObjectUtil.java new file mode 100644 index 0000000..0676ba7 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/ObjectUtil.java @@ -0,0 +1,74 @@ +package com.liuhuiyu.util; + +/** + * 此函数已经作废 尽量使用 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-01-28 8:23 + */ +public class ObjectUtil { + public static boolean isNull(Object o) { + return o == null; + } + + public static boolean equals(Object o1, Object o2) { + if (o1 == null) { + return o2 == null; + } + return o1.equals(o2); + } + + public static Integer parseInteger(Object o) { + return parseInteger(o, 0, 0); + } + + public static Integer parseInteger(Object o, Integer defValue, Integer nullValue) { + if (isNull(o)) { + return nullValue; + } + if (o instanceof Integer) { + return (Integer) o; + } else { + try { + return Integer.parseInt(o.toString()); + } catch (Exception ex) { + return defValue; + } + } + } + + public static Long parseLong(Object o) { + return parseLong(o.toString(), 0L, 0L); + } + + public static Long parseLong(Object o, Long defValue, Long nullValue) { + if (isNull(o)) { + return nullValue; + } + if (o instanceof Long) { + return (Long) o; + } else { + try { + return Long.parseLong(o.toString()); + } catch (Exception ex) { + return defValue; + } + } + } + + public static String parseString(Object o) { + return parseString(o, "", ""); + } + + public static String parseString(Object o, String defValue, String nullValue) { + if (isNull(o)) { + return nullValue; + } else { + if (o instanceof String) { + return (String) o; + } else { + return o.toString(); + } + } + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/asserts/LhyAssert.java b/util/src/main/java/com/liuhuiyu/util/asserts/LhyAssert.java new file mode 100644 index 0000000..8556bcb --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/asserts/LhyAssert.java @@ -0,0 +1,147 @@ +package com.liuhuiyu.util.asserts; + +import com.liuhuiyu.util.constant.enums.ResultEnum; +import com.liuhuiyu.util.exception.LhyException; + +import java.lang.reflect.Proxy; +import java.util.EventListener; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2020-09-10 8:41 + */ +public class LhyAssert { + static Function exceptionProxy; + + private static RuntimeException throwEx(String message) { + if (exceptionProxy == null) { + return new RuntimeException(message); + } + else { + return exceptionProxy.apply(message); + } + } + + /** + * 接受到异常信息后的异常抛出处理 + * + * @param proxy 接受到异常信息后的代理。 + * @author LiuHuiYu + * Created DateTime 2021-12-10 14:43 + */ + public static void exceptionProxy(Function proxy) { + exceptionProxy = proxy; + } + //region assertTrue + + public static void assertTrue(boolean value, RuntimeException exception) { + if (!value) { + throw exception; + } + } + + public static void assertTrue(boolean value, String message) { + assertTrue(value, throwEx(message)); + } + //endregion + + //region assertFalse + + public static void assertFalse(boolean value, String message) { + assertTrue(!value, message); + } + + public static void assertFalse(boolean value, RuntimeException exception) { + assertTrue(!value, exception); + } + //endregion + + //region assertNotNull + public static void assertNotNull(Object object, RuntimeException exception) { + assertTrue(object != null, exception); + } + + /** + * 对象为空则抛出异常 + * + * @param object 对象 + */ + public static void assertNotNull(Object object, String message) { + assertTrue(object != null, message); + } + + + //endregion + + //region assertNull + + /** + * 对象不为空则抛出异常 + * + * @param object 对象 + */ + public static void assertNull(Object object, RuntimeException exception) { + assertTrue(object == null, exception); + } + + /** + * 对象不为空则抛出异常 + * + * @param object 对象 + */ + public static void assertNull(Object object, String message) { + assertTrue(object == null, message); + } + //endregion + + //region 枚举模式拦截 + + /** + * 对象不为空则抛出异常 + * + * @param value 对象 + * @param resultEnum 错误枚举 + */ + public static void assertTrue(boolean value, ResultEnum resultEnum) { + if (!value) { + throw new LhyException(resultEnum); + } + } + + /** + * 对象为空则抛出异常 + * + * @param object 对象 + * @param resultEnum 错误枚举 + */ + public static void assertNotNull(Object object, ResultEnum resultEnum) { + assertTrue(object != null, resultEnum); + } + + /** + * 对象不为空则抛出异常 + * + * @param object 对象 + * @param resultEnum 错误枚举 + */ + public static void assertNull(Object object, ResultEnum resultEnum) { + assertTrue(object == null, resultEnum); + } + //endregion + + + public static void assertLen(String value, int min, int max, String message) { + assertNotNull(value, message + "未设定"); + assertTrue( + (min <= 0 || value.length() >= min) && + (max < 0 || value.length() <= max), message + "(长度范围[" + min + "-" + max + "])"); + } + + public static void assertLen(String value, int min, int max, RuntimeException exception) { + assertNotNull(value, exception); + assertTrue(value.length() >= min && value.length() <= max, exception); + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/bytes/ByteUtil.java b/util/src/main/java/com/liuhuiyu/util/bytes/ByteUtil.java new file mode 100644 index 0000000..e8a3dab --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/bytes/ByteUtil.java @@ -0,0 +1,221 @@ +package com.liuhuiyu.util.bytes; + +import java.math.BigInteger; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-09-03 10:46 + */ +public class ByteUtil { + public static String bytesOut(byte[] bytes) { + return bytesOut(bytes, " "); + } + + public static String bytesOut(byte[] bytes, String intervalSymbol) { + StringBuilder outString = new StringBuilder(); + for (byte aByte : bytes) { + String hex = Integer.toHexString(aByte & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex; + } + outString.append(intervalSymbol).append(hex); + } + return outString.toString(); + } + + + /** + * 将byte[]转为各种进制的字符串 + * + * @param bytes byte[] + * @param radix 基数可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制 + * @return 转换后的字符串 + */ + public static String binary(byte[] bytes, int radix) { + return new BigInteger(1, bytes).toString(radix);// 这里的1代表正数 + } + + /** + * 字节数组转16进制字符串 + * + * @param b 字节数组 + * @return 16进制字符串 + */ + public static String bytes2HexString(byte[] b) { + StringBuilder result = new StringBuilder(); + for (byte value : b) { + result.append(String.format("%02X", value)); + } + return result.toString(); + } + + /** + * 16进制字符串转字节数组 + * + * @param src 16进制字符串 + * @return 字节数组 + */ + public static byte[] hexString2Bytes(String src) { + int l = src.length() / 2; + byte[] ret = new byte[l]; + for (int i = 0; i < l; i++) { + ret[i] = Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue(); + } + return ret; + } + + /** + * 字符UTF8串转16进制字符串 + * + * @param strPart 字符串 + * @return 16进制字符串 + */ + public static String string2HexUTF8(String strPart) { + + return string2HexString(strPart, "UTF-8"); + } + + /** + * 字符Unicode串转16进制字符串 + * + * @param strPart 字符串 + * @return 16进制字符串 + */ + public static String string2HexUnicode(String strPart) { + + return string2HexString(strPart, "Unicode"); + } + + /** + * 字符GBK串转16进制字符串 + * + * @param strPart 字符串 + * @return 16进制字符串 + */ + public static String string2HexGBK(String strPart) { + + return string2HexString(strPart, "GBK"); + } + + /** + * 字符串转16进制字符串 + * + * @param strPart 字符串 + * @param tochartype hex目标编码 + * @return 16进制字符串 + */ + public static String string2HexString(String strPart, String tochartype) { + try { + return bytes2HexString(strPart.getBytes(tochartype)); + } + catch (Exception e) { + return ""; + } + } + + /** + * 16进制UTF-8字符串转字符串 + * + * @param src 16进制字符串 + * @return 字节数组 + */ + public static String hexUTF82String(String src) { + return hexString2String(src, "UTF-8", "UTF-8"); + } + + /** + * 16进制GBK字符串转字符串 + * + * @param src 16进制字符串 + * @return 字节数组 + */ + public static String hexGBK2String(String src) { + + return hexString2String(src, "GBK", "UTF-8"); + } + + /** + * 16进制Unicode字符串转字符串 + * + * @param src 16进制字符串 + * @return 字节数组 + */ + public static String hexUnicode2String(String src) { + return hexString2String(src, "Unicode", "UTF-8"); + } + + /** + * 16进制字符串转字符串 + * + * @param src 16进制字符串 + * @return 字节数组 + */ + public static String hexString2String(String src, String oldchartype, String chartype) { + byte[] bts = hexString2Bytes(src); + try { + return oldchartype.equals(chartype) ? + new String(bts, oldchartype) : + new String(new String(bts, oldchartype).getBytes(), chartype); + } + catch (Exception e) { + + return ""; + } + } + + /** + * int转16进制字符串,使用1字节表示16进制字符串 + * + * @param src int + * @return String + */ + public static String numToHex8(int src) { + //2表示需要两个16进制数 + return String.format("%02x", src); + } + + /** + * int转16进制字符串,使用2字节表示16进制字符串 + * + * @param src int + * @return String + */ + public static String numToHex16(int src) { + //4表示需要两个16进制数 + return String.format("%04x", src); + } + + /** + * 将一个int数字转换为二进制的字符串形式。 + * @param src int 需要转换的int类型数据 + * @param digit int 要转换的二进制位数,位数不足则在前面补0 + * @return String 二进制的字符串形式 + */ + public static String binary2decimal(int src, int digit) { + StringBuilder binStr = new StringBuilder(); + for (int i = digit - 1; i >= 0; i--) { + binStr.append((src >> i) & 1); + } + return binStr.toString(); + } + + /** + * 将一个二进制字符串转十六进制字符串形式。 + * @param src String 需要转换的二进制字符串 比如:000000111111 转换成16进制为 0F 注意长度不是8的倍数高位要补全0 + * @return String 二进制的字符串形式 + */ + public static String bin2hex(String src) { + StringBuilder sb = new StringBuilder(); + int len = src.length(); + //System.out.println("原数据长度:" + (len / 8) + "字节"); + for (int i = 0; i < len / 4; i++) { + //每4个二进制位转换为1个十六进制位 + String temp = src.substring(i * 4, (i + 1) * 4); + int tempInt = Integer.parseInt(temp, 2); + String tempHex = Integer.toHexString(tempInt).toUpperCase(); + sb.append(tempHex); + } + return sb.toString(); + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/constant/enums/ResultEnum.java b/util/src/main/java/com/liuhuiyu/util/constant/enums/ResultEnum.java new file mode 100644 index 0000000..712f7fa --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/constant/enums/ResultEnum.java @@ -0,0 +1,33 @@ +package com.liuhuiyu.util.constant.enums; + +/** + * 返回信息集合 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2020-07-08 11:45 + */ +public enum ResultEnum { + /** + * 成功 + */ + SUCCESS(0, "成功"), + CUSTOM_ERROR(-1,"自定义错误"), + ; + + private Integer code; + private String message; + + ResultEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + public Integer getCode() { + return code; + } + + public String getMessage() { + return message; + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/crontab/BaseExecutionTask.java b/util/src/main/java/com/liuhuiyu/util/crontab/BaseExecutionTask.java new file mode 100644 index 0000000..5d44780 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/crontab/BaseExecutionTask.java @@ -0,0 +1,108 @@ +package com.liuhuiyu.util.crontab; + +import com.liuhuiyu.util.thread.ExecutorBuilder; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * 定时执行任务基础类 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-03-29 10:36 + */ +public abstract class BaseExecutionTask { + private static final Logger LOG = LogManager.getLogger(BaseExecutionTask.class); + static final ThreadPoolTaskExecutor THREAD_POOL = ExecutorBuilder.create().maxPoolSize(30).threadName("task-loop-").builder(); + + private ScheduledExecutorService ses; + private Runnable runnable; + private long initialDelay; + private long period; + private TimeUnit unit; + private ScheduledFuture scheduledFuture; + CrontabReg appStartupRunner; + + public BaseExecutionTask(CrontabReg appStartupRunner, Boolean ignore) { + this.appStartupRunner = appStartupRunner; + if (!ignore) { + reg(); + } + + } + + /** + * 后期注册 + * + * @author LiuHuiYu + * Created DateTime 2022-09-01 19:33 + */ + public void reg() { + LOG.debug("注册自己的名称:{}", this.getClass().getName()); + this.appStartupRunner.reg(this.getClass().getName(), this); + this.runnable = () -> { + try { + this.execution(); + } + catch (Exception e) { + LOG.error("定时任务执行失败", e); + } + }; + this.initialDelay = 0; + this.period = 5; + this.unit = TimeUnit.SECONDS; + this.ses = new ScheduledThreadPoolExecutor(1, THREAD_POOL); + } + + /** + * 启动 + * + * @author LiuHuiYu + * Created DateTime 2022-03-29 10:45 + */ + public void run() { + LOG.debug("启动{}", this.getClass().getName()); + if (period > 0) { + this.scheduledFuture = this.ses.scheduleWithFixedDelay(runnable, initialDelay, period, unit); + } + } + + /** + * 停止服务 + * + * @author LiuHuiYu + * Created DateTime 2022-03-29 15:53 + */ + public void stop() { + this.scheduledFuture.cancel(true); + } + + /** + * 设定定时执行参数 + * + * @param initialDelay 第一次执行时间 + * @param period 执行周期 + * @param unit 周期单位 + * @author LiuHuiYu + * Created DateTime 2022-03-29 10:54 + */ + protected void setScheduleWithFixedDelayParameter(long initialDelay, long period, TimeUnit unit) { + this.initialDelay = initialDelay; + this.period = period; + this.unit = unit; + } + + /** + * 执行任务 + * + * @author LiuHuiYu + * Created DateTime 2022-03-29 10:46 + */ + protected abstract void execution(); +} diff --git a/util/src/main/java/com/liuhuiyu/util/crontab/CrontabReg.java b/util/src/main/java/com/liuhuiyu/util/crontab/CrontabReg.java new file mode 100644 index 0000000..007432b --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/crontab/CrontabReg.java @@ -0,0 +1,20 @@ +package com.liuhuiyu.util.crontab; + +/** + * 定时任务注册接口 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-10 18:18 + */ +public interface CrontabReg { + /** + * 定时任务注册接口 + * + * @param name 任务名称 + * @param executionTask 定时任务 + * @author LiuHuiYu + * Created DateTime 2022-05-10 18:24 + */ + void reg(String name, BaseExecutionTask executionTask); +} diff --git a/util/src/main/java/com/liuhuiyu/util/date/LocalDateUtil.java b/util/src/main/java/com/liuhuiyu/util/date/LocalDateUtil.java new file mode 100644 index 0000000..c0dd1a2 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/date/LocalDateUtil.java @@ -0,0 +1,235 @@ +package com.liuhuiyu.util.date; + +import com.liuhuiyu.util.asserts.LhyAssert; +import com.liuhuiyu.util.list.ExecutionFunction; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +/** + * 本地日期时间工具 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-05-22 14:39 + */ +public class LocalDateUtil { + public static final String FORMAT_YEAR_MONTH_DAY = "yyyy-MM-dd"; + public static final String FORMAT_YEAR_MONTH_DAY_HOUR = "yyyy-MM-dd HH"; + public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE = "yyyy-MM-dd HH:mm"; + public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss"; + + public static String dateToString(LocalDate date, String format) { + return date.format(DateTimeFormatter.ofPattern(format)); + } + + public static String dateToString(LocalDateTime date, String format) { + return date.format(DateTimeFormatter.ofPattern(format)); + } + + public static String dateToString(LocalTime date, String format) { + return date.format(DateTimeFormatter.ofPattern(format)); + } + + //region 常量 + /** + * 时间分隔符 + * Created DateTime 2022-09-05 10:56 + */ + public static final String TIME_DELIMITER_REGEX = ":"; + /** + * 日期时间分隔符 + * Created DateTime 2022-09-05 10:56 + */ + public static final String DATE_TIME_DELIMITER_REGEX = " "; + /** + * 日期分隔符 + * Created DateTime 2022-09-05 10:56 + */ + public static final String DATE_DELIMITER_REGEX = "[-/\\\\]"; + + public static final int PRECISION_YEAR = 1; + public static final int PRECISION_MONTH = 2; + public static final int PRECISION_DAY = 3; + public static final int PRECISION_HOUR = 4; + public static final int PRECISION_MINUTE = 5; + public static final int PRECISION_SECOND = 6; + public static final int PRECISION_NANO = 7; + public static final int DEFINE_YEAR = 1970; + public static final int DEFINE_MONTH = 1; + public static final int DEFINE_DAY = 1; + public static final int DEFINE_HOUR = 0; + public static final int DEFINE_MINUTE = 0; + public static final int DEFINE_SECOND = 0; + public static final int DEFINE_NANO = 0; + //endregion + + /** + * 字符串转日期 + * + * @param value 字符串 + * @return java.time.LocalDate + * @author LiuHuiYu + * Created DateTime 2022-09-05 10:46 + */ + public static LocalDate stringToDate(String value) { + return stringToDate(value, LocalDate.of(DEFINE_YEAR, DEFINE_MONTH, DEFINE_DAY)); + } + + /** + * 字符串转日期 + * + * @param value 字符串 + * @return java.time.LocalDate + * @author LiuHuiYu + * Created DateTime 2022-09-05 10:46 + */ + public static LocalDate stringToDate(String value, LocalDate defValue) { + return stringToDate(value, defValue, PRECISION_DAY); + } + + /** + * 字符串转日期 + * + * @param value 字符串 + * @return java.time.LocalDate + * @author LiuHuiYu + * Created DateTime 2022-09-05 10:46 + */ + public static LocalDate stringToDate(String value, LocalDate defValue, int precision) { + final String[] split = value.split(DATE_DELIMITER_REGEX); + try { + int year = getValue(split, 0, precision < PRECISION_YEAR, DEFINE_YEAR); + int month = getValue(split, 1, precision < PRECISION_MONTH, DEFINE_MONTH); + int day = getValue(split, 2, precision < PRECISION_DAY, DEFINE_DAY); + return LocalDate.of(year, month, day); + } + catch (Exception ignored) { + return defValue; + } + } + + /** + * 字符串转时间 + * + * @param value 字符串 + * @return java.time.LocalTime + * @author LiuHuiYu + * Created DateTime 2022-09-05 14:15 + */ + public static LocalTime stringToTime(String value) { + return stringToTime(value, LocalTime.of(DEFINE_HOUR, DEFINE_MINUTE, DEFINE_SECOND, DEFINE_NANO)); + } + + /** + * 字符串转时间 + * + * @param value 字符串 + * @param defValue 默认值 + * @return java.time.LocalTime + * @author LiuHuiYu + * Created DateTime 2022-09-05 14:15 + */ + public static LocalTime stringToTime(String value, LocalTime defValue) { + return stringToTime(value, defValue, PRECISION_MINUTE); + } + + /** + * 字符串转时间 + * + * @param value 字符串 + * @param defValue 默认值 + * @param precision 解析精度 + * @return java.time.LocalTime + * @author LiuHuiYu + * Created DateTime 2022-09-05 14:15 + */ + public static LocalTime stringToTime(String value, LocalTime defValue, int precision) { + final String[] split = value.split(TIME_DELIMITER_REGEX); + try { + int hour = getValue(split, 0, precision < PRECISION_HOUR, DEFINE_HOUR); + int minute = getValue(split, 1, precision < PRECISION_MINUTE, DEFINE_MINUTE); + int second = getValue(split, 2, precision < PRECISION_SECOND, DEFINE_SECOND); + int nanoOfSecond = getValue(split, 3, precision < PRECISION_NANO, DEFINE_NANO); + return LocalTime.of(hour, minute, second, nanoOfSecond); + } + catch (Exception ignored) { + return defValue; + } + } + + /** + * 字符串转日期时间 + * + * @param value 字符串(默认精确解析到日) + * @return java.time.LocalDateTime + * @author LiuHuiYu + * Created DateTime 2022-09-05 14:04 + */ + public static LocalDateTime stringToDateTime(String value) { + return stringToDateTime(value, LocalDateTime.of(DEFINE_YEAR, DEFINE_MONTH, DEFINE_DAY, DEFINE_HOUR, DEFINE_MINUTE, DEFINE_SECOND, DEFINE_NANO)); + } + + /** + * 字符串转日期时间 + * + * @param value 字符串(默认精确解析到日) + * @param defDateTime 解析失败默认值 + * @return java.time.LocalDateTime + * @author LiuHuiYu + * Created DateTime 2022-09-05 14:04 + */ + public static LocalDateTime stringToDateTime(String value, LocalDateTime defDateTime) { + return stringToDateTime(value, defDateTime, PRECISION_DAY); + } + + /** + * 字符串转日期时间 + * + * @param value 字符串 + * @param defDateTime 解析失败默认值 + * @param precision 解析精度 + *
YEAR_PRECISION:年
+ *
MONTH_PRECISION:月
+ *
DAY_PRECISION:日
+ *
HOUR_PRECISION:时
+ *
MINUTE_PRECISION:分
+ *
SECOND_PRECISION:秒
+ *
NANO_PRECISION:纳秒
+ * @return java.time.LocalDateTime + * @author LiuHuiYu + * Created DateTime 2022-09-05 14:04 + */ + public static LocalDateTime stringToDateTime(String value, LocalDateTime defDateTime, int precision) { + final String[] splitBase = value.split(DATE_TIME_DELIMITER_REGEX); + try { + LocalDate localDate = (LocalDate) ExecutionFunction.begin(splitBase) + .notSucceedExecution(v -> stringToDate(v[0], null, precision)) + .orElse(null); + LhyAssert.assertNotNull(localDate, ""); + LocalTime localTime = (LocalTime) ExecutionFunction.begin(splitBase) + .notSucceedExecution(v -> stringToTime(v[1], null, precision)) + .notSucceedExecution(v -> { + LhyAssert.assertTrue(precision < PRECISION_HOUR, ""); + return LocalTime.MIN; + }) + .orElse(null); + LhyAssert.assertNotNull(localTime, ""); + return LocalDateTime.of(localDate, localTime); + } + catch (Exception ignored) { + return defDateTime; + } + } + + private static int getValue(String[] split, int index, boolean precisionVerify, int defValue) { + return (int) ExecutionFunction.begin(split) + .notSucceedExecution(v -> Integer.parseInt(split[index])) + .notSucceedExecution((v) -> { + LhyAssert.assertTrue(precisionVerify, ""); + return defValue; + }).get(); + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/date/TimePeriod.java b/util/src/main/java/com/liuhuiyu/util/date/TimePeriod.java new file mode 100644 index 0000000..3af530e --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/date/TimePeriod.java @@ -0,0 +1,71 @@ +package com.liuhuiyu.util.date; + +import java.sql.Timestamp; + +/** + * 时间段信息 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-28 15:54 + */ +public class TimePeriod { + final Timestamp beginTime; + final Timestamp endTime; + + public TimePeriod(String beginTime, String endTime) { + Timestamp b = TimestampUtil.beginTime(beginTime); + Timestamp e = TimestampUtil.beginTime(endTime); + if (b == null || e == null) { + this.beginTime = null; + this.endTime = null; + } + else { + this.beginTime = b.before(e) ? b : e; + this.endTime = b.after(e) ? TimestampUtil.endTime(beginTime) : TimestampUtil.endTime(endTime); + } + } + + public TimePeriod(Timestamp beginTime, Timestamp endTime) { + if (beginTime == null || endTime == null) { + this.beginTime = null; + this.endTime = null; + } + else { + this.beginTime = beginTime.before(endTime) ? beginTime : endTime; + this.endTime = beginTime.after(endTime) ? beginTime : endTime; + } + } + + public TimePeriod stringCreate(String beginTime, String endTime) { + return new TimePeriod(beginTime, endTime); + } + + public TimePeriod timestampCreate(String beginTime, String endTime) { + return new TimePeriod(beginTime, endTime); + } + + /** + * 时间点在当前时间段内部(不包含边界) + * + * @param timestamp 检测时间点 + * @return boolean + * @author LiuHuiYu + * Created DateTime 2022-11-29 10:49 + */ + public boolean isInTimePeriod(Timestamp timestamp) { + return beginTime.before(timestamp) && endTime.after(timestamp); + } + + public Timestamp getBeginTime() { + return beginTime; + } + + public Timestamp getEndTime() { + return endTime; + } + + public boolean isValidTime() { + return beginTime != null; + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/date/TimestampUtil.java b/util/src/main/java/com/liuhuiyu/util/date/TimestampUtil.java new file mode 100644 index 0000000..0be8047 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/date/TimestampUtil.java @@ -0,0 +1,91 @@ +package com.liuhuiyu.util.date; + +import java.sql.Timestamp; +import java.text.SimpleDateFormat; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-28 15:55 + */ +public class TimestampUtil { + public static final String FORMAT_YEAR_MONTH_DAY = "yyyy-MM-dd"; + public static final String FORMAT_YEAR_MONTH_DAY_HOUR = "yyyy-MM-dd HH"; + public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE = "yyyy-MM-dd HH:mm"; + public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss"; + + /** + * 转换成开始时间 + * + * @param value 字符串 + * @return java.sql.Timestamp + * @author LiuHuiYu + * Created DateTime 2022-01-06 15:38 + */ + public static Timestamp beginTime(String value) { + try { + String tempV = value; + if (tempV.length() == FORMAT_YEAR_MONTH_DAY.length()) { + tempV += " 00:00:00"; + } + else if (tempV.length() == FORMAT_YEAR_MONTH_DAY_HOUR.length()) { + tempV += ":00:00"; + } + else if (tempV.length() == FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE.length()) { + tempV += ":00"; + } + return Timestamp.valueOf(tempV); + } + catch (Exception e) { + return null; + } + } + + /** + * 转换成结束时间 + * + * @param value 字符串 + * @return java.sql.Timestamp + * @author LiuHuiYu + * Created DateTime 2022-01-06 15:38 + */ + public static Timestamp endTime(String value) { + try { + String tempV = value; + if (tempV.length() == FORMAT_YEAR_MONTH_DAY.length()) { + tempV += " 23:59:59"; + } + else if (tempV.length() == FORMAT_YEAR_MONTH_DAY_HOUR.length()) { + tempV += ":59:59"; + } + else if (tempV.length() == FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE.length()) { + tempV += ":59"; + } + return Timestamp.valueOf(tempV); + } + catch (Exception e) { + return null; + } + } + + /** + * 可以转换为 Timestamp 的字符串 + * + * @param value 字符串 + * @return boolean + * @author LiuHuiYu + * Created DateTime 2022-01-06 15:37 + */ + public static boolean isTimestampString(String value) { + return endTime(value) != null; + } + + public static String toString(Timestamp timestamp, String format) { + try { + return new SimpleDateFormat(format).format(timestamp); + } + catch (Exception ex) { + return ""; + } + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/exception/LhyException.java b/util/src/main/java/com/liuhuiyu/util/exception/LhyException.java new file mode 100644 index 0000000..6cb5e52 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/exception/LhyException.java @@ -0,0 +1,54 @@ +package com.liuhuiyu.util.exception; + +import com.liuhuiyu.util.constant.enums.ResultEnum; +import org.jetbrains.annotations.NotNull; + +/** + * 自定义报错类 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2020-06-23 13:27 + */ +public class LhyException extends RuntimeException { + private Integer errId; +/* + public ArchivesManagementException(Integer code, String message) { + super(message); + this.code = code; + } +*/ + + public LhyException(@NotNull ResultEnum resultEnum) { + super(resultEnum.getMessage()); + this.errId = resultEnum.getCode(); + } + + public LhyException(@NotNull ResultEnum resultEnum, String message) { + super(resultEnum.getMessage() + ":" + message); + this.errId = resultEnum.getCode(); + } + + public LhyException(String message, @NotNull ResultEnum resultEnum) { + super(message + resultEnum.getMessage()); + this.errId = resultEnum.getCode(); + } + + public LhyException(String message, @NotNull ResultEnum resultEnum, String message1) { + super(message + resultEnum.getMessage() + message1); + this.errId = resultEnum.getCode(); + } + + public LhyException(String message) { + super(message); + this.errId = 0; + } + + public Integer getErrId() { + return errId; + } + + public void setErrId(Integer errId) { + this.errId = errId; + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/exception/ResultException.java b/util/src/main/java/com/liuhuiyu/util/exception/ResultException.java new file mode 100644 index 0000000..24707cf --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/exception/ResultException.java @@ -0,0 +1,17 @@ +package com.liuhuiyu.util.exception; + +import com.liuhuiyu.util.constant.enums.ResultEnum; +import org.jetbrains.annotations.NotNull; + +/** + * Result解析报错 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-12-10 16:25 + */ +public class ResultException extends LhyException{ + + public ResultException(String message) { + super(message); + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/exception/RetryUtil.java b/util/src/main/java/com/liuhuiyu/util/exception/RetryUtil.java new file mode 100644 index 0000000..f1c5b20 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/exception/RetryUtil.java @@ -0,0 +1,101 @@ +package com.liuhuiyu.util.exception; + + +import java.util.concurrent.Callable; + +/** + * 重复执行 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-07-05 15:44 + */ +public class RetryUtil { + /** + * 多次重试 + * + * @param num 重试次数 + * @param callFunctions 重试调用函数 + * @author LiuHuiYu + * Created DateTime 2021-07-05 16:58 + */ + public static R retry(int num, Callable callFunctions) { + return retry(num, false, callFunctions); + } + + /** + * 多次重试 + * + * @param num 执行次数(失败后重试) + * @param callFunctions 重试调用函数 + * @param failedCall 调用函数失败后执行 + * @author LiuHuiYu + * Created DateTime 2021-07-05 16:58 + */ + public static R retry(int num, Callable callFunctions, Runnable failedCall) { + return retry(num, true, callFunctions, failedCall); + } + + /** + * 重试一次 + * + * @param callFunctions 重试调用函数 + * @param failedCall 调用函数失败后执行 + * @author LiuHuiYu + * Created DateTime 2021-07-05 16:58 + */ + public static R retry(Callable callFunctions, Runnable failedCall) { + return retry(2, true, callFunctions, failedCall); + } + + /** + * 失败重试 + * + * @param num 重试次数 + * @param callFunctions [0]重拾函数,>0 失败后按照失败次数顺序执行 (失败1 执行【1】) + * @author LiuHuiYu + * Created DateTime 2021-07-05 17:13 + */ + public static R retry(int num, Callable callable, Runnable... callFunctions) { + return retry(num, true, callable, callFunctions); + } + + /** + * 失败重试 + * + * @param num 重试次数 + * @param loop 循环执行 + * @param callable 执行调用 + * @param callFunctions [0]重拾函数,>0 失败后按照失败次数顺序执行 (失败1 执行【1】) + * @author LiuHuiYu + * Created DateTime 2021-07-05 17:13 + */ + public static R retry(int num, boolean loop, Callable callable, Runnable... callFunctions) { + int pointer = -1; + try { + for (int i = 0; i < num - 1; i++) { + try { + return callable.call(); + } + catch (Exception e) { + if (pointer >= callFunctions.length - 1) { + if (loop) { + pointer = 0; + } + else { + continue; + } + } + else { + pointer++; + } + callFunctions[pointer].run(); + } + } + return callable.call(); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/file/FileUtil.java b/util/src/main/java/com/liuhuiyu/util/file/FileUtil.java new file mode 100644 index 0000000..7eab745 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/file/FileUtil.java @@ -0,0 +1,41 @@ +package com.liuhuiyu.util.file; + +import java.io.File; + +/** + * 文件工具类 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-12-13 17:14 + */ +public class FileUtil { + + public static String getExt(String fileName) { + String name = getFullFileName(fileName); + int index = separatorIndex(name); + return (index + 1) >= name.length() ? "" : name.substring(index + 1); + } + + private static int separatorIndex(String fileName) { + return fileName.lastIndexOf("."); + } + + /** + * 完整文件名获取(不带目录) + * + * @param fileName 文件名 + * @return java.lang.String + * @author LiuHuiYu + * Created DateTime 2021-12-13 17:26 + */ + public static String getFullFileName(String fileName) { + return new File(fileName).getName(); + } + + public static String getFileName(String fileName) { + String name = getFullFileName(fileName); + int index = separatorIndex(name); + return index < 1 ? name : name.substring(0, index); + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/functional/Execution.java b/util/src/main/java/com/liuhuiyu/util/functional/Execution.java new file mode 100644 index 0000000..ed9cbcb --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/functional/Execution.java @@ -0,0 +1,18 @@ +package com.liuhuiyu.util.functional; + +/** + * 可以直接使用 Runnable + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-23 23:06 + */ +@FunctionalInterface +@Deprecated +public interface Execution { + /** + * 执行 + * @author LiuHuiYu + * Created DateTime 2022-05-23 23:15 + */ + void run(); +} diff --git a/util/src/main/java/com/liuhuiyu/util/functional/MapToT.java b/util/src/main/java/com/liuhuiyu/util/functional/MapToT.java new file mode 100644 index 0000000..e2d9ed0 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/functional/MapToT.java @@ -0,0 +1,18 @@ +package com.liuhuiyu.util.functional; + +import java.util.Map; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-03-23 16:49 + */ +@FunctionalInterface +public interface MapToT { + /** + * Object 转换成 类型 T + * @param map Map + * @return T + */ + T mapToT(Map map); +} diff --git a/util/src/main/java/com/liuhuiyu/util/functional/ObjectToT.java b/util/src/main/java/com/liuhuiyu/util/functional/ObjectToT.java new file mode 100644 index 0000000..d662806 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/functional/ObjectToT.java @@ -0,0 +1,16 @@ +package com.liuhuiyu.util.functional; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-03-23 16:48 + */ +@FunctionalInterface +public interface ObjectToT { + /** + * Object 转换成 类型 T + * @param o Object + * @return T + */ + T objectToT(Object o); +} diff --git a/util/src/main/java/com/liuhuiyu/util/functional/package-info.java b/util/src/main/java/com/liuhuiyu/util/functional/package-info.java new file mode 100644 index 0000000..1dd6266 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/functional/package-info.java @@ -0,0 +1,7 @@ +/** + * 函数式 接口 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-03-23 16:47 + */ +package com.liuhuiyu.util.functional; \ No newline at end of file diff --git a/util/src/main/java/com/liuhuiyu/util/list/ExecutionFunction.java b/util/src/main/java/com/liuhuiyu/util/list/ExecutionFunction.java new file mode 100644 index 0000000..30a4df0 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/list/ExecutionFunction.java @@ -0,0 +1,170 @@ +package com.liuhuiyu.util.list; + +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * 执行功能(成功一次后后面的将不执行) + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-09-05 10:22 + */ +public class ExecutionFunction { + @SuppressWarnings("All") + Optional> optionalR = Optional.empty(); + T t; + RuntimeException exception = null; + + public ExecutionFunction(T t) { + this.t = t; + } + + /** + * 获取当前执行值 + * + * @return java.util.Optional + * @author LiuHuiYu + * Created DateTime 2022-09-05 10:32 + */ + private Optional getR() { + return optionalR.orElse(null); + } + + public static ExecutionFunction begin(T t) { + return new ExecutionFunction<>(t); + } + + public static ExecutionFunction begin() { + return new ExecutionFunction<>(null); + } + + /** + * 没有成功就执行 + * + * @param function 执行函数 + * @return com.liuhuiyu.util.date.LocalDateUtil.ExecutionFunction + * @author LiuHuiYu + * Created DateTime 2022-09-05 9:56 + */ + public ExecutionFunction notSucceedExecution(Function function) { + if (!this.hasExecutedSuccess()) { + try { + R r = function.apply(t); + this.optionalR = Optional.of(Optional.ofNullable(r)); + } + catch (Exception ex) { + this.exception = new RuntimeException(ex); + } + } + return this; + } + /** + * 没有成功就执行 + * + * @param supplier 执行函数 + * @return com.liuhuiyu.util.date.LocalDateUtil.ExecutionFunction + * @author LiuHuiYu + * Created DateTime 2022-09-05 9:56 + */ + public ExecutionFunction notSucceedExecution(Supplier supplier) { + if (!this.hasExecutedSuccess()) { + try { + R r = supplier.get(); + this.optionalR = Optional.of(Optional.ofNullable(r)); + } + catch (Exception ex) { + this.exception = new RuntimeException(ex); + } + } + return this; + } + /** + * 已执行成功 + * + * @return boolean + * @author LiuHuiYu + * Created DateTime 2022-09-05 10:31 + */ + private boolean hasExecutedSuccess() { + return optionalR.isPresent(); + } + + /** + * 获取执行结果 + * + * @return R + * @author LiuHuiYu + * Created DateTime 2022-09-05 10:33 + */ + public R get() { + if (this.hasExecutedSuccess()) { + return getR().orElse(null); + } + else { + if (exception == null) { + throw new NullPointerException("没有执行任何操作。"); + } + else { + throw exception; + } + } + } + + /** + * 执行失败返回默认值 + * + * @param defValue 默认值 + * @return R + * @author LiuHuiYu + * Created DateTime 2022-09-05 10:33 + */ + public R orElse(R defValue) { + if (this.hasExecutedSuccess()) { + return getR().orElse(null); + } + else { + if (exception == null) { + throw new NullPointerException("没有执行任何操作。"); + } + else { + return defValue; + } + } + } + + /** + * 执行失败就执行指定函数 + * + * @param other 指定函数 + * @return R + * @author LiuHuiYu + * Created DateTime 2022-09-05 10:34 + */ + public R orElseGet(Supplier other) { + if (this.hasExecutedSuccess()) { + return getR().orElse(null); + } + else { + return other.get(); + } + } + + /** + * 执行失败就抛出异常 + * + * @param exceptionSupplier 抛出异常 + * @return R + * @author LiuHuiYu + * Created DateTime 2022-09-05 10:34 + */ + public R orElseThrow(Supplier exceptionSupplier) throws X { + if (this.hasExecutedSuccess()) { + return getR().orElse(null); + } + else { + throw exceptionSupplier.get(); + } + } +} \ No newline at end of file diff --git a/util/src/main/java/com/liuhuiyu/util/list/IfRun.java b/util/src/main/java/com/liuhuiyu/util/list/IfRun.java new file mode 100644 index 0000000..544a546 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/list/IfRun.java @@ -0,0 +1,292 @@ +package com.liuhuiyu.util.list; + +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * 链式多条件执行并返回结果 + * 多个条件符合的情况下只执行第一个符合条件的表达式并返回结果 + * + * @author LiuHuiYu + * Created DateTime 2022-05-21 15:41 + */ +public class IfRun { + private final T t; + private R defineValue; + + private RuntimeException exception; + private Function defineFunction; + private Supplier defineSupplier; + private Optional resOptional; + + public static IfRun ifRun(T t) { + return new IfRun<>(t); + } + + public IfRun() { + this.t = null; + } + + /** + * 链式多条件执行并返回结果,如果都没有执行将返回默认 + * + * @param t 输出参数 + * @author LiuHuiYu + * Created DateTime 2022-05-21 16:16 + */ + public IfRun(T t) { + this.t = t; + } + + /** + * 链式多条件执行并返回结果,如果都没有执行将返回默认 + * + * @param t 输入参数 + * @param defineValue 默认值 + * @author LiuHuiYu + * Created DateTime 2022-05-21 16:15 + */ + public IfRun(T t, R defineValue) { + this.t = t; + this.defineValue = defineValue; + } + + /** + * 链式多条件执行并返回结果,如果都没有执行将抛出异常 + * + * @param t 输入参数 + * @param exception 抛出异常 + * @author LiuHuiYu + * Created DateTime 2022-05-21 16:17 + */ + public IfRun(T t, RuntimeException exception) { + this.t = t; + this.exception = exception; + } + + /** + * 链式多条件执行并返回结果,如果都没有执行将执行默认函数 + * + * @param t 输入参数 + * @param defineFunction 默认执行 + * @author LiuHuiYu + * Created DateTime 2022-05-21 16:17 + */ + public IfRun(T t, Function defineFunction) { + this.t = t; + this.defineFunction = defineFunction; + } + + /** + * 链式多条件执行并返回结果,如果都没有执行将执行默认函数 + * + * @param t 输入参数 + * @param defineSupplier 默认执行 + * @author LiuHuiYu + * Created DateTime 2022-05-21 16:17 + */ + public IfRun(T t, Supplier defineSupplier) { + this.t = t; + this.defineSupplier = defineSupplier; + } + + public void setDefineValue(R defineValue) { + this.defineValue = defineValue; + } + + public void setRuntimeException(RuntimeException exception) { + this.exception = exception; + } + + public void setDefineFunction(Function defineFunction) { + this.defineFunction = defineFunction; + } + + public void setDefineSupplier(Supplier defineSupplier) { + this.defineSupplier = defineSupplier; + } + + /** + * 添加执行 + * + * @param b 判断是否执行 + * @param f 要执行的函数 + * @return com.liuhuiyu.util.list.IfRun + * @author LiuHuiYu + * @deprecated 使用ifRun函数 + * Created DateTime 2022-05-21 16:17 + */ + @Deprecated + public IfRun add(Boolean b, Function f) { + return this.ifRun(b, f); + } + + /** + * 添加执行 + * + * @param b 判断是否执行 + * @param f 要执行的函数 + * @return com.liuhuiyu.util.list.IfRun + * @author LiuHuiYu + * Created DateTime 2022-05-21 16:17 + */ + public IfRun ifRun(Boolean b, Function f) { + if (isAllowExecution(b)) { + this.resOptional = Optional.ofNullable(f.apply(t)); + } + return this; + } + + /** + * 允许执行方法(之前没有任何可用的执行方法) + * + * @param b 执行条件 + * @return boolean + * @author LiuHuiYu + * Created DateTime 2023-01-24 14:09 + */ + private boolean isAllowExecution(Boolean b) { + return b && !isAlreadyExecution(); + } + /** + * 已经有执行的函数了 + * @author LiuHuiYu + * Created DateTime 2023-01-24 14:10 + * @return boolean + */ + @SuppressWarnings("all") + private boolean isAlreadyExecution() { + return null != this.resOptional; + } + + /** + * 添加执行 + * + * @param b 判断是否执行 + * @param supplier 要执行的函数 + * @return com.liuhuiyu.util.list.IfRun + * @author LiuHuiYu + * Created DateTime 2022-05-21 16:17 + * @deprecated 使用ifRun函数 + */ + @Deprecated + public IfRun add(Boolean b, Supplier supplier) { + return this.ifRun(b, supplier); + } + + /** + * 添加执行 + * + * @param b 判断是否执行 + * @param supplier 要执行的函数 + * @return com.liuhuiyu.util.list.IfRun + * @author LiuHuiYu + * Created DateTime 2022-05-21 16:17 + */ + public IfRun ifRun(Boolean b, Supplier supplier) { +// if (this.supplier == null && this.function == null && b) { +// this.supplier = supplier; +// } + if (this.isAllowExecution(b)) { + this.resOptional = Optional.ofNullable(supplier.get()); + } + return this; + } + + /** + * 获取执行结果 + * + * @return java.util.Optional + * @author LiuHuiYu + * Created DateTime 2022-05-21 16:18 + */ + public Optional run() { + if (this.isAlreadyExecution()) { + return this.resOptional; + } + else if (this.defineFunction != null) { + this.resOptional = Optional.ofNullable(this.defineFunction.apply(t)); + return this.resOptional; + } + else if (this.defineSupplier != null) { + this.resOptional = Optional.ofNullable(this.defineSupplier.get()); + } + else if (this.defineValue != null) { + this.resOptional = Optional.of(defineValue); + } + else if (this.exception != null) { + throw exception; + } + else { + return Optional.empty(); + } + return this.resOptional; + } + + /** + * 没有可用将执行 + * + * @param other 要执行的函数 + * @return R + * @author LiuHuiYu + * Created DateTime 2022-06-06 16:45 + */ + public R elseRun(Supplier other) { + this.run(); + if (this.isAlreadyExecution()) { + return this.resOptional.orElse(null); + } + else { + return other.get(); + } + } + + /** + * 没有返回结构将抛出异常 + * + * @param exceptionSupplier 将返回要抛出的异常的供应商 + * @return R + * @author LiuHuiYu + * Created DateTime 2022-06-06 16:51 + */ + public R orElseThrow(Supplier exceptionSupplier) throws X { + this.run(); + if (this.isAlreadyExecution()) { + return this.resOptional.orElse(null); + } + else { + throw exceptionSupplier.get(); + } + } + + /** + * 如果上面任何一个条件都不满足就返回指定值 + * + * @param r 指定值 + * @return R + * @author LiuHuiYu + * Created DateTime 2023-01-24 13:56 + */ + public R orElse(R r) { + this.run(); + if (this.isAlreadyExecution()) { + return this.resOptional.orElse(null); + } + else { + return r; + } + } + + public static IfRun ifRun() { + return new IfRun<>(); + } + + public IfRun ifRun(Boolean b, Runnable execution) { + if (this.isAllowExecution(b)) { + execution.run(); + this.resOptional = Optional.empty(); + } + return this; + } +} \ No newline at end of file diff --git a/util/src/main/java/com/liuhuiyu/util/list/ListUtil.java b/util/src/main/java/com/liuhuiyu/util/list/ListUtil.java new file mode 100644 index 0000000..5716f62 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/list/ListUtil.java @@ -0,0 +1,249 @@ +package com.liuhuiyu.util.list; + +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * 对象转换成List + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-04-14 10:59 + */ +public class ListUtil { + public static final String ARRAY_HEAD = "["; + + /** + * 将对象 转换成 List + * + * @param obj List对象 或者 array对象 + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2021-07-17 9:26 + */ + public static List objectToList(Object obj) { + return objectToListT(obj, (o) -> o); +// if (obj == null) { +// return new ArrayList<>(0); +// } +// else if (obj instanceof List) { +// List resList; +// List list = (List) obj; +// resList = new ArrayList<>(list.size()); +// resList.addAll(list); +// return resList; +// } +// else if (obj instanceof Collection) { +// List resList; +// Collection list = (Collection) obj; +// resList = new ArrayList<>(list.size()); +// resList.addAll(list); +// return resList; +// } +// else if (obj instanceof Object[]) { +// Object[] objects = (Object[]) obj; +// List resList = new ArrayList<>(objects.length); +// Collections.addAll(resList, objects); +// return resList; +// } +// else if (obj.getClass().getName().indexOf(ARRAY_HEAD) == 0) { +// return new ArrayList<>(0); +// } +// else { +// throw new RuntimeException("无法转换"); +// } + + } + + /** + * 将对象 转换成 List + * + * @param obj List对象 + * @param function 转换函数 + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2021-07-17 9:26 + */ + public static List objectToListT(Object obj, Function function) { + if (obj == null) { + return new ArrayList<>(0); + } + else if (obj instanceof List) { + List resList; + List list = (List) obj; + resList = new ArrayList<>(list.size()); + list.forEach((o) -> { + T t = function.apply(o); + if (t != null) { + resList.add(t); + } + }); + return resList; + } + else if (obj instanceof Collection) { + List resList; + Collection list = (Collection) obj; + resList = new ArrayList<>(list.size()); + list.forEach((o) -> { + T t = function.apply(o); + if (t != null) { + resList.add(t); + } + }); + return resList; + } + else if (obj instanceof Object[]) { + Object[] objects = (Object[]) obj; + if (objects.length == 0) { + return new ArrayList<>(0); + } + else { + List resList = new ArrayList<>(objects.length); + for (Object object : objects) { + T t = function.apply(object); + if (t != null) { + resList.add(function.apply(t)); + } + } + return resList; + } + } + else if (obj.getClass().getName().indexOf(ARRAY_HEAD) == 0) { + return new ArrayList<>(0); + } + else { + throw new RuntimeException("无法转换"); + } + } + + /** + * 获取元素t 在列表中 对应的索引 + * + * @param t 查询的对象 + * @param list 列表对象 + * @param comparable 列表比较函数式 + * @return java.lang.Integer + * @author LiuHuiYu + * Created DateTime 2021-05-19 22:48 + */ + public static Integer getIndex(T t, U[] list, BiFunction comparable) { + for (int i = 0; i < list.length; i++) { + if (comparable == null) { + if (t.equals(list[i])) { + return i; + } + } + else if (comparable.apply(t, list[i])) { + return i; + } + } + return -1; + } + + /** + * 获取排序后的列表 + * + * @param list 要排序的列表 + * @param sorts 排序的排列顺序 + * @param compare 排序匹配规则 + * @return java.util.List + */ + public static List getSortList(List list, L[] sorts, BiFunction compare) { + return getSortList(list, sorts, compare, true, true, true); + } + + /** + * 获取排序后的列表 + * + * @param list 要排序的列表 + * @param sorts 排序的排列顺序 + * @param compare 排序匹配规则 + * @param asc 按照排序顺序输出 + * @param notMatchedPostfix 未匹配的元素放到最后 + * @param notMatchedAsc 未匹配的元素顺序输出 + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2021-05-25 19:13 + */ + public static List getSortList(List list, L[] sorts, BiFunction compare, Boolean asc, Boolean notMatchedPostfix, Boolean notMatchedAsc) { + + List resList = new ArrayList<>(list.size()); + list.stream().sorted((a1, a2) -> { + Integer index1 = ListUtil.getIndex(a1, sorts, compare); + Integer index2 = ListUtil.getIndex(a2, sorts, compare); + if (index1 == -1 && index2 == -1) { + return notMatchedPostfix ? 1 : -1; + } + else if (index1 == -1) { + return notMatchedAsc ? 1 : -1; + } + else if (index2 == -1) { + return notMatchedAsc ? -1 : 1; + } + else if (asc) { + return index1.compareTo(index2); + } + else { + return index2.compareTo(index1); + } + }).forEach(resList::add); + return resList; + } + + /** + * List 转换 + * + * @param tList 原始list + * @param function 转换规则 + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2021-06-04 16:08 + */ + public static List listToList(List tList, Function function) { + List rList = new ArrayList<>(0); + for (T item : tList) { + rList.add(function.apply(item)); + } + return rList; + } + + /** + * list 转换成 数组 + * + * @param list List + * @return T[] + * @author LiuHuiYu + * Created DateTime 2021-07-17 9:17 + */ + public static T[] listToArray(List list) { + if (list.size() == 0) { + @SuppressWarnings("unchecked") final T[] a1 = (T[]) new Object[0]; + return a1; + } + Class z = list.get(0).getClass(); + @SuppressWarnings("unchecked") final T[] a = (T[]) Array.newInstance(z, list.size()); + for (int i = 0; i < list.size(); i++) { + a[i] = list.get(i); + } + return a; + } + + /** + * 数组转换 List + * + * @param array 数组 + * @return java.util.List + * @author LiuHuiYu + * Created DateTime 2021-07-17 9:17 + */ + public static List arrayToList(T[] array) { + List list = new ArrayList<>(array.length); + Collections.addAll(list, array); + return list; + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/list/TaskChain.java b/util/src/main/java/com/liuhuiyu/util/list/TaskChain.java new file mode 100644 index 0000000..5812c56 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/list/TaskChain.java @@ -0,0 +1,24 @@ +package com.liuhuiyu.util.list; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +/** + * 任务链 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-20 10:11 + */ +public class TaskChain { + public List> taskList = new ArrayList<>(); + + public void addTask(Consumer consumer) { + taskList.add(consumer); + } + + public void execution(T t) { + taskList.forEach(consumer -> consumer.accept(t)); + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/map/MapUtil.java b/util/src/main/java/com/liuhuiyu/util/map/MapUtil.java new file mode 100644 index 0000000..09ff986 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/map/MapUtil.java @@ -0,0 +1,646 @@ +package com.liuhuiyu.util.map; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; +import com.google.gson.internal.Primitives; +import com.google.gson.reflect.TypeToken; +import com.liuhuiyu.util.asserts.LhyAssert; +import com.liuhuiyu.util.exception.ResultException; +import com.liuhuiyu.util.functional.MapToT; +import com.liuhuiyu.util.model.Result; +import org.apache.commons.beanutils.BeanUtils; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +//import org.springframework.boot.autoconfigure.gson.GsonBuilderCustomizer; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; + +import javax.naming.CompositeName; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.security.Key; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.*; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-01-20 14:53 + */ +public class MapUtil { + + boolean throwException = false; + + public boolean isThrowException() { + return throwException; + } + + public void setThrowException(boolean throwException) { + this.throwException = throwException; + } + + //region 静态方法 + + /** + * Map对象转换成Map对象 + * + * @param obj Map对象 + * @return Map对象 + */ + public static Map mapObjectToStringKeyMap(Object obj) { + if (obj == null) { + return null; + } + else if (obj instanceof Map) { + Map map = (Map) obj; + Map resMap = new HashMap<>(map.size()); + map.forEach((k, v) -> resMap.put(k.toString(), v)); + return resMap; + } + else { + return new HashMap<>(0); + } + } + + private Object getMapObjectValue(Map map, String key) { + return getMapObjectValue(map, key, null); + } + + private Object getMapObjectValue(Map map, String key, Object defValue) { + return map.getOrDefault(key, defValue); + } + + public static String getMapStringValue(Map map, String key) { + return getMapStringValue(map, key, ""); + } + + /** + * 获取字符串(如果key 不存在返回 “”) + * + * @param map map + * @param key key + * @return 字符串 + */ + public static String getMapStringValue(Map map, String key, String defValue) { + if (map.containsKey(key)) { + Object obj = map.get(key); + return obj == null ? defValue : obj.toString(); + } + else { + return defValue; + } + } + + public static Integer getMapIntegerValue(Map map, String key) { + return getMapIntegerValue(map, key, 0); + } + + public static Integer getMapIntegerValue(Map map, String key, Integer defValue) { + Object obj = map.getOrDefault(key, defValue); + if (obj == null) { + return defValue; + } + else if (obj instanceof Number) { + return ((Number) obj).intValue(); + } + else { + String value = obj.toString(); + try { + return Integer.parseInt(value); + } + catch (NumberFormatException ex) { + return defValue; + } + } + } + + public static Float getMapFloatValue(Map map, String key) { + return getMapFloatValue(map, key, 0F); + } + + public static Float getMapFloatValue(Map map, String key, Float defValue) { + Object obj = map.getOrDefault(key, defValue); + if (obj == null) { + return defValue; + } + else if (obj instanceof Number) { + return ((Number) obj).floatValue(); + } + else { + String value = obj.toString(); + try { + return Float.parseFloat(value); + } + catch (NumberFormatException ex) { + return defValue; + } + } + } + + public static Long getMapLongValue(Map map, String key) { + return getMapLongValue(map, key, 0L); + } + + public static Long getMapLongValue(Map map, String key, Long defValue) { + Object obj = map.getOrDefault(key, defValue); + if (obj == null) { + return defValue; + } + else if (obj instanceof Number) { + return ((Number) obj).longValue(); + } + else { + String value = obj.toString(); + try { + return Long.parseLong(value); + } + catch (NumberFormatException ex) { + return defValue; + } + } + } + + public static Boolean getMapBooleanValue(Map map, String key) { + return getMapBooleanValue(map, key, false); + } + + public static Boolean getMapBooleanValue(Map map, String key, boolean defValue) { + Object obj = map.getOrDefault(key, defValue); + if (obj == null) { + return defValue; + } + else if (obj instanceof Boolean) { + return (Boolean) obj; + } + try { + return Boolean.parseBoolean(obj.toString()); + } + catch (Exception ex) { + return defValue; + } + } + + /** + * 将 map 中的 可转化为 int 的数字转化为 int + * + * @param resultMap map + * @return 修正后的map + */ + public static Map mapNumberToInt(Map resultMap) { + Map res = new HashMap<>(resultMap.size()); + for (Object keyObj : resultMap.keySet()) { + String key = keyObj.toString(); + if (resultMap.get(key) instanceof Double) { + Double value = (Double) resultMap.get(key); + if (value.intValue() == value) { + res.put(key, ((Double) resultMap.get(key)).intValue()); + } + else { + res.put(key, resultMap.get(key)); + } + } + else if (resultMap.get(key) instanceof List) { + res.put(key, listNumberToInt((List) resultMap.get(key))); + } + else if (resultMap.get(key) instanceof Map) { + res.put(key, mapNumberToInt((Map) resultMap.get(key))); + } + else { + res.put(key, resultMap.get(key)); + } + } + return res; + } + + /** + * 将 list 中的 可转化为 int 的数字转化为 int + * + * @param list list + * @return 修正后的list + */ + public static List listNumberToInt(List list) { + List res = new ArrayList<>(list.size()); + for (Object o : list) { + if (o instanceof Number) { + Double value = (Double) o; + if (value.intValue() == value) { + Object v = value.intValue(); + res.add(v); + } + else { + res.add(value); + } + } + else if (o instanceof Map) { + res.add(mapNumberToInt((Map) o)); + } + else if (o instanceof List) { + res.add(listNumberToInt((List) o)); + } + else { + res.add(o); + } + } + return res; + } + + @Deprecated + public static T mapToObject(Map map, T t) { + if (map == null) { + return null; + } + try { + BeanUtils.populate(t, map); + } + catch (Exception e) { + throw new RuntimeException(e); + } + return t; + } + + + //endregion + public static Map mapOfJsonString(String jsonString) { + try { + Map resultMap = new Gson().fromJson(jsonString, new TypeToken>() { + }.getType()); + return mapDoubleToInt(resultMap); + } + catch (JsonSyntaxException e) { + throw new RuntimeException("无法解析成Map格式数据"); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * 将Map序列化成指定类 + * + * @param map map + * @param classOfT T.class + * @param 得到的类 + * @return T + * @author LiuHuiYu + * Created DateTime 2022-01-22 16:42 + */ + public static T fromMap(Map map, Class classOfT) { + String json = new Gson().toJson(map); + return new Gson().fromJson(json, classOfT); + } + + /** + * 将Map序列化成指定类 + * + * @param map map + * @param classOfT T.class + * @param 得到的类 + * @return T + * @author LiuHuiYu + * Created DateTime 2022-01-22 16:42 + */ + public static T fromMap(Map map, Class classOfT, GsonAdapter[] typeAdapter) { + GsonBuilder gsonBuilder = new GsonBuilder(); + for (GsonAdapter gsonAdapter : typeAdapter) { + gsonBuilder.registerTypeAdapter(gsonAdapter.type, gsonAdapter.typeAdapter); + } + Gson gson = gsonBuilder.create(); + String json = gson.toJson(map); + return new Gson().fromJson(json, classOfT); + } + + public static class GsonAdapter { + Type type; + Object typeAdapter; + + public GsonAdapter(Type type, Object typeAdapter) { + this.type = type; + this.typeAdapter = typeAdapter; + } + } + + public static Map mapDoubleToInt(Map resultMap) { + Map res = new HashMap<>(resultMap.size()); + for (Object keyObj : resultMap.keySet()) { + String key = keyObj.toString(); + if (resultMap.get(key) instanceof Double) { + Double value = (Double) resultMap.get(key); + if (value.intValue() == value) { + res.put(key, ((Double) resultMap.get(key)).intValue()); + } + else { + res.put(key, resultMap.get(key)); + } + } + else if (resultMap.get(key) instanceof List) { + res.put(key, listDoubleToInt((List) resultMap.get(key))); + } + else if (resultMap.get(key) instanceof Map) { + res.put(key, mapDoubleToInt((Map) resultMap.get(key))); + } + else { + res.put(key, resultMap.get(key)); + } + } + return res; + } + + public static List listDoubleToInt(List list) { + List res = new ArrayList<>(list.size()); + for (Object o : list) { + if (o instanceof Number) { + Double value = (Double) o; + if (value.intValue() == value) { + Object v = value.intValue(); + res.add(v); + } + else { + res.add(value); + } + } + else if (o instanceof Map) { + res.add(mapDoubleToInt((Map) o)); + } + else if (o instanceof List) { + res.add(listDoubleToInt((List) o)); + } + else { + res.add(o); + } + } + return res; + } + + public static MapUtil ofJsonString(String jsonString) { + Map map = mapOfJsonString(jsonString); + return new MapUtil(map); + } + + private final Map map; + + public MapUtil(Map map) { + this.map = map; + } + + public String getStringValue(String key) { + return getMapStringValue(this.map, key); + } + + public String getStringValue(String key, String defValue) { + return getMapStringValue(this.map, key, defValue); + } + + public Integer getIntegerValue(String key) { + return getMapIntegerValue(map, key); + } + + public Integer getIntegerValue(String key, Integer defValue) { + return getMapIntegerValue(map, key, defValue); + } + + public Float getFloatValue(String key) { + return getMapFloatValue(map, key); + } + + public Float getFloatValue(String key, Float defValue) { + return getMapFloatValue(map, key, defValue); + } + + public Long getLongValue(String key) { + return getMapLongValue(map, key); + } + + public Long getLongValue(String key, Long defValue) { + return getMapLongValue(map, key, defValue); + } + + public Object getObjectValue(String key) { + return getMapObjectValue(map, key); + } + + public Object getObjectValue(String key, Object defValue) { + return getMapObjectValue(map, key, defValue); + } + + public T getValue(String key, T defValue) { + Object obj = map.getOrDefault(key, defValue); + if (obj.getClass().equals(defValue.getClass())) { + return (T) obj; + } + else if (throwException) { + throw new RuntimeException("类型转换失败。"); + } + else { + return defValue; + } + } + + public Boolean getBooleanValue(String key) { + return getMapBooleanValue(map, key); + } + + public Boolean getBooleanValue(String key, boolean defValue) { + return getMapBooleanValue(map, key, defValue); + } + + public Timestamp getTimestampValue(String key) { + return getTimestampValue(key, Timestamp.valueOf(LocalDateTime.now())); + } + + public Timestamp getTimestampValue(String key, Timestamp defValue) { + Object obj = map.get(key); + if (obj == null) { + return defValue; + } + else if (obj instanceof Timestamp) { + return (Timestamp) obj; + } + else if (obj instanceof Number) { + return new Timestamp(((Number) obj).longValue()); + } + else if (obj instanceof String) { + try { + return Timestamp.valueOf((String) obj); + } + catch (Exception ex) { + return defValue; + } + } + else { + return defValue; + } + } + + public BigDecimal getBigDecimal(String key) { + return getBigDecimal(key, BigDecimal.ZERO); + } + + public BigDecimal getBigDecimal(String key, BigDecimal defValue) { + Object obj = map.get(key); + if (obj == null) { + return defValue; + } + else if (obj instanceof Double) { + return BigDecimal.valueOf((Double) obj); + } + else if (obj instanceof Long) { + return BigDecimal.valueOf((Long) obj); + } + else if (obj instanceof Number) { + return BigDecimal.valueOf(((Number) obj).doubleValue()); + } + else if (obj instanceof String) { + try { + return new BigDecimal((String) obj); + } + catch (Exception ex) { + return defValue; + } + } + else { + return defValue; + } + } + + public T getValue(String key, Function function) { + return function.apply(map.getOrDefault(key, null)); + } + + public List getListValue(String key, Function function) { + Function> function2 = (obj) -> new ResInfo<>(true, function.apply(obj)); + return getCollectionValueAllowJudgment(key, function2, () -> new ArrayList<>(0)); + } + + /** + * Collection获取(List;Set) + * + * @param key 键值 + * @param function 转换 + * @param initializeCollection 初始化 Collection + * @return java.util.Collection + * @author LiuHuiYu + * Created DateTime 2021-08-06 9:50 + */ + public > R getCollectionValue(String key, Function function, Supplier initializeCollection) { + Function> function2 = (obj) -> new ResInfo<>(true, function.apply(obj)); + return getCollectionValueAllowJudgment(key, function2, initializeCollection); + } + + /** + * Collection获取(List;Set) + * + * @param key 键值 + * @param function 转换 + * @param initializeCollection 初始化 Collection + * @return java.util.Collection + * @author LiuHuiYu + * Created DateTime 2021-08-06 9:50 + */ + public > R getCollectionValueAllowJudgment(String key, Function> function, Supplier initializeCollection) { + R resList = initializeCollection.get(); + if (this.map.containsKey(key)) { + Object obj = this.map.get(key); + if (obj instanceof Collection) { + Collection list = (Collection) obj; + list.forEach(item -> { + ResInfo resInfo = function.apply(item); + if (resInfo.res) { + resList.add(resInfo.resData); + } + }); + return resList; + } + else if (this.throwException) { + throw new RuntimeException("无法解析非List数据"); + } + else { + return resList; + } + } + else if (this.throwException) { + throw new RuntimeException("不存在的键值。"); + } + else { + return resList; + } + } + + public Map getMap(String key) { + return getMap(key, new HashMap<>(0)); + } + + public Map getMap(String key, Map defValue) { + Object obj = map.get(key); + if (obj == null) { + return defValue; + } + else { + try { + return mapObjectToStringKeyMap(obj); + } + catch (Exception ignored) { + return defValue; + } + } + } + + public PageImpl getPageImpl(String key, MapToT mapToT) { + PageImpl def = new PageImpl<>(new ArrayList<>(0)); + return getPageImpl(key, mapToT, def); + } + + public PageImpl getPageImpl(String key, MapToT mapToT, PageImpl defValue) { + Object obj = map.get(key); + if (obj == null) { + return defValue; + } + else { + try { + Map map = mapObjectToStringKeyMap(obj); + return mapToPageImpl(map, mapToT); + } + catch (Exception ignored) { + return defValue; + } + } + } + + /** + * 获取ResultMap模型中的分页数据 + * + * @param map 原始map数据 + * @param mapToT 转换函数 + * @param 泛型 + * @return org.springframework.data.domain.PageImpl + * @author LiuHuiYu + * Created DateTime 2021-11-29 17:18 + */ + public static @NotNull PageImpl mapToPageImpl(Map map, MapToT mapToT) { + MapUtil mapUtil = new MapUtil(map); + int number = mapUtil.getIntegerValue("number", 0); + int size = mapUtil.getIntegerValue("size", 0); + PageRequest pageable = PageRequest.of(number, size); + long totalElements = mapUtil.getLongValue("totalElements", 0L); + List list = mapUtil.getListValue("content", obj -> mapToT.mapToT(MapUtil.mapObjectToStringKeyMap(obj))); + return new PageImpl<>(list, pageable, totalElements); + } + + public static class ResInfo { + Boolean res; + T resData; + + public ResInfo(Boolean res, T resData) { + this.res = res; + this.resData = resData; + } + } + + public static T cloneObj(T a, Class classOfT) { + String json = new Gson().toJson(a); + return new Gson().fromJson(json, classOfT); + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/model/DateBetween.java b/util/src/main/java/com/liuhuiyu/util/model/DateBetween.java new file mode 100644 index 0000000..81b4c59 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/model/DateBetween.java @@ -0,0 +1,43 @@ +package com.liuhuiyu.util.model; + +import com.liuhuiyu.util.date.LocalDateUtil; +import org.jetbrains.annotations.NotNull; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + +/** + * 时间范围结构 + * @deprecated 此结构已经迁移到了 jpa包中 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-09-08 9:44 + */ +@Deprecated +public class DateBetween { + LocalDateTime startDateTime; + LocalDateTime endDateTime; + + public DateBetween(@NotNull LocalDateTime time1, @NotNull LocalDateTime time2) { + this.startDateTime = time1.isBefore(time2) ? time1 : time2; + this.endDateTime = time1.isAfter(time2) ? time1 : time2; + } + + public LocalDateTime getStartDateTime() { + return startDateTime; + } + + public LocalDateTime getEndDateTime() { + return endDateTime; + } + + public String oracleBetweenSql(String columnName) { + return "(" + columnName + " between to_date('" + + this.getStartDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + + "','yyyy-MM-dd hh24:mi:ss') and to_date('" + + this.getEndDateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + + "','yyyy-MM-dd hh24:mi:ss'))"; + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/model/Result.java b/util/src/main/java/com/liuhuiyu/util/model/Result.java new file mode 100644 index 0000000..259712f --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/model/Result.java @@ -0,0 +1,282 @@ +package com.liuhuiyu.util.model; + +import com.liuhuiyu.util.asserts.LhyAssert; +import com.liuhuiyu.util.exception.ResultException; +import com.liuhuiyu.util.functional.MapToT; +import com.liuhuiyu.util.functional.ObjectToT; +import com.liuhuiyu.util.map.MapUtil; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2020-07-08 11:44 + */ +public class Result implements Serializable { + public static final int OK = 0; + public static final int ERROR = -1; + + /** + * 返回码 + */ + private Integer flag; + /** + * 信息 + */ + private String msg; + /** + * 返回数据 + */ + private T data; + + public Result() { + this.flag = OK; + this.msg = "操作成功"; + this.data = null; + } + + private Result(T data) { + this(); + this.data = data; + } + + private Result(T data, Integer flag) { + this(); + this.data = data; + this.flag = flag; + } + + private Result(T data, Integer flag, String msg) { + this(); + this.data = data; + this.flag = flag; + this.msg = msg; + } + + public Integer getFlag() { + return flag; + } + + public void setFlag(Integer flag) { + this.flag = flag; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public boolean isSuccess() { + return this.flag.equals(OK); + } + + /** + * 通过静态方法获取实例 + */ + @Contract(value = "_ -> new", pure = true) + public static @NotNull Result of(T data) { + return new Result<>(data); + } + + @Contract(value = "_, _ -> new", pure = true) + public static @NotNull Result of(T data, Integer flag) { + return new Result<>(data, flag); + } + + @Contract(value = "_, _, _ -> new", pure = true) + public static @NotNull Result of(T data, Integer flag, String msg) { + return new Result<>(data, flag, msg); + } + + @Contract(value = "_ -> new", pure = true) + public static @NotNull Result error(String msg) { + return new Result<>(null, ERROR, msg); + } + + @Contract(value = "_, _-> new", pure = true) + public static @NotNull Result error(String msg, int errorCode) { + return new Result<>(null, errorCode, msg); + } + + @Contract(value = " -> new", pure = true) + public static @NotNull Result success() { + return new Result<>(null, OK, ""); + } + + private static final String FLAG_KEY = "flag"; + private static final String MSG_KEY = "msg"; + private static final String DATA_KEY = "data"; + + @Deprecated + public static @NotNull Result ofMap(Map map, Class clazz) { + Result result = new Result<>(); + if (map.containsKey(FLAG_KEY)) { + result.flag = ((Number) map.get(FLAG_KEY)).intValue(); + } + else { + throw new RuntimeException("缺少关键字" + FLAG_KEY); + } + if (map.containsKey(MSG_KEY)) { + result.msg = map.get(MSG_KEY).toString(); + } + else { + throw new RuntimeException("缺少关键字" + MSG_KEY); + } + if (map.containsKey(DATA_KEY)) { + if (clazz.isInstance(map.get(DATA_KEY))) { + result.data = clazz.cast(map.get(DATA_KEY)); + } + else { + throw new RuntimeException("Map 关键字‘" + DATA_KEY + "’无法转换为当前类型。"); + } + } + else { + throw new RuntimeException("缺少关键字" + DATA_KEY); + } + return result; + } + + /** + * 获取ResultMap模型中的数据 + * + * @param map 传入数据 + * @return java.lang.Object + * @author LiuHuiYu + * Created DateTime 2021-11-25 17:11 + */ + public static Object getResultObj(Map map) { + return getValueOfResultMap(map, o -> o); + } + + /** + * 获取ResultMap模型中的数据 + * + * @param map 传入数据 + * @param mapToT 转换函数 + * @param 转换类型 + * @return java.util.List 返回转换后的数组(过滤null数据) + * @author LiuHuiYu + * Created DateTime 2021-11-25 17:05 + */ + public static List getResultToList(Map map, MapToT mapToT) { + LhyAssert.assertNotNull(mapToT, new ResultException("不能传入null解析方法mapToT。")); + LhyAssert.assertNotNull(map, new ResultException("传入null值,无法进行解析map。")); + ArrayList arrayList = getValueOfResultMap(map, o -> { + LhyAssert.assertTrue(o instanceof ArrayList, new ResultException("对象无法解析成列表")); + return (ArrayList) o; + }); + List list = new ArrayList<>(arrayList.size()); + for (Object obj : arrayList) { + Map itemMap = MapUtil.mapObjectToStringKeyMap(obj); + final T t = mapToT.mapToT(itemMap); + if (t != null) { + list.add(t); + } + } + return list; + } + + /** + * 获取ResultMap模型中的数据 + * + * @param map 传入数据 + * @param mapToT 转换函数 + * @param 转换类型 + * @return T 返回转换后的结果 + * @author LiuHuiYu + * Created DateTime 2021-11-25 17:10 + */ + public static T getResultData(Map map, MapToT mapToT) { + LhyAssert.assertNotNull(mapToT, new ResultException("不能传入null解析方法mapToT。")); + Object obj = getValueOfResultMap(map, o -> o); + Map itemMap = MapUtil.mapObjectToStringKeyMap(obj); + return mapToT.mapToT(itemMap); + } + + /** + * 将map转换成Result + * + * @param map Result的map结构 + * @return com.liuhuiyu.util.model.Result 返回Result结构 + * @author LiuHuiYu + * Created DateTime 2021-11-25 17:08 + */ + public static Result getResult(Map map) { + LhyAssert.assertNotNull(map, new ResultException("传入null值,无法进行解析map。")); + Result result = new Result<>(); + LhyAssert.assertTrue(map.containsKey(FLAG_KEY), new ResultException("flag信息有效判定字段不存在。")); + result.setFlag((int) map.get(FLAG_KEY)); + if (map.containsKey(MSG_KEY)) { + result.setMsg((String)map.get(MSG_KEY)); + } + if (map.containsKey(DATA_KEY)) { + result.setData(map.get(DATA_KEY)); + } + return result; + } + + /** + * 获取ResultMap的数据 + * + * @param map Result Map形式 + * @param objectToT 数据转换函数 + * @param 转换后的类型 + * @return T 转换后的结果 + * @author LiuHuiYu + * Created DateTime 2021-11-25 16:52 + */ + public static T getValueOfResultMap(Map map, ObjectToT objectToT) { + LhyAssert.assertNotNull(objectToT, new ResultException("不能传入null解析方法mapToT。")); + LhyAssert.assertNotNull(map, new ResultException("传入null值,无法进行解析map。")); + Result result = getResult(map); + LhyAssert.assertTrue(result.isSuccess(), result.getMsg()); + return objectToT.objectToT(result.getData()); + } + + /** + * 获取ResultMap模型中的分页数据 + * + * @param map 原始map数据 + * @param mapToT 转换函数 + * @param 泛型 + * @return org.springframework.data.domain.PageImpl + * @author LiuHuiYu + * Created DateTime 2021-11-29 17:18 + */ + @Contract("_, _ -> new") + public static @NotNull PageImpl getResultToPageImpl(Map map, MapToT mapToT) { + LhyAssert.assertNotNull(mapToT, new ResultException("不能传入null解析方法mapToT。")); + Result result = getResult(map); + if (result.isSuccess()) { + MapUtil mapUtil = new MapUtil(MapUtil.mapObjectToStringKeyMap(result.getData())); + int number = mapUtil.getIntegerValue("number", 0); + int size = mapUtil.getIntegerValue("size", 0); + PageRequest pageable = PageRequest.of(number, size); + long totalElements = mapUtil.getLongValue("totalElements", 0L); + List list = mapUtil.getListValue("content", obj -> mapToT.mapToT(MapUtil.mapObjectToStringKeyMap(obj))); + return new PageImpl<>(list, pageable, totalElements); + } + else { + throw new RuntimeException(result.getMsg()); + } + } +} \ No newline at end of file diff --git a/util/src/main/java/com/liuhuiyu/util/security/Md5SaltUtil.java b/util/src/main/java/com/liuhuiyu/util/security/Md5SaltUtil.java new file mode 100644 index 0000000..8d47e69 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/security/Md5SaltUtil.java @@ -0,0 +1,164 @@ +package com.liuhuiyu.util.security; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.Arrays; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-11-15 14:53 + */ +public class Md5SaltUtil { + private static final String HEX_NUMS_STR = "0123456789ABCDEF"; + /** + * 密码总长度=SALT_LENGTH * 2 + 32 + */ + private static final Integer SALT_LENGTH = 16; + private static final String CHARSET = "UTF-8"; + private static final String MD5_ALGORITHM = "MD5"; + + + /** + * 将16进制字符串转换成字节数组 + * + * @param hex hex + * @return 将16进制字符串转换成字节数组 + */ + private static byte[] hexStringToByte(String hex) { + int len = (hex.length() / 2); + byte[] result = new byte[len]; + char[] hexChars = hex.toCharArray(); + for (int i = 0; i < len; i++) { + int pos = i * 2; + result[i] = (byte) (HEX_NUMS_STR.indexOf(hexChars[pos]) << 4 + | HEX_NUMS_STR.indexOf(hexChars[pos + 1])); + } + return result; + } + + /** + * 将指定byte数组转换成16进制字符串 + * + * @param b byte数组 + * @return 16进制字符串 + */ + private static String byteToHexString(byte[] b) { + StringBuilder hexString = new StringBuilder(); + for (byte value : b) { + String hex = Integer.toHexString(value & 0xFF); + if (hex.length() == 1) { + hex = '0' + hex; + } + hexString.append(hex.toUpperCase()); + } + return hexString.toString(); + } + + /** + * 验证口令是否合法 + * + * @param password 密码 + * @param passwordInDb 验证密码 + * @return 密码是否匹配 + * @throws NoSuchAlgorithmException 异常 + * @throws UnsupportedEncodingException 异常 + */ + public static boolean validPassword(String password, String passwordInDb) + throws NoSuchAlgorithmException, UnsupportedEncodingException { + return validPassword(password, passwordInDb, SALT_LENGTH); + } + + /** + * 验证口令是否合法 + * + * @param password 密码 + * @param passwordInDb 验证密码 + * @param saltLength 混淆盐长度 + * @return 密码是否匹配 + * @throws NoSuchAlgorithmException 异常 + * @throws UnsupportedEncodingException 异常 + */ + public static boolean validPassword(String password, String passwordInDb, Integer saltLength) + throws NoSuchAlgorithmException, UnsupportedEncodingException { + //将16进制字符串格式口令转换成字节数组 + byte[] pwdInDb = hexStringToByte(passwordInDb); + //声明盐变量 + byte[] salt = new byte[saltLength]; + //将盐从数据库中保存的口令字节数组中提取出来 + System.arraycopy(pwdInDb, 0, salt, 0, saltLength); + //创建消息摘要对象 + MessageDigest md = MessageDigest.getInstance(MD5_ALGORITHM); + //将盐数据传入消息摘要对象 + md.update(salt); + //将口令的数据传给消息摘要对象 + md.update(password.getBytes(CHARSET)); + //生成输入口令的消息摘要 + byte[] digest = md.digest(); + //声明一个保存数据库中口令消息摘要的变量 + byte[] digestInDb = new byte[pwdInDb.length - saltLength]; + //取得数据库中口令的消息摘要 + System.arraycopy(pwdInDb, saltLength, digestInDb, 0, digestInDb.length); + //比较根据输入口令生成的消息摘要和数据库中消息摘要是否相同 + return Arrays.equals(digest, digestInDb); + } + + /** + * 获得加密后的16进制形式口令 + * + * @param password 密码 + * @return 加密后的口令 + * @throws NoSuchAlgorithmException 异常 + * @throws UnsupportedEncodingException 异常 + */ + public static String getEncryptedPwd(String password) + throws NoSuchAlgorithmException, UnsupportedEncodingException { + return getEncryptedPwd(password, SALT_LENGTH); + } + + /** + * 功能描述 + * + * @param password 密码 + * @param saltLength 混淆盐长度 + * @return java.lang.String 加密后的密码 + * @author LiuHuiYu + * Created DateTime 2021-11-15 15:31 + */ + public static String getEncryptedPwd(String password, Integer saltLength) + throws NoSuchAlgorithmException, UnsupportedEncodingException { + //声明加密后的口令数组变量 + byte[] pwd;// = null; + //随机数生成器 + SecureRandom random = new SecureRandom(); + //声明盐数组变量 12 + byte[] salt = new byte[saltLength]; + //将随机数放入盐变量中 + random.nextBytes(salt); + + //声明消息摘要对象 + MessageDigest md;// = null; + //创建消息摘要 + md = MessageDigest.getInstance(MD5_ALGORITHM); + //将盐数据传入消息摘要对象 + md.update(salt); + //将口令的数据传给消息摘要对象 + md.update(password.getBytes(CHARSET)); + //获得消息摘要的字节数组 + byte[] digest = md.digest(); + + //因为要在口令的字节数组中存放盐,所以加上盐的字节长度 + pwd = new byte[digest.length + saltLength]; + //将盐的字节拷贝到生成的加密口令字节数组的前12个字节,以便在验证口令时取出盐 + System.arraycopy(salt, 0, pwd, 0, saltLength); + //将消息摘要拷贝到加密口令字节数组从第13个字节开始的字节 + System.arraycopy(digest, 0, pwd, saltLength, digest.length); +// for(int i=0;i createKeys(int keySize) { + //为RSA算法创建一个KeyPairGenerator对象 + KeyPairGenerator kpg; + try { + kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM); + } catch (NoSuchAlgorithmException e) { + throw new IllegalArgumentException("没有[" + RSA_ALGORITHM + "]的算法"); + } + + //初始化KeyPairGenerator对象,密钥长度 + kpg.initialize(keySize); + //生成密匙对 + KeyPair keyPair = kpg.generateKeyPair(); + //得到公钥 + Key publicKey = keyPair.getPublic(); + String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded()); + //得到私钥 + Key privateKey = keyPair.getPrivate(); + String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded()); + Map keyPairMap = new HashMap<>(2); + keyPairMap.put(MAP_KEY_PUBLIC, publicKeyStr); + keyPairMap.put(MAP_KEY_PRIVATE, privateKeyStr); + + return keyPairMap; + } + + /** + * 得到公钥 + * + * @param publicKey 密钥字符串(经过base64编码) + * @throws NoSuchAlgorithmException 字符串错误 + */ + public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException { + //通过X509编码的Key指令获得公钥对象 + KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey)); + return (RSAPublicKey) keyFactory.generatePublic(x509KeySpec); + } + + /** + * 得到私钥 + * + * @param privateKey 密钥字符串(经过base64编码) + * @throws NoSuchAlgorithmException 字符串错误 + */ + public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException { + //通过PKCS#8编码的Key指令获得私钥对象 + KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM); + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey)); + return (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec); + } + + /** + * 公钥加密 + * + * @param data 要加密数据 + * @param publicKey 公钥 + * @return 加密后的数据 + */ + public static String publicEncrypt(String data, RSAPublicKey publicKey) { + return encrypt(data, publicKey); + } + + private static String encrypt(String data, Key key) { + try { + RSAKey rsaKey = (RSAKey) key; + Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); + cipher.init(Cipher.ENCRYPT_MODE, key); + return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), rsaKey.getModulus().bitLength())); + } catch (Exception e) { + throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e); + } + } + + /** + * 私钥解密 + * + * @param data 要解密数据 + * @param privateKey 私钥 + * @return 解密后的数据 + */ + public static String privateDecrypt(String data, RSAPrivateKey privateKey) { + return decrypt(data, privateKey); + } + + /** + * 私钥加密 + * + * @param data 要加密的数据 + * @param privateKey 私钥 + * @return 加密后的数据 + */ + public static String privateEncrypt(String data, RSAPrivateKey privateKey) { + return encrypt(data, privateKey); + } + + /** + * 公钥解密 + * + * @param data 要解密的数据 + * @param publicKey 公钥 + * @return 解密后的数据 + */ + public static String publicDecrypt(String data, RSAPublicKey publicKey) { + return decrypt(data, publicKey); + } + + private static String decrypt(String data, Key key) { + try { + RSAKey rsaKey = (RSAKey) key; + Cipher cipher = Cipher.getInstance(RSA_ALGORITHM); + cipher.init(Cipher.DECRYPT_MODE, key); + return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), rsaKey.getModulus().bitLength()), CHARSET); + } catch (Exception e) { + throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e); + } + } + + + + private static byte[] rsaSplitCodec(Cipher cipher, int opMode, byte[] dataBytes, int keySize) throws IOException { + int maxBlock; + if (opMode == Cipher.DECRYPT_MODE) { + maxBlock = keySize / 8; + } + else { + maxBlock = keySize / 8 - 11; + } + try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { + int offSet = 0; + byte[] buff; + int i = 0; + try { + while (dataBytes.length > offSet) { + if (dataBytes.length - offSet > maxBlock) { + buff = cipher.doFinal(dataBytes, offSet, maxBlock); + } + else { + buff = cipher.doFinal(dataBytes, offSet, dataBytes.length - offSet); + } + out.write(buff, 0, buff.length); + i++; + offSet = i * maxBlock; + } + } catch (Exception e) { + throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e); + } + return out.toByteArray(); + } + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/string/StringUtil.java b/util/src/main/java/com/liuhuiyu/util/string/StringUtil.java new file mode 100644 index 0000000..155dfe1 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/string/StringUtil.java @@ -0,0 +1,44 @@ +package com.liuhuiyu.util.string; + +import com.liuhuiyu.util.asserts.LhyAssert; + +/** + * 字符串工具 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-01-24 9:08 + */ +public class StringUtil { + + /** + * 子串截取 + * + * @param value 原始字符 + * @param beginIndex 开始索引(0开始) + * @param len 截取长度(注意这里是截取的最大长度>0) + * @return java.lang.String + * @author LiuHuiYu + * Created DateTime 2022-01-24 9:10 + */ + public static String substring(String value, int beginIndex, int len) { + if (value == null) { + return ""; + } + if (len <= 0) { + len = value.length(); + } + if (beginIndex < 0) { + beginIndex = 0; + } + if (beginIndex + len > value.length()) { + return value.substring(beginIndex, beginIndex + len); + } + else if (beginIndex > value.length()) { + return ""; + } + else { + return value.substring(beginIndex); + } + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/thread/ExecutorBuilder.java b/util/src/main/java/com/liuhuiyu/util/thread/ExecutorBuilder.java new file mode 100644 index 0000000..14ff684 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/thread/ExecutorBuilder.java @@ -0,0 +1,134 @@ +package com.liuhuiyu.util.thread; + +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.concurrent.ThreadPoolExecutor; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-07-17 10:29 + */ +public class ExecutorBuilder { + /** + * 参数初始化(初始化cpu数量) + * Created DateTime 2021-07-17 10:31 + */ + private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); + /** + * 初始化线程数量(2-4) + * Created DateTime 2021-07-17 10:51 + */ + private int corePoolSize = Math.max(2, Math.min(CPU_COUNT - 1, 4)); + /** + * 线程池大小(cpu * 2 +1) + * Created DateTime 2021-07-17 10:51 + */ + private int maxPoolSize = CPU_COUNT * 2 + 1; + /** + * 阻塞队列(20) + * Created DateTime 2021-07-17 10:52 + */ + private int workQueue = 20; + /** + * 线程空闲后的存活时长(30秒) + * Created DateTime 2021-07-17 10:52 + */ + private int keepAliveSeconds = 30; + private String threadName = "taskExecutor-"; + + public static ExecutorBuilder create() { + return new ExecutorBuilder(); + } + + /** + * 核心线程数量大小 + * + * @param corePoolSize 核心线程数量大小 + * @return com.liuhuiyu.util.thread.ThreadUtil.ExecutorBuilder + * @author LiuHuiYu + * Created DateTime 2021-07-17 10:28 + */ + public ExecutorBuilder corePoolSize(int corePoolSize) { + this.corePoolSize = corePoolSize; + return this; + } + + /** + * 线程池最大容纳线程数 + * + * @param maxPoolSize 线程池最大容纳线程数 + * @return com.liuhuiyu.util.thread.ThreadUtil.ExecutorBuilder + * @author LiuHuiYu + * Created DateTime 2021-07-17 10:28 + */ + public ExecutorBuilder maxPoolSize(int maxPoolSize) { + this.maxPoolSize = maxPoolSize; + return this; + } + + /** + * 阻塞队列 + * + * @param workQueue 阻塞队列 + * @return com.liuhuiyu.util.thread.ThreadUtil.ExecutorBuilder + * @author LiuHuiYu + * Created DateTime 2021-07-17 10:28 + */ + public ExecutorBuilder workQueue(int workQueue) { + this.workQueue = workQueue; + return this; + } + + /** + * 线程空闲后的存活时长 + * + * @param keepAliveSeconds 线程空闲后的存活时长 + * @return com.liuhuiyu.util.thread.ThreadUtil.ExecutorBuilder + * @author LiuHuiYu + * Created DateTime 2021-07-17 10:27 + */ + public ExecutorBuilder keepAliveSeconds(int keepAliveSeconds) { + this.keepAliveSeconds = keepAliveSeconds; + return this; + } + + /** + * 线程名称 + * + * @param threadName 线程名称 + * @return com.liuhuiyu.util.thread.ThreadUtil.ExecutorBuilder + * @author LiuHuiYu + * Created DateTime 2021-07-17 10:27 + */ + public ExecutorBuilder threadName(String threadName) { + this.threadName = threadName; + return this; + } + + public ThreadPoolTaskExecutor builder() { + ThreadPoolExecutor t; +// return (r)->{ +// Thread thread=new Thread(r); +// thread.setName(threadName); +// thread.start(); +// }; + ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor(); + //核心线程数 + threadPoolTaskExecutor.setCorePoolSize(corePoolSize); + //最大线程数 + threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize); + //等待队列 + threadPoolTaskExecutor.setQueueCapacity(workQueue); + //线程前缀 + threadPoolTaskExecutor.setThreadNamePrefix(threadName); + //线程池维护线程所允许的空闲时间,单位为秒 + threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds); + // 线程池对拒绝任务(无线程可用)的处理策略 + threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + threadPoolTaskExecutor.initialize(); + return threadPoolTaskExecutor; + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/thread/ThreadUtil.java b/util/src/main/java/com/liuhuiyu/util/thread/ThreadUtil.java new file mode 100644 index 0000000..8b4744c --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/thread/ThreadUtil.java @@ -0,0 +1,89 @@ +package com.liuhuiyu.util.thread; + +import org.jetbrains.annotations.NotNull; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; +import java.util.concurrent.Executor; + +/** + * 多线程工具 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-04-14 14:02 + */ +public class ThreadUtil { + /** + * 异步List循环(等待返回结果) + * + * @param list list + * @param consumer list处理 + * @author LiuHuiYu + * Created DateTime 2021-04-14 14:03 + */ + public static void asynchronousDataLoading(List list, Consumer consumer) { + asynchronousDataLoading(list, consumer, ExecutorBuilder.create().threadName("async-load-").builder()); + } + + /** + * 异步List循环(等待返回结果) + * + * @param list list + * @param consumer list处理 + * @param executor 线程池 + * @author LiuHuiYu + * Created DateTime 2021-04-14 14:03 + */ + public static void asynchronousDataLoading(@NotNull List list, Consumer consumer, ThreadPoolTaskExecutor executor) { + asynchronousDataLoading(list, consumer, executor, executor::shutdown); + } + + /** + * 异步List循环(等待返回结果) + * + * @param list list + * @param consumer list处理 + * @param executor 线程池 + * @param closeExecutor 提供关闭线程池的方法 + * @author LiuHuiYu + * Created DateTime 2021-04-14 14:03 + */ + public static void asynchronousDataLoading(@NotNull List list, Consumer consumer, Executor executor, Runnable closeExecutor) { + CompletableFuture.allOf(list.stream() + .map(item -> CompletableFuture.runAsync(() -> consumer.accept(item), executor)) + .toArray(CompletableFuture[]::new)).join(); + closeExecutor.run(); + } + + /** + * 休眠(带返回状态(成功:正常无中断;失败:异常中断引发休眠结束)) + * + * @param millis 休眠时间 + * @author LiuHuiYu + * Created DateTime 2021-08-20 14:43 + */ + @SuppressWarnings("All") + public static boolean sleep(long millis) { + try { + Thread.sleep(millis); + return true; + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + /* +如果不加上这一句,那么cd将会都是false,因为在捕捉到InterruptedException异常的时候就会自动的中断标志置为了false + Boolean c = Thread.interrupted(); + Boolean d = Thread.interrupted(); + log.error("中断引发休眠异常:{};重置中断位{}->{}", e.getMessage(), c, d); + */ + return false; + } + } + + public static void concurrent(){ + + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/web/AddressRoutingUtil.java b/util/src/main/java/com/liuhuiyu/util/web/AddressRoutingUtil.java new file mode 100644 index 0000000..da4df2d --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/web/AddressRoutingUtil.java @@ -0,0 +1,51 @@ +package com.liuhuiyu.util.web; + +import javax.servlet.http.HttpServletRequest; +import java.util.Map; + +/** + * 地址生成工具 + * + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2020-06-23 13:42 + */ +public class AddressRoutingUtil { + /** + * 获取地址 + * + * @param request request + * @param root 根目录 + * @param path 网页路径 + * @return 可以访问的地址 + */ + public static String getFullAddress(HttpServletRequest request, String root, String path) { + return getFullAddress(request, root, path, null); + } + + /** + * 获取地址 + * + * @param request request + * @param root 根目录 + * @param path 网页路径 + * @param parameter 参数对 + * @return 可以访问的地址 + */ + public static String getFullAddress(HttpServletRequest request, String root, String path, Map parameter) { + String foot = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath(); + String address; + address = foot + root + path; + + if (null == parameter) { + return address; + } else { + String linkSymbol = "?"; + for (String key : parameter.keySet()) { + address = String.format("%1$s%2$s%3$s=%4$s", address, linkSymbol, key, parameter.get(key).toString()); + linkSymbol = "&"; + } + return address; + } + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/web/HttpUtil.java b/util/src/main/java/com/liuhuiyu/util/web/HttpUtil.java new file mode 100644 index 0000000..394aa12 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/web/HttpUtil.java @@ -0,0 +1,29 @@ +package com.liuhuiyu.util.web; + +import com.liuhuiyu.util.asserts.*; +import org.jetbrains.annotations.NotNull; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2020-06-23 13:23 + */ +public class HttpUtil { + public static @NotNull HttpServletRequest getHttpServletRequest() { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + LhyAssert.assertNotNull(attributes, "Spring配置错误"); + return attributes.getRequest(); + } + + public static HttpServletResponse getHttpServletResponse() { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + LhyAssert.assertNotNull(attributes, "Spring配置错误"); + return attributes.getResponse(); + } +} + diff --git a/util/src/main/java/com/liuhuiyu/util/web/JsUtil.java b/util/src/main/java/com/liuhuiyu/util/web/JsUtil.java new file mode 100644 index 0000000..9f79089 --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/web/JsUtil.java @@ -0,0 +1,107 @@ +package com.liuhuiyu.util.web; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-03-09 11:35 + */ +public class JsUtil { + private static final String BASE_64_HASH = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + public static final String VALUE_RANGE_REGEX = "([^\\u0000-\\u00ff])"; + + public static boolean isMatcher(String inStr, String reg) { + Pattern pattern = Pattern.compile(reg); + Matcher matcher = pattern.matcher(inStr); + return matcher.matches(); + } + + /** + * btoa method + * + * @param inStr 字符串 + * @return 加密后的字符串 + */ + public static String btoa(String inStr) { + if (inStr == null || isMatcher(inStr, VALUE_RANGE_REGEX)) { + return null; + } + StringBuilder result = new StringBuilder(); + int i = 0; + int mod = 0; + int ascii; + int prev = 0; + while (i < inStr.length()) { + ascii = inStr.charAt(i); + mod = i % 3; + switch (mod) { + case 0: + result.append(BASE_64_HASH.charAt(ascii >> 2)); + break; + case 1: + result.append(BASE_64_HASH.charAt((prev & 3) << 4 | (ascii >> 4))); + break; + case 2: + result.append(BASE_64_HASH.charAt((prev & 0x0f) << 2 | (ascii >> 6))); + result.append(BASE_64_HASH.charAt(ascii & 0x3f)); + break; + default: + break; + } + prev = ascii; + i++; + } + + if (mod == 0) { + result.append(BASE_64_HASH.charAt((prev & 3) << 4)); + result.append("=="); + } + else if (mod == 1) { + result.append(BASE_64_HASH.charAt((prev & 0x0f) << 2)); + result.append("="); + } + return result.toString(); + } + + + /** + * // atob method + * // 逆转encode的思路即可 + * + * @param inStr 加密字符串 + * @return 解密后字符串 + */ + public static String atob(String inStr) { + if (inStr == null) { + return null; + } + inStr = inStr.replaceAll("\\s|=", ""); + StringBuilder result = new StringBuilder(); + int cur; + int prev = -1; + int mod; + int i = 0; + while (i < inStr.length()) { + cur = BASE_64_HASH.indexOf(inStr.charAt(i)); + mod = i % 4; + switch (mod) { + case 1: + result.append((char) (prev << 2 | cur >> 4)); + break; + case 2: + result.append((char) ((prev & 0x0f) << 4 | cur >> 2)); + break; + case 3: + result.append((char) ((prev & 3) << 6 | cur)); + break; + default: + break; + } + prev = cur; + i++; + } + return result.toString(); + } +} diff --git a/util/src/main/java/com/liuhuiyu/util/web/TomcatUtil.java b/util/src/main/java/com/liuhuiyu/util/web/TomcatUtil.java new file mode 100644 index 0000000..9ea988d --- /dev/null +++ b/util/src/main/java/com/liuhuiyu/util/web/TomcatUtil.java @@ -0,0 +1,124 @@ +package com.liuhuiyu.util.web; + +import javax.management.*; +import java.lang.management.ManagementFactory; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Optional; +import java.util.Set; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-09-29 10:50 + */ +public class TomcatUtil { + + public static final int NULL_PORT = -1; + + /** + * 获取tomcat启动端口 + * + * @return java.util.Optional + * @author LiuHuiYu + * Created DateTime 2022-09-29 10:51 + */ + public static Optional getTomcatPort1() { + MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer(); + try { + Set objectNames = beanServer.queryNames(new ObjectName("*:type=Connector,*"), Query.match(Query.attr("protocol"), Query.value("HTTP/1.1"))); + Iterator iterator = objectNames.iterator(); + if (!iterator.hasNext()) { + return Optional.empty(); + } + else { + return Optional.of(Integer.getInteger(objectNames.iterator().next().getKeyProperty("port"))); + } + } + catch (Exception e) { + return Optional.empty(); + } + } + + /** + * 获取tomcat启动端口 + * + * @return java.util.Optional + * @author LiuHuiYu + * Created DateTime 2022-09-29 10:51 + */ + public static Optional getTomcatPort2() { + MBeanServer mBeanServer = null; + ArrayList mBeanServers = MBeanServerFactory.findMBeanServer(null); + if (mBeanServers.size() > 0) { + mBeanServer = mBeanServers.get(0); + } + if (mBeanServer == null) { + return Optional.empty(); + } + Set objectNames; + try { + objectNames = mBeanServer.queryNames(new ObjectName("Catalina:type=Connector,*"), null); + if (objectNames == null || objectNames.size() <= 0) { + throw new IllegalStateException("没有发现JVM中关联的MBeanServer : " + mBeanServer.getDefaultDomain() + " 中的对象名称."); + } + for (ObjectName objectName : objectNames) { + String protocol = (String) mBeanServer.getAttribute(objectName, "protocol"); + if ("HTTP/1.1".equals(protocol) + || "org.apache.coyote.http11.Http11Nio2Protocol".equals(protocol) + || "org.apache.coyote.http11.Http11NioProtocol".equals(protocol)) { + return Optional.of((Integer) mBeanServer.getAttribute(objectName, "port")); + } + } + } + catch (Exception e) { + return Optional.empty(); + } + return Optional.empty(); + } + + public static Optional getTomcatPort3() { + MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer(); + try { + QueryExp protocol = Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")); + ObjectName name = new ObjectName("*:type=Connector,*"); + Set objectNames = beanServer.queryNames(name, protocol); + + for (ObjectName objectName : objectNames) { + String catalina = objectName.getDomain(); + if ("Catalina".equals(catalina)) { + return Optional.of(Integer.parseInt(objectName.getKeyProperty("port"))); + } + } + + } + catch (Exception e) { + return Optional.empty(); + } + return Optional.empty(); + } + + /** + * 获取tomcat启动端口 + * + * @return java.util.Optional + * @author LiuHuiYu + * Created DateTime 2022-09-29 10:51 + */ + public static Integer getTomcatPort(Integer defPort) { + return getTomcatPort1() + .orElseGet(() -> getTomcatPort2() + .orElseGet(() -> getTomcatPort3() + .orElse(defPort))); + } + + public static Optional getTomcatPort() { + Integer port = getTomcatPort(NULL_PORT); + if (port.equals(NULL_PORT)) { + return Optional.empty(); + } + else { + return Optional.of(port); + } + } +} diff --git a/util/src/test/java/com/liuhuiyu/util/HttpUtilTest.java b/util/src/test/java/com/liuhuiyu/util/HttpUtilTest.java new file mode 100644 index 0000000..8f81d1b --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/HttpUtilTest.java @@ -0,0 +1,32 @@ +package com.liuhuiyu.util; + + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2020-12-29 9:16 + */ +public class HttpUtilTest { + +// private volatile boolean s; +// private volatile String b(){ +// +// } +// @Contended +// class b{ +////LoadLoad; +////StoreStore; +// void s2(){ +// ----StoreStoreBarrier---- +// Load; +// Store; +// } +//// StoreLoad; +// } + + public void testStringToInt() { + String s = "123s"; + Integer i = Integer.getInteger(s, 101); +// log.info("i = {}", i); + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/bytes/ByteUtilTest.java b/util/src/test/java/com/liuhuiyu/util/bytes/ByteUtilTest.java new file mode 100644 index 0000000..89aed5f --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/bytes/ByteUtilTest.java @@ -0,0 +1,39 @@ +package com.liuhuiyu.util.bytes; + +import org.junit.jupiter.api.Test; + +import java.lang.ref.SoftReference; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-09-22 10:06 + */ +public class ByteUtilTest { + @Test + public void bytesOut() { + byte[] bytes = {'a', 'b', 'c'}; + String s = ByteUtil.bytesOut(bytes); +// log.info("s={}", s); + } + + @Test + public void binary() { + byte[] bytes = {'a', 'b', 'c'}; + String s = ByteUtil.binary(bytes, 16); +// log.info("s={}", s); + } + + @Test + public void string2HexUTF8() { + String hello = ByteUtil.string2HexUTF8("大家好"); +// log.info(hello); + String hello2 = ByteUtil.string2HexUnicode("大家好"); +// log.info(hello2); + } + + public void soft() { + SoftReference sr = new SoftReference<>(new byte[100]); + SoftReference sr2 = new SoftReference<>(new String[100]); + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/date/LocalDateUtilTest.java b/util/src/test/java/com/liuhuiyu/util/date/LocalDateUtilTest.java new file mode 100644 index 0000000..137d370 --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/date/LocalDateUtilTest.java @@ -0,0 +1,62 @@ +package com.liuhuiyu.util.date; + + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Test; + +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; + + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-09-07 14:10 + */ +public class LocalDateUtilTest { + private static final Logger LOG = LogManager.getLogger(LocalDateUtilTest.class); + + @Test + public void testStringToDate() { + String dateStr = "2021-02-11"; + LocalDateTime time2 = LocalDateUtil.stringToDateTime(dateStr); + LOG.info(time2); + LocalDateTime time1 = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-d H:m:s")); + LOG.info(time1); + } + + @Test + public void t1() { + String dateStr = "2021-02-11 9"; + LocalDateTime time4 = LocalDateUtil.stringToDateTime(dateStr); + LOG.error(time4); + LocalDateTime time3 = LocalDateUtil.stringToDateTime(dateStr, LocalDateTime.now(), LocalDateUtil.PRECISION_MINUTE); + LOG.error(time3); + LocalDateTime time2 = LocalDateUtil.stringToDateTime(dateStr, LocalDateTime.now(), LocalDateUtil.PRECISION_HOUR); + LOG.error(time2); + LocalDateTime time1 = LocalDateUtil.stringToDateTime(dateStr, LocalDateTime.now(), LocalDateUtil.PRECISION_DAY); + LOG.error(time1); + } + + @Test + public void stringToTime() { + String[] vs = new String[]{"","1","1:6","01:6:15","01:6:15:77"}; + for (String v : vs) { + LOG.error("str:{}", v); + LocalTime localTime = LocalDateUtil.stringToTime(v); + LOG.error("原始:{}",localTime); + localTime = LocalDateUtil.stringToTime(v,LocalTime.now()); + LOG.error("当前时间:{}",localTime); + localTime = LocalDateUtil.stringToTime(v,LocalTime.now(),LocalDateUtil.PRECISION_HOUR); + LOG.error("小时精度:{}",localTime); + localTime = LocalDateUtil.stringToTime(v,LocalTime.now(),LocalDateUtil.PRECISION_MINUTE); + LOG.error("分钟精度:{}",localTime); + localTime = LocalDateUtil.stringToTime(v,LocalTime.now(),LocalDateUtil.PRECISION_SECOND); + LOG.error("秒精度:{}",localTime); + localTime = LocalDateUtil.stringToTime(v,LocalTime.now(),LocalDateUtil.PRECISION_NANO); + LOG.error("纳秒精度:{}",localTime); + } + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/date/TimePeriodTest.java b/util/src/test/java/com/liuhuiyu/util/date/TimePeriodTest.java new file mode 100644 index 0000000..b05642a --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/date/TimePeriodTest.java @@ -0,0 +1,47 @@ +package com.liuhuiyu.util.date; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; + +import java.sql.Timestamp; +import java.time.LocalDateTime; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-05-28 16:14 + */ +class TimePeriodTest extends TestBase { + + @Test + public void testNull() { + TimePeriod timePeriod = new TimePeriod("", ""); + LOG.info("{}:{}-{}", timePeriod.isValidTime(), timePeriod.getBeginTime(), timePeriod.getEndTime()); + } + + @Test + public void testNull2() { + TimePeriod timePeriod = new TimePeriod("", "2012-03-07"); + LOG.info("{}-{}", timePeriod.getBeginTime(), timePeriod.getEndTime()); + } + + @Test + public void testTime() { + TimePeriod timePeriod = new TimePeriod("2022-11-30", "2022-11-30"); + LOG.info("{} - {}", timePeriod.getBeginTime(), timePeriod.getEndTime()); + Timestamp nowTime = new Timestamp(System.currentTimeMillis()); + LOG.info("{} in {}", nowTime, timePeriod.isInTimePeriod(nowTime)); + } + + @Test + public void testTime2() { + TimePeriod timePeriod = new TimePeriod(null, Timestamp.valueOf(LocalDateTime.now())); + LOG.info("{}-{}", timePeriod.getBeginTime(), timePeriod.getEndTime()); + } + + @Test + public void testTime3() { + TimePeriod timePeriod = new TimePeriod(Timestamp.valueOf(LocalDateTime.now().plusHours(1)), Timestamp.valueOf(LocalDateTime.now())); + LOG.info("{}-{}", timePeriod.getBeginTime(), timePeriod.getEndTime()); + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/date/TimestampUtilTest.java b/util/src/test/java/com/liuhuiyu/util/date/TimestampUtilTest.java new file mode 100644 index 0000000..c311175 --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/date/TimestampUtilTest.java @@ -0,0 +1,25 @@ +package com.liuhuiyu.util.date; + +import org.junit.jupiter.api.Test; + +import java.sql.Timestamp; +import java.time.LocalDateTime; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-07-09 12:53 + */ +class TimestampUtilTest { + @Test + public void isTimestampString() { + Timestamp timestamp = Timestamp.valueOf(LocalDateTime.now()); + String value = TimestampUtil.toString(timestamp, TimestampUtil.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND); + if (TimestampUtil.isTimestampString(value)) { + System.out.println("不是日期格式"); + } + } + +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/exception/RetryUtilTest.java b/util/src/test/java/com/liuhuiyu/util/exception/RetryUtilTest.java new file mode 100644 index 0000000..b8aa0ab --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/exception/RetryUtilTest.java @@ -0,0 +1,286 @@ +package com.liuhuiyu.util.exception; + +import com.liuhuiyu.util.thread.ThreadUtil; +import org.junit.jupiter.api.Test; + +import java.time.Duration; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-07-05 15:59 + */ +public class RetryUtilTest { +// @Test +// public void t1() { +// time = System.currentTimeMillis(); +// String s = s1(time, "abc"); +// log.info("返回信息:{}", s); +// } +// +// long time; + +// private String s1(long time, String s) { +// log.info("进入时间{}", time); +// getTime(); +// long newTime = System.currentTimeMillis(); +// log.info("{},{}", time, newTime); +// if (newTime > time + 1000) { +// return s; +// } +// Object o = RetryUtil.setRetryTimes(13).retry(s); +// if (o != null) { +// return o.toString(); +// } +// throw new RuntimeException("错误"); +// } + + private long getTime() { +// log.info("gettime"); + return System.currentTimeMillis(); + } + + private int retryTimes = 3; + + @Test + public void upperMethod() { + method("123", "456"); + } + + public void method(String param1, String param2) { + System.out.println(param1 + param2); + + // 其他一些操作,但是没有得到预期的返回结果,或者抛出异常 + boolean isException = true; + if (isException && retryTimes > 0) { + retryTimes--; + method(param1, param2); + } + } + + @Test + public void upperMethod2() { + method(3, "123", "456"); + } + + public void method(int retryTimes, String param1, String param2) { + System.out.println(param1 + param2); + + // 其他一些操作,但是没有得到预期的返回结果,或者抛出异常 + boolean isException = ThreadLocalRandom.current().nextBoolean(); + if (isException && retryTimes > 0) { + method(--retryTimes, param1, param2); + } + } + + // @Test +// public void mainMethod() throws InterruptedException { +// String s = subMethod("123", "456"); +// log.info(s); +// } +// +// public String subMethod(String param1, String param2) throws InterruptedException { +// long t = System.currentTimeMillis(); +// log.info("begin:{},{},{}", param1, param2, t); +// Thread.sleep(100); +// new RetryUtil().retry(10, param1, param2); +// long t2 = System.currentTimeMillis(); +// log.info("end:{},{},{}-{}", param1, param2, t, t2); +// return param1 + param2 + t; +// } + @Test + public void retry() { + Map map = new HashMap<>(1); + long time = System.currentTimeMillis(); + final Boolean res = RetryUtil.retry(3, () -> { + try { + Thread.sleep(600); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + map.put("res", s(time)); + return false; + }); + System.out.println(res); + System.out.println(map); + } + + @Test + public void retry2() { + Map map = new HashMap<>(1); + long time = System.currentTimeMillis(); + final Long retry = RetryUtil.retry(10, () -> time, () -> { + try { +// log.info("失败次执行"); + Thread.sleep(300); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + }); + System.out.println(map); + System.out.println(retry); + } + + @Test + public void retry3() { + Map map = new HashMap<>(1); + long time = System.currentTimeMillis(); + final Long res = RetryUtil.retry(3, () -> { + map.put("res", s(time)); + return time; + }, () -> { + try { +// log.info("失败1次执行"); + Thread.sleep(500); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + }, () -> { + try { +// log.info("失败2次执行"); + Thread.sleep(500); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + }); + System.out.println(res); + } + + @Test + public void retry4() { + Map map = new HashMap<>(1); + long time = System.currentTimeMillis(); + final Long res = RetryUtil.retry(() -> { + map.put("res", s(time)); + return time; + }, + () -> { + try { +// log.info("失败1次执行"); + Thread.sleep(500); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + }); + System.out.println(res); + } + + @Test + public void retry5() { + Map map = new HashMap<>(1); + long time = System.currentTimeMillis(); + final Long res = RetryUtil.retry(10, true, () -> { + map.put("res", s(time)); + return time; + }, + () -> { + try { +// log.info("失败1次执行"); + Thread.sleep(500); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + }, + () -> { + try { +// log.info("失败1次执行"); + Thread.sleep(500); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + }, + () -> { + try { +// log.info("失败1次执行"); + Thread.sleep(500); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + }, + () -> { + try { +// log.info("失败1次执行"); + Thread.sleep(500); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + }, + () -> { + try { +// log.info("失败1次执行"); + Thread.sleep(500); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + ); + System.out.println(res); + } + + private String s(long o) { + long time = System.currentTimeMillis(); + if (o > time - 1000) { + throw new RuntimeException(""); + } + return "" + time; + } + + @Test + public void uuid() { + UUID uuid = UUID.randomUUID(); + String uuidString = UUID.randomUUID().toString().replace("-", "").toUpperCase(); +// log.info("{}【{}】",uuidString,uuidString.length()); + + } + + @Test + public void testTime() { + + LocalDateTime time = LocalDateTime.now().plusSeconds(5); + ThreadUtil.sleep(2000); +// log.info("2秒后比较{}",time.isBefore(LocalDateTime.now())); + ThreadUtil.sleep(2000); +// log.info("2秒后比较{}",time.isBefore(LocalDateTime.now())); + ThreadUtil.sleep(2000); +// log.info("2秒后比较{}",time.isBefore(LocalDateTime.now())); + } + + @Test + public void duration() { + LocalDateTime time = LocalDateTime.now(); + LocalDateTime time2 = LocalDateTime.now().plusSeconds(1005); +// log.info("{}",Duration.between(time, time2).getSeconds()); +// log.info("{}",Duration.between(time2, time).getSeconds()); + } + + @Test + public void du() { + Duration duration = Duration.between(LocalDateTime.now(), LocalDate.now().plusDays(1).atStartOfDay()); + Duration duration2 = Duration.between(LocalDate.now().plusDays(1).atStartOfDay(), LocalDateTime.now()); +// log.info("({}秒{})",duration.getSeconds()/3600,duration2.getSeconds()/3600); + } + + @Test + public void timeToString() { + LocalDateTime localDateTime = LocalDateTime.now().plusSeconds(30); +// log.info(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/file/FileUtilTest.java b/util/src/test/java/com/liuhuiyu/util/file/FileUtilTest.java new file mode 100644 index 0000000..0b5bd1f --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/file/FileUtilTest.java @@ -0,0 +1,27 @@ +package com.liuhuiyu.util.file; + + +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-12-13 17:19 + */ +public class FileUtilTest { + + @Test + public void test01() { + String s = "\\a\\c\\d.e.f.g"; + File file = new File(s); + String fullFileName=FileUtil.getFullFileName(s); + final String ext = FileUtil.getExt(s); + final String fileName = FileUtil.getFileName(s); + final String yyyyMMdd = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/functional/ExecutionTest.java b/util/src/test/java/com/liuhuiyu/util/functional/ExecutionTest.java new file mode 100644 index 0000000..5a5fcb5 --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/functional/ExecutionTest.java @@ -0,0 +1,21 @@ +package com.liuhuiyu.util.functional; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-07-09 13:20 + */ +class ExecutionTest { + @Test + public void run() { + Execution execution = () -> { + System.out.println("测试执行"); + }; + execution.run(); + } + +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/list/ExecutionFunctionTest.java b/util/src/test/java/com/liuhuiyu/util/list/ExecutionFunctionTest.java new file mode 100644 index 0000000..e1aae27 --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/list/ExecutionFunctionTest.java @@ -0,0 +1,90 @@ +package com.liuhuiyu.util.list; + +import com.liuhuiyu.test.TestBase; +import com.liuhuiyu.util.asserts.LhyAssert; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-09-05 14:22 + */ +class ExecutionFunctionTest extends TestBase { + + @Test + public void test01() { + for (int i = -10; i < 10; i++) { + try { + final String s = this.executionFunction1(i); + LOG.info("{}:{}", i, s); + } + catch (Exception e) { + LOG.error("{}:{}", i, e); + } + } + } + @Test + public void test02() { + for (int i = -10; i < 10; i++) { + try { + final String s = this.executionFunction(i); + LOG.info("{}:{}", i, s); + } + catch (Exception e) { + LOG.error("{}:{}", i, e); + } + } + } + private String executionFunction1(int i) { + return (String) ExecutionFunction.begin(i) + .notSucceedExecution((v) -> { + LhyAssert.assertTrue(v > 3, "e1"); + return "a"; + }) + .notSucceedExecution((v) -> { + LhyAssert.assertTrue(v > 2, "e2"); + return "b"; + }) + .notSucceedExecution((v) -> { + LhyAssert.assertTrue(v > 1, "e3"); + return "c"; + }) + .notSucceedExecution((v) -> { + LhyAssert.assertTrue(v > 0, "e4"); + return "d"; + }) + .notSucceedExecution(() -> { + LhyAssert.assertTrue(i > -1, "e5"); + return "f"; + }) + .get(); + } + private String executionFunction(int i) { + return (String) ExecutionFunction.begin() + .notSucceedExecution(() -> { + LhyAssert.assertTrue(i > 3, "e1"); + return "a"; + }) + .notSucceedExecution(() -> { + LhyAssert.assertTrue(i > 2, "e2"); + return "b"; + }) + .notSucceedExecution(() -> { + LhyAssert.assertTrue(i > 1, "e3"); + return "c"; + }) + .notSucceedExecution(() -> { + LhyAssert.assertTrue(i > 0, "e4"); + return "d"; + }) + .notSucceedExecution(() -> { + LhyAssert.assertTrue(i > -1, "e5"); + return "f"; + }) + .get(); + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/list/IfRunTest.java b/util/src/test/java/com/liuhuiyu/util/list/IfRunTest.java new file mode 100644 index 0000000..bbb8ee5 --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/list/IfRunTest.java @@ -0,0 +1,59 @@ +package com.liuhuiyu.util.list; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.Optional; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicReference; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-06-25 9:02 + */ +class IfRunTest extends TestBase { + @Test + public void testIf() { + Integer s = ThreadLocalRandom.current().nextInt(2); + final Optional run = IfRun.ifRun(s) + .ifRun(s.equals(1), this::ss) + .ifRun(s.equals(0), this::ss2) + .run(); + } + + public Void ss() { + return null; + } + + public Void ss2() { + return null; + } + + @ParameterizedTest + @ValueSource(strings = {"s", "", "null", "onull"}) + public void testNull(String v) { + String v1 = v.equals("null") ? null : v; + Optional optional = null; + if (!"onull".equals(v)) { + optional = Optional.ofNullable(v1); + } + LOG.info("{}:{}", v1, optional); + } + + @ParameterizedTest + @ValueSource(strings = {"", "a", "ab", "abc", "abcd"}) + public void testIfRun(String v) { + int i = v.length(); + AtomicReference t = new AtomicReference<>(false); + final Optional run = IfRun.ifRun(v) + .ifRun(i == 1, (s) -> "测试Function[" + s + "]") + .ifRun(i == 2, () -> "测试Supplier[" + v + "]") + .ifRun(i == 3, () -> t.set(true)) + .run(); + + LOG.info("原始数据:{};长度:{};执行信息:{};执行Runnable:{}", v, i, run.orElse(t.get() ? "测试Runnable" : "未设定的解析类型。"), t.get()); + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/list/ListUtilTest.java b/util/src/test/java/com/liuhuiyu/util/list/ListUtilTest.java new file mode 100644 index 0000000..12de9ac --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/list/ListUtilTest.java @@ -0,0 +1,147 @@ +package com.liuhuiyu.util.list; + + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.BiFunction; +import java.util.stream.Collectors; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-05-25 19:16 + */ +public class ListUtilTest { + @Test + public void objectToList() { + Object o = getList(); + List list = ListUtil.objectToList(o); +// //log.info("转换List:{}", list); + Object o1 = getArray(); + List list1 = ListUtil.objectToList(o1); +// //log.info("转换List:{}", list1); + Object o2 = new int[]{}; + List list2 = ListUtil.objectToList(o2); + //log.info("转换List:{}", list2); + } + + @Test + public void objectToListT() { + Object o = getList(); + List list = ListUtil.objectToListT(o, (obj) -> { + if (obj instanceof Integer) { + return (Integer) obj; + } + else { + return 0; + } + }); + //log.info("转换List:{}", list); + Object o1 = getArray(); + List list1 = ListUtil.objectToListT(o1, (obj) -> { + if (obj instanceof Integer) { + return (Integer) obj; + } + else { + return 0; + } + }); + //log.info("转换List:{}", list1); + } + + + @Test + public void getSortList() { + List list = new ArrayList<>(); + Collections.addAll(list, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9); + Integer[] sorts = {1, 3, 5, 7, 9, 4, 8}; + BiFunction compare = Integer::equals; + List res; + res = ListUtil.getSortList(list, sorts, compare); + //log.info(res); + res = ListUtil.getSortList(list, sorts, compare, true, false, false); + //log.info(res); + res = ListUtil.getSortList(list, sorts, compare, true, false, true); + //log.info(res); + res = ListUtil.getSortList(list, sorts, compare, true, true, false); + //log.info(res); + res = ListUtil.getSortList(list, sorts, compare, true, true, true); + //log.info(res); + res = ListUtil.getSortList(list, sorts, compare, false, false, false); + //log.info(res); + res = ListUtil.getSortList(list, sorts, compare, false, false, true); + //log.info(res); + res = ListUtil.getSortList(list, sorts, compare, false, true, false); + //log.info(res); + res = ListUtil.getSortList(list, sorts, compare, false, true, true); + //log.info(res); + } + + @Test + public void testSort() { + String[] f = {"0", "1", "2", "-", "7", "8","4"}; + List list = Arrays.stream(f).collect(Collectors.toList()); + //log.info(list); + list.sort((a, b) -> { + Integer i, j; + try { + i = Integer.parseInt(a); + } + catch (Exception exception) { + i = null; + } + try { + j = Integer.parseInt(b); + } + catch (Exception exception) { + j = null; + } + if (i == null) { + return 1; + } + if (j == null) { + return -1; + } + return j.compareTo(i); + }); + //log.info(list); + } + + @Test + public void listToList() { + List integerList = this.getList(); + List longList = ListUtil.listToList(integerList, Integer::longValue); + List strList = ListUtil.listToList(integerList, (i) -> "'" + i.toString() + "'"); + //log.info("{}->{}->{}", integerList, longList, strList); + } + + @Test + public void listToArray() { + List integerList = this.getList(); + Integer[] is = ListUtil.listToArray(integerList); + //log.info("{}->{}", integerList, is); + } + + @Test + public void arrayToList() { + Integer[] array = getArray(); + List list = ListUtil.arrayToList(array); + //log.info("{}->{}", array, list); + } + + private List getList() { + List integerList = new ArrayList<>(10); + for (int i = 0; i < 10; i++) { + integerList.add(i); + } + return integerList; + } + + private Integer[] getArray() { + return new Integer[]{1, 2, 3, 4, 5, 6, 7}; + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/map/MapUtilTest.java b/util/src/test/java/com/liuhuiyu/util/map/MapUtilTest.java new file mode 100644 index 0000000..429dad3 --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/map/MapUtilTest.java @@ -0,0 +1,27 @@ +package com.liuhuiyu.util.map; + + +import org.junit.jupiter.api.Test; + +import java.util.Map; + + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-06-07 9:02 + */ +public class MapUtilTest { + @Test + public void test() { + String json = "{a:1,b:1.5,c:[{j:1,k:1.6},{j:2,k:1.7}],d:8088.0,16}"; + Map map = MapUtil.mapOfJsonString(json); +// log.info(map); + } + + @Test + public void ss(){ + String s="abv"; + String s1=MapUtil.cloneObj(s,String.class); + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/security/Md5SaltUtilTest.java b/util/src/test/java/com/liuhuiyu/util/security/Md5SaltUtilTest.java new file mode 100644 index 0000000..271f297 --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/security/Md5SaltUtilTest.java @@ -0,0 +1,26 @@ +package com.liuhuiyu.util.security; + + +import org.junit.jupiter.api.Test; + +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; + + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-11-15 14:59 + */ +public class Md5SaltUtilTest { + + @Test + public void test01() throws UnsupportedEncodingException, NoSuchAlgorithmException { + String password = "大家好"; + final String encryptedPwd = Md5SaltUtil.getEncryptedPwd(password); + //log.info("原始密码:{}", password); + //log.info("加密密码:{}", encryptedPwd); + final boolean b = Md5SaltUtil.validPassword(password, encryptedPwd); + //log.info("密码校验:{}", b); + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/security/RSAUtilTest.java b/util/src/test/java/com/liuhuiyu/util/security/RSAUtilTest.java new file mode 100644 index 0000000..8b14a3f --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/security/RSAUtilTest.java @@ -0,0 +1,81 @@ +package com.liuhuiyu.util.security; + + +import org.junit.jupiter.api.Test; + +import java.security.NoSuchAlgorithmException; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.util.Map; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-02-18 9:22 + */ +public class RSAUtilTest { + + @Test + public void createKeys() { + int keySize = 512; + Map map = RsaUtil.createKeys(keySize); + //log.info(map); + } + + @Test + public void getPublicKey() throws InvalidKeySpecException, NoSuchAlgorithmException { + int keySize = 512; + Map map = RsaUtil.createKeys(keySize); + RSAPublicKey key = RsaUtil.getPublicKey(map.get(RsaUtil.MAP_KEY_PUBLIC)); + //log.info(key); + } + + @Test + public void getPrivateKey() throws InvalidKeySpecException, NoSuchAlgorithmException { + int keySize = 512; + Map map = RsaUtil.createKeys(keySize); + RSAPrivateKey key = RsaUtil.getPrivateKey(map.get(RsaUtil.MAP_KEY_PRIVATE)); + //log.info(key); + } + + @Test + public void publicEncrypt() throws InvalidKeySpecException, NoSuchAlgorithmException { + int keySize = 512; + String info = "abcd"; + Map map = RsaUtil.createKeys(keySize); + String encryptInfo = RsaUtil.publicEncrypt(info, RsaUtil.getPublicKey(map.get(RsaUtil.MAP_KEY_PUBLIC))); + //log.info(encryptInfo); + } + + @Test + public void privateDecrypt() throws InvalidKeySpecException, NoSuchAlgorithmException { + int keySize = 512; + String info = "abcd"; + Map map = RsaUtil.createKeys(keySize); + String encryptInfo = RsaUtil.publicEncrypt(info, RsaUtil.getPublicKey(map.get(RsaUtil.MAP_KEY_PUBLIC))); + //log.info(encryptInfo); + String decryptInfo=RsaUtil.privateDecrypt(encryptInfo,RsaUtil.getPrivateKey(map.get(RsaUtil.MAP_KEY_PRIVATE))); + //log.info(decryptInfo); + } + + @Test + public void privateEncrypt() throws InvalidKeySpecException, NoSuchAlgorithmException { + int keySize = 512; + String info = "abcd"; + Map map = RsaUtil.createKeys(keySize); + String encryptInfo = RsaUtil.privateEncrypt(info, RsaUtil.getPrivateKey(map.get(RsaUtil.MAP_KEY_PRIVATE))); + //log.info(encryptInfo); + } + + @Test + public void publicDecrypt() throws InvalidKeySpecException, NoSuchAlgorithmException { + int keySize = 512; + String info = "abcd"; + Map map = RsaUtil.createKeys(keySize); + String encryptInfo = RsaUtil.privateEncrypt(info, RsaUtil.getPrivateKey(map.get(RsaUtil.MAP_KEY_PRIVATE))); + //log.info(encryptInfo); + String decryptInfo=RsaUtil.publicDecrypt(encryptInfo,RsaUtil.getPublicKey(map.get(RsaUtil.MAP_KEY_PUBLIC))); + //log.info(decryptInfo); + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/thread/ConcurrentTest.java b/util/src/test/java/com/liuhuiyu/util/thread/ConcurrentTest.java new file mode 100644 index 0000000..9a21569 --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/thread/ConcurrentTest.java @@ -0,0 +1,67 @@ +package com.liuhuiyu.util.thread; + +import org.junit.jupiter.api.Test; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-02-21 10:32 + */ +public class ConcurrentTest { + static int m = 0; + + @Test + public void concurrentTest() { + AtomicInteger integer = new AtomicInteger(0); + new ConcurrentTest().begin(10, () -> { + for (int i = 0; i < 10000; i++) { + integer.addAndGet(1); + m++; + } + }, () ->{ + System.out.println(m); + System.out.println(integer.get()); + }); + } + + /** + * 多线程测试用例 + * + * @param threadCount 开启线程数 + * @param run 线程执行方法 + * @param finish 线程全部执行结束后运行方法 + */ + public void begin(int threadCount, Run run, Finish finish) { + CountDownLatch countDownLatch = new CountDownLatch(1); + ExecutorService fixedThreadPool = Executors.newFixedThreadPool(threadCount); + for (int i = 0; i < threadCount; i++) { + fixedThreadPool.execute(() -> { + try { + countDownLatch.await(); + run.run(); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + }); + } + countDownLatch.countDown(); + fixedThreadPool.shutdown(); + while (!fixedThreadPool.isTerminated()) { + } + finish.finish(); + } + + public interface Run { + void run(); + } + + public interface Finish { + void finish(); + } +} diff --git a/util/src/test/java/com/liuhuiyu/util/thread/ThreadCpu.java b/util/src/test/java/com/liuhuiyu/util/thread/ThreadCpu.java new file mode 100644 index 0000000..9bbf42b --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/thread/ThreadCpu.java @@ -0,0 +1,50 @@ +package com.liuhuiyu.util.thread; + + +import org.junit.jupiter.api.Test; + +import java.util.concurrent.CompletableFuture; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-07-30 20:25 + */ +public class ThreadCpu { + private static int x = 0, y = 0; + private static int a = 0, b = 0; + int i = 0; + + @Test + public void test() throws InterruptedException { + int i = 0; + for (; ; ) { + i++; + x = 0; + y = 0; + a = 0; + b = 0; + Thread one = new Thread(() -> { + a = 1; + x = b; + }); + + Thread other = new Thread(() -> { + b = 1; + y = a; + }); + one.start(); + other.start(); + one.join(); + other.join(); + String result = "第" + i + "次 (" + x + "," + y + ")"; + // 出现00组合 证明cpu乱序执行了 + if (x == 0 && y == 0) { + System.err.println(result); + break; + } else { + //System.out.println(result); + } + } + } +} diff --git a/util/src/test/java/com/liuhuiyu/util/thread/ThreadUtilTest.java b/util/src/test/java/com/liuhuiyu/util/thread/ThreadUtilTest.java new file mode 100644 index 0000000..40c20a2 --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/thread/ThreadUtilTest.java @@ -0,0 +1,171 @@ +package com.liuhuiyu.util.thread; + +import com.liuhuiyu.test.TestBase; +import org.junit.jupiter.api.Test; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-07-17 10:36 + */ +public class ThreadUtilTest extends TestBase { + + @Test + public void asynchronousDataLoading() { + List list = new ArrayList<>(5); + Collections.addAll(list, 5, 1, 6, 4, 3, 2, 7, 5, 6); + ThreadUtil.asynchronousDataLoading(list, this::testExe); + } + + @Test + public void asynchronousDataLoading2() { + List list = new ArrayList<>(5); + Collections.addAll(list, 5, 1, 9, 4, 3, 2, 7, 8, 6); + for (int i = 0; i < 100; i++) { + ThreadPoolTaskExecutor threadPoolTaskExecutor = ExecutorBuilder.create().corePoolSize(list.size()).threadName("test-" + i + "-").builder(); + ThreadUtil.asynchronousDataLoading(list, this::testExe, threadPoolTaskExecutor); + } + } + + private void testExe(Integer i) { + try { + LOG.info("开始:{}", i); + Thread.sleep(i * 1000); + LOG.info("完成:{}", i); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + + @Test + public void s() { + List list = new ArrayList() {{ + this.add("1"); + this.add("2"); + this.add("3"); + this.add("3"); + this.add("32"); + }}; + String[] array = list.toArray(new String[0]); + //log.info("{},{}", list, list.size()); + //log.info(":{};{};", array, array.length); + } + + private List getIntegerList() { + return new ArrayList() {{ + this.add(1); + this.add(2); + this.add(3); + this.add(4); + this.add(5); + }}; + } + + @Test + @SuppressWarnings({"rawtypes", "unused"}) + public void testCompletableFuture() throws ExecutionException, InterruptedException { + List integerList = getIntegerList(); +// AtomicReference> future = new AtomicReference<>(); + integerList.forEach(i -> { + CompletableFuture future01 = CompletableFuture.supplyAsync(() -> { + sleep(i); + return i; + }); +// future.set(future01); + }); + CompletableFuture.supplyAsync(() -> integerList.stream().map((item) -> CompletableFuture.runAsync(() -> sleep(item))).collect(Collectors.toList())); + CompletableFuture[] s2 = integerList.stream().map((item) -> CompletableFuture.runAsync(() -> sleep(item))).toArray(CompletableFuture[]::new); + CompletableFuture.anyOf(s2).thenAccept((a) -> { + }).get(); + } + + private void sleep(Integer i) { +// //log.info("进入{}",i); + //log.info("任务{}线程:", Thread.currentThread().getId()); + + if (i < 3) + throw new RuntimeException(); + try { + Thread.sleep(i * 1000); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + //log.info("离开{}", Thread.currentThread().getId()); + } + + @Test + public void testSleep() { + Runnable runnable = () -> { + long millis = 10_000; + //log.info("开始执行:{}毫秒延时。", millis); + if (ThreadUtil.sleep(millis)) { + //log.info("正常结束。"); + } + else { + //log.info("线程内异常,中断休眠"); + } + }; + Thread thread = new Thread(runnable); + thread.start(); + //log.info("3秒后引发中断。"); + if (ThreadUtil.sleep(3_000)) { + //log.info("引发中断。"); + thread.interrupt(); + //log.info("引发中断完成。"); + } + long millis = 100_000; + //log.info("程序完成。"); + if (!ThreadUtil.sleep(millis)) { + //log.info("异常中断休眠"); + } + } + + /** + * 重入不影响已经传入的变量,但是会影响非原子变量 + * @author LiuHuiYu + * Created DateTime 2021-09-09 16:37 + */ + @Test + public void testThread() { + CopyOnWriteArrayList list = new CopyOnWriteArrayList<>(); + AtomicReference atomicInt=new AtomicReference<>(0); + for (int i1 = 0; i1 < 10; i1++) { + atomicInt.set(i1); + Integer i = i1; + //log.info("开始{}",i); + Thread thread = new Thread(() -> { + //log.info("线程开始:{}",Thread.currentThread().getName()); + ThreadUtil.sleep(100); + list.add(Thread.currentThread().getName()+":"+i+atomicInt.get()); + ss(i); + }); + thread.setName("SetName" + i1); + thread.start(); + //log.info("结束{}",i); + } + int j = 0; + while (j < 10) { + if (j != list.size()) { + j = list.size(); + } + ThreadUtil.sleep(1000); + } + //log.info("list={}", list); + } + + private void ss(int i) { + //log.info("id[{}]={}", Thread.currentThread().getName(), i); + } +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/web/TomcatUtilTest.java b/util/src/test/java/com/liuhuiyu/util/web/TomcatUtilTest.java new file mode 100644 index 0000000..2392cd6 --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/web/TomcatUtilTest.java @@ -0,0 +1,21 @@ +package com.liuhuiyu.util.web; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.Test; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-09-29 10:52 + */ +class TomcatUtilTest { + private static final Logger LOG = LogManager.getLogger(TomcatUtilTest.class); + + @Test + public void getTomcatPort() { + final Integer port = TomcatUtil.getTomcatPort().orElse(0); + LOG.info("端口:{}", port); + } + +} \ No newline at end of file diff --git a/util/src/test/java/com/liuhuiyu/util/web/WebUtilTest.java b/util/src/test/java/com/liuhuiyu/util/web/WebUtilTest.java new file mode 100644 index 0000000..8eb9abf --- /dev/null +++ b/util/src/test/java/com/liuhuiyu/util/web/WebUtilTest.java @@ -0,0 +1,20 @@ +package com.liuhuiyu.util.web; + + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-03-09 11:42 + */ +public class WebUtilTest { + public void testBtoA() { + String b = "abcd"; + String a = JsUtil.btoa(b); + //log.info("bToA a={};b={}", a, b); + } + public void testAtoB() { + String a = "YWJjZA=="; + String b = JsUtil.atob(a); + //log.info("aToB a={};b={}", a, b); + } +} \ No newline at end of file diff --git a/util/src/test/java/resources/log4j.properties b/util/src/test/java/resources/log4j.properties new file mode 100644 index 0000000..e603692 --- /dev/null +++ b/util/src/test/java/resources/log4j.properties @@ -0,0 +1,15 @@ +### direct log messages to stdout ### +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n + +### direct messages to file mylog.log ### +log4j.appender.file=org.apache.log4j.FileAppender +log4j.appender.file.File=d:/mylog.log +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n + +### set log levels - for more verbose logging change 'info' to 'debug' ### + +log4j.rootLogger=debug, stdout \ No newline at end of file diff --git a/util/util.iml b/util/util.iml new file mode 100644 index 0000000..75e316d --- /dev/null +++ b/util/util.iml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web-service-util/pom.xml b/web-service-util/pom.xml new file mode 100644 index 0000000..63657ea --- /dev/null +++ b/web-service-util/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + com.liuhuiyu + web-service-util + 2022.1.0 + Web Service Util + + + 8 + 8 + UTF-8 + 1.4 + 1.1 + 2022.1.0 + + + + org.apache.axis + axis + ${org.apache.axis.version} + + + jdom + jdom + ${jdom.version} + + + com.liuhuiyu + test2 + ${com.liuhuiyu.test2.version} + test + + + \ No newline at end of file diff --git a/web-service-util/src/main/java/com/liuhuiyu/web/service/WebServiceUtil.java b/web-service-util/src/main/java/com/liuhuiyu/web/service/WebServiceUtil.java new file mode 100644 index 0000000..f3a8dd4 --- /dev/null +++ b/web-service-util/src/main/java/com/liuhuiyu/web/service/WebServiceUtil.java @@ -0,0 +1,49 @@ +package com.liuhuiyu.web.service; + +import org.apache.axis.message.MessageElement; +import org.jdom.Document; +import org.jdom.Element; +import org.jdom.input.SAXBuilder; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-12-21 15:56 + */ +public class WebServiceUtil { + public static Stream> dataSetXmlToStream(MessageElement[] any) { + if (any == null || any.length <= 1 || any[1].getChildren() == null) { + return new ArrayList>(0).stream(); + } + SAXBuilder sb = new SAXBuilder(); + return any[1].getChildren().stream().flatMap(child -> { + String str = child.toString(); + InputStream in = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8)); + Document doc; + try { + doc = sb.build(in); + } + catch (Exception e) { + throw new RuntimeException(e); + } + Element root = doc.getRootElement(); // 得到根元素 + return root.getChildren().stream().map((elementRowObj) -> { + Element elementRow = (Element) elementRowObj; + Map tmp = new HashMap<>(); + elementRow.getChildren().forEach(elementObj -> { + Element element = (Element) elementObj; + tmp.put(element.getName(), element.getText()); + }); + return tmp; + }); + }); + } +} diff --git a/web-service-util/src/main/java/com/liuhuiyu/web/service/package-info.java b/web-service-util/src/main/java/com/liuhuiyu/web/service/package-info.java new file mode 100644 index 0000000..661ccf2 --- /dev/null +++ b/web-service-util/src/main/java/com/liuhuiyu/web/service/package-info.java @@ -0,0 +1,7 @@ +/** + * web service 工具 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2022-12-21 15:54 + */ +package com.liuhuiyu.web.service; \ No newline at end of file diff --git a/web-service-util/web-service-util.iml b/web-service-util/web-service-util.iml new file mode 100644 index 0000000..ee27122 --- /dev/null +++ b/web-service-util/web-service-util.iml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/web/pom.xml b/web/pom.xml new file mode 100644 index 0000000..83bbe92 --- /dev/null +++ b/web/pom.xml @@ -0,0 +1,73 @@ + + + + 4.0.0 + + com.liuhuiyu + web + 2022.1.0 + + web + http://com.liuhuiyu.com + + + UTF-8 + 1.8 + 1.8 + 2.1.6.RELEASE + + + + + junit + junit + 4.11 + test + + + org.springframework.boot + spring-boot-starter-aop + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter + + + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot.version} + + + org.springframework.boot + spring-boot-starter + + + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + + + compile + + + jar-no-fork + + + + + + + + diff --git a/web/src/main/java/com/liuhuiyu/web/IpUtil.java b/web/src/main/java/com/liuhuiyu/web/IpUtil.java new file mode 100644 index 0000000..f0af9c4 --- /dev/null +++ b/web/src/main/java/com/liuhuiyu/web/IpUtil.java @@ -0,0 +1,34 @@ +package com.liuhuiyu.web; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-02-23 21:05 + */ +public class IpUtil { + public static final String UNKNOWN="unknown"; + public static String getIpAddress(HttpServletRequest request) { + String ip = request.getHeader("x-forwarded-for"); + if (isNullIp(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (isNullIp(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (isNullIp(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (isNullIp(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (isNullIp(ip)) { + ip = request.getRemoteAddr(); + } + return ip; + } + public static boolean isNullIp(String ip){ + return ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip); + } +} \ No newline at end of file diff --git a/web/src/main/java/com/liuhuiyu/web/RequestParametersUtil.java b/web/src/main/java/com/liuhuiyu/web/RequestParametersUtil.java new file mode 100644 index 0000000..ab82128 --- /dev/null +++ b/web/src/main/java/com/liuhuiyu/web/RequestParametersUtil.java @@ -0,0 +1,78 @@ +package com.liuhuiyu.web; + +import javax.servlet.http.HttpServletRequest; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.HashMap; +import java.util.Map; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-07-20 13:53 + */ +public class RequestParametersUtil { + public static final String GET = "GET"; + public static final String POST = "POST"; + + /** + * 获取request中参数 + * + * @param request 页面请求 + */ + public static Map getRequestParameters(HttpServletRequest request) { + //请求参数 + String parameters = ""; + //GET请求时的参数 + if (GET.equals(request.getMethod())) { + //网址中的参数 + String urlParameter = request.getQueryString(); + if (urlParameter != null && !"".equals(urlParameter)) { + try { + urlParameter = URLDecoder.decode(urlParameter, "UTF-8"); + } + catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + else { + urlParameter = ""; + } + parameters = urlParameter; + } + //POST请求时的参数 + else if (POST.equals(request.getMethod())) { + //表单及网址中全部参数 + StringBuilder totalParameter = new StringBuilder(); + Map params = request.getParameterMap(); + //参数个数 + int parametersNum = request.getParameterMap().size(); + int flag = 1; + for (String key : params.keySet()) { + + String[] values = params.get(key); + for (String value : values) { + totalParameter.append(key).append("=").append(value); + } + if (flag < parametersNum) { + totalParameter.append("&"); + } + flag += 1; + } + parameters = totalParameter.toString(); + } + Map map = new HashMap<>(0); + String[] arr = parameters.split("&"); + for (String s : arr) { + int index = s.indexOf("="); + //=不能是首位或者是末尾 + if (index < 1 || index >= (s.length() - 1)) { + break; + } + String key = s.substring(0, index); + String value = s.substring(index + 1); + map.put(key, value); + } + return map; + } +} diff --git a/web/src/main/java/com/liuhuiyu/web/aspect/BaseAspect.java b/web/src/main/java/com/liuhuiyu/web/aspect/BaseAspect.java new file mode 100644 index 0000000..ca115be --- /dev/null +++ b/web/src/main/java/com/liuhuiyu/web/aspect/BaseAspect.java @@ -0,0 +1,51 @@ +package com.liuhuiyu.web.aspect; + +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.reflect.Method; + +/** + * 基础拦截器 + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2018-06-28 16:49 + */ +public abstract class BaseAspect { + + + protected Boolean isResponseBody (ProceedingJoinPoint pjp){ + MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); + Method method = methodSignature.getMethod(); + return method.getAnnotation(ResponseBody.class)!=null; + } + + /** + * 获取 HttpServletRequest + * @return HttpServletRequest + */ + protected HttpServletRequest getHttpServletRequest() { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (attributes == null) { + throw new RuntimeException("ServletRequestAttributes 空指针异常。"); + } + return attributes.getRequest(); + } + + /** + * 获取 HttpServletResponse + * @return HttpServletResponse + */ + protected HttpServletResponse getHttpServletResponse() { + ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); + if (attributes == null) { + throw new RuntimeException("ServletRequestAttributes 空指针异常。"); + } + return attributes.getResponse(); + } +} \ No newline at end of file diff --git a/web/src/main/java/com/liuhuiyu/web/controller/AbsBaseController.java b/web/src/main/java/com/liuhuiyu/web/controller/AbsBaseController.java new file mode 100644 index 0000000..d6e8556 --- /dev/null +++ b/web/src/main/java/com/liuhuiyu/web/controller/AbsBaseController.java @@ -0,0 +1,35 @@ +package com.liuhuiyu.web.controller; + +import javax.servlet.http.HttpServletRequest; + +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2020-12-29 8:48 + */ +public abstract class AbsBaseController { + /** + * 首页 + */ + protected static final String PATH_INDEX = "/index"; + /** + * 当前目录默认地址 + */ + protected static final String PATH_DEFAULT = "/"; + /** + * 页号属性 + */ + public static final String ATTRIBUTE_PAGE_INDEX = "page_index"; + /** + * 页面大小 + */ + public static final String ATTRIBUTE_PAGE_SIZE = "page_size"; + /** + * id + */ + public static final String ATTRIBUTE_ID = "id"; + /** + * 默认页面大小 + */ + protected static final int DEF_PAGE_SIZE = 20; +} diff --git a/web/src/main/java/com/liuhuiyu/web/package-info.java b/web/src/main/java/com/liuhuiyu/web/package-info.java new file mode 100644 index 0000000..ac428ae --- /dev/null +++ b/web/src/main/java/com/liuhuiyu/web/package-info.java @@ -0,0 +1,6 @@ +/** + * @author LiuHuiYu + * @version v1.0.0.0 + * Created DateTime 2021-01-12 11:13 + */ +package com.liuhuiyu.web; \ No newline at end of file diff --git a/web/web.iml b/web/web.iml new file mode 100644 index 0000000..d3a4bcb --- /dev/null +++ b/web/web.iml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file