-
Notifications
You must be signed in to change notification settings - Fork 153
Expand file tree
/
Copy pathSpringResourceTemplateResource.java
More file actions
221 lines (166 loc) · 7.15 KB
/
SpringResourceTemplateResource.java
File metadata and controls
221 lines (166 loc) · 7.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/*
* =============================================================================
*
* Copyright (c) 2011-2018, The THYMELEAF team (http://www.thymeleaf.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* =============================================================================
*/
package org.thymeleaf.spring4.templateresource;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.Resource;
import org.thymeleaf.templateresource.ITemplateResource;
import org.thymeleaf.util.StringUtils;
import org.thymeleaf.util.Validate;
/**
* <p>
* Implementation of {@link ITemplateResource} that resolves
* resources by delegating on Spring's resource resolution mechanism, implemented by the
* {@link org.springframework.core.io.ResourceLoader} interface.
* </p>
* <p>
* This resource resolver accesses the Spring resource resolution mechanism by means of
* calls to {@link ApplicationContext#getResource(String)}.
* </p>
*
* @author Daniel Fernández
*
* @since 3.0.0
*
*/
public final class SpringResourceTemplateResource implements ITemplateResource {
private final Resource resource;
private final String characterEncoding;
public SpringResourceTemplateResource(
final ApplicationContext applicationContext, final String location, final String characterEncoding) {
super();
Validate.notNull(applicationContext, "Application Context cannot be null");
Validate.notEmpty(location, "Resource Location cannot be null or empty");
// Character encoding CAN be null (system default will be used)
this.resource = applicationContext.getResource(location);
this.characterEncoding = characterEncoding;
}
public SpringResourceTemplateResource(
final Resource resource, final String characterEncoding) {
super();
Validate.notNull(resource, "Resource cannot be null");
// Character encoding CAN be null (system default will be used)
this.resource = resource;
this.characterEncoding = characterEncoding;
}
public String getDescription() {
return this.resource.getDescription();
}
public String getBaseName() {
return computeBaseName(this.resource.getFilename());
}
public boolean exists() {
return this.resource.exists();
}
public Reader reader() throws IOException {
// Will never return null, but an IOException if not found
final InputStream inputStream = inputStream();
if (!StringUtils.isEmptyOrWhitespace(this.characterEncoding)) {
return new BufferedReader(new InputStreamReader(new BufferedInputStream(inputStream), this.characterEncoding));
}
return new BufferedReader(new InputStreamReader(new BufferedInputStream(inputStream)));
}
public InputStream inputStream() throws IOException {
// Will never return null, but an IOException if not found
return this.resource.getInputStream();
}
public ITemplateResource relative(final String relativeLocation) {
final Resource relativeResource;
try {
relativeResource = this.resource.createRelative(relativeLocation);
} catch (final IOException e) {
// Given we have delegated the createRelative(...) mechanism to Spring, it's better if we don't do
// any assumptions on what this IOException means and simply return a resource object that returns
// no reader and exists() == false.
return new SpringResourceInvalidRelativeTemplateResource(getDescription(), relativeLocation, e);
}
return new SpringResourceTemplateResource(relativeResource, this.characterEncoding);
}
static String computeBaseName(final String path) {
if (path == null || path.length() == 0) {
return null;
}
// First remove a trailing '/' if it exists
final String basePath = (path.charAt(path.length() - 1) == '/'? path.substring(0,path.length() - 1) : path);
final int slashPos = basePath.lastIndexOf('/');
if (slashPos != -1) {
final int dotPos = basePath.lastIndexOf('.');
if (dotPos != -1 && dotPos > slashPos + 1) {
return basePath.substring(slashPos + 1, dotPos);
}
return basePath.substring(slashPos + 1);
} else {
final int dotPos = basePath.lastIndexOf('.');
if (dotPos != -1) {
return basePath.substring(0, dotPos);
}
}
return (basePath.length() > 0? basePath : null);
}
private static final class SpringResourceInvalidRelativeTemplateResource implements ITemplateResource {
private final String originalResourceDescription;
private final String relativeLocation;
private final IOException ioException;
SpringResourceInvalidRelativeTemplateResource(
final String originalResourceDescription,
final String relativeLocation,
final IOException ioException) {
super();
this.originalResourceDescription = originalResourceDescription;
this.relativeLocation = relativeLocation;
this.ioException = ioException;
}
@Override
public String getDescription() {
return "Invalid relative resource for relative location \"" + this.relativeLocation +
"\" and original resource " + this.originalResourceDescription + ": " + this.ioException.getMessage();
}
@Override
public String getBaseName() {
return "Invalid relative resource for relative location \"" + this.relativeLocation +
"\" and original resource " + this.originalResourceDescription + ": " + this.ioException.getMessage();
}
@Override
public boolean exists() {
return false;
}
@Override
public Reader reader() throws IOException {
throw new IOException("Invalid relative resource", this.ioException);
}
@Override
public InputStream inputStream() throws IOException {
throw new IOException("Invalid relative resource", this.ioException);
}
@Override
public ITemplateResource relative(final String relativeLocation) {
return this;
}
@Override
public String toString() {
return getDescription();
}
}
}