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

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

fix some Sonar issues (JLS order)

  • Property svn:eol-style set to native
File size: 5.4 KB
RevLine 
[1450]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;
[2986]9import java.io.IOException;
[1450]10
11import org.openstreetmap.josm.Main;
[5874]12import org.openstreetmap.josm.tools.Utils;
[1450]13
[1610]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
[4709]18 * @param <T> a {@link Throwable} that may be thrown during {@link #updateData()},
19 * use {@link RuntimeException} if no exception must be handled.
[1610]20 * @author xeen
21 *
22 */
[4709]23public abstract class CacheCustomContent<T extends Throwable> {
[1450]24 /**
25 * Common intervals
26 */
[6889]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;
[1610]33
[1450]34 /**
[1610]35 * Where the data will be stored
[1450]36 */
37 private byte[] data = null;
[1610]38
[1450]39 /**
40 * The ident that identifies the stored file. Includes file-ending.
41 */
[6889]42 private final String ident;
[1610]43
[1450]44 /**
45 * The (file-)path where the data will be stored
46 */
[6889]47 private final File path;
[1610]48
[1450]49 /**
50 * How often to update the cached version
51 */
[6889]52 private final int updateInterval;
[1610]53
[1450]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 */
[4709]60 protected abstract byte[] updateData() throws T;
[1610]61
[1450]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;
[1610]68 }
69
[1450]70 /**
71 * Initializes the class. Note that all read data will be stored in memory until it is flushed
[1610]72 * by flushData().
[1450]73 * @param ident
74 * @param updateInterval
75 */
76 public CacheCustomContent(String ident, int updateInterval) {
77 this.ident = ident;
78 this.updateInterval = updateInterval;
[4810]79 this.path = new File(Main.pref.getCacheDirectory(), ident);
[1450]80 }
[1610]81
[1450]82 /**
83 * Updates data if required
84 * @return Returns the data
85 */
[4709]86 public byte[] updateIfRequired() throws T {
[6102]87 if (Main.pref.getInteger("cache." + ident, 0) + updateInterval < System.currentTimeMillis()/1000
[1450]88 || !isCacheValid())
89 return updateForce();
90 return getData();
91 }
[1610]92
[1450]93 /**
94 * Updates data if required
95 * @return Returns the data as string
96 */
[4709]97 public String updateIfRequiredString() throws T {
[6102]98 if (Main.pref.getInteger("cache." + ident, 0) + updateInterval < System.currentTimeMillis()/1000
[1450]99 || !isCacheValid())
100 return updateForceString();
101 return getDataString();
102 }
[1610]103
[1450]104 /**
105 * Executes an update regardless of updateInterval
106 * @return Returns the data
107 */
[4709]108 public byte[] updateForce() throws T {
[1450]109 this.data = updateData();
110 saveToDisk();
[6102]111 Main.pref.putInteger("cache." + ident, (int)(System.currentTimeMillis()/1000));
[1450]112 return data;
113 }
[1610]114
[1450]115 /**
116 * Executes an update regardless of updateInterval
117 * @return Returns the data as String
118 */
[4709]119 public String updateForceString() throws T {
[1450]120 updateForce();
[6552]121 return new String(data, Utils.UTF_8);
[1450]122 }
123
124 /**
125 * Returns the data without performing any updates
126 * @return the data
127 */
[4709]128 public byte[] getData() throws T {
[4810]129 if (data == null) {
[1450]130 loadFromDisk();
[2986]131 }
[1450]132 return data;
133 }
[1610]134
[1450]135 /**
136 * Returns the data without performing any updates
137 * @return the data as String
138 */
[4709]139 public String getDataString() throws T {
[6552]140 return new String(getData(), Utils.UTF_8);
[1450]141 }
142
143 /**
[1610]144 * Tries to load the data using the given ident from disk. If this fails, data will be updated
[1450]145 */
[4709]146 private void loadFromDisk() throws T {
[4810]147 if (Main.applet)
[1450]148 this.data = updateForce();
[3947]149 else {
[5874]150 BufferedInputStream input = null;
[3947]151 try {
[5874]152 input = new BufferedInputStream(new FileInputStream(path));
[3947]153 this.data = new byte[input.available()];
154 input.read(this.data);
[4810]155 } catch (IOException e) {
[3947]156 this.data = updateForce();
[5874]157 } finally {
158 Utils.close(input);
[3947]159 }
[1450]160 }
161 }
[1610]162
[1450]163 /**
164 * Stores the data to disk
165 */
166 private void saveToDisk() {
[4810]167 if (Main.applet)
[3947]168 return;
[5874]169 BufferedOutputStream output = null;
[1450]170 try {
[5874]171 output = new BufferedOutputStream(new FileOutputStream(path));
[1450]172 output.write(this.data);
173 output.flush();
[2986]174 } catch(Exception e) {
[6643]175 Main.error(e);
[5874]176 } finally {
177 Utils.close(output);
[2986]178 }
[1610]179 }
180
[1450]181 /**
182 * Flushes the data from memory. Class automatically reloads it from disk or updateData() if
183 * required
184 */
185 public void flushData() {
186 data = null;
187 }
188}
Note: See TracBrowser for help on using the repository browser.