19bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato/*
29bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato * Copyright (C) 2009 The Android Open Source Project
39bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato *
49bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
59bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato * you may not use this file except in compliance with the License.
69bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato * You may obtain a copy of the License at
79bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato *
89bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
99bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato *
109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato * Unless required by applicable law or agreed to in writing, software
119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato * See the License for the specific language governing permissions and
149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato * limitations under the License.
159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato */
169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
171afd1c90ebe789b8d3a137004127a50d2db7e3b5Dianne Hackbornpackage com.android.internal.util;
189bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
199bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.File;
209bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratoimport java.io.IOException;
219bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
2239606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackborn/**
2367f9d5070a74a0bf34f0335899a96dedcac26c96Jeff Sharkey * @deprecated Use {@code AtomicFile} instead.  It would
2439606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackborn * be nice to update all existing uses of this to switch to AtomicFile, but since
2539606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackborn * their on-file semantics are slightly different that would run the risk of losing
2639606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackborn * data if at the point of the platform upgrade to the new code it would need to
2739606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackborn * roll back to the backup file.  This can be solved...  but is it worth it and
2839606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackborn * all of the testing needed to make sure it is correct?
2939606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackborn */
3039606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackborn@Deprecated
319bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onoratopublic class JournaledFile {
329bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    File mReal;
339bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    File mTemp;
349bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    boolean mWriting;
359bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
369bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    public JournaledFile(File real, File temp) {
379bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        mReal = real;
389bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        mTemp = temp;
399bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
409bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
419bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    /** Returns the file for you to read.
429bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     * @more
439bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     * Prefers the real file.  If it doesn't exist, uses the temp one, and then copies
449bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     * it to the real one.  If there is both a real file and a temp one, assumes that the
459bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     * temp one isn't fully written and deletes it.
469bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     */
479bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    public File chooseForRead() {
489bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        File result;
499bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (mReal.exists()) {
509bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            result = mReal;
519bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            if (mTemp.exists()) {
529bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                mTemp.delete();
539bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
549bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } else if (mTemp.exists()) {
559bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            result = mTemp;
569bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            mTemp.renameTo(mReal);
579bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        } else {
589bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            return mReal;
599bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
609bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        return result;
619bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
629bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
639bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    /**
649bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     * Returns a file for you to write.
659bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     * @more
669bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     * If a write is already happening, throws.  In other words, you must provide your
679bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     * own locking.
689bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     * <p>
699bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     * Call {@link #commit} to commit the changes, or {@link #rollback} to forget the changes.
709bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     */
719bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    public File chooseForWrite() {
729bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (mWriting) {
739bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            throw new IllegalStateException("uncommitted write already in progress");
749bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
759bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (!mReal.exists()) {
769bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // If the real one doesn't exist, it's either because this is the first time
779bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // or because something went wrong while copying them.  In this case, we can't
789bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // trust anything that's in temp.  In order to have the chooseForRead code not
799bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // use the temporary one until it's fully written, create an empty file
809bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            // for real, which will we'll shortly delete.
819bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            try {
829bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                mReal.createNewFile();
839bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            } catch (IOException e) {
849bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato                // Ignore
859bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            }
869bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
879bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
889bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (mTemp.exists()) {
899bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            mTemp.delete();
909bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
919bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        mWriting = true;
929bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        return mTemp;
939bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
949bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
959bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    /**
969bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     * Commit changes.
979bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     */
989bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    public void commit() {
999bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (!mWriting) {
1009bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            throw new IllegalStateException("no file to commit");
1019bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
1029bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        mWriting = false;
1039bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        mTemp.renameTo(mReal);
1049bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
1059bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato
1069bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    /**
1079bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     * Roll back changes.
1089bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato     */
1099bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    public void rollback() {
1109bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        if (!mWriting) {
1119bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            throw new IllegalStateException("no file to roll back");
1129bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        }
1139bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        mWriting = false;
1149bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato        mTemp.delete();
1159bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato    }
1169bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato}
117