aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/files/LocalStorage.java
diff options
context:
space:
mode:
Diffstat (limited to 'main/src/cgeo/geocaching/files/LocalStorage.java')
-rw-r--r--main/src/cgeo/geocaching/files/LocalStorage.java93
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();
}