Skip to content

Commit

Permalink
Modernize Java code using pattern matching for switch to make code co…
Browse files Browse the repository at this point in the history
…ncise #866
  • Loading branch information
JamesChenX committed Dec 10, 2023
1 parent 7ac72c2 commit 6b8af4e
Show file tree
Hide file tree
Showing 12 changed files with 262 additions and 303 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -548,19 +548,15 @@ private static HttpHandlerResult<ResponseDTO<?>> translateThrowable(Throwable th
return HttpHandlerResult.create(statusCode.getHttpStatusCode(),
new ResponseDTO<>(statusCode, reason));
} else {
ResponseStatusCode statusCode;
if (throwable instanceof IllegalArgumentException
|| throwable instanceof ConstraintViolationException) {
statusCode = ResponseStatusCode.ILLEGAL_ARGUMENT;
} else if (throwable instanceof DuplicateKeyException) {
statusCode = ResponseStatusCode.RECORD_CONTAINS_DUPLICATE_KEY;
} else if (throwable instanceof DuplicateResourceException) {
statusCode = ResponseStatusCode.DUPLICATE_RESOURCE;
} else if (throwable instanceof ResourceNotFoundException) {
statusCode = ResponseStatusCode.RESOURCE_NOT_FOUND;
} else {
statusCode = ResponseStatusCode.SERVER_INTERNAL_ERROR;
}
ResponseStatusCode statusCode = switch (throwable) {
case IllegalArgumentException ignored -> ResponseStatusCode.ILLEGAL_ARGUMENT;
case ConstraintViolationException ignored -> ResponseStatusCode.ILLEGAL_ARGUMENT;
case DuplicateKeyException ignored ->
ResponseStatusCode.RECORD_CONTAINS_DUPLICATE_KEY;
case DuplicateResourceException ignored -> ResponseStatusCode.DUPLICATE_RESOURCE;
case ResourceNotFoundException ignored -> ResponseStatusCode.RESOURCE_NOT_FOUND;
default -> ResponseStatusCode.SERVER_INTERNAL_ERROR;
};
String reason = throwable.getMessage();
return HttpHandlerResult.create(statusCode.getHttpStatusCode(),
new ResponseDTO<>(statusCode, reason));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,6 @@ private void onMemberUpdated(String nodeId, UpdateDescription updateDescription)
// better maintainability considering possible field changes
String fieldName = entry.getKey();
BsonValue value = entry.getValue();
// TODO: pattern matching
// Check status change
if (fieldName.endsWith(Member.MemberStatus.Fields.lastHeartbeatDate)) {
memberToUpdate.getStatus()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,19 +191,18 @@ public static int getSize(@Nullable Map<?, ?> map) {
}

public static int getSize(@Nullable Iterable<?> iterable) {
if (iterable == null) {
return 0;
} else if (iterable instanceof Collection<?> collection) {
return collection.size();
} else if (iterable instanceof Map<?, ?> map) {
return map.size();
} else {
int size = 0;
for (Object ignored : iterable) {
size++;
return switch (iterable) {
case null -> 0;
case Collection<?> collection -> collection.size();
case Map<?, ?> map -> map.size();
default -> {
int size = 0;
for (Object ignored : iterable) {
size++;
}
yield size;
}
return size;
}
};
}

public static <T> boolean isEmpty(@Nullable Collection<T> collection) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package im.turms.server.common.infra.exception;

import jakarta.annotation.Nullable;

import im.turms.server.common.access.common.ResponseStatusCode;
import im.turms.server.common.infra.cluster.service.rpc.exception.RpcException;
import im.turms.server.common.infra.io.ResourceNotFoundException;
Expand All @@ -28,27 +30,24 @@
*/
public record ThrowableInfo(
ResponseStatusCode code,
String reason
@Nullable String reason
) {
public static ThrowableInfo get(Throwable throwable) {
if (throwable instanceof ResponseException e) {
return new ThrowableInfo(e.getCode(), e.getReason());
} else if (throwable instanceof RpcException e) {
return new ThrowableInfo(e.getStatusCode(), e.getMessage());
} else if (throwable instanceof DuplicateKeyException e) {
return switch (throwable) {
case ResponseException e -> new ThrowableInfo(e.getCode(), e.getReason());
case RpcException e -> new ThrowableInfo(e.getStatusCode(), e.getMessage());
// We consider DuplicateKeyException as a client error here,
// because if it is an exception caused by the illegal args provided
// by the server, it should recover in the upstream rather than
// passing down DuplicateKeyException
return new ThrowableInfo(
ResponseStatusCode.RECORD_CONTAINS_DUPLICATE_KEY,
e.getMessage());
} else if (throwable instanceof ResourceNotFoundException e) {
return new ThrowableInfo(ResponseStatusCode.RESOURCE_NOT_FOUND, e.getMessage());
} else if (throwable instanceof ExtensionPointExecutionException e) {
return get(e.getCause());
}
return new ThrowableInfo(ResponseStatusCode.SERVER_INTERNAL_ERROR, throwable.getMessage());
case DuplicateKeyException e ->
new ThrowableInfo(ResponseStatusCode.RECORD_CONTAINS_DUPLICATE_KEY, e.getMessage());
case ResourceNotFoundException e ->
new ThrowableInfo(ResponseStatusCode.RESOURCE_NOT_FOUND, e.getMessage());
case ExtensionPointExecutionException e -> get(e.getCause());
default ->
new ThrowableInfo(ResponseStatusCode.SERVER_INTERNAL_ERROR, throwable.getMessage());
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -154,43 +154,48 @@ private static int estimateRecordSize(Object value) {
}

private static int estimateNonRecordSize(Object value) {
int size = 0;
if (value instanceof Iterable<?> iterable) {
for (Object element : iterable) {
size += estimateSize(element);
return switch (value) {
case Iterable<?> iterable -> {
int size = 0;
for (Object element : iterable) {
size += estimateSize(element);
}
yield size;
}
case Map<?, ?> map -> {
int size = 0;
for (Map.Entry<?, ?> entry : map.entrySet()) {
size += entry.getKey() instanceof String str
? StringUtil.getLength(str)
: 16;
Object entryValue = entry.getValue();
size += estimateSize(entryValue);
size += ESTIMATED_JSON_FIELD_METADATA_SIZE;
}
yield size;
}
} else if (value.getClass()
.isArray()) {
if (value instanceof byte[] array) {
size += array.length;
} else if (value instanceof Object[] array) {
case Date ignored -> DateUtil.DATE_TIME_LENGTH;
case String str -> StringUtil.getLength(str);
case byte[] array -> array.length;
case Object[] array -> {
int size = 0;
for (Object element : array) {
size += estimateSize(element);
}
} else {
// We don't support other array types now because we don't use them
LOGGER.warn("Unknown array type: "
+ value.getClass()
.getName());
yield size;
}
} else if (value instanceof Map<?, ?> map) {
for (Map.Entry<?, ?> entry : map.entrySet()) {
size += entry.getKey() instanceof String str
? StringUtil.getLength(str)
: 16;
Object entryValue = entry.getValue();
size += estimateSize(entryValue);
size += ESTIMATED_JSON_FIELD_METADATA_SIZE;
default -> {
if (value.getClass()
.isArray()) {
// We don't support other array types now because we don't use them
LOGGER.warn("Unknown array type: "
+ value.getClass()
.getName());
}
// We don't use "String.valueOf(val).length()" for better performance
yield 16;
}
} else if (value instanceof Date) {
size += DateUtil.DATE_TIME_LENGTH;
} else if (value instanceof String str) {
size += StringUtil.getLength(str);
} else {
// We don't use "String.valueOf(val).length()" for better performance
size += 16;
}
return size;
};
}

private static RecordMetadata getRecordMetadata(Object value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,48 +159,34 @@ public static String getString(ByteBuf buffer) {
}

public static ByteBuf writeObject(Object obj) {
if (obj instanceof ByteBuf element) {
return element;
}
if (obj instanceof Byte element) {
return getPooledPreferredByteBuffer(element.intValue());
}
if (obj instanceof Short element) {
return PooledByteBufAllocator.DEFAULT.directBuffer(Short.BYTES)
return switch (obj) {
case ByteBuf element -> element;
case Byte element -> getPooledPreferredByteBuffer(element.intValue());
case Short element -> PooledByteBufAllocator.DEFAULT.directBuffer(Short.BYTES)
.writeShort(element);
}
if (obj instanceof Integer element) {
return getPooledPreferredIntegerBuffer(element);
}
if (obj instanceof Long element) {
return PooledByteBufAllocator.DEFAULT.directBuffer(Long.BYTES)
case Integer element -> getPooledPreferredIntegerBuffer(element);
case Long element -> PooledByteBufAllocator.DEFAULT.directBuffer(Long.BYTES)
.writeLong(element);
}
if (obj instanceof String element) {
byte[] bytes = StringUtil.getUtf8Bytes(element);
return PooledByteBufAllocator.DEFAULT.directBuffer(bytes.length)
.writeBytes(bytes);
}
if (obj instanceof Float element) {
return PooledByteBufAllocator.DEFAULT.directBuffer(Float.BYTES)
case String element -> {
byte[] bytes = StringUtil.getUtf8Bytes(element);
yield PooledByteBufAllocator.DEFAULT.directBuffer(bytes.length)
.writeBytes(bytes);
}
case Float element -> PooledByteBufAllocator.DEFAULT.directBuffer(Float.BYTES)
.writeFloat(element);
}
if (obj instanceof Double element) {
return PooledByteBufAllocator.DEFAULT.directBuffer(Double.BYTES)
case Double element -> PooledByteBufAllocator.DEFAULT.directBuffer(Double.BYTES)
.writeDouble(element);
}
if (obj instanceof Character element) {
return PooledByteBufAllocator.DEFAULT.directBuffer(Character.BYTES)
case Character element -> PooledByteBufAllocator.DEFAULT.directBuffer(Character.BYTES)
.writeChar(element);
}
if (obj instanceof Boolean element) {
return getPooledPreferredByteBuffer(element
case Boolean element -> getPooledPreferredByteBuffer(element
? 1
: 0);
}
throw new IllegalArgumentException(
"Could not serialize the unknown value: "
+ obj);
case null,
default ->
throw new IllegalArgumentException(
"Could not serialize the unknown value: "
+ obj);
};
}

public static ByteBuf[] writeObjects(Object... objs) {
Expand Down Expand Up @@ -230,22 +216,21 @@ public static ByteBuf join(int estimatedSize, int delimiter, Object... elements)
ByteBuf buffer = PooledByteBufAllocator.DEFAULT.directBuffer(estimatedSize);
for (int i = 0, length = elements.length, last = length - 1; i < length; i++) {
Object element = elements[i];
if (element instanceof Integer num) {
buffer.writeBytes(NumberFormatter.toCharBytes(num));
} else if (element instanceof Long num) {
buffer.writeBytes(NumberFormatter.toCharBytes(num));
} else if (element instanceof String s) {
buffer.writeBytes(StringUtil.getBytes(s));
} else if (element instanceof byte[] bytes) {
buffer.writeBytes(bytes);
} else if (element instanceof Character c) {
buffer.writeChar(c);
} else if (element != null) {
buffer.release();
throw new IllegalArgumentException(
"Unsupported class: "
+ element.getClass()
.getName());
switch (element) {
case null -> {
}
case Integer num -> buffer.writeBytes(NumberFormatter.toCharBytes(num));
case Long num -> buffer.writeBytes(NumberFormatter.toCharBytes(num));
case Character c -> buffer.writeChar(c);
case String s -> buffer.writeBytes(StringUtil.getBytes(s));
case byte[] bytes -> buffer.writeBytes(bytes);
default -> {
buffer.release();
throw new IllegalArgumentException(
"Unsupported class: "
+ element.getClass()
.getName());
}
}
if (i != last) {
buffer.writeByte(delimiter);
Expand All @@ -254,4 +239,4 @@ public static ByteBuf join(int estimatedSize, int delimiter, Object... elements)
return buffer;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public class ValueDecoder {
private ValueDecoder() {
}

@Nullable
public static Object decode(@Nullable Value value) {
// TODO: pattern matching
if (value == null || value.isNull()) {
return null;
} else if (value.isString()) {
Expand Down Expand Up @@ -150,26 +150,26 @@ public static Mono<?> decodeAsMonoIfPromise(Value value, boolean decodePromiseVa
}

public static ScriptExecutionException translateException(Object exception) {
if (exception instanceof ScriptExecutionException e) {
return e;
} else if (exception instanceof PolyglotException e) {
ScriptExceptionSource source = e.isHostException()
? ScriptExceptionSource.HOST
: ScriptExceptionSource.SCRIPT;
return new ScriptExecutionException(e, source);
} else if (exception instanceof Throwable t) {
return new ScriptExecutionException(t, ScriptExceptionSource.HOST);
} else if (exception instanceof Value value && value.isException()) {
Throwable t;
try {
t = value.throwException();
} catch (Exception e) {
t = e;
return switch (exception) {
case ScriptExecutionException e -> e;
case PolyglotException e -> new ScriptExecutionException(
e,
e.isHostException()
? ScriptExceptionSource.HOST
: ScriptExceptionSource.SCRIPT);
case Throwable t -> new ScriptExecutionException(t, ScriptExceptionSource.HOST);
case Value value when value.isException() -> {
Throwable t;
try {
t = value.throwException();
} catch (Exception e) {
t = e;
}
yield new ScriptExecutionException(t, ScriptExceptionSource.SCRIPT);
}
return new ScriptExecutionException(t, ScriptExceptionSource.SCRIPT);
} else {
return new ScriptExecutionException(exception.toString(), ScriptExceptionSource.SCRIPT);
}
default ->
new ScriptExecutionException(exception.toString(), ScriptExceptionSource.SCRIPT);
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,15 @@ private Validator() {
}

public static boolean isFalsy(@Nullable Object item) {
if (item == null) {
return true;
}
if (item instanceof String str) {
return str.isEmpty();
} else if (item instanceof Collection<?> collection) {
return collection.isEmpty();
} else if (item.getClass()
.isArray()) {
return Array.getLength(item) <= 0;
} else if (item instanceof Map<?, ?> map) {
return map.isEmpty();
}
return false;
return switch (item) {
case null -> true;
case String str -> str.isEmpty();
case Collection<?> collection -> collection.isEmpty();
case Map<?, ?> map -> map.isEmpty();
default -> item.getClass()
.isArray()
&& Array.getLength(item) == 0;
};
}

public static boolean isTruthy(@Nullable Object item) {
Expand Down
Loading

0 comments on commit 6b8af4e

Please sign in to comment.