/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Utility methods for copying and moving files.
*/
class WindowsFileCopy {
private WindowsFileCopy() {
}
/**
* Copy file from source to target
*/
final WindowsPath target,
CopyOption... options)
throws IOException
{
// map options
boolean replaceExisting = false;
boolean copyAttributes = false;
boolean followLinks = true;
boolean interruptible = false;
replaceExisting = true;
continue;
}
followLinks = false;
continue;
}
copyAttributes = true;
continue;
}
interruptible = true;
continue;
}
throw new NullPointerException();
throw new UnsupportedOperationException("Unsupported copy option");
}
// check permissions. If the source file is a symbolic link then
// later we must also check LinkPermission
target.checkWrite();
}
// get attributes of source file
// attempt to get attributes of target file
// if both files are the same there is nothing to do
// if target exists and !replace then throw exception
long sourceHandle = 0L;
try {
} catch (WindowsException x) {
}
try {
// source attributes
try {
} catch (WindowsException x) {
}
// open target (don't follow links)
long targetHandle = 0L;
try {
try {
// if both files are the same then nothing to do
return;
}
// can't replace file
if (!replaceExisting) {
throw new FileAlreadyExistsException(
}
} finally {
}
} catch (WindowsException x) {
// ignore
}
} finally {
}
// if source file is a symbolic link then we must check for LinkPermission
}
// if target exists then delete it.
if (targetAttrs != null) {
try {
} else {
}
} catch (WindowsException x) {
if (targetAttrs.isDirectory()) {
// ERROR_ALREADY_EXISTS is returned when attempting to delete
// non-empty directory on SAMBA servers.
if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
x.lastError() == ERROR_ALREADY_EXISTS)
{
throw new DirectoryNotEmptyException(
}
}
}
}
// Use CopyFileEx if the file is not a directory or junction
final int flags =
if (interruptible) {
// interruptible copy
public int cancelValue() {
return 1; // TRUE
}
public void implRun() throws IOException {
try {
} catch (WindowsException x) {
}
}
};
try {
} catch (ExecutionException e) {
if (t instanceof IOException)
throw (IOException)t;
throw new IOException(t);
}
} else {
// non-interruptible copy
try {
} catch (WindowsException x) {
}
}
if (copyAttributes) {
// CopyFileEx does not copy security attributes
try {
} catch (IOException x) {
// ignore
}
}
return;
}
// copy directory or directory junction
try {
if (sourceAttrs.isDirectory()) {
} else {
flags);
}
} catch (WindowsException x) {
}
if (copyAttributes) {
// copy DOS/timestamps attributes
try {
} catch (IOException x) {
if (sourceAttrs.isDirectory()) {
try {
} catch (WindowsException ignore) { }
}
}
// copy security attributes. If this fail it doesn't cause the move
// to fail.
try {
} catch (IOException ignore) { }
}
}
/**
* Move file from source to target
*/
throws IOException
{
// map options
boolean atomicMove = false;
boolean replaceExisting = false;
atomicMove = true;
continue;
}
replaceExisting = true;
continue;
}
// ignore
continue;
}
throw new UnsupportedOperationException("Unsupported copy option");
}
source.checkWrite();
target.checkWrite();
}
// atomic case
if (atomicMove) {
try {
} catch (WindowsException x) {
if (x.lastError() == ERROR_NOT_SAME_DEVICE) {
throw new AtomicMoveNotSupportedException(
x.errorString());
}
}
return;
}
// get attributes of source file
// attempt to get attributes of target file
// if both files are the same there is nothing to do
// if target exists and !replace then throw exception
long sourceHandle = 0L;
try {
} catch (WindowsException x) {
}
try {
// source attributes
try {
} catch (WindowsException x) {
}
// open target (don't follow links)
long targetHandle = 0L;
try {
try {
// if both files are the same then nothing to do
return;
}
// can't replace file
if (!replaceExisting) {
throw new FileAlreadyExistsException(
}
} finally {
}
} catch (WindowsException x) {
// ignore
}
} finally {
}
// if target exists then delete it.
if (targetAttrs != null) {
try {
} else {
}
} catch (WindowsException x) {
if (targetAttrs.isDirectory()) {
// ERROR_ALREADY_EXISTS is returned when attempting to delete
// non-empty directory on SAMBA servers.
if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
x.lastError() == ERROR_ALREADY_EXISTS)
{
throw new DirectoryNotEmptyException(
}
}
}
}
// first try MoveFileEx (no options). If target is on same volume then
// all attributes (including security attributes) are preserved.
try {
return;
} catch (WindowsException x) {
if (x.lastError() != ERROR_NOT_SAME_DEVICE)
}
// target is on different volume so use MoveFileEx with copy option
try {
} catch (WindowsException x) {
}
// MoveFileEx does not copy security attributes when moving
// across volumes.
try {
} catch (IOException x) {
// ignore
}
return;
}
// moving directory or directory-link to another file system
// create new directory or directory junction
try {
if (sourceAttrs.isDirectory()) {
} else {
}
} catch (WindowsException x) {
}
// copy timestamps/DOS attributes
try {
} catch (IOException x) {
// rollback
try {
} catch (WindowsException ignore) { }
throw x;
}
// copy security attributes. If this fails it doesn't cause the move
// to fail.
try {
} catch (IOException ignore) { }
// delete source
try {
} catch (WindowsException x) {
// rollback
try {
} catch (WindowsException ignore) { }
// ERROR_ALREADY_EXISTS is returned when attempting to delete
// non-empty directory on SAMBA servers.
if (x.lastError() == ERROR_DIR_NOT_EMPTY ||
x.lastError() == ERROR_ALREADY_EXISTS)
{
throw new DirectoryNotEmptyException(
}
}
}
try {
return path.getPathForWin32Calls();
} catch (WindowsException x) {
return null;
}
}
/**
*/
boolean followLinks)
throws IOException
{
// may need SeRestorePrivilege to set file owner
try {
int request = (DACL_SECURITY_INFORMATION |
try {
try {
} catch (WindowsException x) {
}
} finally {
}
} finally {
}
}
}