@ -58,6 +58,7 @@ import org.eclipse.jgit.JGitText;
import org.eclipse.jgit.errors.ConfigInvalidException ;
import org.eclipse.jgit.errors.ConfigInvalidException ;
import org.eclipse.jgit.lib.Config ;
import org.eclipse.jgit.lib.Config ;
import org.eclipse.jgit.lib.Constants ;
import org.eclipse.jgit.lib.Constants ;
import org.eclipse.jgit.lib.ObjectId ;
import org.eclipse.jgit.lib.StoredConfig ;
import org.eclipse.jgit.lib.StoredConfig ;
import org.eclipse.jgit.util.FS ;
import org.eclipse.jgit.util.FS ;
import org.eclipse.jgit.util.IO ;
import org.eclipse.jgit.util.IO ;
@ -68,8 +69,9 @@ import org.eclipse.jgit.util.RawParseUtils;
* /
* /
public class FileBasedConfig extends StoredConfig {
public class FileBasedConfig extends StoredConfig {
private final File configFile ;
private final File configFile ;
private volatile long lastModified ;
private final FS fs ;
private final FS fs ;
private volatile FileSnapshot snapshot ;
private volatile ObjectId hash ;
/ * *
/ * *
* Create a configuration with no default fallback .
* Create a configuration with no default fallback .
@ -99,6 +101,8 @@ public class FileBasedConfig extends StoredConfig {
super ( base ) ;
super ( base ) ;
configFile = cfgLocation ;
configFile = cfgLocation ;
this . fs = fs ;
this . fs = fs ;
this . snapshot = FileSnapshot . DIRTY ;
this . hash = ObjectId . zeroId ( ) ;
}
}
@Override
@Override
@ -125,11 +129,24 @@ public class FileBasedConfig extends StoredConfig {
* /
* /
@Override
@Override
public void load ( ) throws IOException , ConfigInvalidException {
public void load ( ) throws IOException , ConfigInvalidException {
lastModified = getFile ( ) . lastModified ( ) ;
final FileSnapshot oldSnapshot = snapshot ;
final FileSnapshot newSnapshot = FileSnapshot . save ( getFile ( ) ) ;
try {
try {
fromText ( RawParseUtils . decode ( IO . readFully ( getFile ( ) ) ) ) ;
final byte [ ] in = IO . readFully ( getFile ( ) ) ;
final ObjectId newHash = hash ( in ) ;
if ( hash . equals ( newHash ) ) {
if ( oldSnapshot . equals ( newSnapshot ) )
oldSnapshot . setClean ( newSnapshot ) ;
else
snapshot = newSnapshot ;
} else {
fromText ( RawParseUtils . decode ( in ) ) ;
snapshot = newSnapshot ;
hash = newHash ;
}
} catch ( FileNotFoundException noFile ) {
} catch ( FileNotFoundException noFile ) {
clear ( ) ;
clear ( ) ;
snapshot = newSnapshot ;
} catch ( IOException e ) {
} catch ( IOException e ) {
final IOException e2 = new IOException ( MessageFormat . format ( JGitText . get ( ) . cannotReadFile , getFile ( ) ) ) ;
final IOException e2 = new IOException ( MessageFormat . format ( JGitText . get ( ) . cannotReadFile , getFile ( ) ) ) ;
e2 . initCause ( e ) ;
e2 . initCause ( e ) ;
@ -157,18 +174,29 @@ public class FileBasedConfig extends StoredConfig {
if ( ! lf . lock ( ) )
if ( ! lf . lock ( ) )
throw new IOException ( MessageFormat . format ( JGitText . get ( ) . cannotLockFile , getFile ( ) ) ) ;
throw new IOException ( MessageFormat . format ( JGitText . get ( ) . cannotLockFile , getFile ( ) ) ) ;
try {
try {
lf . setNeedStatInformation ( true ) ;
lf . setNeedSnapshot ( true ) ;
lf . write ( out ) ;
lf . write ( out ) ;
if ( ! lf . commit ( ) )
if ( ! lf . commit ( ) )
throw new IOException ( MessageFormat . format ( JGitText . get ( ) . cannotCommitWriteTo , getFile ( ) ) ) ;
throw new IOException ( MessageFormat . format ( JGitText . get ( ) . cannotCommitWriteTo , getFile ( ) ) ) ;
} finally {
} finally {
lf . unlock ( ) ;
lf . unlock ( ) ;
}
}
lastModified = lf . getCommitLastModified ( ) ;
snapshot = lf . getCommitSnapshot ( ) ;
hash = hash ( out ) ;
// notify the listeners
// notify the listeners
fireConfigChangedEvent ( ) ;
fireConfigChangedEvent ( ) ;
}
}
@Override
public void clear ( ) {
hash = hash ( new byte [ 0 ] ) ;
super . clear ( ) ;
}
private static ObjectId hash ( final byte [ ] rawText ) {
return ObjectId . fromRaw ( Constants . newMessageDigest ( ) . digest ( rawText ) ) ;
}
@Override
@Override
public String toString ( ) {
public String toString ( ) {
return getClass ( ) . getSimpleName ( ) + "[" + getFile ( ) . getPath ( ) + "]" ;
return getClass ( ) . getSimpleName ( ) + "[" + getFile ( ) . getPath ( ) + "]" ;
@ -179,6 +207,6 @@ public class FileBasedConfig extends StoredConfig {
* than the file on disk
* than the file on disk
* /
* /
public boolean isOutdated ( ) {
public boolean isOutdated ( ) {
return getFile ( ) . lastModified ( ) ! = lastModified ;
return snapshot . isModified ( getFile ( ) ) ;
}
}
}
}