1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
// Copyright (C) 2001-2003 Jon A. Maxwell (JAM)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
package net.sourceforge.jnlp.util;
import java.io.*;
import java.util.*;
/**
* A properties object backed by a specified file without throwing
* exceptions. The properties are automatically loaded from the
* file when the first property is requested, but the save method
* must be called before changes are saved to the file.<p>
*
* @author <a href="mailto:jmaxwell@users.sourceforge.net">Jon A. Maxwell (JAM)</a> - initial author
* @version $Revision: 1.4 $
*/
public class PropertiesFile extends Properties {
/** the file to save to */
File file;
/** the header string */
String header = "netx file";
/** time of last modification, lazy loaded on getProperty */
long lastStore;
/**
* Create a properties object backed by the specified file.
*
* @param file the file to save and load to
*/
public PropertiesFile(File file) {
this.file = file;
}
/**
* Create a properties object backed by the specified file.
*
* @param file the file to save and load to
* @param header the file header
*/
public PropertiesFile(File file, String header) {
this.file = file;
this.header = header;
}
/**
* Returns the value of the specified key, or null if the key
* does not exist.
*/
public String getProperty(String key) {
if (lastStore == 0)
load();
return super.getProperty(key);
}
/**
* Returns the value of the specified key, or the default value
* if the key does not exist.
*/
public String getProperty(String key, String defaultValue) {
if (lastStore == 0)
load();
return super.getProperty(key, defaultValue);
}
/**
* Sets the value for the specified key.
*
* @return the previous value
*/
public Object setProperty(String key, String value) {
if (lastStore == 0)
load();
return super.setProperty(key, value);
}
/**
* Returns the file backing this properties object.
*/
public File getStoreFile() {
return file;
}
/**
* Ensures that the file backing these properties has been
* loaded; call this method before calling any method defined by
* a superclass.
*
* @return true, if file was (re-)loaded
* false, if file was still current
*/
public boolean load() {
if (!file.exists()) {
return false;
}
long currentStore = file.lastModified();
long currentTime = System.currentTimeMillis();
/* (re)load file, if
* - it wasn't loaded/stored, yet (lastStore == 0)
* - current file modification timestamp has changed since last store (currentStore != lastStore) OR
* - current file modification timestamp has not changed since last store AND current system time equals current file modification timestamp
* This is necessary because some filesystems seems only to provide accuracy of the timestamp on the level of seconds!
*/
if(lastStore == 0 || currentStore != lastStore || (currentStore == lastStore && currentStore / 1000 == currentTime / 1000)) {
InputStream s = null;
try {
try {
s = new FileInputStream(file);
load(s);
} finally {
if (s != null) {
s.close();
lastStore=currentStore;
return true;
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return false;
}
/**
* Saves the properties to the file.
*/
public void store() {
FileOutputStream s = null;
try {
try {
file.getParentFile().mkdirs();
s = new FileOutputStream(file);
store(s, header);
// fsync()
s.getChannel().force(true);
lastStore = file.lastModified();
} finally {
if (s != null) s.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
|