2 * Copyright 2014 Gustavo Martin Morcuende
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package name.gumartinm.weather.information.service;
19 import java.io.FileNotFoundException;
20 import java.io.FileOutputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.ObjectInputStream;
24 import java.io.ObjectOutputStream;
25 import java.io.StreamCorruptedException;
26 import java.text.MessageFormat;
28 import android.content.Context;
29 import android.util.Log;
31 import name.gumartinm.weather.information.model.currentweather.Current;
32 import name.gumartinm.weather.information.model.forecastweather.Forecast;
35 public class PermanentStorage {
36 private static final String TAG = "PermanentStorage";
37 private static final String CURRENT_DATA_FILE = "current.file";
38 private static final String FORECAST_DATA_FILE = "forecast.file";
39 private static final String WIDGET_CURRENT_DATA_FILE = "current.{0}.file";
40 private final Context context;
42 public PermanentStorage(final Context context) {
43 this.context = context;
46 public void saveCurrent(final Current current) {
49 this.saveObject(CURRENT_DATA_FILE, current);
50 } catch (FileNotFoundException e) {
51 Log.e(TAG, "saveCurrent exception: ", e);
52 } catch (IOException e) {
53 Log.e(TAG, "saveCurrent exception: ", e);
57 public Current getCurrent() {
60 return (Current) this.getObject(CURRENT_DATA_FILE);
61 } catch (final StreamCorruptedException e) {
62 Log.e(TAG, "getCurrent exception: ", e);
63 } catch (final FileNotFoundException e) {
64 Log.e(TAG, "getCurrent exception: ", e);
65 } catch (final IOException e) {
66 Log.e(TAG, "getCurrent exception: ", e);
67 } catch (final ClassNotFoundException e) {
68 Log.e(TAG, "getCurrent exception: ", e);
74 public void saveWidgetCurrentData(final Current current, final int appWidgetId) {
76 final String fileName = MessageFormat.format(WIDGET_CURRENT_DATA_FILE, appWidgetId);
78 this.saveObject(fileName, current);
79 } catch (FileNotFoundException e) {
80 Log.e(TAG, "saveWidgetCurrentData exception: ", e);
81 } catch (IOException e) {
82 Log.e(TAG, "saveWidgetCurrentData exception: ", e);
86 public Current getWidgetCurrentData(final int appWidgetId) {
88 final String fileName = MessageFormat.format(WIDGET_CURRENT_DATA_FILE, appWidgetId);
90 return (Current) this.getObject(fileName);
91 } catch (final StreamCorruptedException e) {
92 Log.e(TAG, "getWidgetCurrentData exception: ", e);
93 } catch (final FileNotFoundException e) {
94 Log.e(TAG, "getWidgetCurrentData exception: ", e);
95 } catch (final IOException e) {
96 Log.e(TAG, "getWidgetCurrentData exception: ", e);
97 } catch (final ClassNotFoundException e) {
98 Log.e(TAG, "getWidgetCurrentData exception: ", e);
104 public void removeWidgetCurrentData(final int appWidgetId) {
106 final String fileName = MessageFormat.format(WIDGET_CURRENT_DATA_FILE, appWidgetId);
109 this.removeFile(fileName);
110 } catch (final IOException e) {
111 Log.e(TAG, "removeWidgetCurrentData exception: ", e);
115 public void saveForecast(final Forecast forecast) {
118 this.saveObject(FORECAST_DATA_FILE, forecast);
119 } catch (FileNotFoundException e) {
120 Log.e(TAG, "saveForecast exception: ", e);
121 } catch (IOException e) {
122 Log.e(TAG, "saveForecast exception: ", e);
126 public Forecast getForecast() {
129 return (Forecast) this.getObject(FORECAST_DATA_FILE);
130 } catch (final StreamCorruptedException e) {
131 Log.e(TAG, "getForecast exception: ", e);
132 } catch (final FileNotFoundException e) {
133 Log.e(TAG, "getForecast exception: ", e);
134 } catch (final IOException e) {
135 Log.e(TAG, "getForecast exception: ", e);
136 } catch (final ClassNotFoundException e) {
137 Log.e(TAG, "getForecast exception: ", e);
143 private void saveObject(final String fileName, final Object objectToStore)
144 throws FileNotFoundException, IOException {
145 final String temporaryFileName = fileName.concat(".tmp");
147 final FileOutputStream tmpPersistFile = this.context.openFileOutput(
148 temporaryFileName, Context.MODE_PRIVATE);
150 final ObjectOutputStream oos = new ObjectOutputStream(tmpPersistFile);
152 oos.writeObject(objectToStore);
154 // Don't fear the fsync!
155 // http://thunk.org/tytso/blog/2009/03/15/dont-fear-the-fsync/
156 tmpPersistFile.flush();
157 tmpPersistFile.getFD().sync();
162 tmpPersistFile.close();
165 this.renameFile(temporaryFileName, fileName);
168 private Object getObject(final String fileName) throws StreamCorruptedException, FileNotFoundException,
169 IOException, ClassNotFoundException {
170 final InputStream persistFile = this.context.openFileInput(fileName);
172 final ObjectInputStream ois = new ObjectInputStream(persistFile);
174 return ois.readObject();
183 private void renameFile(final String fromFileName, final String toFileName) throws IOException {
184 final File filesDir = this.context.getFilesDir();
185 final File fromFile = new File(filesDir, fromFileName);
186 final File toFile = new File(filesDir, toFileName);
187 if (!fromFile.renameTo(toFile)) {
188 if (!fromFile.delete()) {
189 throw new IOException("PermanentStorage, delete file error");
191 throw new IOException("PermanentStorage, rename file error");
195 private void removeFile(final String fileName) throws IOException {
196 final File filesDir = this.context.getFilesDir();
197 final File file = new File(filesDir, fileName);
199 if (!file.delete()) {
200 throw new IOException("PermanentStorage, remove file error");