5
5
* The ASF licenses this file to You under the Apache License, Version 2.0
6
6
* (the "License"); you may not use this file except in compliance with
7
7
* the License. You may obtain a copy of the License at
9
9
* http://www.apache.org/licenses/LICENSE-2.0
11
11
* Unless required by applicable law or agreed to in writing, software
12
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
15
* limitations under the License.
18
/* $Id: AbstractImageSessionContext.java 662487 2008-06-02 16:54:59Z jeremias $ */
18
/* $Id: AbstractImageSessionContext.java 828814 2009-10-22 18:52:33Z jeremias $ */
20
20
package org.apache.xmlgraphics.image.loader.impl;
22
22
import java.io.File;
23
23
import java.io.FileNotFoundException;
24
24
import java.io.IOException;
25
25
import java.io.InputStream;
26
import java.lang.reflect.InvocationHandler;
27
import java.lang.reflect.Method;
28
import java.lang.reflect.Proxy;
26
29
import java.net.MalformedURLException;
27
30
import java.net.URL;
52
55
private static Log log = LogFactory.getLog(AbstractImageSessionContext.class);
54
57
private static boolean noSourceReuse = false;
57
60
//TODO Temporary measure to track down a problem
58
61
//See: http://markmail.org/message/k6mno3jsxmovaz2e
60
63
AbstractImageSessionContext.class.getName() + ".no-source-reuse");
61
64
noSourceReuse = Boolean.valueOf(v).booleanValue();
65
68
* Attempts to resolve the given URI.
66
69
* @param uri URI to access
67
70
* @return A {@link javax.xml.transform.Source} object, or null if the URI
70
73
protected abstract Source resolveURI(String uri);
82
85
//Return any non-stream Sources and let the ImageLoaders deal with them
86
89
ImageSource imageSource = null;
88
91
String resolvedURI = source.getSystemId();
91
94
url = new URL(resolvedURI);
92
95
} catch (MalformedURLException e) {
95
98
File f = /*FileUtils.*/toFile(url);
97
100
boolean directFileAccess = true;
125
128
if (directFileAccess) {
126
129
//Close as the file is reopened in a more optimal way
127
130
IOUtils.closeQuietly(in);
129
//We let the OS' file system cache do the caching for us
130
//--> lower Java memory consumption, probably no speed loss
131
imageSource = new ImageSource(ImageIO.createImageInputStream(f),
132
// We let the OS' file system cache do the caching for us
133
// --> lower Java memory consumption, probably no speed loss
134
final ImageInputStream newInputStream = ImageIO
135
.createImageInputStream(f);
136
if (newInputStream == null) {
137
log.error("Unable to create ImageInputStream for local file "
139
+ " from system identifier '"
140
+ source.getSystemId() + "'");
143
imageSource = new ImageSource(newInputStream,
133
146
} catch (IOException ioe) {
134
147
log.error("Unable to create ImageInputStream for local file"
135
148
+ " from system identifier '"
163
176
//Buffer and uncompress if necessary
164
177
in = ImageUtil.autoDecorateInputStream(in);
165
178
imageSource = new ImageSource(
166
ImageIO.createImageInputStream(in), source.getSystemId(), false);
179
createImageInputStream(in), source.getSystemId(), false);
167
180
} catch (IOException ioe) {
168
181
log.error("Unable to create ImageInputStream for InputStream"
169
182
+ " from system identifier '"
173
186
return imageSource;
189
protected ImageInputStream createImageInputStream(InputStream in) throws IOException {
190
ImageInputStream iin = ImageIO.createImageInputStream(in);
191
return (ImageInputStream)Proxy.newProxyInstance(
192
ImageInputStream.class.getClassLoader(),
193
new Class[] {ImageInputStream.class},
194
new ObservingImageInputStreamInvocationHandler(iin, in));
197
private static class ObservingImageInputStreamInvocationHandler
198
implements InvocationHandler {
200
private ImageInputStream iin;
201
private InputStream in;
203
public ObservingImageInputStreamInvocationHandler(ImageInputStream iin,
204
InputStream underlyingStream) {
206
this.in = underlyingStream;
210
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
211
if ("close".equals(method.getName())) {
213
return method.invoke(iin, args);
215
IOUtils.closeQuietly(this.in);
219
return method.invoke(iin, args);
177
226
* Convert from a <code>URL</code> to a <code>File</code>.
192
241
if (url == null || !url.getProtocol().equals("file")) {
195
String filename = "";
196
if (url.getHost() != null) {
197
filename += Character.toString(File.separatorChar)
198
+ Character.toString(File.separatorChar)
201
filename += url.getFile().replace('/', File.separatorChar);
203
while ((pos = filename.indexOf('%', pos)) >= 0) {
204
if (pos + 2 < filename.length()) {
205
String hexStr = filename.substring(pos + 1, pos + 3);
206
char ch = (char) Integer.parseInt(hexStr, 16);
207
filename = filename.substring(0, pos) + ch + filename.substring(pos + 3);
210
return new File(filename);
245
String filename = "";
246
if (url.getHost() != null && url.getHost().length() > 0) {
247
filename += Character.toString(File.separatorChar)
248
+ Character.toString(File.separatorChar)
251
filename += url.getFile().replace('/', File.separatorChar);
252
filename = java.net.URLDecoder.decode(filename, "UTF-8");
253
final File f = new File(filename);
258
} catch (java.io.UnsupportedEncodingException uee) {
214
265
private SoftMapCache sessionSources = new SoftMapCache(false); //no need for synchronization
216
267
/** {@inheritDoc} */
217
268
public Source getSource(String uri) {
218
269
return (Source)sessionSources.remove(uri);
221
272
/** {@inheritDoc} */
222
273
public Source needSource(String uri) throws FileNotFoundException {
223
274
Source src = getSource(uri);
224
275
if (src == null) {
225
276
if (log.isDebugEnabled()) {
226
277
log.debug("Creating new Source for " + uri);
229
280
src = newSource(uri);
230
281
if (src == null) {