• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
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 
17 package com.android.internal.util;
18 
19 import java.io.File;
20 import java.io.IOException;
21 
22 /**
23  * @deprecated Use {@link com.android.internal.os.AtomicFile} instead.  It would
24  * be nice to update all existing uses of this to switch to AtomicFile, but since
25  * their on-file semantics are slightly different that would run the risk of losing
26  * data if at the point of the platform upgrade to the new code it would need to
27  * roll back to the backup file.  This can be solved...  but is it worth it and
28  * all of the testing needed to make sure it is correct?
29  */
30 @Deprecated
31 public class JournaledFile {
32     File mReal;
33     File mTemp;
34     boolean mWriting;
35 
JournaledFile(File real, File temp)36     public JournaledFile(File real, File temp) {
37         mReal = real;
38         mTemp = temp;
39     }
40 
41     /** Returns the file for you to read.
42      * @more
43      * Prefers the real file.  If it doesn't exist, uses the temp one, and then copies
44      * it to the real one.  If there is both a real file and a temp one, assumes that the
45      * temp one isn't fully written and deletes it.
46      */
chooseForRead()47     public File chooseForRead() {
48         File result;
49         if (mReal.exists()) {
50             result = mReal;
51             if (mTemp.exists()) {
52                 mTemp.delete();
53             }
54         } else if (mTemp.exists()) {
55             result = mTemp;
56             mTemp.renameTo(mReal);
57         } else {
58             return mReal;
59         }
60         return result;
61     }
62 
63     /**
64      * Returns a file for you to write.
65      * @more
66      * If a write is already happening, throws.  In other words, you must provide your
67      * own locking.
68      * <p>
69      * Call {@link #commit} to commit the changes, or {@link #rollback} to forget the changes.
70      */
chooseForWrite()71     public File chooseForWrite() {
72         if (mWriting) {
73             throw new IllegalStateException("uncommitted write already in progress");
74         }
75         if (!mReal.exists()) {
76             // If the real one doesn't exist, it's either because this is the first time
77             // or because something went wrong while copying them.  In this case, we can't
78             // trust anything that's in temp.  In order to have the chooseForRead code not
79             // use the temporary one until it's fully written, create an empty file
80             // for real, which will we'll shortly delete.
81             try {
82                 mReal.createNewFile();
83             } catch (IOException e) {
84                 // Ignore
85             }
86         }
87 
88         if (mTemp.exists()) {
89             mTemp.delete();
90         }
91         mWriting = true;
92         return mTemp;
93     }
94 
95     /**
96      * Commit changes.
97      */
commit()98     public void commit() {
99         if (!mWriting) {
100             throw new IllegalStateException("no file to commit");
101         }
102         mWriting = false;
103         mTemp.renameTo(mReal);
104     }
105 
106     /**
107      * Roll back changes.
108      */
rollback()109     public void rollback() {
110         if (!mWriting) {
111             throw new IllegalStateException("no file to roll back");
112         }
113         mWriting = false;
114         mTemp.delete();
115     }
116 }
117