refactor: Optimised codes.

Move all private or protected to the last of files.
This commit is contained in:
Zihlu Wang
2024-03-31 17:47:42 +08:00
parent d593c83cc8
commit bb79c126fa
10 changed files with 296 additions and 283 deletions
@@ -44,13 +44,6 @@ import java.util.UUID;
@Slf4j
public final class AesUtil {
private AesUtil() {
}
private static final String AES = "AES";
private static final String AES_CBC_CIPHER = "AES/CBC/PKCS5Padding";
/**
* Encrypts the data using the AES algorithm with the given secret.
*
@@ -133,4 +126,20 @@ public final class AesUtil {
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
}
/**
* Private constructor will protect this class from being instantiated.
*/
private AesUtil() {
}
/**
* The algorithm AES.
*/
private static final String AES = "AES";
/**
* The algorithm AES/CBC/PKCS5Padding.
*/
private static final String AES_CBC_CIPHER = "AES/CBC/PKCS5Padding";
}
@@ -56,14 +56,6 @@ import java.util.Objects;
*/
public final class Base64Util {
private static Base64.Encoder encoder;
private static Base64.Decoder decoder;
private static Base64.Encoder urlEncoder;
private static Base64.Decoder urlDecoder;
/**
* Ensure that there is only one Base64 Encoder.
*
@@ -210,4 +202,12 @@ public final class Base64Util {
return decodeUrlComponents(value, StandardCharsets.UTF_8);
}
private static Base64.Encoder encoder;
private static Base64.Decoder decoder;
private static Base64.Encoder urlEncoder;
private static Base64.Decoder urlDecoder;
}
@@ -77,11 +77,6 @@ import java.util.function.Supplier;
*/
public final class BranchUtil<T> {
/**
* The final result of the boolean expression.
*/
private final boolean result;
/**
* Create a {@code BranchUtil} instance.
*
@@ -239,4 +234,9 @@ public final class BranchUtil<T> {
handle(ifHandler, null);
}
/**
* The final result of the boolean expression.
*/
private final boolean result;
}
@@ -95,12 +95,6 @@ import java.util.function.Function;
@Getter
public final class ChainedCalcUtil {
/**
* -- GETTER --
* Returns the current value as a BigDecimal.
*/
private BigDecimal value;
/**
* Creates a {@code ChainedCalcUtil} instance with the specified initial
* value.
@@ -359,4 +353,10 @@ public final class ChainedCalcUtil {
return res;
}
/**
* -- GETTER --
* Returns the current value as a BigDecimal.
*/
private BigDecimal value;
}
@@ -69,48 +69,6 @@ import java.util.Optional;
*/
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.
@@ -286,4 +244,46 @@ public final class HashUtil {
return hash("SHA-512", value, StandardCharsets.UTF_8);
}
/**
* Private constructor will protect this class from being instantiated.
*/
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 "";
}
}
}
@@ -37,12 +37,6 @@ import java.util.Map;
@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.
@@ -219,4 +213,10 @@ public final class MapUtil {
return String.valueOf(obj);
}
}
/**
* Private constructor will protect this class from being instantiated.
*/
private MapUtil() {
}
}
@@ -15,13 +15,13 @@
* limitations under the License.
*/
package cn.org.codecrafters.guid;
package cn.org.codecrafters.guid.impl;
import cn.org.codecrafters.guid.GuidCreator;
import cn.org.codecrafters.guid.exceptions.TimingException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
/**
* The {@code SnowflakeGuidCreator} generates unique identifiers using the
@@ -49,48 +49,6 @@ import java.time.ZoneOffset;
*/
public final class SnowflakeGuidCreator implements GuidCreator<Long> {
/**
* Default custom epoch.
*
* @value 2015-01-01T00:00:00Z
*/
private static final long DEFAULT_CUSTOM_EPOCH = 1_420_070_400_000L;
/**
* The start epoch timestamp to generate IDs from.
*/
private final long startEpoch;
/**
* The number of bits reserved for the worker ID.
*/
private final long workerIdBits = 5L;
/**
* The number of bits reserved for the data centre ID.
*/
private final long dataCentreIdBits = 5L;
/**
* The worker ID assigned to this generator.
*/
private final long workerId;
/**
* The data centre ID assigned to this generator.
*/
private final long dataCentreId;
/**
* The current sequence number.
*/
private long sequence = 0L;
/**
* The timestamp of the last generated ID.
*/
private long lastTimestamp = -1L;
/**
* Constructs a SnowflakeGuidGenerator with the default start epoch and
* custom worker ID, data centre ID.
@@ -204,5 +162,48 @@ public final class SnowflakeGuidCreator implements GuidCreator<Long> {
private long currentTimestamp() {
return LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
/**
* Default custom epoch.
*
* @value 2015-01-01T00:00:00Z
*/
private static final long DEFAULT_CUSTOM_EPOCH = 1_420_070_400_000L;
/**
* The start epoch timestamp to generate IDs from.
*/
private final long startEpoch;
/**
* The number of bits reserved for the worker ID.
*/
private final long workerIdBits = 5L;
/**
* The number of bits reserved for the data centre ID.
*/
private final long dataCentreIdBits = 5L;
/**
* The worker ID assigned to this generator.
*/
private final long workerId;
/**
* The data centre ID assigned to this generator.
*/
private final long dataCentreId;
/**
* The current sequence number.
*/
private long sequence = 0L;
/**
* The timestamp of the last generated ID.
*/
private long lastTimestamp = -1L;
}
@@ -70,8 +70,6 @@ import java.util.Optional;
*/
public class PropertyGuard implements EnvironmentPostProcessor {
private final String PREFIX = "pg";
/**
* Process the encryption environment variables.
*
@@ -108,4 +106,6 @@ public class PropertyGuard implements EnvironmentPostProcessor {
}
}
}
private static final String PREFIX = "pg";
}
@@ -104,34 +104,6 @@ import java.util.*;
@Slf4j
public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
/**
* GuidCreator used for generating unique identifiers for "jti" claim in
* JWT tokens.
*/
private final GuidCreator<?> jtiCreator;
/**
* The algorithm used for signing and verifying JWT tokens.
*/
private final Algorithm algorithm;
/**
* The issuer claim value to be included in JWT tokens.
*/
private final String issuer;
/**
* The JSON Web Token resolver.
*/
private final JWTVerifier verifier;
/**
* Jackson JSON handler.
*/
private final ObjectMapper objectMapper;
private final AuthzeroTokenResolverConfig config = AuthzeroTokenResolverConfig.getInstance();
/**
* Creates a new instance of {@code AuthzeroTokenResolver} with the
* provided configurations.
@@ -150,7 +122,7 @@ public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
throw new IllegalArgumentException("A secret is required to build a JSON Web Token.");
}
if (secret.length() <= 32) {
if (secret.length() < 32) {
log.warn("The provided secret which owns {} characters is too weak. Please consider replacing it with a stronger one.", secret.length());
}
@@ -224,104 +196,6 @@ public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
log.info("The secret has been set to {}.", secret);
}
/**
* Builds the basic information of the JSON Web Token (JWT) using the
* provided parameters and adds it to the JWTCreator.Builder.
*
* @param subject the subject claim value to be included in the JWT
* @param audience an array of audience claim values to be included in
* the JWT
* @param expireAfter the duration after which the JWT will expire
* @param builder the JWTCreator.Builder instance to which the basic
* information will be added
*/
private void buildBasicInfo(JWTCreator.Builder builder, Duration expireAfter, String subject, String... audience) {
var now = LocalDateTime.now();
// bind issuer (iss)
builder.withIssuer(issuer);
// bind issued at (iat)
builder.withIssuedAt(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()));
// bind not before (nbf)
builder.withNotBefore(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()));
// bind audience (aud)
builder.withAudience(audience);
// bind subject (sub)
builder.withSubject(subject);
// bind expire at (exp)
builder.withExpiresAt(Date.from(now.plus(expireAfter).atZone(ZoneId.systemDefault()).toInstant()));
// bind JWT Id (jti)
builder.withJWTId(jtiCreator.nextId().toString());
}
/**
* Add a claim to a builder.
*
* @param builder the builder to build this JSON Web Token
* @param name the property name
* @param value the property value
*/
private void addClaim(JWTCreator.Builder builder, String name, Object value) {
if (Objects.nonNull(value)) {
if (value instanceof Boolean v) {
builder.withClaim(name, v);
} else if (value instanceof Double v) {
builder.withClaim(name, v);
} else if (value instanceof Float v) {
builder.withClaim(name, v.doubleValue());
} else if (value instanceof Integer v) {
builder.withClaim(name, v);
} else if (value instanceof Long v) {
builder.withClaim(name, v);
} else if (value instanceof String v) {
builder.withClaim(name, v);
} else if (value instanceof Date v) {
builder.withClaim(name, v);
} else if (value instanceof List<?> v) {
builder.withClaim(name, v);
} else {
log.warn("""
Unable to determine the type of field {}, we will handle it as a String.""", name);
builder.withClaim(name, value.toString());
}
} else {
builder.withNullClaim(name);
}
}
/**
* Builds the custom claims of the JSON Web Token (JWT) using the provided
* Map of claims and adds them to the JWTCreator.Builder.
* <p>
* This method is used to add custom claims to the JWT. It takes a Map of
* claims, where each entry represents a custom claim name (key) and its
* corresponding value (value). The custom claims will be added to the JWT
* using the JWTCreator.Builder.
*
* @param claims a Map containing the custom claims to be added to the JWT
* @param builder the JWTCreator.Builder instance to which the custom
* claims will be added
*/
private void buildMapClaims(JWTCreator.Builder builder, Map<String, Object> claims) {
if (Objects.nonNull(claims)) {
for (var e : claims.entrySet()) {
addClaim(builder, e.getKey(), e.getValue());
}
}
}
/**
* Finish creating a token.
* <p>
* This is the final step of create a token, to sign this token.
*
* @param builder the builder to build this JWT
* @return the generated token as a {@code String}
*/
private String buildToken(JWTCreator.Builder builder) {
return builder.sign(algorithm);
}
/**
* Creates a new token with the specified expiration duration, subject, and
* audience.
@@ -552,8 +426,137 @@ public class AuthzeroTokenResolver implements TokenResolver<DecodedJWT> {
return renew(oldToken, Duration.ofMinutes(30), payload);
}
/**
* Builds the basic information of the JSON Web Token (JWT) using the
* provided parameters and adds it to the JWTCreator.Builder.
*
* @param subject the subject claim value to be included in the JWT
* @param audience an array of audience claim values to be included in
* the JWT
* @param expireAfter the duration after which the JWT will expire
* @param builder the JWTCreator.Builder instance to which the basic
* information will be added
*/
private void buildBasicInfo(JWTCreator.Builder builder, Duration expireAfter, String subject, String... audience) {
var now = LocalDateTime.now();
// bind issuer (iss)
builder.withIssuer(issuer);
// bind issued at (iat)
builder.withIssuedAt(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()));
// bind not before (nbf)
builder.withNotBefore(Date.from(now.atZone(ZoneId.systemDefault()).toInstant()));
// bind audience (aud)
builder.withAudience(audience);
// bind subject (sub)
builder.withSubject(subject);
// bind expire at (exp)
builder.withExpiresAt(Date.from(now.plus(expireAfter).atZone(ZoneId.systemDefault()).toInstant()));
// bind JWT Id (jti)
builder.withJWTId(jtiCreator.nextId().toString());
}
/**
* Add a claim to a builder.
*
* @param builder the builder to build this JSON Web Token
* @param name the property name
* @param value the property value
*/
private void addClaim(JWTCreator.Builder builder, String name, Object value) {
if (Objects.nonNull(value)) {
if (value instanceof Boolean v) {
builder.withClaim(name, v);
} else if (value instanceof Double v) {
builder.withClaim(name, v);
} else if (value instanceof Float v) {
builder.withClaim(name, v.doubleValue());
} else if (value instanceof Integer v) {
builder.withClaim(name, v);
} else if (value instanceof Long v) {
builder.withClaim(name, v);
} else if (value instanceof String v) {
builder.withClaim(name, v);
} else if (value instanceof Date v) {
builder.withClaim(name, v);
} else if (value instanceof List<?> v) {
builder.withClaim(name, v);
} else {
log.warn("""
Unable to determine the type of field {}, we will handle it as a String.""", name);
builder.withClaim(name, value.toString());
}
} else {
builder.withNullClaim(name);
}
}
/**
* Builds the custom claims of the JSON Web Token (JWT) using the provided
* Map of claims and adds them to the JWTCreator.Builder.
* <p>
* This method is used to add custom claims to the JWT. It takes a Map of
* claims, where each entry represents a custom claim name (key) and its
* corresponding value (value). The custom claims will be added to the JWT
* using the JWTCreator.Builder.
*
* @param claims a Map containing the custom claims to be added to the JWT
* @param builder the JWTCreator.Builder instance to which the custom
* claims will be added
*/
private void buildMapClaims(JWTCreator.Builder builder, Map<String, Object> claims) {
if (Objects.nonNull(claims)) {
for (var e : claims.entrySet()) {
addClaim(builder, e.getKey(), e.getValue());
}
}
}
/**
* Finish creating a token.
* <p>
* This is the final step of create a token, to sign this token.
*
* @param builder the builder to build this JWT
* @return the generated token as a {@code String}
*/
private String buildToken(JWTCreator.Builder builder) {
return builder.sign(algorithm);
}
/**
* Default type reference for Map.
*/
private static class MapTypeReference extends TypeReference<Map<String, Object>> {
MapTypeReference() {
}
}
/**
* GuidCreator used for generating unique identifiers for "jti" claim in
* JWT tokens.
*/
private final GuidCreator<?> jtiCreator;
/**
* The algorithm used for signing and verifying JWT tokens.
*/
private final Algorithm algorithm;
/**
* The issuer claim value to be included in JWT tokens.
*/
private final String issuer;
/**
* The JSON Web Token resolver.
*/
private final JWTVerifier verifier;
/**
* Jackson JSON handler.
*/
private final ObjectMapper objectMapper;
private final AuthzeroTokenResolverConfig config = AuthzeroTokenResolverConfig.getInstance();
}
@@ -62,42 +62,6 @@ import java.util.function.Function;
*/
public final class AuthzeroTokenResolverConfig implements TokenResolverConfig<Function<String, Algorithm>> {
/**
* Constructs a new instance of {@code AuthzeroTokenResolverConfig}.
* <p>
* The constructor is set as private to enforce the singleton pattern for
* this configuration class. Instances of
* {@code AuthzeroTokenResolverConfig} should be obtained through the
* {@link #getInstance()} method.
*/
private AuthzeroTokenResolverConfig() {
}
/**
* The singleton instance of {@code AuthzeroTokenResolverConfig}.
* <p>
* This instance is used to ensure that only one instance of
* {@code AuthzeroTokenResolverConfig} is created and shared throughout the
* application. The singleton pattern is implemented to provide centralised
* configuration and avoid redundant object creation.
*/
private static AuthzeroTokenResolverConfig instance;
/**
* The supported algorithms and their corresponding algorithm functions.
* <p>
* This map stores the supported algorithms as keys and their corresponding
* algorithm functions as values. The algorithm functions represent the
* functions used by the {@code com.auth0:java-jwt} library to handle the
* specific algorithms. The mapping is used to provide proper algorithm
* resolution and processing within the {@link AuthzeroTokenResolver}.
*/
private static final Map<TokenAlgorithm, Function<String, Algorithm>> SUPPORTED_ALGORITHMS = new HashMap<>() {{
put(TokenAlgorithm.HS256, Algorithm::HMAC256);
put(TokenAlgorithm.HS384, Algorithm::HMAC384);
put(TokenAlgorithm.HS512, Algorithm::HMAC512);
}};
/**
* Gets the instance of {@code AuthzeroTokenResolverConfig}.
* <p>
@@ -140,4 +104,40 @@ public final class AuthzeroTokenResolverConfig implements TokenResolverConfig<Fu
return Optional.of(SUPPORTED_ALGORITHMS).map((entry) -> entry.get(algorithm))
.orElseThrow(() -> new UnsupportedAlgorithmException("The specified algorithm is not supported yet."));
}
/**
* Constructs a new instance of {@code AuthzeroTokenResolverConfig}.
* <p>
* The constructor is set as private to enforce the singleton pattern for
* this configuration class. Instances of
* {@code AuthzeroTokenResolverConfig} should be obtained through the
* {@link #getInstance()} method.
*/
private AuthzeroTokenResolverConfig() {
}
/**
* The singleton instance of {@code AuthzeroTokenResolverConfig}.
* <p>
* This instance is used to ensure that only one instance of
* {@code AuthzeroTokenResolverConfig} is created and shared throughout the
* application. The singleton pattern is implemented to provide centralised
* configuration and avoid redundant object creation.
*/
private static AuthzeroTokenResolverConfig instance;
/**
* The supported algorithms and their corresponding algorithm functions.
* <p>
* This map stores the supported algorithms as keys and their corresponding
* algorithm functions as values. The algorithm functions represent the
* functions used by the {@code com.auth0:java-jwt} library to handle the
* specific algorithms. The mapping is used to provide proper algorithm
* resolution and processing within the {@link AuthzeroTokenResolver}.
*/
private static final Map<TokenAlgorithm, Function<String, Algorithm>> SUPPORTED_ALGORITHMS = new HashMap<>() {{
put(TokenAlgorithm.HS256, Algorithm::HMAC256);
put(TokenAlgorithm.HS384, Algorithm::HMAC384);
put(TokenAlgorithm.HS512, Algorithm::HMAC512);
}};
}