diff options
Diffstat (limited to 'main/src/cgeo/geocaching/files/LocalStorage.java')
| -rw-r--r-- | main/src/cgeo/geocaching/files/LocalStorage.java | 93 |
1 files changed, 71 insertions, 22 deletions
diff --git a/main/src/cgeo/geocaching/files/LocalStorage.java b/main/src/cgeo/geocaching/files/LocalStorage.java index b5fa5f6..6853c08 100644 --- a/main/src/cgeo/geocaching/files/LocalStorage.java +++ b/main/src/cgeo/geocaching/files/LocalStorage.java @@ -1,18 +1,20 @@ package cgeo.geocaching.files; -import cgeo.geocaching.Settings; import cgeo.geocaching.utils.CryptUtils; +import cgeo.geocaching.utils.Log; import org.apache.commons.lang3.StringUtils; +import org.apache.http.Header; import org.apache.http.HttpResponse; import android.os.Environment; -import android.util.Log; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -59,12 +61,7 @@ public class LocalStorage { */ static String getExtension(final String url) { final String urlExt = StringUtils.substringAfterLast(url, "."); - if (urlExt.length() > 4) { - return ""; - } else if (urlExt.length() > 0) { - return "." + urlExt; - } - return ""; + return urlExt.length() >= 1 && urlExt.length() <= 4 ? "." + urlExt : ""; } /** @@ -143,7 +140,7 @@ public class LocalStorage { * the entity whose content will be saved * @param targetFile * the target file, which will be created if necessary - * @return true if the operation was successful, false otherwise + * @return true if the operation was successful, false otherwise, in which case the file will not exist */ public static boolean saveEntityToFile(final HttpResponse response, final File targetFile) { if (response == null) { @@ -151,16 +148,65 @@ public class LocalStorage { } try { - return saveToFile(response.getEntity().getContent(), targetFile); + final boolean saved = saveToFile(response.getEntity().getContent(), targetFile); + saveHeader("etag", saved ? response : null, targetFile); + saveHeader("last-modified", saved ? response : null, targetFile); + return saved; } catch (IOException e) { - Log.e(Settings.tag, "LocalStorage.saveEntityToFile", e); + Log.e("LocalStorage.saveEntityToFile", e); } return false; } + private static void saveHeader(final String name, final HttpResponse response, final File baseFile) { + final Header header = response != null ? response.getFirstHeader(name) : null; + final File file = filenameForHeader(baseFile, name); + if (header == null) { + file.delete(); + } else { + saveToFile(new ByteArrayInputStream(header.getValue().getBytes()), file); + } + } + + private static File filenameForHeader(final File baseFile, final String name) { + return new File(baseFile.getAbsolutePath() + "-" + name); + } + + /** + * Get the saved header value for this file. + * + * @param baseFile + * the name of the cached resource + * @param name + * the name of the header ("etag" or "last-modified") + * @return null if no value has been cached, the value otherwise + */ + public static String getSavedHeader(final File baseFile, final String name) { + try { + final File file = filenameForHeader(baseFile, name); + final FileReader f = new FileReader(file); + try { + // No header will be more than 256 bytes + final char[] value = new char[256]; + final int count = f.read(value); + return new String(value, 0, count); + } finally { + f.close(); + } + } catch (final FileNotFoundException e) { + // Do nothing, the file does not exist + } catch (final Exception e) { + Log.w("could not read saved header " + name + " for " + baseFile, e); + } + return null; + } + /** * Save an HTTP response to a file. + * <p/> + * If the response could not be saved to the file due, for example, to a network error, + * the file will not exist when this method returns. * * @param entity * the entity whose content will be saved @@ -176,16 +222,18 @@ public class LocalStorage { try { try { final FileOutputStream fos = new FileOutputStream(targetFile); - try { - return copy(inputStream, fos); - } finally { - fos.close(); + final boolean written = copy(inputStream, fos); + fos.close(); + if (!written) { + targetFile.delete(); } + return written; } finally { inputStream.close(); } } catch (IOException e) { - Log.e(Settings.tag, "LocalStorage.saveToFile", e); + Log.e("LocalStorage.saveToFile", e); + targetFile.delete(); } return false; } @@ -208,7 +256,7 @@ public class LocalStorage { input = new FileInputStream(source); output = new FileOutputStream(destination); } catch (FileNotFoundException e) { - Log.e(Settings.tag, "LocalStorage.copy: could not open file", e); + Log.e("LocalStorage.copy: could not open file", e); if (input != null) { try { input.close(); @@ -225,7 +273,7 @@ public class LocalStorage { input.close(); output.close(); } catch (IOException e) { - Log.e(Settings.tag, "LocalStorage.copy: could not close file", e); + Log.e("LocalStorage.copy: could not close file", e); return false; } @@ -233,15 +281,16 @@ public class LocalStorage { } private static boolean copy(final InputStream input, final OutputStream output) { - byte[] buffer = new byte[4096]; + final byte[] buffer = new byte[4096]; int length; try { while ((length = input.read(buffer)) > 0) { output.write(buffer, 0, length); } - output.flush(); // FIXME: is that necessary? + // Flushing is only necessary if the stream is not immediately closed afterwards. + // We rely on all callers to do that correctly outside of this method } catch (IOException e) { - Log.e(Settings.tag, "LocalStorage.copy: error when copying data", e); + Log.e("LocalStorage.copy: error when copying data", e); return false; } @@ -267,7 +316,7 @@ public class LocalStorage { } } } - + return path.delete(); } |
