11/*
2- * Copyright 2002-2019 the original author or authors.
2+ * Copyright 2002-2023 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1919import java .io .ByteArrayOutputStream ;
2020import java .io .IOException ;
2121import java .io .ObjectOutputStream ;
22- import java .io . UnsupportedEncodingException ;
22+ import java .nio . charset . StandardCharsets ;
2323import java .util .UUID ;
24+ import java .util .regex .Pattern ;
2425
2526import org .springframework .core .convert .converter .Converter ;
2627import org .springframework .util .ClassUtils ;
3031 *
3132 * @author Dave Syer
3233 * @author Gary Russell
34+ * @author Christian Tzolov
35+ * @author Artem Bilan
3336 */
3437public class UUIDConverter implements Converter <Object , UUID > {
3538
39+ /**
40+ * @deprecated since 6.0.8 as it is not used internally by the UUIDConverter.
41+ * The internal implementation relies on {@link StandardCharsets#UTF_8} instead.
42+ */
43+ @ Deprecated
3644 public static final String DEFAULT_CHARSET = "UTF-8" ;
3745
46+ private static final Pattern UUID_REGEX =
47+ 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}$" );
3848
3949 /**
40- * Convert the input to a UUID using the convenience method
41- * {@link #getUUID(Object)}.
42- *
50+ * Convert the input to a UUID using the convenience method {@link #getUUID(Object)}.
4351 * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object)
4452 */
4553 @ Override
@@ -52,17 +60,12 @@ public UUID convert(Object source) {
5260 * <ul>
5361 * <li>null: returns null</li>
5462 * <li>a UUID: returns the input unchanged</li>
55- * <li>a String formatted as a UUID: returns the result of
56- * {@link UUID#fromString(String)}</li>
57- * <li>any other String: returns {@link UUID#nameUUIDFromBytes(byte[])} with
58- * bytes generated from the input</li>
59- * <li>a primitive or primitive wrapper: converts to a String ans then uses
60- * the previous conversion method</li>
61- * <li>Serializable: returns the {@link UUID#nameUUIDFromBytes(byte[])} with
62- * the serialized bytes of the input</li>
63+ * <li>a String formatted as a UUID: returns the result of {@link UUID#fromString(String)}</li>
64+ * <li>any other String: returns {@link UUID#nameUUIDFromBytes(byte[])} with bytes generated from the input</li>
65+ * <li>a primitive or primitive wrapper: converts to a String ans then uses the previous conversion method</li>
66+ * <li>Serializable: returns the {@link UUID#nameUUIDFromBytes(byte[])} with the serialized bytes of the input</li>
6367 * </ul>
6468 * If none of the above applies there will be an exception trying to serialize.
65- *
6669 * @param input an Object
6770 * @return a UUID constructed from the input
6871 */
@@ -73,34 +76,25 @@ public static UUID getUUID(Object input) {
7376 if (input instanceof UUID ) {
7477 return (UUID ) input ;
7578 }
76- if (input instanceof String ) {
77- try {
78- return UUID .fromString (( String ) input );
79+ if (input instanceof String inputText ) {
80+ if ( isValidUuidStringRepresentation ( inputText )) {
81+ return UUID .fromString (inputText );
7982 }
80- catch (Exception e ) {
81- try {
82- return UUID .nameUUIDFromBytes (((String ) input ).getBytes (DEFAULT_CHARSET ));
83- }
84- catch (UnsupportedEncodingException ex ) {
85- IllegalStateException exception =
86- new IllegalStateException ("Cannot convert String using charset=" + DEFAULT_CHARSET , ex );
87- exception .addSuppressed (e );
88- throw exception ; // NOSONAR - added to suppressed exceptions
89- }
83+ else {
84+ return fromStringBytes (inputText );
9085 }
9186 }
9287 if (ClassUtils .isPrimitiveOrWrapper (input .getClass ())) {
93- try {
94- return UUID .nameUUIDFromBytes (input .toString ().getBytes (DEFAULT_CHARSET ));
95- }
96- catch (UnsupportedEncodingException e ) {
97- throw new IllegalStateException ("Cannot convert primitive using charset=" + DEFAULT_CHARSET , e );
98- }
88+ return fromStringBytes (input .toString ());
9989 }
10090 byte [] bytes = serialize (input );
10191 return UUID .nameUUIDFromBytes (bytes );
10292 }
10393
94+ private static UUID fromStringBytes (String input ) {
95+ return UUID .nameUUIDFromBytes (input .getBytes (StandardCharsets .UTF_8 ));
96+ }
97+
10498 private static byte [] serialize (Object object ) {
10599 if (object == null ) {
106100 return null ;
@@ -109,10 +103,14 @@ private static byte[] serialize(Object object) {
109103 try {
110104 new ObjectOutputStream (stream ).writeObject (object );
111105 }
112- catch (IOException e ) {
113- throw new IllegalArgumentException ("Could not serialize object of type: " + object .getClass (), e );
106+ catch (IOException ex ) {
107+ throw new IllegalArgumentException ("Could not serialize object of type: " + object .getClass (), ex );
114108 }
115109 return stream .toByteArray ();
116110 }
117111
112+ private static boolean isValidUuidStringRepresentation (String uuid ) {
113+ return UUID_REGEX .matcher (uuid ).matches ();
114+ }
115+
118116}
0 commit comments