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