try {
// The temporary file used for partial PUT.
tmp = new File(file.getCanonicalPath() + "."
+ getTemporaryExtension());
// Support only one range.
Range range = request.getRanges().get(0);
if (tmp.exists() && !isResumeUpload()) {
tmp.delete();
}
if (!tmp.exists()) {
// Copy the target file.
final BufferedReader br = new BufferedReader(
new FileReader(file));
final BufferedWriter wr = new BufferedWriter(
new FileWriter(tmp));
String s;
while ((s = br.readLine()) != null) {
wr.append(s);
}
br.close();
wr.flush();
wr.close();
}
raf = new RandomAccessFile(tmp, "rwd");
// Go to the desired offset.
if (range.getIndex() == Range.INDEX_LAST) {
if (raf.length() <= range.getSize()) {
raf.seek(range.getSize());
} else {
raf
.seek(raf.length()
- range.getSize());
}
} else {
raf.seek(range.getIndex());
}
// Write the entity to the temporary file.
if (request.isEntityAvailable()) {
ByteUtils.write(request.getEntity()
.getStream(), raf);
}
} catch (IOException ioe) {
getLogger().log(Level.WARNING,
"Unable to create the temporary file",
ioe);
response.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Unable to create a temporary file"));
error = true;
} finally {
try {
if (raf != null) {
raf.close();
// Calling the garbage collector helps
// to workaround lock issues on Windows
System.gc();
}
} catch (IOException ioe) {
getLogger()
.log(
Level.WARNING,
"Unable to close the temporary file",
ioe);
response.setStatus(
Status.SERVER_ERROR_INTERNAL, ioe);
error = true;
}
}
} else {
FileOutputStream fos = null;
try {
tmp = File.createTempFile("restlet-upload",
"bin");
if (request.isEntityAvailable()) {
fos = new FileOutputStream(tmp);
ByteUtils.write(request.getEntity()
.getStream(), fos);
}
} catch (IOException ioe) {
getLogger().log(Level.WARNING,
"Unable to create the temporary file",
ioe);
response.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Unable to create a temporary file"));
error = true;
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException ioe) {
getLogger()
.log(
Level.WARNING,
"Unable to close the temporary file",
ioe);
response.setStatus(
Status.SERVER_ERROR_INTERNAL, ioe);
error = true;
}
}
}
if (error) {
if (tmp.exists() && !isResumeUpload()) {
tmp.delete();
}
return;
}
// Then delete the existing file
if (tmp.exists() && file.delete()) {
// Finally move the temporary file to the
// existing file location
boolean renameSuccessfull = false;
if (tmp.renameTo(file)) {
if (request.getEntity() == null) {
response
.setStatus(Status.SUCCESS_NO_CONTENT);
} else {
response.setStatus(Status.SUCCESS_OK);
}
renameSuccessfull = true;
} else {
// Many aspects of the behavior of the method
// "renameTo" are inherently platform-dependent:
// the rename operation might not be able to
// move a file from one filesystem to another.
if (tmp.exists()) {
try {
final BufferedReader br = new BufferedReader(
new FileReader(tmp));
final BufferedWriter wr = new BufferedWriter(
new FileWriter(file));
String s;
while ((s = br.readLine()) != null) {
wr.append(s);
}
br.close();
wr.flush();
wr.close();
renameSuccessfull = true;
tmp.delete();
} catch (Exception e) {
renameSuccessfull = false;
}
}
if (!renameSuccessfull) {
getLogger()
.log(Level.WARNING,
"Unable to move the temporary file to replace the existing file");
response
.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Unable to move the temporary file to replace the existing file"));
}
}
} else {
getLogger().log(Level.WARNING,
"Unable to delete the existing file");
response.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Unable to delete the existing file"));
if (tmp.exists() && !isResumeUpload()) {
tmp.delete();
}
}
} else {
// The file does not exist yet.
final File parent = file.getParentFile();
if ((parent != null) && !parent.exists()) {
// Create the parent directories then the new file
if (!parent.mkdirs()) {
getLogger()
.log(Level.WARNING,
"Unable to create the parent directory");
response
.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Unable to create the parent directory"));
}
}
// Create the new file
if (partialPut) {
// This is a partial PUT
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(file, "rwd");
// Support only one range.
Range range = request.getRanges().get(0);
// Go to the desired offset.
if (range.getIndex() == Range.INDEX_LAST) {
if (raf.length() <= range.getSize()) {
raf.seek(range.getSize());
} else {
raf
.seek(raf.length()
- range.getSize());
}
} else {
raf.seek(range.getIndex());
}
// Write the entity to the file.
if (request.isEntityAvailable()) {
ByteUtils.write(request.getEntity()
.getStream(), raf);