package org.jano;
import fi.iki.elonen.NanoHTTPD;
import fi.iki.elonen.NanoHTTPD.Response;
import fi.iki.elonen.NanoHTTPD.Response.Status;
import fi.iki.elonen.NanoHTTPD.IHTTPSession;
import org.jano.resources.Resource;
import org.jano.resources.ResourceRef;
import org.jano.resources.ResourceSystem;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Default plugin for resource content management
*/
public class ContentPlugin implements JanoPlugin {
public static final String DEFAULT_CONTENT_CHARSET = "UTF-8";
public static final String APPEND_PREFIX = "+";
private static final Charset charset = Charset.forName(DEFAULT_CONTENT_CHARSET);
@Override
public boolean canServe(String uri, NanoHTTPD.Method method) {
return true;
}
@Override
public Response serve(IHTTPSession session, ResourceSystem resourceSystem) throws Exception {
ResourceRef ref = resourceSystem.get(session.getUri());
switch (session.getMethod()) {
case GET: return get(ref);
case POST: {
session.parseBody(new HashMap<String, String>());
return post(ref, session.getParms(), resourceSystem);
}
case DELETE: return delete(ref);
default:
return Reply.with(Status.METHOD_NOT_ALLOWED);
}
}
private Response get(ResourceRef ref) {
if (ref.isBrowsable()) {
//Ok. Try to browse resource
return browse(ref);
} else if (ref.isMaterial()) {
//Ok. Send resource content
byte[] content = Resource.get(ref);
return Reply.with(Status.OK, mimeTypeOf(ref), content);
} else {
//Not Found
return Reply.with(Status.NOT_FOUND, ref);
}
}
private Response browse(ResourceRef ref) {
ResourceRef[] children = ref.browse();
List<JsonModel.ResourceRef> listing = new ArrayList<JsonModel.ResourceRef>();
for (ResourceRef resourceRef : children) {
if (resourceRef.exists()) {
listing.add(JsonModel.build(resourceRef));
}
}
return Reply.with(Response.Status.OK, listing);
}
private Response post(ResourceRef dir, Map<String, String> postParams, ResourceSystem resourceSystem) throws Exception {
Map<String, Object> reply = new HashMap<String, Object>();
//we process each parameter of post request as file name
for (String param : postParams.keySet()) {
//determine
boolean append = isAppendOp(param);
String fileName = getFileName(param);
//obtain resource references for parameter
ResourceRef ref = resourceSystem.get(Uri.of(dir.uri(), fileName));
try {
byte[] content = postParams.get(param).getBytes(charset);
Resource.put(ref, content, append);
reply.put(fileName, JsonModel.build(ref));
} catch (Exception e) {
Diagnostic.log(e);
if (postParams.size() == 1) {
return Reply.with(Status.INTERNAL_ERROR, e);
} else {
reply.put(fileName, JsonModel.build(e));
}
}
}
if (postParams.size() == 1) {
return Reply.with(Status.OK, reply.values().iterator().next());
} else {
return Reply.with(Status.OK, reply);
}
}
private Response delete(ResourceRef ref) {
boolean deleted = ref.delete();
return Reply.with(deleted ? Status.OK : Status.NO_CONTENT, ref);
}
private boolean isAppendOp(String param) {
return param.startsWith(APPEND_PREFIX);
}
private String getFileName(String param) {
return param.startsWith(APPEND_PREFIX) ? param.substring(APPEND_PREFIX.length()) : param;
}
private String mimeTypeOf(ResourceRef ref) {
return MimeType.of(ref.uri());
}
}