Skip to content

Commit 1f9bc50

Browse files
committed
Include charset in EncodedResource.equals()
Prior to this commit, the implementation of equals() in EncodedResource was based solely on the resource and encoding. Thus, if a Charset were specified instead of an encoding, invocations of equals() would not work as expected. This commit addresses this issue by including the charset in the implementation of equals() and introducing corresponding tests in a new EncodedResourceTests class. Furthermore, this commit makes EncodedResource immutable and updates all Javadoc to reflect support for the encoding and charset properties. Issue: SPR-12767 (cherry picked from commit 93c70b7)
1 parent 2d3fe96 commit 1f9bc50

File tree

2 files changed

+126
-35
lines changed

2 files changed

+126
-35
lines changed

spring-core/src/main/java/org/springframework/core/io/support/EncodedResource.java

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2015 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.
@@ -27,87 +27,91 @@
2727
import org.springframework.util.ObjectUtils;
2828

2929
/**
30-
* Holder that combines a {@link org.springframework.core.io.Resource}
31-
* with a specific encoding to be used for reading from the resource.
30+
* Holder that combines a {@link Resource} descriptor with a specific encoding
31+
* or {@code Charset} to be used for reading from the resource.
3232
*
33-
* <p>Used as argument for operations that support to read content with
34-
* a specific encoding (usually through a {@code java.io.Reader}.
33+
* <p>Used as an argument for operations that support reading content with
34+
* a specific encoding, typically via a {@code java.io.Reader}.
3535
*
3636
* @author Juergen Hoeller
37+
* @author Sam Brannen
3738
* @since 1.2.6
3839
* @see java.io.Reader
40+
* @see java.nio.charset.Charset
3941
*/
4042
public class EncodedResource {
4143

4244
private final Resource resource;
4345

44-
private String encoding;
46+
private final String encoding;
4547

46-
private Charset charset;
48+
private final Charset charset;
4749

4850

4951
/**
50-
* Create a new EncodedResource for the given Resource,
51-
* not specifying a specific encoding.
52-
* @param resource the Resource to hold
52+
* Create a new {@code EncodedResource} for the given {@code Resource},
53+
* not specifying an explicit encoding or {@code Charset}.
54+
* @param resource the {@code Resource} to hold; never {@code null}
5355
*/
5456
public EncodedResource(Resource resource) {
55-
Assert.notNull(resource, "Resource must not be null");
56-
this.resource = resource;
57+
this(resource, null, null);
5758
}
5859

5960
/**
60-
* Create a new EncodedResource for the given Resource,
61-
* using the specified encoding.
62-
* @param resource the Resource to hold
61+
* Create a new {@code EncodedResource} for the given {@code Resource},
62+
* using the specified {@code encoding}.
63+
* @param resource the {@code Resource} to hold; never {@code null}
6364
* @param encoding the encoding to use for reading from the resource
6465
*/
6566
public EncodedResource(Resource resource, String encoding) {
66-
Assert.notNull(resource, "Resource must not be null");
67-
this.resource = resource;
68-
this.encoding = encoding;
67+
this(resource, encoding, null);
6968
}
7069

7170
/**
72-
* Create a new EncodedResource for the given Resource,
73-
* using the specified encoding.
74-
* @param resource the Resource to hold
75-
* @param charset the charset to use for reading from the resource
71+
* Create a new {@code EncodedResource} for the given {@code Resource},
72+
* using the specified {@code Charset}.
73+
* @param resource the {@code Resource} to hold; never {@code null}
74+
* @param charset the {@code Charset} to use for reading from the resource
7675
*/
7776
public EncodedResource(Resource resource, Charset charset) {
77+
this(resource, null, charset);
78+
}
79+
80+
private EncodedResource(Resource resource, String encoding, Charset charset) {
81+
super();
7882
Assert.notNull(resource, "Resource must not be null");
7983
this.resource = resource;
84+
this.encoding = encoding;
8085
this.charset = charset;
8186
}
8287

83-
8488
/**
85-
* Return the Resource held.
89+
* Return the {@code Resource} held by this {@code EncodedResource}.
8690
*/
8791
public final Resource getResource() {
8892
return this.resource;
8993
}
9094

9195
/**
92-
* Return the encoding to use for reading from the resource,
96+
* Return the encoding to use for reading from the {@linkplain #getResource() resource},
9397
* or {@code null} if none specified.
9498
*/
9599
public final String getEncoding() {
96100
return this.encoding;
97101
}
98102

99103
/**
100-
* Return the charset to use for reading from the resource,
104+
* Return the {@code Charset} to use for reading from the {@linkplain #getResource() resource},
101105
* or {@code null} if none specified.
102106
*/
103107
public final Charset getCharset() {
104108
return this.charset;
105109
}
106110

107-
108111
/**
109112
* Determine whether a {@link Reader} is required as opposed to an {@link InputStream},
110-
* i.e. whether an encoding or a charset has been specified.
113+
* i.e. whether an {@linkplain #getEncoding() encoding} or a {@link #getCharset() Charset}
114+
* has been specified.
111115
* @see #getReader()
112116
* @see #getInputStream()
113117
*/
@@ -116,10 +120,12 @@ public boolean requiresReader() {
116120
}
117121

118122
/**
119-
* Open a {@code java.io.Reader} for the specified resource,
120-
* using the specified encoding (if any).
123+
* Open a {@code java.io.Reader} for the specified resource, using the specified
124+
* {@link #getCharset() Charset} or {@linkplain #getEncoding() encoding}
125+
* (if any).
121126
* @throws IOException if opening the Reader failed
122127
* @see #requiresReader()
128+
* @see #getInputStream()
123129
*/
124130
public Reader getReader() throws IOException {
125131
if (this.charset != null) {
@@ -134,10 +140,11 @@ else if (this.encoding != null) {
134140
}
135141

136142
/**
137-
* Open an {@code java.io.InputStream} for the specified resource,
138-
* typically assuming that there is no specific encoding to use.
143+
* Open a {@code java.io.InputStream} for the specified resource, ignoring any
144+
* specified {@link #getCharset() Charset} or {@linkplain #getEncoding() encoding}.
139145
* @throws IOException if opening the InputStream failed
140146
* @see #requiresReader()
147+
* @see #getReader()
141148
*/
142149
public InputStream getInputStream() throws IOException {
143150
return this.resource.getInputStream();
@@ -150,9 +157,10 @@ public boolean equals(Object obj) {
150157
return true;
151158
}
152159
if (obj instanceof EncodedResource) {
153-
EncodedResource otherRes = (EncodedResource) obj;
154-
return (this.resource.equals(otherRes.resource) &&
155-
ObjectUtils.nullSafeEquals(this.encoding, otherRes.encoding));
160+
EncodedResource that = (EncodedResource) obj;
161+
return (this.resource.equals(that.resource) &&
162+
ObjectUtils.nullSafeEquals(this.charset, that.charset) &&
163+
ObjectUtils.nullSafeEquals(this.encoding, that.encoding));
156164
}
157165
return false;
158166
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright 2002-2015 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.core.io.support;
18+
19+
import java.nio.charset.Charset;
20+
21+
import org.junit.Test;
22+
import org.springframework.core.io.DescriptiveResource;
23+
import org.springframework.core.io.Resource;
24+
25+
import static org.junit.Assert.*;
26+
27+
/**
28+
* Unit tests for {@link EncodedResource}.
29+
*
30+
* @author Sam Brannen
31+
* @since 3.2.14
32+
*/
33+
public class EncodedResourceTests {
34+
35+
private static final String UTF8 = "UTF-8";
36+
private static final String UTF16 = "UTF-16";
37+
private static final Charset UTF8_CS = Charset.forName(UTF8);
38+
private static final Charset UTF16_CS = Charset.forName(UTF16);
39+
40+
private final Resource resource = new DescriptiveResource("test");
41+
42+
43+
@Test
44+
public void equalsWithNullOtherObject() {
45+
assertFalse(new EncodedResource(resource).equals(null));
46+
}
47+
48+
@Test
49+
public void equalsWithSameEncoding() {
50+
EncodedResource er1 = new EncodedResource(resource, UTF8);
51+
EncodedResource er2 = new EncodedResource(resource, UTF8);
52+
assertEquals(er1, er2);
53+
}
54+
55+
@Test
56+
public void equalsWithDifferentEncoding() {
57+
EncodedResource er1 = new EncodedResource(resource, UTF8);
58+
EncodedResource er2 = new EncodedResource(resource, UTF16);
59+
assertNotEquals(er1, er2);
60+
}
61+
62+
@Test
63+
public void equalsWithSameCharset() {
64+
EncodedResource er1 = new EncodedResource(resource, UTF8_CS);
65+
EncodedResource er2 = new EncodedResource(resource, UTF8_CS);
66+
assertEquals(er1, er2);
67+
}
68+
69+
@Test
70+
public void equalsWithDifferentCharset() {
71+
EncodedResource er1 = new EncodedResource(resource, UTF8_CS);
72+
EncodedResource er2 = new EncodedResource(resource, UTF16_CS);
73+
assertNotEquals(er1, er2);
74+
}
75+
76+
@Test
77+
public void equalsWithEncodingAndCharset() {
78+
EncodedResource er1 = new EncodedResource(resource, UTF8);
79+
EncodedResource er2 = new EncodedResource(resource, UTF8_CS);
80+
assertNotEquals(er1, er2);
81+
}
82+
83+
}

0 commit comments

Comments
 (0)