1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-15 04:55:22 +02:00

[209825] fix: Update SystemTarHandler so that archive operations could be cancelable.

This commit is contained in:
Xuan Chen 2007-11-30 16:45:52 +00:00
parent 1ad0910bd2
commit 78845993fb
3 changed files with 642 additions and 410 deletions

View file

@ -8,6 +8,7 @@
* {Name} (company) - description of contribution. * {Name} (company) - description of contribution.
* *
* Xuan Chen (IBM) - initial API and implementation * Xuan Chen (IBM) - initial API and implementation
* Xuan Chen (IBM) - [209825] add some info of printing the lock status
********************************************************************************/ ********************************************************************************/
package org.eclipse.rse.services.clientserver; package org.eclipse.rse.services.clientserver;
@ -207,4 +208,21 @@ public class SystemReentrantMutex {
} }
} }
/*
* Method used to debug this mutex
* uncomment it when needed
*
private void printLockMessage(int status, Thread myself)
{
if (status == LOCK_STATUS_AQUIRED)
{
System.out.println("Lock is AQUIRED by thread " + myself.getId());
}
else if (status == LOCK_STATUS_BORROWED)
{
System.out.println("Lock is BORROWED by thread " + myself.getId());
}
}
*/
} }

View file

@ -16,6 +16,8 @@
* Xuan Chen (IBM) - [194293] [Local][Archives] Saving file second time in an Archive Errors * Xuan Chen (IBM) - [194293] [Local][Archives] Saving file second time in an Archive Errors
* Xuan Chen (IBM) - [199132] [Archives-TAR][Local-Windows] Can't open files in tar archives * Xuan Chen (IBM) - [199132] [Archives-TAR][Local-Windows] Can't open files in tar archives
* Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread * Xuan Chen (IBM) - [160775] [api] rename (at least within a zip) blocks UI thread
* Xuan Chen (IBM) - [209828] Need to move the Create operation to a job.
* Xuan Chen (IBM) - [209825] Update SystemTarHandler so that archive operations could be cancelable.
*******************************************************************************/ *******************************************************************************/
package org.eclipse.rse.services.clientserver.archiveutils; package org.eclipse.rse.services.clientserver.archiveutils;
@ -43,6 +45,7 @@ import org.eclipse.rse.internal.services.clientserver.archiveutils.TarFile;
import org.eclipse.rse.internal.services.clientserver.archiveutils.TarOutputStream; import org.eclipse.rse.internal.services.clientserver.archiveutils.TarOutputStream;
import org.eclipse.rse.services.clientserver.ISystemFileTypes; import org.eclipse.rse.services.clientserver.ISystemFileTypes;
import org.eclipse.rse.services.clientserver.ISystemOperationMonitor; import org.eclipse.rse.services.clientserver.ISystemOperationMonitor;
import org.eclipse.rse.services.clientserver.SystemReentrantMutex;
import org.eclipse.rse.services.clientserver.java.BasicClassFileParser; import org.eclipse.rse.services.clientserver.java.BasicClassFileParser;
import org.eclipse.rse.services.clientserver.search.SystemSearchLineMatch; import org.eclipse.rse.services.clientserver.search.SystemSearchLineMatch;
import org.eclipse.rse.services.clientserver.search.SystemSearchStringMatchLocator; import org.eclipse.rse.services.clientserver.search.SystemSearchStringMatchLocator;
@ -57,6 +60,7 @@ public class SystemTarHandler implements ISystemArchiveHandler {
protected File file; protected File file;
protected long modTimeDuringCache; protected long modTimeDuringCache;
protected VirtualFileSystem vfs; protected VirtualFileSystem vfs;
protected SystemReentrantMutex _mutex;
/** /**
* This class represents a virtual file system. A virtual file system is simply a data structure that * This class represents a virtual file system. A virtual file system is simply a data structure that
@ -556,6 +560,7 @@ public class SystemTarHandler implements ISystemArchiveHandler {
init(file); init(file);
createCache(); createCache();
modTimeDuringCache = file.lastModified(); modTimeDuringCache = file.lastModified();
_mutex = new SystemReentrantMutex();
} }
/** /**
@ -836,15 +841,18 @@ public class SystemTarHandler implements ISystemArchiveHandler {
*/ */
public boolean extractVirtualFile(String fullVirtualName, File destination, ISystemOperationMonitor archiveOperationMonitor) { public boolean extractVirtualFile(String fullVirtualName, File destination, ISystemOperationMonitor archiveOperationMonitor) {
fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName);
TarEntry entry = getTarFile().getEntry(fullVirtualName); TarEntry entry = null;
try { InputStream inStream = null;
OutputStream outStream = null;
int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK;
try
{
mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE);
if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus)
{
entry = getTarFile().getEntry(fullVirtualName);
updateCache(); updateCache();
}
catch (IOException e) {
// TODO: log error
return false;
}
// if the entry is a directory, simply create the destination and set the last modified time to // if the entry is a directory, simply create the destination and set the last modified time to
// the entry's last modified time // the entry's last modified time
@ -862,11 +870,6 @@ public class SystemTarHandler implements ISystemArchiveHandler {
return true; return true;
} }
// entry is not a directory
InputStream inStream = null;
OutputStream outStream = null;
try {
inStream = getTarFile().getInputStream(entry); inStream = getTarFile().getInputStream(entry);
if (inStream == null) { if (inStream == null) {
@ -892,6 +895,7 @@ public class SystemTarHandler implements ISystemArchiveHandler {
numRead = inStream.read(buf); numRead = inStream.read(buf);
} }
} }
}
catch (IOException e) { catch (IOException e) {
// TODO: log error // TODO: log error
} }
@ -906,14 +910,19 @@ public class SystemTarHandler implements ISystemArchiveHandler {
if (inStream != null) { if (inStream != null) {
inStream.close(); inStream.close();
} }
}
catch (IOException e) {
// TODO: log error
}
// finished creating and writing to the file, so now set the last modified time // finished creating and writing to the file, so now set the last modified time
// to the entry's last modified time // to the entry's last modified time
if (entry != null)
{
destination.setLastModified(entry.getModificationTime()); destination.setLastModified(entry.getModificationTime());
}
}
catch (IOException e) {
e.printStackTrace();
}
releaseMutex(mutexLockStatus);
} }
return true; return true;
@ -946,14 +955,15 @@ public class SystemTarHandler implements ISystemArchiveHandler {
fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName);
// update our cache before accessing cache
try { int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK;
try
{
mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE);
if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus)
{
updateCache(); updateCache();
}
catch (IOException e) {
// TODO: log error
return false;
}
VirtualChild dir = vfs.getEntry(fullVirtualName); VirtualChild dir = vfs.getEntry(fullVirtualName);
@ -990,7 +1000,11 @@ public class SystemTarHandler implements ISystemArchiveHandler {
return false; // log error and quit if we fail to create the directory return false; // log error and quit if we fail to create the directory
} }
else { else {
extractVirtualFile(fullVirtualName, topDir, archiveOperationMonitor); boolean returnCode = extractVirtualFile(fullVirtualName, topDir, archiveOperationMonitor);
if (returnCode == false)
{
return returnCode;
}
} }
// get the children of this directory // get the children of this directory
@ -1001,18 +1015,33 @@ public class SystemTarHandler implements ISystemArchiveHandler {
String childPath = topDirPath + File.separator + tempChild.name; String childPath = topDirPath + File.separator + tempChild.name;
File childFile = new File(childPath); File childFile = new File(childPath);
boolean returnCode = false;
// if the child is a directory, then we need to extract it and its children // if the child is a directory, then we need to extract it and its children
if (tempChild.isDirectory) { if (tempChild.isDirectory) {
// and now extract its children // and now extract its children
extractVirtualDirectory(tempChild.fullName, childFile, (File) null, archiveOperationMonitor); returnCode = extractVirtualDirectory(tempChild.fullName, childFile, (File) null, archiveOperationMonitor);
} }
// otherwise if the child is a file, simply extract it // otherwise if the child is a file, simply extract it
else { else {
extractVirtualFile(tempChild.fullName, childFile, archiveOperationMonitor); returnCode = extractVirtualFile(tempChild.fullName, childFile, archiveOperationMonitor);
}
if (returnCode == false)
{
return returnCode;
} }
} }
}
}
catch (IOException e)
{
e.printStackTrace();
return false;
}
finally
{
releaseMutex(mutexLockStatus);
}
return true; return true;
} }
@ -1022,19 +1051,29 @@ public class SystemTarHandler implements ISystemArchiveHandler {
public boolean add(File file, String virtualPath, String name, ISystemOperationMonitor archiveOperationMonitor ) { public boolean add(File file, String virtualPath, String name, ISystemOperationMonitor archiveOperationMonitor ) {
virtualPath = ArchiveHandlerManager.cleanUpVirtualPath(virtualPath); virtualPath = ArchiveHandlerManager.cleanUpVirtualPath(virtualPath);
int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK;
try
{
mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE);
if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus)
{
if (!file.isDirectory()) { if (!file.isDirectory()) {
// if it exists, call replace // if it exists, call replace
String fullVirtualName = getFullVirtualName(virtualPath, name); String fullVirtualName = getFullVirtualName(virtualPath, name);
if (exists(fullVirtualName, archiveOperationMonitor)) { if (exists(fullVirtualName, archiveOperationMonitor)) {
return replace(fullVirtualName, file, name, archiveOperationMonitor); boolean returnCode = replace(fullVirtualName, file, name, archiveOperationMonitor);
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return returnCode;
} }
else { else {
File[] files = new File[1]; File[] files = new File[1];
files[0] = file; files[0] = file;
String[] names = new String[1]; String[] names = new String[1];
names[0] = name; names[0] = name;
return add(files, virtualPath, names, archiveOperationMonitor); boolean returnCode = add(files, virtualPath, names, archiveOperationMonitor);
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return returnCode;
} }
} }
else { else {
@ -1062,9 +1101,23 @@ public class SystemTarHandler implements ISystemArchiveHandler {
newNames[numOfChildren] = newNames[numOfChildren] + "/"; //$NON-NLS-1$ newNames[numOfChildren] = newNames[numOfChildren] + "/"; //$NON-NLS-1$
} }
return add(sources, virtualPath, newNames, archiveOperationMonitor); boolean returnCode = add(sources, virtualPath, newNames, archiveOperationMonitor);
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return returnCode;
} }
} }
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
releaseMutex(mutexLockStatus);
}
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return false;
}
/** /**
* Helper method. . . populates <code>found</code> with a * Helper method. . . populates <code>found</code> with a
@ -1090,14 +1143,17 @@ public class SystemTarHandler implements ISystemArchiveHandler {
*/ */
public boolean add(File[] files, String virtualPath, String[] names, ISystemOperationMonitor archiveOperationMonitor) { public boolean add(File[] files, String virtualPath, String[] names, ISystemOperationMonitor archiveOperationMonitor) {
// update our cache before accessing cache int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK;
try { File outputTempFile = null;
TarOutputStream outStream = null;
try
{
mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE);
if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus)
{
updateCache(); updateCache();
}
catch (IOException e) {
// TODO: log error
return false;
}
virtualPath = ArchiveHandlerManager.cleanUpVirtualPath(virtualPath); virtualPath = ArchiveHandlerManager.cleanUpVirtualPath(virtualPath);
@ -1106,6 +1162,7 @@ public class SystemTarHandler implements ISystemArchiveHandler {
for (int i = 0; i < numFiles; i++) { for (int i = 0; i < numFiles; i++) {
if (!files[i].exists() || !files[i].canRead()) { if (!files[i].exists() || !files[i].canRead()) {
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return false; return false;
} }
@ -1114,22 +1171,33 @@ public class SystemTarHandler implements ISystemArchiveHandler {
// I think we should check each entry and replace or create for each one // I think we should check each entry and replace or create for each one
String fullVirtualName = getFullVirtualName(virtualPath, names[i]); String fullVirtualName = getFullVirtualName(virtualPath, names[i]);
if (exists(fullVirtualName, archiveOperationMonitor)) { if (exists(fullVirtualName, archiveOperationMonitor)) {
return replace(fullVirtualName, files[i], names[i], archiveOperationMonitor);
}
}
try { boolean returnCode = replace(fullVirtualName, files[i], names[i], archiveOperationMonitor);
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return returnCode;
}
}
// open a new temp file which will be our destination for the new tar file // open a new temp file which will be our destination for the new tar file
File outFile = new File(file.getAbsolutePath() + "temp"); //$NON-NLS-1$ outputTempFile = new File(file.getAbsolutePath() + "temp"); //$NON-NLS-1$
TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outFile)); outStream = new TarOutputStream(new FileOutputStream(outputTempFile));
// get all the entries in the current tar // get all the entries in the current tar
VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor); VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor);
// if it is an empty temp file, no need to recreate it // if it is an empty temp file, no need to recreate it
if (children.length != 0) { if (children.length != 0) {
createTar(children, outStream, (HashSet)null); boolean isCanceled = createTar(children, outStream, (HashSet)null, archiveOperationMonitor);
if (isCanceled)
{
outStream.close();
if (outputTempFile != null)
{
outputTempFile.delete();
}
return false;
}
} }
// for each new file to add // for each new file to add
@ -1152,14 +1220,36 @@ public class SystemTarHandler implements ISystemArchiveHandler {
// replace the current tar file with the new one, and do not update cache since // replace the current tar file with the new one, and do not update cache since
// we just did // we just did
replaceFile(outFile, false); replaceFile(outputTempFile, false);
}
} }
catch (IOException e) { catch (IOException e) {
// TODO: log error e.printStackTrace();
// close output stream
if (outStream != null)
{
try
{
outStream.close();
}
catch (Exception exp)
{
exp.printStackTrace();
}
}
if (outputTempFile != null)
{
outputTempFile.delete();
}
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return false; return false;
} }
finally
{
releaseMutex(mutexLockStatus);
}
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return true; return true;
} }
@ -1169,13 +1259,14 @@ public class SystemTarHandler implements ISystemArchiveHandler {
* @param children an array of virtual children from which to create a tar file. * @param children an array of virtual children from which to create a tar file.
* @param outStream the tar output stream to use. * @param outStream the tar output stream to use.
* @param omitChildren the set of names for children that should be omitted from the given array of virtual children. * @param omitChildren the set of names for children that should be omitted from the given array of virtual children.
* @param the operation progress monitor
* @throws IOException if an I/O exception occurs. * @throws IOException if an I/O exception occurs.
*/ */
protected void createTar(VirtualChild[] children, TarOutputStream outStream, HashSet omitChildren) throws IOException { protected boolean createTar(VirtualChild[] children, TarOutputStream outStream, HashSet omitChildren, ISystemOperationMonitor archiveOperationMonitor) throws IOException {
// TODO: if all children are to be deleted, we leave the tar file with a dummy entry // TODO: if all children are to be deleted, we leave the tar file with a dummy entry
if (omitChildren != null && children.length == omitChildren.size()) { if (omitChildren != null && children.length == omitChildren.size()) {
return; return false;
} }
TarFile tarFile = getTarFile(); TarFile tarFile = getTarFile();
@ -1183,6 +1274,11 @@ public class SystemTarHandler implements ISystemArchiveHandler {
// go through each child // go through each child
for (int i = 0; i < children.length; i++) { for (int i = 0; i < children.length; i++) {
if (archiveOperationMonitor != null && archiveOperationMonitor.isCanceled())
{
//the operation has been canceled
return true;
}
// if entry name is in the omit set, then do not include it // if entry name is in the omit set, then do not include it
if (omitChildren != null && omitChildren.contains(children[i].fullName)) { if (omitChildren != null && omitChildren.contains(children[i].fullName)) {
continue; continue;
@ -1229,6 +1325,7 @@ public class SystemTarHandler implements ISystemArchiveHandler {
outStream.closeEntry(); outStream.closeEntry();
} }
} }
return false;
} }
/** /**
@ -1414,6 +1511,11 @@ public class SystemTarHandler implements ISystemArchiveHandler {
protected VirtualChild getVirtualChild(TarEntry entry) { protected VirtualChild getVirtualChild(TarEntry entry) {
VirtualChild child = new VirtualChild(this, entry.getName()); VirtualChild child = new VirtualChild(this, entry.getName());
child.isDirectory = entry.isDirectory(); child.isDirectory = entry.isDirectory();
child.setComment(""); //$NON-NLS-1$
child.setCompressedSize(entry.getSize());
child.setCompressionMethod(""); //$NON-NLS-1$;
child.setSize(entry.getSize());
child.setTimeStamp(entry.getModificationTime());
return child; return child;
} }
@ -1484,9 +1586,9 @@ public class SystemTarHandler implements ISystemArchiveHandler {
try { try {
// open a new temp file which will be our destination for the new tar file // open a new temp file which will be our destination for the new tar file
File outFile = new File(getArchive().getAbsolutePath() + "temp"); //$NON-NLS-1$ File outputTempFile = new File(getArchive().getAbsolutePath() + "temp"); //$NON-NLS-1$
TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outFile)); TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outputTempFile));
// get all the entries // get all the entries
VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor); VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor);
@ -1497,8 +1599,17 @@ public class SystemTarHandler implements ISystemArchiveHandler {
// add the virtual file to be replaced // add the virtual file to be replaced
omissions.add(fullVirtualName); omissions.add(fullVirtualName);
// create the temp tar boolean isCanceled = createTar(children, outStream, omissions, archiveOperationMonitor);
createTar(children, outStream, omissions); if (isCanceled)
{
outStream.close();
if (outputTempFile != null)
{
outputTempFile.delete();
}
return false;
}
// now append the new file to the tar // now append the new file to the tar
String parentVirtualPath = null; String parentVirtualPath = null;
@ -1539,7 +1650,7 @@ public class SystemTarHandler implements ISystemArchiveHandler {
// replace the current tar file with the new one, and do not update cache since // replace the current tar file with the new one, and do not update cache since
// we just did // we just did
replaceFile(outFile, false); replaceFile(outputTempFile, false);
return true; return true;
} }
@ -1552,17 +1663,24 @@ public class SystemTarHandler implements ISystemArchiveHandler {
/** /**
* @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#delete(java.lang.String, ISystemOperationMonitor) * @see org.eclipse.rse.services.clientserver.archiveutils.ISystemArchiveHandler#delete(java.lang.String, ISystemOperationMonitor)
*/ */
public boolean delete(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { public boolean delete(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor)
{
boolean returnCode = doDelete(fullVirtualName, archiveOperationMonitor);
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return returnCode;
}
// update our cache before accessing cache
try { protected boolean doDelete(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) {
File outputTempFile = null;
int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK;
try
{
mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE);
if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus)
{
updateCache(); updateCache();
}
catch (IOException e) {
// TODO: log error
return false;
}
fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName);
VirtualChild child = getVirtualFile(fullVirtualName, archiveOperationMonitor); VirtualChild child = getVirtualFile(fullVirtualName, archiveOperationMonitor);
VirtualChild[] omitArray = new VirtualChild[0]; VirtualChild[] omitArray = new VirtualChild[0];
@ -1577,11 +1695,9 @@ public class SystemTarHandler implements ISystemArchiveHandler {
omitArray = getVirtualChildrenList(fullVirtualName, archiveOperationMonitor); omitArray = getVirtualChildrenList(fullVirtualName, archiveOperationMonitor);
} }
try {
// open a new temp file which will be our destination for the new tar file // open a new temp file which will be our destination for the new tar file
File outFile = new File(file.getAbsolutePath() + "temp"); //$NON-NLS-1$ outputTempFile = new File(file.getAbsolutePath() + "temp"); //$NON-NLS-1$
TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outFile)); TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outputTempFile));
// get all the entries in the current tar // get all the entries in the current tar
VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor); VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor);
@ -1598,8 +1714,17 @@ public class SystemTarHandler implements ISystemArchiveHandler {
omissions.add(omitArray[i].fullName); omissions.add(omitArray[i].fullName);
} }
// create the tar boolean isCanceled = createTar(children, outStream, omissions, archiveOperationMonitor);
createTar(children, outStream, omissions); if (isCanceled)
{
outStream.close();
if (outputTempFile != null)
{
outputTempFile.delete();
}
return false;
}
// delete the child from the cache (this will also delete its children if it // delete the child from the cache (this will also delete its children if it
// is a directory) // is a directory)
@ -1610,14 +1735,22 @@ public class SystemTarHandler implements ISystemArchiveHandler {
// replace the current tar file with the new one, and do not update cache since // replace the current tar file with the new one, and do not update cache since
// we just did // we just did
replaceFile(outFile, false); replaceFile(outputTempFile, false);
return true; return true;
} }
}
catch (IOException e) { catch (IOException e) {
// TODO: log error System.out.println(e.getMessage());
System.out.println("Could not delete " + fullVirtualName); //$NON-NLS-1$
if (!(outputTempFile == null)) outputTempFile.delete();
return false; return false;
} }
finally
{
releaseMutex(mutexLockStatus);
}
return false;
} }
/** /**
@ -1627,15 +1760,21 @@ public class SystemTarHandler implements ISystemArchiveHandler {
fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName);
int i = fullVirtualName.lastIndexOf("/"); //$NON-NLS-1$ int i = fullVirtualName.lastIndexOf("/"); //$NON-NLS-1$
boolean resultCode = false;
// if the original does not have any separator, simply rename it. // if the original does not have any separator, simply rename it.
if (i == -1) { if (i == -1)
return fullRename(fullVirtualName, newName, archiveOperationMonitor); {
resultCode = fullRename(fullVirtualName, newName, archiveOperationMonitor);
} }
// otherwise, get the parent path and append the new name to it. // otherwise, get the parent path and append the new name to it.
else { else
{
String fullNewName = fullVirtualName.substring(0, i+1) + newName; String fullNewName = fullVirtualName.substring(0, i+1) + newName;
return fullRename(fullVirtualName, fullNewName, archiveOperationMonitor); resultCode = fullRename(fullVirtualName, fullNewName, archiveOperationMonitor);
} }
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return resultCode;
} }
/** /**
@ -1663,14 +1802,14 @@ public class SystemTarHandler implements ISystemArchiveHandler {
*/ */
public boolean fullRename(String fullVirtualName, String newFullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { public boolean fullRename(String fullVirtualName, String newFullVirtualName, ISystemOperationMonitor archiveOperationMonitor) {
int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK;
File outputTempFile = null;
// update our cache before accessing cache // update our cache before accessing cache
try { try
updateCache(); {
} mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE);
catch (IOException e) { if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus)
// TODO: log error {
return false;
}
fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName);
newFullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(newFullVirtualName); newFullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(newFullVirtualName);
@ -1681,11 +1820,10 @@ public class SystemTarHandler implements ISystemArchiveHandler {
return false; return false;
} }
try {
// open a new temp file which will be our destination for the new tar file // open a new temp file which will be our destination for the new tar file
File outFile = new File(file.getAbsolutePath() + "temp"); //$NON-NLS-1$ outputTempFile = new File(file.getAbsolutePath() + "temp"); //$NON-NLS-1$
TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outFile)); TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outputTempFile));
// get all the entries // get all the entries
VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor); VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor);
@ -1735,6 +1873,16 @@ public class SystemTarHandler implements ISystemArchiveHandler {
// create tar with renamed entries // create tar with renamed entries
boolean isCanceled = createTar(children, outStream, names, archiveOperationMonitor); boolean isCanceled = createTar(children, outStream, names, archiveOperationMonitor);
if (isCanceled)
{
outStream.close();
if (outputTempFile != null)
{
outputTempFile.delete();
}
return false;
}
if (true == isCanceled) if (true == isCanceled)
{ {
@ -1747,15 +1895,27 @@ public class SystemTarHandler implements ISystemArchiveHandler {
// TODO: we force a fresh update of the cache because it is seemingly complicated // TODO: we force a fresh update of the cache because it is seemingly complicated
// to do the delta upgrade of the cache. But investigate this, since it will // to do the delta upgrade of the cache. But investigate this, since it will
// probably be more efficient // probably be more efficient
replaceFile(outFile, true); replaceFile(outputTempFile, true);
updateCache();
return true; return true;
} }
catch (IOException e) { else
// TODO: log error {
return false; return false;
} }
} }
catch (IOException e) {
e.printStackTrace();
System.out.println("Could not rename " + fullVirtualName); //$NON-NLS-1$
if (!(outputTempFile == null)) outputTempFile.delete();
return false;
}
finally
{
releaseMutex(mutexLockStatus);
}
}
/** /**
* Creates a tar file from the given virtual child objects, using the given output stream and renaming entries * Creates a tar file from the given virtual child objects, using the given output stream and renaming entries
@ -1773,8 +1933,9 @@ public class SystemTarHandler implements ISystemArchiveHandler {
// go through each child // go through each child
for (int i = 0; i < children.length; i++) { for (int i = 0; i < children.length; i++) {
if (archiveOperationMonitor.isCanceled()) if (archiveOperationMonitor != null && archiveOperationMonitor.isCanceled())
{ {
//the operation has been canceled
return true; return true;
} }
@ -1901,7 +2062,9 @@ public class SystemTarHandler implements ISystemArchiveHandler {
public boolean createFolder(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { public boolean createFolder(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) {
fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName);
fullVirtualName = fullVirtualName + "/"; //$NON-NLS-1$ fullVirtualName = fullVirtualName + "/"; //$NON-NLS-1$
return createVirtualObject(fullVirtualName, archiveOperationMonitor); boolean returnCode = createVirtualObject(fullVirtualName, archiveOperationMonitor);
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return returnCode;
} }
/** /**
@ -1909,7 +2072,9 @@ public class SystemTarHandler implements ISystemArchiveHandler {
*/ */
public boolean createFile(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) { public boolean createFile(String fullVirtualName, ISystemOperationMonitor archiveOperationMonitor) {
fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName); fullVirtualName = ArchiveHandlerManager.cleanUpVirtualPath(fullVirtualName);
return createVirtualObject(fullVirtualName, archiveOperationMonitor); boolean returnCode = createVirtualObject(fullVirtualName, archiveOperationMonitor);
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return returnCode;
} }
/** /**
@ -1920,32 +2085,42 @@ public class SystemTarHandler implements ISystemArchiveHandler {
*/ */
protected boolean createVirtualObject(String name, ISystemOperationMonitor archiveOperationMonitor) { protected boolean createVirtualObject(String name, ISystemOperationMonitor archiveOperationMonitor) {
// update our cache before accessing cache File outputTempFile = null;
try { TarOutputStream outStream = null;
int mutexLockStatus = SystemReentrantMutex.LOCK_STATUS_NOLOCK;
try
{
mutexLockStatus = _mutex.waitForLock(archiveOperationMonitor, Long.MAX_VALUE);
if (SystemReentrantMutex.LOCK_STATUS_NOLOCK != mutexLockStatus)
{
updateCache(); updateCache();
}
catch (IOException e) {
// TODO: log error
return false;
}
// if the object already exists, return false // if the object already exists, return false
if (exists(name, archiveOperationMonitor)) { if (exists(name, archiveOperationMonitor)) {
return false; return false;
} }
try {
// open a new temp file which will be our destination for the new tar file // open a new temp file which will be our destination for the new tar file
File outFile = new File(file.getAbsolutePath() + "temp"); //$NON-NLS-1$ outputTempFile = new File(file.getAbsolutePath() + "temp"); //$NON-NLS-1$
TarOutputStream outStream = new TarOutputStream(new FileOutputStream(outFile)); outStream = new TarOutputStream(new FileOutputStream(outputTempFile));
// get all the entries // get all the entries
VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor); VirtualChild[] children = getVirtualChildrenList(archiveOperationMonitor);
// if it is an empty temp file, no need to recreate it // if it is an empty temp file, no need to recreate it
if (children.length != 0) { if (children.length != 0) {
createTar(children, outStream, (HashSet)null); boolean isCanceled = createTar(children, outStream, (HashSet)null, archiveOperationMonitor);
if (isCanceled)
{
outStream.close();
if (outputTempFile != null)
{
outputTempFile.delete();
}
return false;
}
} }
// append an empty file to the tar file // append an empty file to the tar file
@ -1960,14 +2135,36 @@ public class SystemTarHandler implements ISystemArchiveHandler {
// replace the current tar file with the new one, but do not update the cache // replace the current tar file with the new one, but do not update the cache
// since we have already updated to the cache // since we have already updated to the cache
replaceFile(outFile, false); replaceFile(outputTempFile, false);
return true; return true;
} }
}
catch (IOException e) { catch (IOException e) {
// TODO: log error e.printStackTrace();
// close output stream
if (outStream != null)
{
try
{
outStream.close();
}
catch (Exception exp)
{
exp.printStackTrace();
}
}
if (outputTempFile != null)
{
outputTempFile.delete();
}
return false; return false;
} }
finally
{
releaseMutex(mutexLockStatus);
}
return false;
} }
/** /**
@ -2297,4 +2494,22 @@ public class SystemTarHandler implements ISystemArchiveHandler {
} }
return fullVirtualName; return fullVirtualName;
} }
private void releaseMutex(int mutexLockStatus)
{
//We only release the mutex if we aquired it, not borrowed it.
if (SystemReentrantMutex.LOCK_STATUS_AQUIRED == mutexLockStatus)
{
_mutex.release();
}
}
private void setArchiveOperationMonitorStatusDone(ISystemOperationMonitor archiveOperationMonitor)
{
//We only set the status of the archive operation montor to done if it is not been canceled.
if (null != archiveOperationMonitor && !archiveOperationMonitor.isCanceled())
{
archiveOperationMonitor.setDone(true);
}
}
} }

View file

@ -1838,7 +1838,9 @@ public class SystemZipHandler implements ISystemArchiveHandler
{ {
name = ArchiveHandlerManager.cleanUpVirtualPath(name); name = ArchiveHandlerManager.cleanUpVirtualPath(name);
name = name + "/"; //$NON-NLS-1$ name = name + "/"; //$NON-NLS-1$
return createVirtualObject(name, true, archiveOperationMonitor); boolean returnCode = createVirtualObject(name, true, archiveOperationMonitor);
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return returnCode;
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -1847,7 +1849,9 @@ public class SystemZipHandler implements ISystemArchiveHandler
public boolean createFile(String name, ISystemOperationMonitor archiveOperationMonitor) public boolean createFile(String name, ISystemOperationMonitor archiveOperationMonitor)
{ {
name = ArchiveHandlerManager.cleanUpVirtualPath(name); name = ArchiveHandlerManager.cleanUpVirtualPath(name);
return createVirtualObject(name, true, archiveOperationMonitor); boolean returnCode = createVirtualObject(name, true, archiveOperationMonitor);
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return returnCode;
} }
/** /**
@ -1862,13 +1866,11 @@ public class SystemZipHandler implements ISystemArchiveHandler
{ {
if (!_exists) if (!_exists)
{ {
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return false; return false;
} }
if (exists(name, archiveOperationMonitor)) if (exists(name, archiveOperationMonitor))
{ {
// The object already exists. // The object already exists.
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return false; return false;
} }
@ -1914,7 +1916,6 @@ public class SystemZipHandler implements ISystemArchiveHandler
replaceOldZip(outputTempFile); replaceOldZip(outputTempFile);
if (closeZipFile) closeZipFile(); if (closeZipFile) closeZipFile();
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return true; return true;
} }
} }
@ -1924,14 +1925,12 @@ public class SystemZipHandler implements ISystemArchiveHandler
System.out.println("Could not add a file."); //$NON-NLS-1$ System.out.println("Could not add a file."); //$NON-NLS-1$
System.out.println(e.getMessage()); System.out.println(e.getMessage());
if (closeZipFile) closeZipFile(); if (closeZipFile) closeZipFile();
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return false; return false;
} }
finally finally
{ {
releaseMutex(mutexLockStatus); releaseMutex(mutexLockStatus);
} }
setArchiveOperationMonitorStatusDone(archiveOperationMonitor);
return false; return false;
} }