Skip to content

Commit 918a4cd

Browse files
nenaraabjzheaux
authored andcommitted
AclClassIdUtils Default GenericConversionService
So that String, Long, and UUID conversions are automatically supported.
1 parent 0e5f124 commit 918a4cd

File tree

2 files changed

+79
-43
lines changed

2 files changed

+79
-43
lines changed

acl/src/main/java/org/springframework/security/acls/jdbc/AclClassIdUtils.java

+39-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 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.
@@ -18,11 +18,17 @@
1818
import java.io.Serializable;
1919
import java.sql.ResultSet;
2020
import java.sql.SQLException;
21+
import java.util.UUID;
2122

2223
import org.apache.commons.logging.Log;
2324
import org.apache.commons.logging.LogFactory;
25+
import org.springframework.core.convert.ConversionFailedException;
2426
import org.springframework.core.convert.ConversionService;
27+
import org.springframework.core.convert.TypeDescriptor;
28+
import org.springframework.core.convert.converter.Converter;
29+
import org.springframework.core.convert.support.GenericConversionService;
2530
import org.springframework.security.acls.model.ObjectIdentity;
31+
import org.springframework.util.Assert;
2632

2733
/**
2834
* Utility class for helping convert database representations of {@link ObjectIdentity#getIdentifier()} into
@@ -36,9 +42,14 @@ class AclClassIdUtils {
3642
private ConversionService conversionService;
3743

3844
public AclClassIdUtils() {
45+
GenericConversionService genericConversionService = new GenericConversionService();
46+
genericConversionService.addConverter(String.class, Long.class, new StringToLongConverter());
47+
genericConversionService.addConverter(String.class, UUID.class, new StringToUUIDConverter());
48+
this.conversionService = genericConversionService;
3949
}
4050

4151
public AclClassIdUtils(ConversionService conversionService) {
52+
Assert.notNull(conversionService, "conversionService must not be null");
4253
this.conversionService = conversionService;
4354
}
4455

@@ -90,17 +101,13 @@ private <T extends Serializable> Class<T> classIdTypeFrom(String className) {
90101
}
91102

92103
private <T> boolean canConvertFromStringTo(Class<T> targetType) {
93-
return hasConversionService() && conversionService.canConvert(String.class, targetType);
104+
return conversionService.canConvert(String.class, targetType);
94105
}
95106

96107
private <T extends Serializable> T convertFromStringTo(String identifier, Class<T> targetType) {
97108
return conversionService.convert(identifier, targetType);
98109
}
99110

100-
private boolean hasConversionService() {
101-
return conversionService != null;
102-
}
103-
104111
/**
105112
* Converts to a {@link Long}, attempting to use the {@link ConversionService} if available.
106113
* @param identifier The identifier
@@ -111,7 +118,7 @@ private boolean hasConversionService() {
111118
*/
112119
private Long convertToLong(Serializable identifier) {
113120
Long idAsLong;
114-
if (hasConversionService()) {
121+
if (canConvertFromStringTo(Long.class)) {
115122
idAsLong = conversionService.convert(identifier, Long.class);
116123
} else {
117124
idAsLong = Long.valueOf(identifier.toString());
@@ -124,6 +131,31 @@ private boolean isString(Serializable object) {
124131
}
125132

126133
public void setConversionService(ConversionService conversionService) {
134+
Assert.notNull(conversionService, "conversionService must not be null");
127135
this.conversionService = conversionService;
128136
}
137+
138+
private static class StringToLongConverter implements Converter<String, Long> {
139+
@Override
140+
public Long convert(String identifierAsString) {
141+
if (identifierAsString == null) {
142+
throw new ConversionFailedException(TypeDescriptor.valueOf(String.class),
143+
TypeDescriptor.valueOf(Long.class), null, null);
144+
145+
}
146+
return Long.parseLong(identifierAsString);
147+
}
148+
}
149+
150+
private static class StringToUUIDConverter implements Converter<String, UUID> {
151+
@Override
152+
public UUID convert(String identifierAsString) {
153+
if (identifierAsString == null) {
154+
throw new ConversionFailedException(TypeDescriptor.valueOf(String.class),
155+
TypeDescriptor.valueOf(UUID.class), null, null);
156+
157+
}
158+
return UUID.fromString(identifierAsString);
159+
}
160+
}
129161
}

acl/src/test/java/org/springframework/security/acls/jdbc/AclClassIdUtilsTest.java

+40-36
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 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.
@@ -16,21 +16,20 @@
1616
package org.springframework.security.acls.jdbc;
1717

1818

19-
import static org.assertj.core.api.Assertions.assertThat;
20-
import static org.mockito.BDDMockito.given;
19+
import org.junit.Before;
20+
import org.junit.Test;
21+
import org.junit.runner.RunWith;
22+
import org.mockito.Mock;
23+
import org.mockito.junit.MockitoJUnitRunner;
24+
import org.springframework.core.convert.ConversionService;
2125

2226
import java.io.Serializable;
2327
import java.sql.ResultSet;
2428
import java.sql.SQLException;
2529
import java.util.UUID;
2630

27-
import org.junit.Before;
28-
import org.junit.Test;
29-
import org.junit.runner.RunWith;
30-
import org.mockito.InjectMocks;
31-
import org.mockito.Mock;
32-
import org.mockito.runners.MockitoJUnitRunner;
33-
import org.springframework.core.convert.ConversionService;
31+
import static org.assertj.core.api.Assertions.assertThat;
32+
import static org.mockito.BDDMockito.given;
3433

3534
/**
3635
* Tests for {@link AclClassIdUtils}.
@@ -46,40 +45,23 @@ public class AclClassIdUtilsTest {
4645
private ResultSet resultSet;
4746
@Mock
4847
private ConversionService conversionService;
49-
@InjectMocks
48+
5049
private AclClassIdUtils aclClassIdUtils;
5150

5251
@Before
53-
public void setUp() throws Exception {
54-
given(conversionService.canConvert(String.class, Long.class)).willReturn(true);
55-
given(conversionService.convert(DEFAULT_IDENTIFIER, Long.class)).willReturn(new Long(DEFAULT_IDENTIFIER));
56-
given(conversionService.convert(DEFAULT_IDENTIFIER_AS_STRING, Long.class)).willReturn(new Long(DEFAULT_IDENTIFIER));
52+
public void setUp() {
53+
aclClassIdUtils = new AclClassIdUtils();
5754
}
5855

5956
@Test
60-
public void shouldReturnLongIfIdentifierIsNotStringAndNoConversionService() throws SQLException {
61-
// given
62-
AclClassIdUtils aclClassIdUtilsWithoutConversionSvc = new AclClassIdUtils();
63-
57+
public void shouldReturnLongIfIdentifierIsLong() throws SQLException {
6458
// when
65-
Serializable newIdentifier = aclClassIdUtilsWithoutConversionSvc.identifierFrom(DEFAULT_IDENTIFIER, resultSet);
59+
Serializable newIdentifier = aclClassIdUtils.identifierFrom(DEFAULT_IDENTIFIER, resultSet);
6660

6761
// then
6862
assertThat(newIdentifier).isEqualTo(DEFAULT_IDENTIFIER);
6963
}
7064

71-
@Test
72-
public void shouldReturnLongIfIdentifierIsNotString() throws SQLException {
73-
// given
74-
Long prevIdentifier = 999L;
75-
76-
// when
77-
Serializable newIdentifier = aclClassIdUtils.identifierFrom(prevIdentifier, resultSet);
78-
79-
// then
80-
assertThat(newIdentifier).isEqualTo(prevIdentifier);
81-
}
82-
8365
@Test
8466
public void shouldReturnLongIfClassIdTypeIsNull() throws SQLException {
8567
// given
@@ -117,10 +99,11 @@ public void shouldReturnLongIfTypeClassNotFound() throws SQLException {
11799
}
118100

119101
@Test
120-
public void shouldReturnLongIfTypeClassCannotBeConverted() throws SQLException {
102+
public void shouldReturnLongEvenIfCustomConversionServiceDoesNotSupportLongConversion() throws SQLException {
121103
// given
122104
given(resultSet.getString("class_id_type")).willReturn("java.lang.Long");
123105
given(conversionService.canConvert(String.class, Long.class)).willReturn(false);
106+
aclClassIdUtils.setConversionService(conversionService);
124107

125108
// when
126109
Serializable newIdentifier = aclClassIdUtils.identifierFrom(DEFAULT_IDENTIFIER_AS_STRING, resultSet);
@@ -145,10 +128,7 @@ public void shouldReturnLongWhenLongClassIdType() throws SQLException {
145128
public void shouldReturnUUIDWhenUUIDClassIdType() throws SQLException {
146129
// given
147130
UUID identifier = UUID.randomUUID();
148-
String identifierAsString = identifier.toString();
149131
given(resultSet.getString("class_id_type")).willReturn("java.util.UUID");
150-
given(conversionService.canConvert(String.class, UUID.class)).willReturn(true);
151-
given(conversionService.convert(identifierAsString, UUID.class)).willReturn(UUID.fromString(identifierAsString));
152132

153133
// when
154134
Serializable newIdentifier = aclClassIdUtils.identifierFrom(identifier.toString(), resultSet);
@@ -157,4 +137,28 @@ public void shouldReturnUUIDWhenUUIDClassIdType() throws SQLException {
157137
assertThat(newIdentifier).isEqualTo(identifier);
158138
}
159139

140+
@Test
141+
public void shouldReturnStringWhenStringClassIdType() throws SQLException {
142+
// given
143+
String identifier = "MY_STRING_IDENTIFIER";
144+
given(resultSet.getString("class_id_type")).willReturn("java.lang.String");
145+
146+
// when
147+
Serializable newIdentifier = aclClassIdUtils.identifierFrom(identifier, resultSet);
148+
149+
// then
150+
assertThat(newIdentifier).isEqualTo(identifier);
151+
}
152+
153+
@Test(expected = IllegalArgumentException.class)
154+
public void shouldNotAcceptNullConversionServiceInConstruction() throws SQLException {
155+
// when
156+
new AclClassIdUtils(null);
157+
}
158+
159+
@Test(expected = IllegalArgumentException.class)
160+
public void shouldNotAcceptNullConversionServiceInSetter() throws SQLException {
161+
// when
162+
aclClassIdUtils.setConversionService(null);
163+
}
160164
}

0 commit comments

Comments
 (0)