61a54987a9e31ed24f4445a6cbd10d79844461e1
[JavaForFun] /
1 /**
2  * Copyright 2014 Gustavo Martin Morcuende
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package name.gumartinm.weather.information.service;
17
18 import java.io.File;
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;
27
28 import android.content.Context;
29 import android.util.Log;
30
31 import name.gumartinm.weather.information.model.currentweather.Current;
32 import name.gumartinm.weather.information.model.forecastweather.Forecast;
33
34
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;
41
42     public PermanentStorage(final Context context) {
43         this.context = context;
44     }
45
46     public void saveCurrent(final Current current) {
47         
48         try {
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);
54                 }
55     }
56
57     public Current getCurrent() {
58         
59         try {
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);
69                 }
70         
71         return null;
72     }
73
74     public void saveWidgetCurrentData(final Current current, final int appWidgetId) {
75
76         final String fileName = MessageFormat.format(WIDGET_CURRENT_DATA_FILE, appWidgetId);
77         try {
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);
83         }
84     }
85
86     public Current getWidgetCurrentData(final int appWidgetId) {
87
88         final String fileName = MessageFormat.format(WIDGET_CURRENT_DATA_FILE, appWidgetId);
89         try {
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);
99         }
100
101         return null;
102     }
103
104     public void removeWidgetCurrentData(final int appWidgetId) {
105
106         final String fileName = MessageFormat.format(WIDGET_CURRENT_DATA_FILE, appWidgetId);
107
108         try {
109             this.removeFile(fileName);
110         } catch (final IOException e) {
111             Log.e(TAG, "removeWidgetCurrentData exception: ", e);
112         }
113     }
114
115     public void saveForecast(final Forecast forecast) {
116
117         try {
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);
123                 }
124     }
125
126     public Forecast getForecast() {
127         
128         try {
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);
138                 }
139         
140         return null;
141     }
142
143     private void saveObject(final String fileName, final Object objectToStore)
144                 throws FileNotFoundException, IOException {
145         final String temporaryFileName = fileName.concat(".tmp");
146         
147         final FileOutputStream tmpPersistFile = this.context.openFileOutput(
148                         temporaryFileName, Context.MODE_PRIVATE);
149         try {
150                 final ObjectOutputStream oos = new ObjectOutputStream(tmpPersistFile);
151                 try {
152                         oos.writeObject(objectToStore);
153                         
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();
158                 } finally {
159                         oos.close();
160                 }
161         } finally {
162                 tmpPersistFile.close();
163         }
164
165         this.renameFile(temporaryFileName, fileName);
166     }
167  
168     private Object getObject(final String fileName) throws StreamCorruptedException, FileNotFoundException,
169                                                                                                            IOException, ClassNotFoundException {
170         final InputStream persistFile = this.context.openFileInput(fileName);
171         try {
172                 final ObjectInputStream ois = new ObjectInputStream(persistFile);
173                 try {
174                         return ois.readObject();
175                 } finally {
176                         ois.close();
177                 }
178         } finally {
179                 persistFile.close();
180         }
181     } 
182     
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");
190                 }       
191                 throw new IOException("PermanentStorage, rename file error");
192         }
193     }
194
195     private void removeFile(final String fileName) throws IOException {
196         final File filesDir = this.context.getFilesDir();
197         final File file = new File(filesDir, fileName);
198
199         if (!file.delete()) {
200             throw new IOException("PermanentStorage, remove file error");
201         }
202     }
203 }
204