1
1
/*
2
- * Copyright 2002-2018 the original author or authors.
2
+ * Copyright 2002-2020 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
@@ -56,7 +56,8 @@ public class UrlResource extends AbstractFileResolvingResource {
56
56
/**
57
57
* Cleaned URL (with normalized path), used for comparisons.
58
58
*/
59
- private final URL cleanedUrl ;
59
+ @ Nullable
60
+ private volatile URL cleanedUrl ;
60
61
61
62
62
63
/**
@@ -69,7 +70,6 @@ public UrlResource(URI uri) throws MalformedURLException {
69
70
Assert .notNull (uri , "URI must not be null" );
70
71
this .uri = uri ;
71
72
this .url = uri .toURL ();
72
- this .cleanedUrl = getCleanedUrl (this .url , uri .toString ());
73
73
}
74
74
75
75
/**
@@ -78,9 +78,8 @@ public UrlResource(URI uri) throws MalformedURLException {
78
78
*/
79
79
public UrlResource (URL url ) {
80
80
Assert .notNull (url , "URL must not be null" );
81
- this .url = url ;
82
- this .cleanedUrl = getCleanedUrl (this .url , url .toString ());
83
81
this .uri = null ;
82
+ this .url = url ;
84
83
}
85
84
86
85
/**
@@ -127,7 +126,6 @@ public UrlResource(String protocol, String location, @Nullable String fragment)
127
126
try {
128
127
this .uri = new URI (protocol , location , fragment );
129
128
this .url = this .uri .toURL ();
130
- this .cleanedUrl = getCleanedUrl (this .url , this .uri .toString ());
131
129
}
132
130
catch (URISyntaxException ex ) {
133
131
MalformedURLException exToThrow = new MalformedURLException (ex .getMessage ());
@@ -144,7 +142,7 @@ public UrlResource(String protocol, String location, @Nullable String fragment)
144
142
* @return the cleaned URL (possibly the original URL as-is)
145
143
* @see org.springframework.util.StringUtils#cleanPath
146
144
*/
147
- private URL getCleanedUrl (URL originalUrl , String originalPath ) {
145
+ private static URL getCleanedUrl (URL originalUrl , String originalPath ) {
148
146
String cleanedPath = StringUtils .cleanPath (originalPath );
149
147
if (!cleanedPath .equals (originalPath )) {
150
148
try {
@@ -157,6 +155,21 @@ private URL getCleanedUrl(URL originalUrl, String originalPath) {
157
155
return originalUrl ;
158
156
}
159
157
158
+ /**
159
+ * Lazily determine a cleaned URL for the given original URL.
160
+ * @see #getCleanedUrl(URL, String)
161
+ */
162
+ private URL getCleanedUrl () {
163
+ URL cleanedUrl = this .cleanedUrl ;
164
+ if (cleanedUrl != null ) {
165
+ return cleanedUrl ;
166
+ }
167
+ cleanedUrl = getCleanedUrl (this .url , (this .uri != null ? this .uri : this .url ).toString ());
168
+ this .cleanedUrl = cleanedUrl ;
169
+ return cleanedUrl ;
170
+ }
171
+
172
+
160
173
/**
161
174
* This implementation opens an InputStream for the given URL.
162
175
* <p>It sets the {@code useCaches} flag to {@code false},
@@ -247,7 +260,7 @@ public Resource createRelative(String relativePath) throws MalformedURLException
247
260
*/
248
261
@ Override
249
262
public String getFilename () {
250
- return StringUtils .getFilename (this . cleanedUrl .getPath ());
263
+ return StringUtils .getFilename (getCleanedUrl () .getPath ());
251
264
}
252
265
253
266
/**
@@ -265,15 +278,15 @@ public String getDescription() {
265
278
@ Override
266
279
public boolean equals (Object other ) {
267
280
return (this == other || (other instanceof UrlResource &&
268
- this . cleanedUrl . equals (((UrlResource ) other ).cleanedUrl )));
281
+ getCleanedUrl (). equals (((UrlResource ) other ).getCleanedUrl () )));
269
282
}
270
283
271
284
/**
272
285
* This implementation returns the hash code of the underlying URL reference.
273
286
*/
274
287
@ Override
275
288
public int hashCode () {
276
- return this . cleanedUrl .hashCode ();
289
+ return getCleanedUrl () .hashCode ();
277
290
}
278
291
279
292
}
0 commit comments