Skip to content

Package: CachedURIResolver

CachedURIResolver

nameinstructionbranchcomplexitylinemethod
CachedURIResolver()
M: 17 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
cacheDocument(File, String)
M: 63 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 17 C: 0
0%
M: 1 C: 0
0%
getCacheFolderPath()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getConnectionTimeout()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getExpirationTime()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getReadTimeout()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
mkdirs(File)
M: 10 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
rename(File, File)
M: 12 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
resolve(String, String)
M: 60 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 12 C: 0
0%
M: 1 C: 0
0%
setCacheFolderPath(String)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
setConnectionTimeout(int)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
setExpirationTime(long)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
setReadTimeout(int)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * #%L
3: * *********************************************************************************************************************
4: *
5: * NorthernWind - lightweight CMS
6: * http://northernwind.tidalwave.it - git clone https://bitbucket.org/tidalwave/northernwind-src.git
7: * %%
8: * Copyright (C) 2011 - 2023 Tidalwave s.a.s. (http://tidalwave.it)
9: * %%
10: * *********************************************************************************************************************
11: *
12: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
13: * the License. You may obtain a copy of the License at
14: *
15: * http://www.apache.org/licenses/LICENSE-2.0
16: *
17: * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
18: * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
19: * specific language governing permissions and limitations under the License.
20: *
21: * *********************************************************************************************************************
22: *
23: *
24: * *********************************************************************************************************************
25: * #L%
26: */
27: package it.tidalwave.northernwind.core.impl.util;
28:
29: import javax.annotation.Nonnull;
30: import java.io.File;
31: import java.io.FileInputStream;
32: import java.io.IOException;
33: import java.io.RandomAccessFile;
34: import java.net.URL;
35: import javax.xml.transform.Source;
36: import javax.xml.transform.TransformerException;
37: import javax.xml.transform.URIResolver;
38: import javax.xml.transform.stream.StreamSource;
39: import org.apache.commons.io.FileUtils;
40: import lombok.Getter;
41: import lombok.Setter;
42: import lombok.extern.slf4j.Slf4j;
43: import static it.tidalwave.northernwind.util.UrlEncoding.encodedUtf8;
44:
45: /***********************************************************************************************************************
46: *
47: * @author Fabrizio Giudici
48: *
49: **********************************************************************************************************************/
50: @Slf4j
51: public class CachedURIResolver implements URIResolver
52: {
53: @Getter @Setter
54: private String cacheFolderPath = System.getProperty("java.io.tmpdir") + "/CachedURIResolver";
55:
56: @Getter @Setter
57: private long expirationTime = 60 * 60 * 1000L; // 1 hour
58:
59: @Getter @Setter
60: private int connectionTimeout = 10 * 1000; // 10 secs
61:
62: @Getter @Setter
63: private int readTimeout = 10 * 1000; // 10 secs
64:
65: /*******************************************************************************************************************
66: *
67: ******************************************************************************************************************/
68: @Override
69: public Source resolve (final String href, final String base)
70: throws TransformerException
71: {
72: try
73: {
74: log.info("resolve({}, {})", href, base);
75:
76: final var cacheFolder = new File(cacheFolderPath);
77:
78:• if (!cacheFolder.exists())
79: {
80: mkdirs(cacheFolder);
81: }
82:
83: final var cachedFile = new File(cacheFolder, encodedUtf8(href));
84: final var elapsed = System.currentTimeMillis() - cachedFile.lastModified();
85:
86: log.debug(">>>> cached file is {} elapsed time is {} msec", cachedFile, elapsed);
87:
88:• if (!cachedFile.exists() || (elapsed > expirationTime))
89: {
90: cacheDocument(cachedFile, href);
91: }
92:
93: return new StreamSource(new FileInputStream(cachedFile));
94: }
95: catch (IOException e)
96: {
97: throw new TransformerException(e);
98: }
99: }
100:
101: /*******************************************************************************************************************
102: *
103: ******************************************************************************************************************/
104: private void cacheDocument (@Nonnull final File cachedFile, @Nonnull final String href)
105: throws IOException
106: {
107: log.debug(">>>> caching external document to {}", cachedFile);
108: final var tempFile = File.createTempFile("temp", ".txt", new File(cacheFolderPath));
109: tempFile.deleteOnExit();
110: log.debug(">>>> waiting for lock...");
111:
112: try (final var channel = new RandomAccessFile(tempFile, "rw").getChannel();
113: final var lock = channel.lock())
114: {
115: log.debug(">>>> got lock: {}", lock);
116: FileUtils.copyURLToFile(new URL(href), tempFile, connectionTimeout, readTimeout);
117: rename(tempFile, cachedFile);
118: }
119: catch (IOException e)
120: {
121:• if (cachedFile.exists())
122: {
123: log.warn("Error while retrieving document from {}: {} - using previously cached file",
124: href, e.toString());
125: }
126: else
127: {
128: throw e;
129: }
130: }
131:
132: log.debug(">>>> done");
133: }
134:
135: /*******************************************************************************************************************
136: *
137: ******************************************************************************************************************/
138: private static void mkdirs (@Nonnull final File folder)
139: throws IOException
140: {
141:• if (!folder.mkdirs())
142: {
143: throw new IOException("Cannot mkdirs for " + folder);
144: }
145: }
146:
147: /*******************************************************************************************************************
148: *
149: ******************************************************************************************************************/
150: private static void rename (@Nonnull final File from, @Nonnull final File to)
151: throws IOException
152: {
153:• if (!from.renameTo(to))
154: {
155: throw new IOException("Cannot rename " + from + " to " + to);
156: }
157: }
158: }