From 68f977a5887f881577abe4243dec14e5fe546028 Mon Sep 17 00:00:00 2001 From: Christian Tzolov Date: Mon, 16 Oct 2023 14:02:58 -0400 Subject: [PATCH] Streamline UUIDConverter * Use `StandardCharsets.UTF_8` as a charset configuration instead of string. Later remove the necessity of handling encoder errors. * Use regular expressions to validate the `UUID` string standard representation. Later obsolete the need for try/catch exceptions. * Deprecate `UUIDConverter.DEFAULT_CHARSET` since it is out of use. **Cherry-pick to `6.1.x` & `6.0.x`** Code clean up for `UUIDConverter` --- .../integration/util/UUIDConverter.java | 68 +++++++++---------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/util/UUIDConverter.java b/spring-integration-core/src/main/java/org/springframework/integration/util/UUIDConverter.java index 2c4283ecc4..c6cabca920 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/util/UUIDConverter.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/util/UUIDConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,9 @@ package org.springframework.integration.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.UUID; +import java.util.regex.Pattern; import org.springframework.core.convert.converter.Converter; import org.springframework.util.ClassUtils; @@ -30,16 +31,23 @@ import org.springframework.util.ClassUtils; * * @author Dave Syer * @author Gary Russell + * @author Christian Tzolov + * @author Artem Bilan */ public class UUIDConverter implements Converter { + /** + * @deprecated since 6.0.8 as it is not used internally by the UUIDConverter. + * The internal implementation relies on {@link StandardCharsets#UTF_8} instead. + */ + @Deprecated public static final String DEFAULT_CHARSET = "UTF-8"; + private static final Pattern UUID_REGEX = + Pattern.compile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"); /** - * Convert the input to a UUID using the convenience method - * {@link #getUUID(Object)}. - * + * Convert the input to a UUID using the convenience method {@link #getUUID(Object)}. * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) */ @Override @@ -52,17 +60,12 @@ public class UUIDConverter implements Converter { *
    *
  • null: returns null
  • *
  • a UUID: returns the input unchanged
  • - *
  • a String formatted as a UUID: returns the result of - * {@link UUID#fromString(String)}
  • - *
  • any other String: returns {@link UUID#nameUUIDFromBytes(byte[])} with - * bytes generated from the input
  • - *
  • a primitive or primitive wrapper: converts to a String ans then uses - * the previous conversion method
  • - *
  • Serializable: returns the {@link UUID#nameUUIDFromBytes(byte[])} with - * the serialized bytes of the input
  • + *
  • a String formatted as a UUID: returns the result of {@link UUID#fromString(String)}
  • + *
  • any other String: returns {@link UUID#nameUUIDFromBytes(byte[])} with bytes generated from the input
  • + *
  • a primitive or primitive wrapper: converts to a String ans then uses the previous conversion method
  • + *
  • Serializable: returns the {@link UUID#nameUUIDFromBytes(byte[])} with the serialized bytes of the input
  • *
* If none of the above applies there will be an exception trying to serialize. - * * @param input an Object * @return a UUID constructed from the input */ @@ -73,34 +76,25 @@ public class UUIDConverter implements Converter { if (input instanceof UUID) { return (UUID) input; } - if (input instanceof String) { - try { - return UUID.fromString((String) input); + if (input instanceof String inputText) { + if (isValidUuidStringRepresentation(inputText)) { + return UUID.fromString(inputText); } - catch (Exception e) { - try { - return UUID.nameUUIDFromBytes(((String) input).getBytes(DEFAULT_CHARSET)); - } - catch (UnsupportedEncodingException ex) { - IllegalStateException exception = - new IllegalStateException("Cannot convert String using charset=" + DEFAULT_CHARSET, ex); - exception.addSuppressed(e); - throw exception; // NOSONAR - added to suppressed exceptions - } + else { + return fromStringBytes(inputText); } } if (ClassUtils.isPrimitiveOrWrapper(input.getClass())) { - try { - return UUID.nameUUIDFromBytes(input.toString().getBytes(DEFAULT_CHARSET)); - } - catch (UnsupportedEncodingException e) { - throw new IllegalStateException("Cannot convert primitive using charset=" + DEFAULT_CHARSET, e); - } + return fromStringBytes(input.toString()); } byte[] bytes = serialize(input); return UUID.nameUUIDFromBytes(bytes); } + private static UUID fromStringBytes(String input) { + return UUID.nameUUIDFromBytes(input.getBytes(StandardCharsets.UTF_8)); + } + private static byte[] serialize(Object object) { if (object == null) { return null; @@ -109,10 +103,14 @@ public class UUIDConverter implements Converter { try { new ObjectOutputStream(stream).writeObject(object); } - catch (IOException e) { - throw new IllegalArgumentException("Could not serialize object of type: " + object.getClass(), e); + catch (IOException ex) { + throw new IllegalArgumentException("Could not serialize object of type: " + object.getClass(), ex); } return stream.toByteArray(); } + private static boolean isValidUuidStringRepresentation(String uuid) { + return UUID_REGEX.matcher(uuid).matches(); + } + }