source: josm/trunk/src/org/openstreetmap/josm/data/cache/CacheEntryAttributes.java@ 14271

Last change on this file since 14271 was 14271, checked in by wiktorn, 6 years ago

Fix checkstyle / PMD

  • Property svn:eol-style set to native
File size: 6.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.cache;
3
4import java.util.Arrays;
5import java.util.Collections;
6import java.util.HashSet;
7import java.util.Map;
8import java.util.Map.Entry;
9import java.util.Optional;
10import java.util.Set;
11import java.util.concurrent.ConcurrentHashMap;
12
13import org.apache.commons.jcs.engine.ElementAttributes;
14import org.openstreetmap.josm.tools.Logging;
15
16/**
17 * Class that contains attributes for JCS cache entries. Parameters are used to properly handle HTTP caching,
18 * and metadata structures, that should be stored together with the cache entry
19 *
20 * @author Wiktor Niesiobędzki
21 * @since 8168
22 */
23public class CacheEntryAttributes extends ElementAttributes {
24 private static final long serialVersionUID = 1L; //version
25 private final Map<String, String> attrs = new ConcurrentHashMap<>(RESERVED_KEYS.size());
26 private static final String NO_TILE_AT_ZOOM = "noTileAtZoom";
27 private static final String ETAG = "Etag";
28 private static final String LAST_MODIFICATION = "lastModification";
29 private static final String EXPIRATION_TIME = "expirationTime";
30 private static final String HTTP_RESPONSE_CODE = "httpResponseCode";
31 private static final String ERROR_MESSAGE = "errorMessage";
32 private static final String EXCEPTION = "exception";
33 // this contains all of the above
34 private static final Set<String> RESERVED_KEYS = new HashSet<>(Arrays.asList(
35 NO_TILE_AT_ZOOM,
36 ETAG,
37 LAST_MODIFICATION,
38 EXPIRATION_TIME,
39 HTTP_RESPONSE_CODE,
40 ERROR_MESSAGE,
41 EXCEPTION
42 ));
43
44 /**
45 * Constructs a new {@code CacheEntryAttributes}.
46 */
47 public CacheEntryAttributes() {
48 super();
49 attrs.put(NO_TILE_AT_ZOOM, "false");
50 attrs.put(LAST_MODIFICATION, "0");
51 attrs.put(EXPIRATION_TIME, "0");
52 attrs.put(HTTP_RESPONSE_CODE, "200");
53 }
54
55 /**
56 * @return if the entry is marked as "no tile at this zoom level"
57 */
58 public boolean isNoTileAtZoom() {
59 return Boolean.toString(true).equals(attrs.get(NO_TILE_AT_ZOOM));
60 }
61
62 /**
63 * Sets the marker for "no tile at this zoom level"
64 * @param noTileAtZoom true if this entry is "no tile at this zoom level"
65 */
66 public void setNoTileAtZoom(boolean noTileAtZoom) {
67 attrs.put(NO_TILE_AT_ZOOM, Boolean.toString(noTileAtZoom));
68 }
69
70 /**
71 * @return ETag header value, that was returned for this entry.
72 */
73 public String getEtag() {
74 return attrs.get(ETAG);
75 }
76
77 /**
78 * Sets the ETag header that was set with this entry
79 * @param etag Etag header
80 */
81 public void setEtag(String etag) {
82 if (etag != null) {
83 attrs.put(ETAG, etag);
84 }
85 }
86
87 /**
88 * Utility for conversion from String to int, with default to 0, in case of any errors
89 *
90 * @param key - integer as string
91 * @return int value of the string
92 */
93 private long getLongAttr(String key) {
94 try {
95 return Long.parseLong(attrs.computeIfAbsent(key, k -> "0"));
96 } catch (NumberFormatException e) {
97 attrs.put(key, "0");
98 return 0;
99 }
100 }
101
102 /**
103 * @return last modification of the object in cache in milliseconds from Epoch
104 */
105 public long getLastModification() {
106 return getLongAttr(LAST_MODIFICATION);
107 }
108
109 /**
110 * sets last modification of the object in cache
111 *
112 * @param lastModification time in format of milliseconds from Epoch
113 */
114 public void setLastModification(long lastModification) {
115 attrs.put(LAST_MODIFICATION, Long.toString(lastModification));
116 }
117
118 /**
119 * @return when the object expires in milliseconds from Epoch
120 */
121 public long getExpirationTime() {
122 return getLongAttr(EXPIRATION_TIME);
123 }
124
125 /**
126 * sets expiration time for the object in cache
127 *
128 * @param expirationTime in format of milliseconds from epoch
129 */
130 public void setExpirationTime(long expirationTime) {
131 attrs.put(EXPIRATION_TIME, Long.toString(expirationTime));
132 }
133
134 /**
135 * Sets the HTTP response code that was sent with the cache entry
136 *
137 * @param responseCode http status code
138 * @since 8389
139 */
140 public void setResponseCode(int responseCode) {
141 attrs.put(HTTP_RESPONSE_CODE, Integer.toString(responseCode));
142 }
143
144 /**
145 * @return http status code
146 * @since 8389
147 */
148 public int getResponseCode() {
149 return (int) getLongAttr(HTTP_RESPONSE_CODE);
150 }
151
152 /**
153 * Sets the metadata about cache entry. As it stores all data together, with other attributes
154 * in common map, some keys might not be stored.
155 *
156 * @param map metadata to save
157 * @since 8418
158 */
159 public void setMetadata(Map<String, String> map) {
160 for (Entry<String, String> e: map.entrySet()) {
161 if (RESERVED_KEYS.contains(e.getKey())) {
162 Logging.info("Metadata key configuration contains key {0} which is reserved for internal use");
163 } else {
164 attrs.put(e.getKey(), e.getValue());
165 }
166 }
167 }
168
169 /**
170 * Returns an unmodifiable Map containing all metadata. Unmodifiable prevents access to metadata within attributes.
171 *
172 * @return unmodifiable Map with cache element metadata
173 * @since 8418
174 */
175 public Map<String, String> getMetadata() {
176 return Collections.unmodifiableMap(attrs);
177 }
178
179 /**
180 * @return error message returned while retrieving this object
181 */
182 public String getErrorMessage() {
183 return attrs.get(ERROR_MESSAGE);
184 }
185
186 /**
187 * @param error error related to this object
188 * @since 10469
189 */
190 public void setError(Exception error) {
191 setErrorMessage(Logging.getErrorMessage(error));
192 }
193
194 /**
195 * @param message error message related to this object
196 */
197 public void setErrorMessage(String message) {
198 attrs.put(ERROR_MESSAGE, message);
199 }
200
201 /**
202 * @param e exception that caused error
203 *
204 */
205 public void setException(Exception e) {
206 attrs.put(EXCEPTION, e.getClass().getCanonicalName());
207 }
208
209 /**
210 * @return Optional exception that was thrown when fetching resource
211 *
212 */
213 public Optional<Class<? extends Exception>> getException() {
214 String className = attrs.get(EXCEPTION);
215 if (className == null) {
216 return Optional.empty();
217 }
218 try {
219 Class<?> klass = Class.forName(className);
220 if (Exception.class.isAssignableFrom(klass)) {
221 return Optional.of(klass.asSubclass(Exception.class));
222 }
223 } catch (ClassNotFoundException | ClassCastException ex) {
224 Logging.trace(ex);
225 }
226 return Optional.empty();
227 }
228}
Note: See TracBrowser for help on using the repository browser.