// As the path may be percent-encoded, it has to be percent-decoded.
// Then, all generated uris must be encoded.
String decodedPath = LocalReference
.localizePath(Reference.decode(path));
File file = new File(decodedPath);
MetadataService metadataService = getMetadataService(request);
if (request.getMethod().equals(Method.GET)
|| request.getMethod().equals(Method.HEAD)) {
Representation output = null;
// Get variants for a resource
boolean found = false;
Iterator<Preference<MediaType>> iterator = request.getClientInfo()
.getAcceptedMediaTypes().iterator();
while (iterator.hasNext() && !found) {
Preference<MediaType> pref = iterator.next();
found = pref.getMetadata().equals(MediaType.TEXT_URI_LIST);
}
if (found) {
// Try to list all variants of this resource
// 1- set up base name as the longest part of the name without
// known extensions (beginning from the left)
String baseName = getBaseName(file, metadataService);
// 2- looking for resources with the same base name
if (file.getParentFile() != null) {
File[] files = file.getParentFile().listFiles();
if (files != null) {
ReferenceList rl = new ReferenceList(files.length);
String encodedParentDirectoryURI = path.substring(0,
path.lastIndexOf("/"));
String encodedFileName = path.substring(path
.lastIndexOf("/") + 1);
for (File entry : files) {
if (entry.getName().startsWith(baseName)) {
rl
.add(LocalReference
.createFileReference(encodedParentDirectoryURI
+ "/"
+ getReencodedVariantFileName(
encodedFileName,
entry.getName())));
}
}
output = rl.getTextRepresentation();
}
}
} else {
if ((file != null) && file.exists()) {
if (file.isDirectory()) {
// Return the directory listing
File[] files = file.listFiles();
ReferenceList rl = new ReferenceList(files.length);
rl.setIdentifier(request.getResourceRef());
String directoryUri = request.getResourceRef()
.toString();
// Ensures that the directory URI ends with a slash
if (!directoryUri.endsWith("/")) {
directoryUri += "/";
}
for (File entry : files) {
rl.add(directoryUri + entry.getName());
}
output = rl.getTextRepresentation();
} else {
// Return the file content
output = new FileRepresentation(file, metadataService
.getDefaultMediaType(), getTimeToLive());
updateMetadata(metadataService, file.getName(), output);
}
}
}
if (output == null) {
response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);
} else {
output.setIdentifier(request.getResourceRef());
response.setEntity(output);
response.setStatus(Status.SUCCESS_OK);
}
} else if (request.getMethod().equals(Method.PUT)) {
// 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());