package org.example;
import java.io.IOException;
import java.nio.charset.Charset;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.common.base.Optional;
import com.google.common.io.ByteProcessor;
public class DocumentStorageService extends HttpServlet {
private final DocumentStorage storage;
private final ReadAllBytesFromInputStream byteReader;
private PathInfoToDocumentId pathInfoToDocumentId;
public DocumentStorageService(){
this(new ReadAllBytesFromInputStream(), new DocumentStorage(new DocumentIdGenerator()), new PathInfoToDocumentId());
}
public DocumentStorageService(ReadAllBytesFromInputStream reader, DocumentStorage storage, PathInfoToDocumentId pathInfoToDocumentId) {
this.byteReader = reader;
this.storage = storage;
this.pathInfoToDocumentId = pathInfoToDocumentId;
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Document document = extractDocumentFromRequest(request);
DocumentId documentId = storage.create(document);
String encoding = "us-ascii";
byte[] bytes = documentId.asString().getBytes(Charset.forName(encoding));
response.setContentType("text/plain");
response.setCharacterEncoding(encoding);
response.setContentLength(bytes.length);
response.setStatus(HttpServletResponse.SC_CREATED);
response.getOutputStream().write(bytes);
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Optional<DocumentId> documentId = extractValidDocumentIdOrHandleSetErrorRespsonse(request, response);
if (!documentId.isPresent()) {
return;
}
Optional<Document> maybeADocument = storage.getDocumentFor(documentId.get());
if (!maybeADocument.isPresent()) {
respondWithNotFound(response);
return;
}
response.getOutputStream().write(maybeADocument.get().getContent());
}
@Override
public void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Optional<DocumentId> documentId = extractValidDocumentIdOrHandleSetErrorRespsonse(request, response);
if (!documentId.isPresent()) {
return;
}
if (!storage.contains(documentId.get())) {
respondWithNotFound(response);
return;
}
Document document = extractDocumentFromRequest(request);
storage.update(documentId.get(), document);
respondWithNoContent(response);
}
@Override
public void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Optional<DocumentId> documentId = extractValidDocumentIdOrHandleSetErrorRespsonse(request, response);
if (!documentId.isPresent()) {
return;
}
Optional<Document> documentOptional = storage.deleteDocumentWith(documentId.get());
if (!documentOptional.isPresent()) {
respondWithNotFound(response);
return;
}
respondWithNoContent(response);
}
private Document extractDocumentFromRequest(HttpServletRequest request) throws IOException {
ByteProcessor<byte[]> processor = byteReader.extractPayload(request.getInputStream());
return new Document(processor.getResult());
}
private Optional<DocumentId> extractValidDocumentIdOrHandleSetErrorRespsonse(HttpServletRequest request, HttpServletResponse response) {
String pathInfo = request.getPathInfo();
Optional<DocumentId> documentId = pathInfoToDocumentId.parseDocumentId(pathInfo);
if (!documentId.isPresent()) {
respondWithNotFound(response);
}
return documentId;
}
private void respondWithNotFound(HttpServletResponse response) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
private void respondWithNoContent(HttpServletResponse response) {
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
}