build(devkit-utils): Renamed module dev-utils to devkit-utils
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>cn.org.codecrafters</groupId>
|
||||
<artifactId>jdevkit</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>devkit-utils</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.org.codecrafters</groupId>
|
||||
<artifactId>devkit-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2023 CodeCraftersCN.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package cn.org.codecrafters.devkit.utils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The {@code Base64Util} class provides static methods to encode and decode
|
||||
* strings using Base64 encoding. It utilizes the {@link Base64} class from the
|
||||
* Java standard library for performing the encoding and decoding operations.
|
||||
* This utility class offers convenient methods to encode and decode strings
|
||||
* with different character sets.
|
||||
*
|
||||
* <p>
|
||||
* This class is designed as a final class with a private constructor to
|
||||
* prevent instantiation. All methods in this class are static, allowing easy
|
||||
* access to the Base64 encoding and decoding functionality.
|
||||
*
|
||||
* <p>
|
||||
* Example usage:
|
||||
* <pre>
|
||||
* String original = "Hello, World!";
|
||||
*
|
||||
* // Encode the string using UTF-8 charset
|
||||
* String encoded = Base64Util.encode(original);
|
||||
* System.out.println("Encoded string: " + encoded);
|
||||
*
|
||||
* // Decode the encoded string using UTF-8 charset
|
||||
* String decoded = Base64Util.decode(encoded);
|
||||
* System.out.println("Decoded string: " + decoded);
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> This utility class uses the default charset (UTF-8) if no
|
||||
* specific charset is provided. It is recommended to specify the charset
|
||||
* explicitly to ensure consistent encoding and decoding.
|
||||
*
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @version 1.0.0
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public final class Base64Util {
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation of the class.
|
||||
*/
|
||||
private Base64Util() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the given string using the specified charset.
|
||||
*
|
||||
* @param value the string to be encoded
|
||||
* @param charset the charset to be used for encoding
|
||||
* @return the Base64 encoded string
|
||||
*/
|
||||
public static String encode(String value, Charset charset) {
|
||||
var encoder = Base64.getEncoder();
|
||||
var encoded = encoder.encode(value.getBytes(charset));
|
||||
|
||||
return new String(encoded);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the given string using the default UTF-8 charset.
|
||||
*
|
||||
* @param value the string to be encoded
|
||||
* @return the Base64 encoded string
|
||||
*/
|
||||
public static String encode(String value) {
|
||||
return encode(value, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the given Base64 encoded string using the specified charset.
|
||||
*
|
||||
* @param value the Base64 encoded string to be decoded
|
||||
* @param charset the charset to be used for decoding
|
||||
* @return the decoded string
|
||||
*/
|
||||
public static String decode(String value, Charset charset) {
|
||||
var decoder = Base64.getDecoder();
|
||||
var decoded = decoder.decode(value.getBytes(charset));
|
||||
|
||||
return new String(decoded);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the given Base64 encoded string using the default UTF-8 charset.
|
||||
*
|
||||
* @param value the Base64 encoded string to be decoded
|
||||
* @return the decoded string
|
||||
*/
|
||||
public static String decode(String value) {
|
||||
return decode(value, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (C) 2023 CodeCraftersCN.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package cn.org.codecrafters.devkit.utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The BranchUtil class provides static methods to simplify conditional logic
|
||||
* in Java development by leveraging lambda expressions. It offers convenient
|
||||
* methods to replace verbose if...else statements with more concise and
|
||||
* expressive functional constructs.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* Developers can use the methods in this utility class to streamline their
|
||||
* code, enhance readability, and promote a more functional style of
|
||||
* programming when dealing with branching logic and conditional statements.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* <b>Example:</b>
|
||||
* <pre>
|
||||
* // If you want to simplify an if (exp1 || exp2), you can use the
|
||||
* // following code:
|
||||
* var r1 = BranchUtil.or(1 == 1, 2 == 1)
|
||||
* .handle(() -> "1 is equal to 1 or 2 is equal to 1.");
|
||||
*
|
||||
* // If you have an else branch, you can use the following code:
|
||||
* var r2 = BranchUtil.or(1 == 1, 2 == 1)
|
||||
* .handle(() -> "1 is equal to 1 or 2 is equal to 1.",
|
||||
* () -> "1 is not equal to 1 and 2 is not equal to 1.");
|
||||
*
|
||||
* // If you only need to execute code without a return value:
|
||||
* BranchUtil.or(1 == 1, 2 == 1)
|
||||
* .handle(() -> {
|
||||
* // do something
|
||||
* }, () -> {
|
||||
* // do something
|
||||
* });
|
||||
* // If you only need an if branch, you can remove the second Supplier
|
||||
* // instance.
|
||||
*
|
||||
* // To check if all boolean expressions are true, use the 'and' method:
|
||||
* BranchUtil.and(1 == 1, 2 == 1)
|
||||
* .handle(() -> {
|
||||
* // do something
|
||||
* }, () -> {
|
||||
* // do something
|
||||
* });
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b>
|
||||
* The {@link #and(Boolean...)} and {@link #or(Boolean...)} methods accept any
|
||||
* number of boolean expressions.
|
||||
*
|
||||
* @param <T> the type of the result to be handled by the methods
|
||||
* @author Zihlu Wang
|
||||
* @version 1.0.0
|
||||
* @see java.util.function.Supplier
|
||||
* @see java.util.function.BooleanSupplier
|
||||
* @see java.lang.Runnable
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public final class BranchUtil<T> {
|
||||
|
||||
/**
|
||||
* The final result of the boolean expression.
|
||||
*/
|
||||
private final boolean result;
|
||||
|
||||
/**
|
||||
* Create a {@code BranchUtil} instance.
|
||||
*
|
||||
* @param result the result of the boolean expressions.
|
||||
*/
|
||||
private BranchUtil(boolean result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code BranchUtil} instance to evaluate a logical OR operation
|
||||
* on the provided boolean expressions.
|
||||
*
|
||||
* @param booleans the boolean expressions to be evaluated
|
||||
* @param <T> the type of the result to be handled by the methods
|
||||
* @return a {@code BranchUtil} instance representing the result of the
|
||||
* logical OR operation
|
||||
*/
|
||||
public static <T> BranchUtil<T> or(Boolean... booleans) {
|
||||
var result = Arrays.stream(booleans)
|
||||
.filter(Objects::nonNull)
|
||||
.anyMatch(Boolean::booleanValue);
|
||||
return new BranchUtil<>(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code BranchUtil} instance to evaluate a logical AND
|
||||
* operation on the provided boolean expressions.
|
||||
*
|
||||
* @param booleans the boolean expressions to be evaluated
|
||||
* @param <T> the type of the result to be handled by the methods
|
||||
* @return a {@code BranchUtil} instance representing the result of the
|
||||
* logical AND operation
|
||||
*/
|
||||
public static <T> BranchUtil<T> and(Boolean... booleans) {
|
||||
var result = Arrays.stream(booleans)
|
||||
.filter(Objects::nonNull)
|
||||
.allMatch(Boolean::booleanValue);
|
||||
return new BranchUtil<>(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code BranchUtil} instance to evaluate a logical OR operation
|
||||
* on the provided boolean suppliers.
|
||||
*
|
||||
* @param booleanSuppliers the boolean suppliers to be evaluated
|
||||
* @param <T> the type of the result to be handled by the
|
||||
* methods
|
||||
* @return a {@code BranchUtil} instance representing the result of the
|
||||
* logical OR operation
|
||||
*/
|
||||
public static <T> BranchUtil<T> or(BooleanSupplier... booleanSuppliers) {
|
||||
var result = Arrays.stream(booleanSuppliers)
|
||||
.filter(Objects::nonNull)
|
||||
.anyMatch(BooleanSupplier::getAsBoolean);
|
||||
return new BranchUtil<>(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code BranchUtil} instance to evaluate a logical AND
|
||||
* operation on the provided boolean suppliers.
|
||||
*
|
||||
* @param booleanSuppliers the boolean suppliers to be evaluated
|
||||
* @param <T> the type of the result to be handled by the
|
||||
* methods
|
||||
* @return a {@code BranchUtil} instance representing the result of the
|
||||
* logical AND operation
|
||||
*/
|
||||
public static <T> BranchUtil<T> and(BooleanSupplier... booleanSuppliers) {
|
||||
var result = Arrays.stream(booleanSuppliers)
|
||||
.filter(Objects::nonNull)
|
||||
.allMatch(BooleanSupplier::getAsBoolean);
|
||||
return new BranchUtil<>(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Handles the result of the boolean expressions by executing the
|
||||
* appropriate handler based on the result.
|
||||
*
|
||||
* <p>
|
||||
* If the result is {@code true}, the {@code ifHandler} is executed. If the
|
||||
* result is {@code false} and an {@code elseHandler} is provided, it is
|
||||
* executed.
|
||||
*
|
||||
* <p>
|
||||
* Returns the result of the executed handler.
|
||||
*
|
||||
* @param ifHandler the handler to be executed if the result is
|
||||
* {@code true}
|
||||
* @param elseHandler the handler to be executed if the result is
|
||||
* {@code false} (optional)
|
||||
* @return the result of the executed handler, or {@code null} if no
|
||||
* {@code elseHandler} is provided
|
||||
*/
|
||||
public T handle(Supplier<T> ifHandler, Supplier<T> elseHandler) {
|
||||
if (this.result && Objects.nonNull(ifHandler)) {
|
||||
return ifHandler.get();
|
||||
}
|
||||
|
||||
if (Objects.isNull(elseHandler)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return elseHandler.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Handles the result of the boolean expressions by executing the provided
|
||||
* handler if the result is {@code true}.
|
||||
*
|
||||
* <p>
|
||||
* Returns the result of the executed handler.
|
||||
*
|
||||
* @param ifHandler the handler to be executed if the result is
|
||||
* {@code true}
|
||||
* @return the result of the executed handler
|
||||
*/
|
||||
public T handle(Supplier<T> ifHandler) {
|
||||
return handle(ifHandler, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Handles the result of the boolean expressions by executing the
|
||||
* appropriate handler based on the result.
|
||||
*
|
||||
* <p>
|
||||
* If the result is {@code true}, the {@code ifHandler} is executed. If the
|
||||
* result is {@code false} and an {@code elseHandler} is provided, it is
|
||||
* executed.
|
||||
*
|
||||
* @param ifHandler the handler to be executed if the result is
|
||||
* {@code true}
|
||||
* @param elseHandler the handler to be executed if the result is
|
||||
* {@code false} (optional)
|
||||
*/
|
||||
public void handle(Runnable ifHandler, Runnable elseHandler) {
|
||||
if (this.result && Objects.nonNull(ifHandler)) {
|
||||
ifHandler.run();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Objects.isNull(elseHandler)) {
|
||||
return;
|
||||
}
|
||||
|
||||
elseHandler.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the result of the boolean expressions by executing the provided
|
||||
* handler if the result is {@code true}.
|
||||
*
|
||||
* @param ifHandler the handler to be executed if the result is
|
||||
* {@code true}
|
||||
*/
|
||||
public void handle(Runnable ifHandler) {
|
||||
handle(ifHandler, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* Copyright (C) 2023 CodeCraftersCN.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package cn.org.codecrafters.devkit.utils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Utility class for chained high-precision calculations using BigDecimal.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* The ChainedCalcUtil class provides a convenient way to perform chained
|
||||
* high-precision calculations using BigDecimal. It allows users to perform
|
||||
* mathematical operations such as addition, subtraction, multiplication,
|
||||
* and division with customizable precision and scale. By using this utility
|
||||
* class, developers can achieve accurate results and avoid precision loss
|
||||
* in their calculations.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* <b>Usage:</b>
|
||||
* <pre>
|
||||
* // Perform addition: 3 + 4
|
||||
* BigDecimal result1 = ChainedCalcUtil.startWith(3)
|
||||
* .add(4)
|
||||
* .getValue();
|
||||
*
|
||||
* // Perform subtraction: 4 - 2
|
||||
* BigDecimal result2 = ChainedCalcUtil.startWith(4)
|
||||
* .subtract(2)
|
||||
* .getValue();
|
||||
*
|
||||
* // Perform multiplication: 3 * 6
|
||||
* BigDecimal result3 = ChainedCalcUtil.startWith(3)
|
||||
* .multiply(6)
|
||||
* .getValue();
|
||||
*
|
||||
* // Perform division: 6 ÷ 2
|
||||
* BigDecimal result4 = ChainedCalcUtil.startWith(6)
|
||||
* .divide(2)
|
||||
* .getValue();
|
||||
*
|
||||
* // Perform division with specified scale: 13 ÷ 7 with a scale of 2
|
||||
* BigDecimal result5 = ChainedCalcUtil.startWith(13)
|
||||
* .divideWithScale(7, 2)
|
||||
* .getValue();
|
||||
*
|
||||
* // Get int, long, or double results
|
||||
* int intResult = ChainedCalcUtil.startWith(3)
|
||||
* .add(4)
|
||||
* .getInteger();
|
||||
*
|
||||
* long longResult = ChainedCalcUtil.startWith(4)
|
||||
* .subtract(2)
|
||||
* .getLong();
|
||||
*
|
||||
* double doubleResult = ChainedCalcUtil.startWith(6)
|
||||
* .divide(2)
|
||||
* .getDouble();
|
||||
*
|
||||
* // Get BigDecimal result with specified scale
|
||||
* BigDecimal result6 = ChainedCalcUtil.startWith(13)
|
||||
* .divide(7)
|
||||
* .getValue(2);
|
||||
* </pre>
|
||||
* The above expressions perform various mathematical calculations using the
|
||||
* ChainedCalcUtil class.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b>
|
||||
* The ChainedCalcUtil class internally uses BigDecimal to handle
|
||||
* high-precision calculations. It is important to note that BigDecimal
|
||||
* operations can be memory-intensive and may have performance implications
|
||||
* for extremely large numbers or complex calculations.
|
||||
*
|
||||
* @author sunzsh
|
||||
* @version 1.0.0
|
||||
* @see java.math.BigDecimal
|
||||
* @since 9 Jul 2023
|
||||
*/
|
||||
public final class ChainedCalcUtil {
|
||||
|
||||
private BigDecimal value;
|
||||
|
||||
/**
|
||||
* Creates a ChainedCalcUtil instance with the specified initial value.
|
||||
*
|
||||
* @param value the initial value for the calculation
|
||||
*/
|
||||
private ChainedCalcUtil(Number value) {
|
||||
this.value = convertBigDecimal(value, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a chained calculation with the specified initial value.
|
||||
*
|
||||
* @param value the initial value for the calculation
|
||||
* @return a ChainedCalcUtil instance for performing chained calculations
|
||||
*/
|
||||
public static ChainedCalcUtil startWith(Number value) {
|
||||
return new ChainedCalcUtil(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified value to the current value.
|
||||
*
|
||||
* @param other the value to be added
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
public ChainedCalcUtil add(Number other) {
|
||||
return operator(BigDecimal::add, other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified value to the current value with a specified scale
|
||||
* before the operation.
|
||||
*
|
||||
* @param other the value to be added
|
||||
* @param beforeOperateScale the scale to be applied before the operation
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
public ChainedCalcUtil add(Number other, Integer beforeOperateScale) {
|
||||
return operator(BigDecimal::add, other, beforeOperateScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the specified value from the current value.
|
||||
*
|
||||
* @param other the value to be subtracted
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
public ChainedCalcUtil subtract(Number other) {
|
||||
return operator(BigDecimal::subtract, other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the specified value from the current value with a specified
|
||||
* scale before the operation.
|
||||
*
|
||||
* @param other the value to be subtracted
|
||||
* @param beforeOperateScale the scale to be applied before the operation
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
public ChainedCalcUtil subtract(Number other, Integer beforeOperateScale) {
|
||||
return operator(BigDecimal::subtract, other, beforeOperateScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies the current value by the specified value.
|
||||
*
|
||||
* @param other the value to be multiplied by
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
public ChainedCalcUtil multiply(Number other) {
|
||||
return operator(BigDecimal::multiply, other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies the current value by the specified value with a specified
|
||||
* scale before the operation.
|
||||
*
|
||||
* @param other the value to be multiplied by
|
||||
* @param beforeOperateScale the scale to be applied before the operation
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
public ChainedCalcUtil multiply(Number other, Integer beforeOperateScale) {
|
||||
return operator(BigDecimal::multiply, other, beforeOperateScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the current value by the specified value.
|
||||
*
|
||||
* @param other the value to divide by
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
public ChainedCalcUtil divide(Number other) {
|
||||
return operator(BigDecimal::divide, other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the current value by the specified value with a specified scale
|
||||
* before the operation.
|
||||
*
|
||||
* @param other the value to divide by
|
||||
* @param beforeOperateScale the scale to be applied before the operation
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
public ChainedCalcUtil divide(Number other, Integer beforeOperateScale) {
|
||||
return operator(BigDecimal::divide, other, beforeOperateScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the current value by the specified value with a specified scale.
|
||||
*
|
||||
* @param other the value to divide by
|
||||
* @param scale the scale for the result
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
public ChainedCalcUtil divideWithScale(Number other, Integer scale) {
|
||||
return baseOperator(otherValue ->
|
||||
this.value.divide(otherValue, scale, RoundingMode.HALF_UP), other, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the current value by the specified value with a specified scale
|
||||
* and a scale applied before the operation.
|
||||
*
|
||||
* @param other the value to divide by
|
||||
* @param scale the scale for the result
|
||||
* @param beforeOperateScale the scale to be applied before the operation
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
public ChainedCalcUtil divideWithScale(Number other, Integer scale, Integer beforeOperateScale) {
|
||||
return baseOperator(otherValue -> this.value.divide(otherValue, scale, RoundingMode.HALF_UP), other, beforeOperateScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value as a BigDecimal.
|
||||
*
|
||||
* @return the current value as a BigDecimal
|
||||
*/
|
||||
public BigDecimal getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value as a BigDecimal with the specified scale.
|
||||
*
|
||||
* @param scale the scale for the result
|
||||
* @return the current value as a BigDecimal with the specified scale
|
||||
*/
|
||||
public BigDecimal getValue(int scale) {
|
||||
return value.setScale(scale, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value as a Double.
|
||||
*
|
||||
* @return the current value as a Double
|
||||
*/
|
||||
public Double getDouble() {
|
||||
return getValue().doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value as a Double with the specified scale.
|
||||
*
|
||||
* @param scale the scale for the result
|
||||
* @return the current value as a Double with the specified scale
|
||||
*/
|
||||
public Double getDouble(int scale) {
|
||||
return getValue(scale).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value as a Long.
|
||||
*
|
||||
* @return the current value as a Long
|
||||
*/
|
||||
public Long getLong() {
|
||||
return getValue().longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current value as an Integer.
|
||||
*
|
||||
* @return the current value as an Integer
|
||||
*/
|
||||
public Integer getInteger() {
|
||||
return getValue().intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified operator function to the current value and another
|
||||
* value.
|
||||
*
|
||||
* @param operator the operator function to apply
|
||||
* @param otherValue the value to apply the operator with
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
private ChainedCalcUtil operator(BiFunction<BigDecimal, BigDecimal, BigDecimal> operator, Object otherValue) {
|
||||
return operator(operator, otherValue, 9);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified operator function to the current value and another
|
||||
* value with a specified scale before the operation.
|
||||
*
|
||||
* @param operator the operator function to apply
|
||||
* @param other the value to apply the operator with
|
||||
* @param beforeOperateScale the scale to be applied before the operation,
|
||||
* or null if not applicable
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
private ChainedCalcUtil operator(BiFunction<BigDecimal, BigDecimal, BigDecimal> operator, Object other, Integer beforeOperateScale) {
|
||||
return baseOperator((otherValue) -> operator.apply(this.value, otherValue), other, beforeOperateScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the specified operator function to the current value and another
|
||||
* value.
|
||||
*
|
||||
* @param operatorFunction the operator function to apply
|
||||
* @param anotherValue the value to apply the operator with
|
||||
* @param beforeOperateScale the scale to be applied before the operation,
|
||||
* or null if not applicable
|
||||
* @return a ChainedCalcUtil instance with the updated value
|
||||
*/
|
||||
private synchronized ChainedCalcUtil baseOperator(Function<BigDecimal, BigDecimal> operatorFunction,
|
||||
Object anotherValue, Integer beforeOperateScale) {
|
||||
if (Objects.isNull(anotherValue)) {
|
||||
return this;
|
||||
}
|
||||
if (anotherValue instanceof ChainedCalcUtil) {
|
||||
this.value = operatorFunction.apply(((ChainedCalcUtil) anotherValue).getValue());
|
||||
return this;
|
||||
}
|
||||
this.value = operatorFunction.apply(convertBigDecimal(anotherValue, beforeOperateScale));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified value to a BigDecimal.
|
||||
*
|
||||
* @param value the value to convert
|
||||
* @param scale the scale to apply to the resulting BigDecimal, or null if
|
||||
* not applicable
|
||||
* @return the converted BigDecimal value
|
||||
*/
|
||||
private BigDecimal convertBigDecimal(Object value, Integer scale) {
|
||||
if (Objects.isNull(value)) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
BigDecimal res;
|
||||
if (value instanceof Number num) {
|
||||
res = BigDecimal.valueOf(num.doubleValue());
|
||||
} else {
|
||||
try {
|
||||
res = new BigDecimal(value.toString());
|
||||
} catch (NumberFormatException ignored) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
if (Objects.nonNull(scale)) {
|
||||
return res.setScale(scale, RoundingMode.HALF_UP);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (C) 2023 CodeCraftersCN.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package cn.org.codecrafters.devkit.utils;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Utility class for performing hash operations on strings.
|
||||
*
|
||||
* <p>
|
||||
* The HashUtil class provides convenient methods for calculating various hash
|
||||
* functions on strings, including MD2, MD5, SHA-1, SHA-224, SHA-256, SHA-384,
|
||||
* and SHA-512. It allows developers to easily obtain the hash value of a given
|
||||
* string using different algorithms.
|
||||
*
|
||||
* <p>
|
||||
* Example usage:
|
||||
* <pre>
|
||||
* // Perform MD2 hash operation
|
||||
* String md2Hash = HashUtil.md2("someString");
|
||||
*
|
||||
* // Perform MD5 hash operation
|
||||
* String md5Hash = HashUtil.md5("someString");
|
||||
*
|
||||
* // Perform SHA-1 hash operation
|
||||
* String sha1Hash = HashUtil.sha1("someString");
|
||||
*
|
||||
* // Perform SHA-224 hash operation
|
||||
* String sha224Hash = HashUtil.sha224("someString");
|
||||
*
|
||||
* // Perform SHA-256 hash operation
|
||||
* String sha256Hash = HashUtil.sha256("someString");
|
||||
*
|
||||
* // Perform SHA-384 hash operation
|
||||
* String sha384Hash = HashUtil.sha384("someString");
|
||||
*
|
||||
* // Perform SHA-512 hash operation
|
||||
* String sha512Hash = HashUtil.sha512("someString");
|
||||
* </pre>
|
||||
* The above examples demonstrate how to use the HashUtil class to calculate
|
||||
* hash values for a given string using different algorithms.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b>
|
||||
* The hash functions provided by the HashUtil class are one-way hash
|
||||
* functions, meaning the original data cannot be retrieved from the hash
|
||||
* value. These hash functions are commonly used for data integrity checks and
|
||||
* password storage, but they should not be used for encryption purposes.
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @version 1.0.0
|
||||
* @see java.security.MessageDigest
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public final class HashUtil {
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation
|
||||
*/
|
||||
private HashUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the hash value of the specified string using the specified
|
||||
* algorithm and charset.
|
||||
*
|
||||
* @param method the hash algorithm to use
|
||||
* @param value the string to calculate the hash value for
|
||||
* @param charset the charset to use for encoding the string (default is
|
||||
* UTF-8 if null)
|
||||
* @return the hash value as a hexadecimal string, or an empty string if
|
||||
* the algorithm is not available
|
||||
* @throws RuntimeException if an unknown algorithm name is provided
|
||||
* (should not occur under controlled usage)
|
||||
*/
|
||||
private static String hash(String method, String value, Charset charset) {
|
||||
try {
|
||||
var messageDigest = MessageDigest.getInstance(method);
|
||||
messageDigest.update(value.getBytes(charset));
|
||||
var bytes = messageDigest.digest();
|
||||
var builder = new StringBuilder();
|
||||
|
||||
for (var b : bytes) {
|
||||
var str = Integer.toHexString(b & 0xff);
|
||||
if (str.length() == 1) {
|
||||
builder.append(0);
|
||||
}
|
||||
builder.append(str);
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
} catch (NoSuchAlgorithmException ignored) {
|
||||
// This should not occur under controlled usage
|
||||
// Only trusted algorithms are allowed
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the MD2 hash value of the specified string using the given
|
||||
* charset.
|
||||
*
|
||||
* @param value the string to calculate the MD2 hash value for
|
||||
* @param charset the charset to use for encoding the string (default is
|
||||
* UTF-8 if null)
|
||||
* @return the MD2 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String md2(String value, Charset charset) {
|
||||
charset = Optional.ofNullable(charset).orElse(StandardCharsets.UTF_8);
|
||||
return hash("MD2", value, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the MD2 hash value of the specified string using the UTF-8
|
||||
* charset.
|
||||
*
|
||||
* @param value the string to calculate the MD2 hash value for
|
||||
* @return the MD2 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String md2(String value) {
|
||||
return hash("MD2", value, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the MD5 hash value of the specified string using the given
|
||||
* charset.
|
||||
*
|
||||
* @param value the string to calculate the MD5 hash value for
|
||||
* @param charset the charset to use for encoding the string (default is
|
||||
* UTF-8 if null)
|
||||
* @return the MD5 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String md5(String value, Charset charset) {
|
||||
charset = Optional.ofNullable(charset).orElse(StandardCharsets.UTF_8);
|
||||
return hash("MD5", value, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the MD5 hash value of the specified string using the UTF-8
|
||||
* charset.
|
||||
*
|
||||
* @param value the string to calculate the MD5 hash value for
|
||||
* @return the MD5 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String md5(String value) {
|
||||
return hash("MD5", value, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the SHA-1 hash value of the specified string using the given
|
||||
* charset.
|
||||
*
|
||||
* @param value the string to calculate the SHA-1 hash value for
|
||||
* @param charset the charset to use for encoding the string (default is
|
||||
* UTF-8 if null)
|
||||
* @return the SHA-1 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String sha1(String value, Charset charset) {
|
||||
charset = Optional.ofNullable(charset).orElse(StandardCharsets.UTF_8);
|
||||
return hash("SHA-1", value, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the SHA-1 hash value of the specified string using the UTF-8
|
||||
* charset.
|
||||
*
|
||||
* @param value the string to calculate the SHA-1 hash value for
|
||||
* @return the SHA-1 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String sha1(String value) {
|
||||
return hash("SHA-1", value, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the SHA-224 hash value of the specified string using the
|
||||
* given charset.
|
||||
*
|
||||
* @param value the string to calculate the SHA-224 hash value for
|
||||
* @param charset the charset to use for encoding the string (default is
|
||||
* UTF-8 if null)
|
||||
* @return the SHA-224 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String sha224(String value, Charset charset) {
|
||||
charset = Optional.ofNullable(charset).orElse(StandardCharsets.UTF_8);
|
||||
return hash("SHA-224", value, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the SHA-224 hash value of the specified string using the
|
||||
* UTF-8 charset.
|
||||
*
|
||||
* @param value the string to calculate the SHA-224 hash value for
|
||||
* @return the SHA-224 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String sha224(String value) {
|
||||
return hash("SHA-224", value, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the SHA-256 hash value of the specified string using the
|
||||
* given charset.
|
||||
*
|
||||
* @param value the string to calculate the SHA-256 hash value for
|
||||
* @param charset the charset to use for encoding the string (default is
|
||||
* UTF-8 if null)
|
||||
* @return the SHA-256 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String sha256(String value, Charset charset) {
|
||||
charset = Optional.ofNullable(charset).orElse(StandardCharsets.UTF_8);
|
||||
return hash("SHA-256", value, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the SHA-256 hash value of the specified string using the
|
||||
* UTF-8 charset.
|
||||
*
|
||||
* @param value the string to calculate the SHA-256 hash value for
|
||||
* @return the SHA-256 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String sha256(String value) {
|
||||
return hash("SHA-256", value, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the SHA-384 hash value of the specified string using the
|
||||
* given charset.
|
||||
*
|
||||
* @param value the string to calculate the SHA-384 hash value for
|
||||
* @param charset the charset to use for encoding the string (default is
|
||||
* UTF-8 if null)
|
||||
* @return the SHA-384 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String sha384(String value, Charset charset) {
|
||||
charset = Optional.ofNullable(charset).orElse(StandardCharsets.UTF_8);
|
||||
return hash("SHA-384", value, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the SHA-384 hash value of the specified string using the
|
||||
* UTF-8 charset.
|
||||
*
|
||||
* @param value the string to calculate the SHA-384 hash value for
|
||||
* @return the SHA-384 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String sha384(String value) {
|
||||
return hash("SHA-384", value, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the SHA-512 hash value of the specified string using the
|
||||
* given charset.
|
||||
*
|
||||
* @param value the string to calculate the SHA-384 hash value for
|
||||
* @param charset the charset to use for encoding the string (default is
|
||||
* UTF-8 if null)
|
||||
* @return the SHA-512 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String sha512(String value, Charset charset) {
|
||||
charset = Optional.ofNullable(charset).orElse(StandardCharsets.UTF_8);
|
||||
return hash("SHA-512", value, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the SHA-512 hash value of the specified string using the
|
||||
* UTF-8 charset.
|
||||
*
|
||||
* @param value the string to calculate the SHA-384 hash value for
|
||||
* @return the SHA-512 hash value as a hexadecimal string
|
||||
*/
|
||||
public static String sha512(String value) {
|
||||
return hash("SHA-512", value, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2023 CodeCraftersCN.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package cn.org.codecrafters.devkit.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* MapUtil is a utility class that provides methods for converting objects to
|
||||
* maps and maps to objects.
|
||||
*
|
||||
* <p>
|
||||
* It also provides methods for getting and setting field values using
|
||||
* reflection.
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @version 1.0.0
|
||||
* @since 16 Jul 2023
|
||||
*/
|
||||
@Slf4j
|
||||
public final class MapUtil {
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation of MapUtil.
|
||||
*/
|
||||
private MapUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an object to a map by mapping the field names to their
|
||||
* corresponding values.
|
||||
*
|
||||
* @param obj the object to be converted to a map
|
||||
* @return a map representing the fields and their values of the object
|
||||
* @throws IllegalAccessException if an error occurs while accessing the
|
||||
* fields of the object
|
||||
*/
|
||||
public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var map = new HashMap<String, Object>();
|
||||
|
||||
var declaredFields = obj.getClass().getDeclaredFields();
|
||||
for (var field : declaredFields) {
|
||||
field.setAccessible(true);
|
||||
Object result = field.get(obj);
|
||||
if (result != null) {
|
||||
map.put(field.getName(), result);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a map to an object of the specified type by setting the field
|
||||
* values using the map entries.
|
||||
*
|
||||
* @param map the map representing the fields and their values
|
||||
* @param requiredType the class of the object to be created
|
||||
* @param <T> the type of the object to be created
|
||||
* @return an object of the specified type with the field values set from
|
||||
* the map
|
||||
* @throws NoSuchMethodException if the constructor of the required
|
||||
* type is not found
|
||||
* @throws InvocationTargetException if an error occurs while invoking the
|
||||
* constructor
|
||||
* @throws InstantiationException if the required type is abstract or an
|
||||
* interface
|
||||
* @throws IllegalAccessException if an error occurs while accessing the
|
||||
* fields of the object
|
||||
*/
|
||||
public static <T> T mapToObject(Map<String, Object> map, Class<T> requiredType) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
|
||||
var bean = requiredType.getConstructor().newInstance();
|
||||
if (map != null) {
|
||||
for (var entry : map.entrySet()) {
|
||||
try {
|
||||
var entryValue = entry.getValue().toString();
|
||||
// get the field by field name
|
||||
var field = requiredType.getDeclaredField(entry.getKey());
|
||||
var fieldType = field.getGenericType();
|
||||
|
||||
// convert field value by class
|
||||
if (fieldType instanceof Class<?> fieldClass) {
|
||||
if (fieldClass == Short.class || fieldClass == short.class) {
|
||||
entry.setValue(Short.parseShort(entryValue));
|
||||
} else if (fieldClass == Integer.class || fieldClass == int.class) {
|
||||
entry.setValue(Integer.parseInt(entryValue));
|
||||
} else if (fieldClass == Long.class || fieldClass == long.class) {
|
||||
entry.setValue(Long.parseLong(entryValue));
|
||||
} else if (fieldClass == Float.class || fieldClass == float.class) {
|
||||
entry.setValue(Float.parseFloat(entryValue));
|
||||
} else if (fieldClass == Double.class || fieldClass == double.class) {
|
||||
entry.setValue(Double.parseDouble(entryValue));
|
||||
} else if (fieldClass == Character.class || fieldClass == char.class) {
|
||||
entry.setValue(entryValue.charAt(0));
|
||||
} else if (fieldClass == Byte.class || fieldClass == byte.class) {
|
||||
entry.setValue(Byte.parseByte(entryValue));
|
||||
} else if (fieldClass == Boolean.class || fieldClass == boolean.class) {
|
||||
entry.setValue(Boolean.parseBoolean(entryValue));
|
||||
} else if (fieldClass == String.class) {
|
||||
entry.setValue(entryValue);
|
||||
} else {
|
||||
log.error("Unable to determine the type of property {}.", field.getName());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
setFieldValue(bean, entry.getKey(), entry.getValue());
|
||||
} catch (Exception e) {
|
||||
log.error("Map to Object failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value of a field from an object using reflection.
|
||||
*
|
||||
* @param obj the object from which to retrieve the field value
|
||||
* @param fieldName the name of the field
|
||||
* @param fieldType the class representing the type of the field value
|
||||
* @param <T> the type of the field value
|
||||
* @return the value of the field in the object, or null if the field does
|
||||
* not exist or cannot be accessed
|
||||
* @throws IllegalAccessException if an error occurs while accessing the
|
||||
* field
|
||||
* @throws InvocationTargetException if an error occurs while invoking the
|
||||
* field getter method
|
||||
* @throws NoSuchMethodException if the specified getter is not present
|
||||
*/
|
||||
public static <T> T getFieldValue(Object obj, String fieldName, Class<T> fieldType) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
||||
var methodName = getMethodName("get", fieldName);
|
||||
var objectClass = obj.getClass();
|
||||
var method = objectClass.getDeclaredMethod(methodName);
|
||||
|
||||
method.setAccessible(true);
|
||||
return cast(method.invoke(obj), fieldType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a field in an object using reflection.
|
||||
*
|
||||
* @param obj the object in which to set the field value
|
||||
* @param fieldName the name of the field
|
||||
* @param fieldValue the value to be set
|
||||
* @throws InvocationTargetException if an error occurs while invoking the
|
||||
* field setter method
|
||||
* @throws IllegalAccessException if an error occurs while accessing the
|
||||
* field
|
||||
* @throws NoSuchMethodException if the specific setter is not present
|
||||
*/
|
||||
public static void setFieldValue(Object obj, String fieldName, Object fieldValue) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
|
||||
var objectClass = obj.getClass();
|
||||
var methodName = getMethodName("set", fieldName);
|
||||
var method = objectClass.getDeclaredMethod(methodName, fieldValue.getClass());
|
||||
method.setAccessible(true);
|
||||
method.invoke(obj, fieldValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a method name based on the given prefix and field name.
|
||||
*
|
||||
* @param prefix the prefix to be added to the field name
|
||||
* @param fieldName the name of the field
|
||||
* @return the constructed method name
|
||||
*/
|
||||
private static String getMethodName(String prefix, String fieldName) {
|
||||
return prefix + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default string representation of the specified object.
|
||||
*
|
||||
* @param obj the object for which to return the default string
|
||||
* representation
|
||||
* @return the default string representation of the object
|
||||
*/
|
||||
private static String defaultObject(Object obj) {
|
||||
if (obj == null) {
|
||||
return "";
|
||||
} else {
|
||||
return String.valueOf(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts the specified value to the required type.
|
||||
*
|
||||
* @param value the value to be casted
|
||||
* @param requiredType the type to which the value should be casted
|
||||
* @param <T> the type to which the value should be casted
|
||||
* @return the casted value, or null if the value cannot be casted to the
|
||||
* required type
|
||||
*/
|
||||
public static <T> T cast(Object value, Class<T> requiredType) {
|
||||
if (requiredType.isInstance(value)) {
|
||||
return requiredType.cast(value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2023 CodeCraftersCN.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This package is part of JDevKit, an open-source Java Development Kit that
|
||||
* provides a set of convenient tools to streamline code development and
|
||||
* enhance productivity. This package serves as the root package for the module
|
||||
* dev-utils, which contains a collection of common utility classes commonly
|
||||
* used in all Java Application development.
|
||||
*
|
||||
* @author Zihlu Wang
|
||||
* @since 1.0.0
|
||||
*/
|
||||
package cn.org.codecrafters.devkit.utils;
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2023 CodeCraftersCN.
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<configuration>
|
||||
|
||||
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} : %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="STDOUT-C" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%date{yyyy-MM-dd HH:mm:ss} [%thread] %highlight(%-5level) %cyan(%logger{50}) : %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT-C"/>
|
||||
</root>
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user