package ef;
import ef.api.*;
import ef.api.Error;
import ef.impl.Config;
import ef.impl.command.CommandFactoryImpl;
import ef.impl.request.SourceRequestReaderImpl;
import ef.impl.response.HeaderUtil;
import ef.impl.response.MapResponse;
import ef.impl.response.WritingResponse;
import ef.impl.volume.VolumeManagerImpl;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
/**
* User: sduchenko
* Date: 22.04.13
* Time: 11:09
*/
public class ElFinderServlet extends HttpServlet {
private static final Logger log = LoggerFactory.getLogger(ElFinderServlet.class);
private final ObjectMapper mapper = new ObjectMapper();
private final Config config = new Config();
private CommandFactory commandFactory;
private VolumeManager volumeManager;
private ServletFileUpload fileUpload;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
volumeManager = new VolumeManagerImpl();
initVolumes();
commandFactory = new CommandFactoryImpl(volumeManager);
DiskFileItemFactory factory = new DiskFileItemFactory();
fileUpload = new ServletFileUpload(factory);
fileUpload.setFileSizeMax(this.config.getUploadMaxSize());
}
private void initVolumes() {
for(Config.Mount mount: config.getMountList()){
if(mount.getType().equalsIgnoreCase("filesystem")){
log.debug("mounting {} of type {}", mount.getBaseName(), mount.getType());
volumeManager.createFsVolume(mount.getRequiredParam("path"),mount.getParam("encoding", "UTF-8"));
}else{
throw new RuntimeException("unsupported mount type: " + mount.getType()+" for mount: "+mount.getBaseName());
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doProcess(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doProcess(req, resp);
}
private void doProcess(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
SourceRequestReader reader = new SourceRequestReaderImpl(req, fileUpload);
try {
String cmd = reader.isUpload() ? reader.getRequiredUploadString("cmd") : reader.getRequiredString("cmd");
Command command = commandFactory.getCommand(cmd);
Request request = command.buildRequest(reader);
log.debug("processing request: {}", ReflectionToStringBuilder.toString(request));
Response response = command.execute(request);
writeResponse(response, resp);
} catch (Exception e) {
log.error("error occurred", e);
if(e instanceof ErrException){
writeError(resp, ((ErrException)e).getErrorArray());
}else{
writeError(resp, Error.errUnknown.getErrName());
}
}
}
private void writeError(HttpServletResponse resp, String ... errors) throws IOException {
MapResponse response = new MapResponse();
response.put("error", errors);
writeResponse(response, resp);
}
private void writeResponse(Response response, HttpServletResponse resp) throws IOException {
log.debug("writing response: {}", response);
HeaderUtil.writeNoCache(resp);
if(response instanceof WritingResponse){
WritingResponse writingResponse = (WritingResponse) response;
writingResponse.write(resp);
}else{
resp.setContentType("application/json");
resp.setCharacterEncoding("UTF-8");
mapper.writeValue(resp.getOutputStream(), response);
}
//resp.flushBuffer();
}
}