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/** 2339606a007a5b1309dd000234f2b8cf156c49fd0fDianne Hackborn * @Deprecated Use {@link com.android.internal.os.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