Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTodor Boev2021-05-31 15:12:19 +0000
committerTodor Boev2021-06-29 14:26:04 +0000
commit297545ddd241eca93f6e6423a9cfa800131b5483 (patch)
tree5943eb981ba119f2a25190c4e533e46a6cea1ece
parent3415227e9f015647b1dedf2407dd62510e7ac1c4 (diff)
downloadrt.equinox.p2-297545ddd241eca93f6e6423a9cfa800131b5483.tar.gz
rt.equinox.p2-297545ddd241eca93f6e6423a9cfa800131b5483.tar.xz
rt.equinox.p2-297545ddd241eca93f6e6423a9cfa800131b5483.zip
Change-Id: I3eb94846144a6683f8ee918f9c4abd2f0deb603f Signed-off-by: Todor Boev <rinsvind@gmail.com> Reviewed-on: https://git.eclipse.org/r/c/equinox/rt.equinox.p2/+/182080 Tested-by: Equinox Bot <equinox-bot@eclipse.org>
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF2
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/p2.inf47
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/pom.xml2
-rw-r--r--bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/BackupStore.java338
4 files changed, 202 insertions, 187 deletions
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF
index 51ed027e6..21663c044 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.equinox.p2.touchpoint.natives;singleton:=true
-Bundle-Version: 1.4.0.qualifier
+Bundle-Version: 1.4.100.qualifier
Bundle-Activator: org.eclipse.equinox.internal.p2.touchpoint.natives.Activator
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/p2.inf b/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/p2.inf
deleted file mode 100644
index 49c767be9..000000000
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/META-INF/p2.inf
+++ /dev/null
@@ -1,47 +0,0 @@
-provides.0.namespace=org.eclipse.equinox.p2.iu
-provides.0.name=org.eclipse.equinox.p2.touchpoint.natives
-provides.0.version=1.1.100.v20140523-0116
-
-provides.1.namespace=org.eclipse.equinox.p2.iu
-provides.1.name=org.eclipse.equinox.p2.touchpoint.natives
-provides.1.version=1.2.0.$qualifier$
-
-provides.2.namespace=org.eclipse.equinox.p2.iu
-provides.2.name=org.eclipse.equinox.p2.touchpoint.natives
-provides.2.version=1.2.100.$qualifier$
-
-provides.3.namespace=org.eclipse.equinox.p2.iu
-provides.3.name=org.eclipse.equinox.p2.touchpoint.natives
-provides.3.version=1.2.200.$qualifier$
-
-provides.4.namespace=org.eclipse.equinox.p2.iu
-provides.4.name=org.eclipse.equinox.p2.touchpoint.natives
-provides.4.version=1.3.0.$qualifier$
-
-provides.5.namespace=org.eclipse.equinox.p2.iu
-provides.5.name=org.eclipse.equinox.p2.touchpoint.natives
-provides.5.version=1.3.100.$qualifier$
-
-provides.6.namespace=org.eclipse.equinox.p2.iu
-provides.6.name=org.eclipse.equinox.p2.touchpoint.natives
-provides.6.version=1.3.200.$qualifier$
-
-provides.7.namespace=org.eclipse.equinox.p2.iu
-provides.7.name=org.eclipse.equinox.p2.touchpoint.natives
-provides.7.version=1.3.300.$qualifier$
-
-provides.8.namespace=org.eclipse.equinox.p2.iu
-provides.8.name=org.eclipse.equinox.p2.touchpoint.natives
-provides.8.version=1.3.400.$qualifier$
-
-provides.9.namespace=org.eclipse.equinox.p2.iu
-provides.9.name=org.eclipse.equinox.p2.touchpoint.natives
-provides.9.version=1.3.500.$qualifier$
-
-provides.10.namespace=org.eclipse.equinox.p2.iu
-provides.10.name=org.eclipse.equinox.p2.touchpoint.natives
-provides.10.version=1.3.600.$qualifier$
-
-provides.11.namespace=org.eclipse.equinox.p2.iu
-provides.11.name=org.eclipse.equinox.p2.touchpoint.natives
-provides.11.version=1.4.0.$qualifier$
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/pom.xml b/bundles/org.eclipse.equinox.p2.touchpoint.natives/pom.xml
index e4fb9cb40..06322447f 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/pom.xml
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/pom.xml
@@ -9,6 +9,6 @@
</parent>
<groupId>org.eclipse.equinox</groupId>
<artifactId>org.eclipse.equinox.p2.touchpoint.natives</artifactId>
- <version>1.4.0-SNAPSHOT</version>
+ <version>1.4.100-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/BackupStore.java b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/BackupStore.java
index 3bd9b5fc5..9206eab61 100644
--- a/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/BackupStore.java
+++ b/bundles/org.eclipse.equinox.p2.touchpoint.natives/src/org/eclipse/equinox/internal/p2/touchpoint/natives/BackupStore.java
@@ -27,71 +27,71 @@ import org.eclipse.osgi.util.NLS;
/**
* Stores files by copying them to a uniquely named temporary directory.
* The BackupStore remembers filenames and can recreate them in their original location.
- *
+ *
* <h3>Usage</h3>
- * The user of this class should instantiate the BackupStore with some prefix that is
- * meaningful to a human. Uniqueness is obtained without the prefix - the prefix is used to
+ * The user of this class should instantiate the BackupStore with some prefix that is
+ * meaningful to a human. Uniqueness is obtained without the prefix - the prefix is used to
* be able to differentiate between different backup directories by a human (in case of crashes etc).
- *
+ *
* If instantiated with a directory this directory will be used to store the backup root directory. If
* this directory is null, the users home directory is used by default.
- *
+ *
* Once instantiated, use the {@link #backup(File)} and {@link #backupDirectory(File)} methods
* to move files to backup instead of deleting them. A file that
- * is backed up should not be deleted - it is simply moved out of the way.
+ * is backed up should not be deleted - it is simply moved out of the way.
* Use {@link #backupCopy(File)} to
* move the file out of harms way, but keep a copy of it in the original location.
* The methods {@link #backupAll(File)} and {@link #backupCopyAll(File)} backs up an entire structure.
- *
- * When backup is finished - the user should either call {@link #restore()} to put all
+ *
+ * When backup is finished - the user should either call {@link #restore()} to put all
* of the files back, or call {@link #discard()} to remove all of the backed up "copies".
- *
+ *
* If {@link #restore()} or {@link #discard()} is not called the backup files will never be deleted.
- *
+ *
* The backup store does not synchronize directories - actions that write new files are
* responsible for removing them. Overwriting existing files should be done by first backing
- * up the file, and then creating a new file. Modifying a file, should be done by
- * using {@link #backupCopy(File)} or
+ * up the file, and then creating a new file. Modifying a file, should be done by
+ * using {@link #backupCopy(File)} or
* first making a copy, then backing up the original, and then renaming the copy.
- *
+ *
* <h3>Read Only and Permissions</h3>
* Directories that are read only (to current user) can not be backed up.
* Backup is performed using {@link File#renameTo(File)} and handling of permissions
* is operating system dependent. It is expected that a Un*x type system retains the
* permissions as a file is moved to the backup store and later gets restored.
* Backup directories are created as they are needed and will (at least on Un*x) inherit the
- * permissions from its parent directory.
- *
+ * permissions from its parent directory.
+ *
* If a rename can not be performed, the backup store will make a copy and delete the original
* file. This makes it possible to backup and restore across volume boundaries.
- *
+ *
* When restoring directories they
- * will be created with permissions in a platform specific way (on UN*IX they will inherit the permissions
+ * will be created with permissions in a platform specific way (on UN*IX they will inherit the permissions
* of the parent directory).
- *
- * <h3>Checkpointing</h3>
+ *
+ * <h3>Checkpointing</h3>
* Checkpointing (i.e. to be able to rollback to a particular point) can be implemented by using
* multiple instances of BackupStore. The client code will need to remember the individual order
* among the backup stores.
- *
+ *
* <h3>Restartability</h3>
* Not implemented - it is possible to obtain the name of the backup directories,
* so manual restore is possible after a crash. An idea is to add persistence to a file, and
* be able to read it back in again.
- *
+ *
* <h3>A note about exceptions</h3>
* In general {@link IllegalArgumentException} is thrown when attempting an operation
* that is considered "wrong use", and an {@link IllegalStateException} or subclass thereof is thrown on an overall
* wrong use of BackupStore (i.e. attempt to backup when store has been restored). Some cases of
* "wrong use" can not be differentiated from I/O errors (like a "file not found" as this could
* be caused by an entire disk disappearing - in these case an {@link IOException} is thrown.
- *
+ *
* <h3>Implementation Note</h3>
- * The backup root directory will contain folders that reflects file system roots. These are encoded using
+ * The backup root directory will contain folders that reflects file system roots. These are encoded using
* "_" for the UNI*X root directory, "__" for a Windows network mounted directory, and single "drive letter" folders
* corresponding to Windows drive letters. Typically, on UN*X there will only be a "_" directory in the backup root,
* and on windows there will typically be a single directory called "C".
- *
+ *
*
*/
public class BackupStore implements IBackupStore {
@@ -104,10 +104,10 @@ public class BackupStore implements IBackupStore {
private static final String ROOTCHAR = "_"; //$NON-NLS-1$
/**
- * Map of directory File to backup root (File) - the backup root has
+ * Map of directory File to backup root (File) - the backup root has
* a directory named {@link #backupName} where the backup is found.
*/
- //private Map backups = new HashMap();
+ // private Map backups = new HashMap();
private final File backupRoot;
/**
@@ -147,8 +147,8 @@ public class BackupStore implements IBackupStore {
/**
* Generates a BackupStore with a default prefix of ".p2bu" for backup directory and
- * probe file.
- * The full id of the store is on the format "prefix_hextime_hexIPport"
+ * probe file.
+ * The full id of the store is on the format "prefix_hextime_hexIPport"
* - see {@link #genUnique()} for more info.
*/
public BackupStore() {
@@ -158,15 +158,17 @@ public class BackupStore implements IBackupStore {
/**
* Generates a BackupStore with a specified prefix for backup directories and
* probe file.
- * The full id of the store is on the format "prefix_hextime_hexipport"
+ * The full id of the store is on the format "prefix_hextime_hexipport"
* - see {@link #genUnique()} for more info.
- *
- * @param buParentDirectory - name of directory where the backup directory should be created - if null, java.io.tmpdir is used
- * @param prefix - prefix used for human identification of backup directories
+ *
+ * @param buParentDirectory - name of directory where the backup directory should be created - if null,
+ * java.io.tmpdir is used
+ * @param prefix - prefix used for human identification of backup directories
*/
public BackupStore(File buParentDirectory, String prefix) {
- if (buParentDirectory == null)
+ if (buParentDirectory == null) {
buParentDirectory = new File(System.getProperty("java.io.tmpdir")); //$NON-NLS-1$
+ }
backupRoot = buParentDirectory;
// generate a name for the backup store and the dummy file used for empty directories
@@ -186,8 +188,9 @@ public class BackupStore implements IBackupStore {
@Override
protected void finalize() throws Throwable {
try {
- if (socket != null && !socket.isClosed())
+ if (socket != null && !socket.isClosed()) {
socket.close();
+ }
} finally {
super.finalize();
}
@@ -195,6 +198,7 @@ public class BackupStore implements IBackupStore {
/**
* Returns the unique backup name (this is the name of generated backup directories).
+ *
* @return the backup name.
*/
@Override
@@ -208,46 +212,54 @@ public class BackupStore implements IBackupStore {
/**
* Backup the file by moving it to the backup store (for later (optional) restore).
- * Calling this method with a file that represents a directory is equivalent to calling
+ * Calling this method with a file that represents a directory is equivalent to calling
* {@link #backupDirectory(File)}.
- *
+ *
* A file (path) can only be backed up once per BackupStore instance.
- * When the file is backed up, it is moved to a directory under this BackupStore instance's directory
+ * When the file is backed up, it is moved to a directory under this BackupStore instance's directory
* with a relative path corresponding to the original relative path from the backup root e.g.
* the file /A/B/C/foo.txt could be moved to /A/.p2bu_ffffff_ffffff/B/C/foo.txt when /A is the
* backup root.
- *
+ *
* If a directory is first backed up, and later replaced by a regular file, and this file
* is backed up (or vice versa) - an {@link IllegalArgumentException} is thrown
- *
- * A backup can not be performed on a closed BackupStore.
- *
+ *
+ * A backup can not be performed on a closed BackupStore.
+ *
* @param file - the file (or directory) to backup
- * @return true if the file was backed up, false if this file (path) has already been backed up (the file is not moved to the store).
- * @throws IOException - if the backup operation fails, or the file does not exist
+ * @return true if the file was backed up, false if this file (path) has already been backed up (the file is not
+ * moved to the store).
+ * @throws IOException - if the backup operation fails, or the file does not exist
* @throws ClosedBackupStoreException - if the BackupStore has been closed
- * @throws IllegalArgumentException - on type mismatch (file vs. directory) of earlier backup, or if file does not exist
+ * @throws IllegalArgumentException - on type mismatch (file vs. directory) of earlier backup, or if file does not
+ * exist
*/
@Override
public boolean backup(File file) throws IOException {
- if (closed)
+ if (closed) {
throw new ClosedBackupStoreException("Can not perform backup()"); //$NON-NLS-1$
- if (!file.exists())
+ }
+ if (!file.exists()) {
throw new IOException(NLS.bind(Messages.BackupStore_file_not_found, file.getAbsolutePath()));
- if (file.isDirectory())
+ }
+ if (file.isDirectory()) {
return backupDirectory(file);
+ }
file = makeParentCanonical(file);
File buFile = getBackupFile(file);
// already backed up, but was a directory = wrong usage
- if (buFile.isDirectory())
- throw new IllegalArgumentException(NLS.bind(Messages.BackupStore_directory_file_mismatch, buFile.getAbsolutePath()));
+ if (buFile.isDirectory()) {
+ throw new IllegalArgumentException(
+ NLS.bind(Messages.BackupStore_directory_file_mismatch, buFile.getAbsolutePath()));
+ }
// has already been backed up - can only be done once with one BackupStore
if (buFile.exists()) {
// although backed up, the file can be still on the file system when, for example,
// two IUs are unzipping their contents to the same location and share a few common file,
// which have to be removed twice
- if (file.exists() && !file.delete())
+ if (file.exists() && !file.delete()) {
throw new IOException(NLS.bind(Messages.BackupStore_can_not_remove, file.getAbsolutePath()));
+ }
return false;
}
@@ -259,16 +271,18 @@ public class BackupStore implements IBackupStore {
/**
* Move/rename file to a backup file. Callers of the method must have ensured that the source file exists and the
* backup file has not been created yet.
- *
- * @param file source file to move; should already exist and must not be directory
+ *
+ * @param file source file to move; should already exist and must not be directory
* @param buFile destination backup file to move to; should not exist and must be a directory
* @throws IOException if the backup operation fails
*/
protected void moveToBackup(File file, File buFile) throws IOException {
// make sure all of the directories exist / gets created
buFile.getParentFile().mkdirs();
- if (buFile.getParentFile().exists() && !buFile.getParentFile().isDirectory())
- throw new IllegalArgumentException(NLS.bind(Messages.BackupStore_file_directory_mismatch, buFile.getParentFile().getAbsolutePath()));
+ if (buFile.getParentFile().exists() && !buFile.getParentFile().isDirectory()) {
+ throw new IllegalArgumentException(
+ NLS.bind(Messages.BackupStore_file_directory_mismatch, buFile.getParentFile().getAbsolutePath()));
+ }
if (moveToBackupStore(file, buFile)) {
backupCounter++;
return;
@@ -278,24 +292,26 @@ public class BackupStore implements IBackupStore {
// but the locked file will fail on the subsequent delete.
//
// Rename in place
- if (isEclipseExe(file))
+ if (isEclipseExe(file)) {
renameInPlace(file);
- else {
+ } else {
Util.copyStream(new FileInputStream(file), true, new FileOutputStream(buFile), true);
backupCounter++;
}
-
+
// File.exists() is not reliable so always attempt to delete first and check why it may have failed second.
- if (!file.delete() && file.exists())
+ if (!file.delete() && file.exists()) {
throw new IOException(NLS.bind(Messages.BackupStore_can_not_delete_after_copy_0, file));
+ }
}
private boolean isEclipseExe(File file) {
String launcher = System.getProperty("eclipse.launcher"); //$NON-NLS-1$
if (launcher != null) {
String base = new File(launcher).getName();
- if (file.getName().equalsIgnoreCase(base))
+ if (file.getName().equalsIgnoreCase(base)) {
return true;
+ }
}
return file.getName().equalsIgnoreCase("eclipse.exe") || file.getName().equalsIgnoreCase("eclipsec.exe"); //$NON-NLS-1$ //$NON-NLS-2$
}
@@ -303,14 +319,14 @@ public class BackupStore implements IBackupStore {
protected boolean moveToBackupStore(File file, File buFile) {
if (file.renameTo(buFile)) {
// if the original file still exists, we have a problem.
- if (file.exists()) {
- // If the renamed work, but the file still exists, remove the backup
- // and return false
- if (buFile.exists())
- buFile.delete();
- } else {
+ if (!file.exists()) {
return true;
}
+ // If the renamed work, but the file still exists, remove the backup
+ // and return false
+ if (buFile.exists()) {
+ buFile.delete();
+ }
}
return false;
}
@@ -335,21 +351,23 @@ public class BackupStore implements IBackupStore {
/**
* Backs up a file, or everything under a directory.
- *
+ *
* @param file - file to backup or directory
* @throws IOException if backup operation failed
*/
@Override
public void backupAll(File file) throws IOException {
- if (!file.exists())
+ if (!file.exists()) {
return;
+ }
file = makeParentCanonical(file);
if (file.isDirectory()) {
File[] files = file.listFiles();
- if (files != null)
+ if (files != null) {
for (File f : files) {
backupAll(f);
}
+ }
}
backup(file);
}
@@ -357,78 +375,93 @@ public class BackupStore implements IBackupStore {
/**
* Backs up a file, or everything under a directory.
* A copy of the backup is left in the original place.
+ *
* @param file
* @throws IOException
*/
@Override
public void backupCopyAll(File file) throws IOException {
- if (!file.exists())
+ if (!file.exists()) {
return;
+ }
file = makeParentCanonical(file);
if (file.isDirectory()) {
File[] files = file.listFiles();
- if (files != null)
+ if (files != null) {
for (File f : files) {
backupCopyAll(f);
}
+ }
// if directory was empty, it needs to be backed up and then recreated
//
if (files == null || files.length == 0) {
backupDirectory(file);
file.mkdir();
}
- } else
+ } else {
backupCopy(file);
+ }
}
/**
* Backup the file by moving it to the backup store (for later (optional) restore) but leaving
* a copy of the contents in the original location.
* Calling this method with a file that represents a directory throws an {@link IllegalArgumentException}.
- *
+ *
* A file (path) can only be backed up once per BackupStore instance.
- * When the file is backed up, it is moved to a directory under this BackupStore instance's directory
+ * When the file is backed up, it is moved to a directory under this BackupStore instance's directory
* with a relative path corresponding to the original relative path from the backup root e.g.
* the file /A/B/C/foo.txt could be moved to /A/.p2bu_ffffff_ffffff/B/C/foo.txt when /A is the
* backup root.
- *
+ *
* If a directory is first backed up, and later replaced by a regular file, and this file
* is backed up (or vice versa) - an {@link IllegalArgumentException} is thrown
- *
- * A backup can not be performed on a closed BackupStore.
- *
+ *
+ * A backup can not be performed on a closed BackupStore.
+ *
* @param file - the file (or directory) to backup
- * @return true if the file was backed up, false if this file (path) has already been backed up (the file is not moved to the store).
- * @throws IOException - if the backup operation fails, or the file does not exist
+ * @return true if the file was backed up, false if this file (path) has already been backed up (the file is not
+ * moved to the store).
+ * @throws IOException - if the backup operation fails, or the file does not exist
* @throws ClosedBackupStoreException - if the BackupStore has been closed
- * @throws IllegalArgumentException - on type mismatch (file vs. directory) of earlier backup, or if file is a Directory
+ * @throws IllegalArgumentException - on type mismatch (file vs. directory) of earlier backup, or if file is a
+ * Directory
*/
@Override
public boolean backupCopy(File file) throws IOException {
- if (closed)
+ if (closed) {
throw new ClosedBackupStoreException(Messages.BackupStore_backupCopy_closed_store);
- if (!file.exists())
+ }
+ if (!file.exists()) {
throw new IOException(NLS.bind(Messages.BackupStore_file_not_found, file.getAbsolutePath()));
- if (file.isDirectory())
- throw new IllegalArgumentException(NLS.bind(Messages.BackupStore_can_not_copy_directory, file.getAbsolutePath()));
+ }
+ if (file.isDirectory()) {
+ throw new IllegalArgumentException(
+ NLS.bind(Messages.BackupStore_can_not_copy_directory, file.getAbsolutePath()));
+ }
file = makeParentCanonical(file);
- //File buRoot = backupRoot;
+ // File buRoot = backupRoot;
// File buRoot = findBackupRoot(file);
File buDir = new File(backupRoot, backupName);
// move the file
// create the relative path from root and use that in buDir
File buFile = new File(buDir, makeRelativeFromRoot(file).getPath());
// already backed up, but was a directory = wrong usage
- if (buFile.isDirectory())
- throw new IllegalArgumentException(NLS.bind(Messages.BackupStore_directory_file_mismatch, buFile.getAbsolutePath()));
+ if (buFile.isDirectory()) {
+ throw new IllegalArgumentException(
+ NLS.bind(Messages.BackupStore_directory_file_mismatch, buFile.getAbsolutePath()));
+ }
// has already been backed up - can only be done once with one BackupStore
- if (buFile.exists())
+ if (buFile.exists()) {
return false;
+ }
// make sure all of the directories exist / gets created
buFile.getParentFile().getCanonicalFile().mkdirs();
- if (buFile.getParentFile().exists() && !buFile.getParentFile().isDirectory())
- throw new IllegalArgumentException(NLS.bind(Messages.BackupStore_file_directory_mismatch, buFile.getParentFile().getAbsolutePath()));
+ if (buFile.getParentFile().exists() && !buFile.getParentFile().isDirectory()) {
+ throw new IllegalArgumentException(
+ NLS.bind(Messages.BackupStore_file_directory_mismatch, buFile.getParentFile().getAbsolutePath()));
+ }
// just make a copy - one has to be made in one direction anyway
// A renameTo followed by a copy is preferred as it preserves file permissions on the moved file
@@ -443,18 +476,23 @@ public class BackupStore implements IBackupStore {
* similar to a delete of a directory). Backup the files of the directory first.
* A call to backup a directory is really only needed for empty directories as a restore
* of a file will also restore all of its parent directories.
+ *
* @param file - the (empty) directory to back up
* @return true if the directory was moved to backup. false if the directory was already backed up
* @throws IllegalArgumentException if file is not a directory, or is not empty.
- * @throws IOException if directory can not be moved to the backup store, or if the directory is not writeable
+ * @throws IOException if directory can not be moved to the backup store, or if the directory is not
+ * writeable
*/
@Override
public boolean backupDirectory(File file) throws IOException {
- if (!file.isDirectory())
+ if (!file.isDirectory()) {
throw new IllegalArgumentException(NLS.bind(Messages.BackupStore_not_a_directory, file.getAbsolutePath()));
+ }
file = makeParentCanonical(file);
- if (file.list().length != 0)
- throw new IllegalArgumentException(NLS.bind(Messages.BackupStore_directory_not_empty, file.getAbsolutePath()));
+ if (file.list().length != 0) {
+ throw new IllegalArgumentException(
+ NLS.bind(Messages.BackupStore_directory_not_empty, file.getAbsolutePath()));
+ }
// the easiest way is to create a dummy file and back that up (the dummy is simply ignored when restoring).
File dummy = new File(file, dummyName);
dummy = makeParentCanonical(dummy);
@@ -463,15 +501,18 @@ public class BackupStore implements IBackupStore {
// backup only if the folder has not been already backed up;
// this can happen if, for example, two IUs unzip to the same folder and then want to delete it
if (!backedUp) {
- if (closed)
+ if (closed) {
throw new ClosedBackupStoreException("Can not perform backup()"); //$NON-NLS-1$
- if (!dummy.createNewFile())
+ }
+ if (!dummy.createNewFile()) {
throw new IOException(NLS.bind(Messages.BackupStore_can_not_create_dummy, dummy.getAbsolutePath()));
+ }
moveToBackup(dummy, buFile);
}
// previous checks have verified that the directory exists
- if (!file.delete())
+ if (!file.delete()) {
throw new IOException(NLS.bind(Messages.BackupStore_can_not_remove, dummy.getAbsolutePath()));
+ }
// will return true if the directory was already backed up at the beginning of the operation and false otherwise
return !backedUp;
}
@@ -482,31 +523,34 @@ public class BackupStore implements IBackupStore {
* in the restore location.
* When the backup has been restored this BackupStore instance is closed and can not be
* used for further backup or restore.
- *
+ *
* If there are unrestorable items (non writable directories, or general IO exceptions) these items
* are written to the log, and the backup copies remain in the file system and can be manually restored
* (using a simple zip of the backup directory, and an unzip to the buRoot once the problem has been corrected).
- *
- * @throws IOException if the backup was not fully restored - unrestored items have been logged.
+ *
+ * @throws IOException if the backup was not fully restored - unrestored items have been logged.
* @throws ClosedBackupStoreException if the backup is already closed.
*/
@Override
public void restore() throws IOException {
- if (closed)
+ if (closed) {
throw new ClosedBackupStoreException(Messages.BackupStore_restore_closed_store);
- // put back all files
+ }
+ // put back all files
// collect things that could not be restored (so final status can be reported)
Set<File> unrestorable = new HashSet<>();
boolean restored = true;
if (!backupRoot.exists()) {
logError(NLS.bind(Messages.BackupStore_missing_backup_directory, backupRoot.getAbsolutePath()));
restored = false;
- } else
+ } else {
restoreRoots(new File(backupRoot, backupName), unrestorable);
+ }
logUnrestorables(unrestorable);
- if (unrestorable.size() > 0)
+ if (unrestorable.size() > 0) {
restored = false;
+ }
close(restored);
closed = true;
}
@@ -515,8 +559,9 @@ public class BackupStore implements IBackupStore {
// if there are unrestorable units log them
//
if (unrestorable != null && unrestorable.size() > 0) {
- for (File file : unrestorable)
+ for (File file : unrestorable) {
logError(NLS.bind(Messages.BackupStore_manual_restore_needed, file.getAbsolutePath()));
+ }
}
}
@@ -526,8 +571,9 @@ public class BackupStore implements IBackupStore {
*/
@Override
public void discard() {
- if (closed)
+ if (closed) {
return;
+ }
closeSocket();
removeBackups();
closed = true;
@@ -537,32 +583,38 @@ public class BackupStore implements IBackupStore {
closeSocket();
// check external tampering with backup store
if (backupCounter != restoreCounter) {
- if (!fullyRestored)
- logError(NLS.bind(Messages.BackupStore_0_of_1_items_restored, Long.valueOf(restoreCounter), Long.valueOf(backupCounter)));
- else {
- logError(NLS.bind(Messages.BackupStore_externally_modified_0_of_1_restored, Long.valueOf(restoreCounter), Long.valueOf(backupCounter)));
+ if (!fullyRestored) {
+ logError(NLS.bind(Messages.BackupStore_0_of_1_items_restored, Long.valueOf(restoreCounter),
+ Long.valueOf(backupCounter)));
+ } else {
+ logError(NLS.bind(Messages.BackupStore_externally_modified_0_of_1_restored,
+ Long.valueOf(restoreCounter), Long.valueOf(backupCounter)));
fullyRestored = false;
}
}
- if (!fullyRestored)
+ if (!fullyRestored) {
throw new IOException(Messages.BackupStore_errors_while_restoring_see_log);
+ }
// everything has been restored - the backup can now be removed
removeBackups();
}
private void closeSocket() {
- if (socket != null && !socket.isClosed())
+ if (socket != null && !socket.isClosed()) {
try {
socket.close();
} catch (IOException e) { /* ignored */
- logWarning(NLS.bind(Messages.BackupStore_can_not_close_tcp_port, Integer.valueOf(socket.getLocalPort())));
+ logWarning(
+ NLS.bind(Messages.BackupStore_can_not_close_tcp_port, Integer.valueOf(socket.getLocalPort())));
}
+ }
}
private void removeBackups() {
File buRoot = new File(backupRoot, backupName);
- if (!fullyDelete(buRoot))
+ if (!fullyDelete(buRoot)) {
logWarning(NLS.bind(Messages.BackupStore_can_not_remove_bu_directory, buRoot.getAbsolutePath()));
+ }
for (String newName : renamedInPlace.values()) {
File buFile = new File(newName);
if (!fullyDelete(buFile)) {
@@ -589,6 +641,7 @@ public class BackupStore implements IBackupStore {
/**
* Deletes a file, or a directory with all of it's children.
+ *
* @param file the file or directory to fully delete
* @return true if, and only if the file is deleted without errors
*/
@@ -623,7 +676,8 @@ public class BackupStore implements IBackupStore {
if (!target.exists() && !target.mkdir()) {
unrestorable.add(bu);
continue; // give up on this branch
- } else if (target.exists() && !target.isDirectory()) {
+ }
+ if (target.exists() && !target.isDirectory()) {
// ouch, there is a file where we need a directory
// that must be deleted.
target.delete();
@@ -643,10 +697,11 @@ public class BackupStore implements IBackupStore {
// if the original was overwritten by something and this file was not
// removed, it needs to be deleted now. If it can't be deleted, the
// renameTo will fail, and the bu is reported as not restorable.
- // fullyDelete will remove a directory completely - we are restoring a file so it can
+ // fullyDelete will remove a directory completely - we are restoring a file so it can
// not be kept.
- if (target.exists())
+ if (target.exists()) {
fullyDelete(target);
+ }
// rename if possible, but must copy if not possible to just rename
if (!bu.renameTo(target)) {
@@ -665,8 +720,9 @@ public class BackupStore implements IBackupStore {
// could not remove the backup after copy - log, safe to remove manually
logWarning(NLS.bind(Messages.BackupStore_can_not_delete_tmp_file, bu.getAbsolutePath()));
}
- } else
+ } else {
restoreCounter++;
+ }
}
}
}
@@ -674,6 +730,7 @@ public class BackupStore implements IBackupStore {
/**
* Restores everything backed up in the buRoot. Responsible for decoding the specially named root
* target directories (i.e. _/, __/, C/, etc.) into the real system names.
+ *
* @param buRoot
* @param unrestorable
*/
@@ -684,7 +741,7 @@ public class BackupStore implements IBackupStore {
return;
}
for (File child : children) {
- // Names are root-chars, or drive letters in the root bu directory
+ // Names are root-chars, or drive letters in the root bu directory
String name = child.getName();
String rName = name;
String prefix = ""; //$NON-NLS-1$
@@ -695,8 +752,9 @@ public class BackupStore implements IBackupStore {
if (prefix.length() < 1) {
// The name is a drive name
rName = rName + ":" + File.separator; //$NON-NLS-1$
- } else
+ } else {
rName = prefix + rName;
+ }
// File root = new File(rName);
File bu = new File(buRoot, name);
File target = new File(rName);
@@ -722,34 +780,35 @@ public class BackupStore implements IBackupStore {
private void restoreRenamedFiles(Set<File> unrestorable) {
for (Entry<String, String> entry : renamedInPlace.entrySet()) {
File bu = new File(entry.getValue());
- if (!bu.renameTo(new File(entry.getKey())))
+ if (!bu.renameTo(new File(entry.getKey()))) {
unrestorable.add(bu);
+ }
}
}
private static long msCounter = 0;
/**
- * Generates a unique hex string by taking currentTimeMillis + sequence
+ * Generates a unique hex string by taking currentTimeMillis + sequence
* number at the end allowing for 32 numbers to be generated per ms.
- * This is sufficient uniqueness in the same VM. (And is still just a fallback solution
+ * This is sufficient uniqueness in the same VM. (And is still just a fallback solution
* if there is no access to a TCP port)
- *
+ *
* To make number unique over multiple VMs - the PID of the process would be enough, but
- * it is complicated to get hold of - a separate program must be launched and its PPID
+ * it is complicated to get hold of - a separate program must be launched and its PPID
* investigated. There is no standard API in Java to get the PID. Instead, a socket port is bound
* to ensure local uniqueness.
- *
+ *
* To make number unique across multiple hosts (we may be provisioning over NFS), the
- * 48 LS bits of the IP address is used (this is more than enough for an IPv4 address).
+ * 48 LS bits of the IP address is used (this is more than enough for an IPv4 address).
* (If there is no IP address, the machine is not on a
- * network) - unfortunately the MAC address can not be used as this requires Java 6 (where
+ * network) - unfortunately the MAC address can not be used as this requires Java 6 (where
* there also is a UUID that should be used instead of this method).
- *
+ *
* This method needs to be modified when IPv6 addressing is the norm - at that time, the
* restriction on Java 1.4 has hopefully been lifted, and it is possible to use the MAC address,
* or the UUID provided since java 1.6
- *
+ *
* @return a unique string
*/
private String genUnique() {
@@ -762,8 +821,9 @@ public class BackupStore implements IBackupStore {
// the returned address can be 32 bits IPv4, or 128 bits IPv6 (?)
// In any case use the LSB bits (as many as will fit
byte[] address = InetAddress.getLocalHost().getAddress();
- for (int i = 0; i < address.length; i++)
- ipPart = ((ipPart << 8) | (address[i] & 0xff));
+ for (byte element : address) {
+ ipPart = ((ipPart << 8) | (element & 0xff));
+ }
} catch (UnknownHostException e) {
// there is no IP address, and there and hence no concurrency from other machines.
// use the default ip part 0
@@ -776,9 +836,10 @@ public class BackupStore implements IBackupStore {
port = socket.getLocalPort();
} catch (IOException e) {
try {
- if (socket != null)
+ if (socket != null) {
socket.close();
- } catch (IOException e1) { // ignore failure to close -
+ }
+ } catch (IOException e1) { // ignore failure to close -
}
// use a random number as port in this case
port = new Random().nextInt() & 0xffff;
@@ -797,7 +858,7 @@ public class BackupStore implements IBackupStore {
* \\Host\C$\File becomes __\Host\C$\File
* /users/test/file becomes _/users/test/file
* C:/somewhere/file becomes C/somewhere/file
- *
+ *
* @param file
* @return a relativized absolute abstract file
*/
@@ -817,16 +878,17 @@ public class BackupStore implements IBackupStore {
// Transform C:/foo to C/foo
//
int idx = path.indexOf(":"); //$NON-NLS-1$
- if (idx < 1)
+ if (idx < 1) {
throw new InternalError("File is neither absolute nor has a drive name: " + path); //$NON-NLS-1$
+ }
path = path.substring(0, idx) + path.substring(idx + 1);
return new File(path);
}
- /**
+ /**
* The parent path may include ".." as a directory name - this must be made canonical. But if the file itself is
- * a symbolic link, it should not be resolved.
+ * a symbolic link, it should not be resolved.
*/
private File makeParentCanonical(File file) throws IOException {
return new File(file.getParentFile().getCanonicalFile(), file.getName());

Back to the top