source: josm/trunk/src/org/openstreetmap/josm/io/CacheCustomContent.java@ 7321

Last change on this file since 7321 was 7082, checked in by Don-vip, 10 years ago

see #8465 - replace Utils.UTF_8 by StandardCharsets.UTF_8, new in Java 7

  • Property svn:eol-style set to native
File size: 5.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import java.io.BufferedInputStream;
5import java.io.BufferedOutputStream;
6import java.io.File;
7import java.io.FileInputStream;
8import java.io.FileOutputStream;
9import java.io.IOException;
10import java.nio.charset.StandardCharsets;
11
12import org.openstreetmap.josm.Main;
13
14/**
15 * Use this class if you want to cache and store a single file that gets updated regularly.
16 * Unless you flush() it will be kept in memory. If you want to cache a lot of data and/or files,
17 * use CacheFiles
18 * @param <T> a {@link Throwable} that may be thrown during {@link #updateData()},
19 * use {@link RuntimeException} if no exception must be handled.
20 * @author xeen
21 *
22 */
23public abstract class CacheCustomContent<T extends Throwable> {
24 /**
25 * Common intervals
26 */
27 public static final int INTERVAL_ALWAYS = -1;
28 public static final int INTERVAL_HOURLY = 60*60;
29 public static final int INTERVAL_DAILY = INTERVAL_HOURLY * 24;
30 public static final int INTERVAL_WEEKLY = INTERVAL_DAILY * 7;
31 public static final int INTERVAL_MONTHLY = INTERVAL_WEEKLY * 4;
32 public static final int INTERVAL_NEVER = Integer.MAX_VALUE;
33
34 /**
35 * Where the data will be stored
36 */
37 private byte[] data = null;
38
39 /**
40 * The ident that identifies the stored file. Includes file-ending.
41 */
42 private final String ident;
43
44 /**
45 * The (file-)path where the data will be stored
46 */
47 private final File path;
48
49 /**
50 * How often to update the cached version
51 */
52 private final int updateInterval;
53
54 /**
55 * This function will be executed when an update is required. It has to be implemented by the
56 * inheriting class and should use a worker if it has a long wall time as the function is
57 * executed in the current thread.
58 * @return the data to cache
59 */
60 protected abstract byte[] updateData() throws T;
61
62 /**
63 * This function serves as a comfort hook to perform additional checks if the cache is valid
64 * @return True if the cached copy is still valid
65 */
66 protected boolean isCacheValid() {
67 return true;
68 }
69
70 /**
71 * Initializes the class. Note that all read data will be stored in memory until it is flushed
72 * by flushData().
73 * @param ident
74 * @param updateInterval
75 */
76 public CacheCustomContent(String ident, int updateInterval) {
77 this.ident = ident;
78 this.updateInterval = updateInterval;
79 this.path = new File(Main.pref.getCacheDirectory(), ident);
80 }
81
82 /**
83 * Updates data if required
84 * @return Returns the data
85 */
86 public byte[] updateIfRequired() throws T {
87 if (Main.pref.getInteger("cache." + ident, 0) + updateInterval < System.currentTimeMillis()/1000
88 || !isCacheValid())
89 return updateForce();
90 return getData();
91 }
92
93 /**
94 * Updates data if required
95 * @return Returns the data as string
96 */
97 public String updateIfRequiredString() throws T {
98 if (Main.pref.getInteger("cache." + ident, 0) + updateInterval < System.currentTimeMillis()/1000
99 || !isCacheValid())
100 return updateForceString();
101 return getDataString();
102 }
103
104 /**
105 * Executes an update regardless of updateInterval
106 * @return Returns the data
107 */
108 public byte[] updateForce() throws T {
109 this.data = updateData();
110 saveToDisk();
111 Main.pref.putInteger("cache." + ident, (int)(System.currentTimeMillis()/1000));
112 return data;
113 }
114
115 /**
116 * Executes an update regardless of updateInterval
117 * @return Returns the data as String
118 */
119 public String updateForceString() throws T {
120 updateForce();
121 return new String(data, StandardCharsets.UTF_8);
122 }
123
124 /**
125 * Returns the data without performing any updates
126 * @return the data
127 */
128 public byte[] getData() throws T {
129 if (data == null) {
130 loadFromDisk();
131 }
132 return data;
133 }
134
135 /**
136 * Returns the data without performing any updates
137 * @return the data as String
138 */
139 public String getDataString() throws T {
140 return new String(getData(), StandardCharsets.UTF_8);
141 }
142
143 /**
144 * Tries to load the data using the given ident from disk. If this fails, data will be updated
145 */
146 private void loadFromDisk() throws T {
147 try (BufferedInputStream input = new BufferedInputStream(new FileInputStream(path))) {
148 this.data = new byte[input.available()];
149 input.read(this.data);
150 } catch (IOException e) {
151 this.data = updateForce();
152 }
153 }
154
155 /**
156 * Stores the data to disk
157 */
158 private void saveToDisk() {
159 try (BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(path))) {
160 output.write(this.data);
161 output.flush();
162 } catch (IOException e) {
163 Main.error(e);
164 }
165 }
166
167 /**
168 * Flushes the data from memory. Class automatically reloads it from disk or updateData() if
169 * required
170 */
171 public void flushData() {
172 data = null;
173 }
174}
Note: See TracBrowser for help on using the repository browser.