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

Revision 4810, 5.6 KB checked in by bastiK, 4 months ago (diff)

move cache files to ~/.josm/cache (only CacheCustomContent)

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