// Several checks : first the consistency of the metadata and the
// filename
if (!checkMetadataConsistency(file.getName(), metadataService,
request.getEntity())) {
// ask the client to reiterate properly its request
response.setStatus(new Status(Status.REDIRECTION_SEE_OTHER,
"The metadata are not consistent with the URI"));
} else {
// Deals with directory
boolean isDirectory = false;
if (file.exists()) {
if (file.isDirectory()) {
isDirectory = true;
response
.setStatus(new Status(
Status.CLIENT_ERROR_FORBIDDEN,
"Can't put a new representation of a directory"));
}
} else {
// No existing file or directory found
if (path.endsWith("/")) {
isDirectory = true;
// Create a new directory and its necessary parents
if (file.mkdirs()) {
response.setStatus(Status.SUCCESS_NO_CONTENT);
} else {
getLogger().log(Level.WARNING,
"Unable to create the new directory");
response.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Unable to create the new directory"));
}
}
}
if (!isDirectory) {
// We look for the possible variants
// 1- set up base name as the longest part of the name
// without known extensions (beginning from the left)
String baseName = getBaseName(file, metadataService);
Set<String> extensions = getExtensions(file,
metadataService);
// 2- loooking for resources with the same base name
File[] files = file.getParentFile().listFiles();
File uniqueVariant = null;
List<File> variantsList = new ArrayList<File>();
if (files != null) {
for (File entry : files) {
if (entry.getName().startsWith(baseName)) {
Set<String> entryExtensions = getExtensions(
entry, metadataService);
if (entryExtensions.containsAll(extensions)) {
variantsList.add(entry);
if (extensions.containsAll(entryExtensions)) {
// The right representation has been
// found.
uniqueVariant = entry;
}
}
}
}
}
if (uniqueVariant != null) {
file = uniqueVariant;
} else {
if (!variantsList.isEmpty()) {
// Negociated resource (several variants, but not
// the right one).
// Check if the request could be completed or not.
// The request could be more precise
response
.setStatus(new Status(
Status.CLIENT_ERROR_NOT_ACCEPTABLE,
"Unable to process properly the request. Several variants exist but none of them suits precisely."));
} else {
// This resource does not exist, yet.
// Complete it with the default metadata
updateMetadata(metadataService, file.getName(),
request.getEntity());
if (request.getEntity().getLanguages().isEmpty()) {
if (metadataService.getDefaultLanguage() != null) {
request.getEntity().getLanguages().add(
metadataService
.getDefaultLanguage());
}
}
if (request.getEntity().getMediaType() == null) {
request.getEntity().setMediaType(
metadataService.getDefaultMediaType());
}
if (request.getEntity().getEncodings().isEmpty()) {
if (metadataService.getDefaultEncoding() != null
&& !metadataService
.getDefaultEncoding().equals(
Encoding.IDENTITY)) {
request.getEntity().getEncodings().add(
metadataService
.getDefaultEncoding());
}
}
// Update the URI
StringBuilder fileName = new StringBuilder(baseName);
if (metadataService.getExtension(request
.getEntity().getMediaType()) != null) {
fileName.append("."
+ metadataService.getExtension(request
.getEntity().getMediaType()));
}
for (Language language : request.getEntity()
.getLanguages()) {
if (metadataService.getExtension(language) != null) {
fileName.append("."
+ metadataService
.getExtension(language));
}
}
for (Encoding encoding : request.getEntity()
.getEncodings()) {
if (metadataService.getExtension(encoding) != null) {
fileName.append("."
+ metadataService
.getExtension(encoding));
}
}
file = new File(file.getParentFile(), fileName
.toString());
}
}
// Before putting the file representation, we check that all
// the extensions are known
if (!checkExtensionsConsistency(file, metadataService)) {
response
.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Unable to process properly the URI. At least one extension is not known by the server."));
} else {
File tmp = null;
if (file.exists()) {
FileOutputStream fos = null;
// Replace the content of the file
// First, create a temporary file
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"));
} finally {
try {
if (fos != null)
fos.close();
} catch (IOException ioe) {
getLogger()
.log(
Level.WARNING,
"Unable to close the temporary file",
ioe);
response
.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Unable to close a temporary file"));
}
}
// Then delete the existing file
if (file.delete()) {
// Finally move the temporary file to the
// existing file location
boolean renameSuccessfull = false;
if ((tmp != null) && 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 != null && tmp.exists()) {
try {
BufferedReader br = new BufferedReader(
new FileReader(tmp));
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"));
}
} else {
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"));
}
}
FileOutputStream fos = null;
// Create the new file
try {
if (file.createNewFile()) {
if (request.getEntity() == null) {
response
.setStatus(Status.SUCCESS_NO_CONTENT);
} else {
fos = new FileOutputStream(file);
ByteUtils.write(request.getEntity()
.getStream(), fos);
response
.setStatus(Status.SUCCESS_CREATED);
}
} else {
getLogger().log(Level.WARNING,
"Unable to create the new file");
response.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Unable to create the new file"));
}
} catch (FileNotFoundException fnfe) {
getLogger().log(Level.WARNING,
"Unable to create the new file", fnfe);
response.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Unable to create the new file"));
} catch (IOException ioe) {
getLogger().log(Level.WARNING,
"Unable to create the new file", ioe);
response.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Unable to create the new file"));
} finally {
try {
if (fos != null)
fos.close();
} catch (IOException ioe) {
getLogger()
.log(
Level.WARNING,
"Unable to close the temporary file",
ioe);
response
.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Unable to close a temporary file"));
}
}
}
}
}
}
} else if (request.getMethod().equals(Method.DELETE)) {
if (file.isDirectory()) {
if (file.listFiles().length == 0) {
if (file.delete()) {
response.setStatus(Status.SUCCESS_NO_CONTENT);
} else {
response.setStatus(new Status(
Status.SERVER_ERROR_INTERNAL,
"Couldn't delete the directory"));
}
} else {
response.setStatus(new Status(
Status.CLIENT_ERROR_FORBIDDEN,
"Couldn't delete the non-empty directory"));
}
} else {
if (file.delete()) {
response.setStatus(Status.SUCCESS_NO_CONTENT);
} else {
response.setStatus(new Status(Status.SERVER_ERROR_INTERNAL,
"Couldn't delete the file"));
}
}
} else {
response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);