package net.blogracy.web;
import java.io.File;
import java.io.IOException;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.blogracy.controller.FileSharing;
import net.blogracy.controller.MediaController;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.shindig.social.opensocial.model.MediaItem;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class ImageGalleryUploader extends HttpServlet {
private final String SERVLET_RELATIVE_URL = "ImageGalleryUploader";
private final String CACHE_RELATIVE_URL = "cache/";
/***
* Retrieves the images that belong to the album
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// Obtaining the current userId and albumId
String userId = request.getParameter("userId");
String albumId = request.getParameter("albumId");
if (userId != null && albumId != null) {
// Getting the media items from user's record db
List<MediaItem> list = MediaController.getSingleton()
.getMediaItemsWithCachedImages(userId, albumId);
response.setContentType("application/json");
List<String> imageUrlList = new ArrayList<String>();
for (MediaItem item : list) {
imageUrlList.add(item.getUrl());
}
String jsonAnswer = toJSON(imageUrlList, albumId, userId);
response.getWriter().write(jsonAnswer);
}
}
/***
* It's used for: - creating a new album (it requires "user" and
* "galleryName" as parameters) - uploading images to the album (it requires
* "user" and "albumId" as parameters alongside the actual files, request
* should be multipart content)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
if (!ServletFileUpload.isMultipartContent(request))
createNewPhotoAlbum(request);
else
addUploadedFilesToPhotoAlbum(request, response);
}
/**
* A certain mediaId is removed from an album. It requires "mediaId",
* "albumId" and "userId" as parameters
*/
protected void doDelete(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String mediaId = request.getParameter("mediaId");
String albumId = request.getParameter("albumId");
String userId = request.getParameter("userId");
try {
MediaController.getSingleton().deletePhotoFromAlbum(userId,
albumId, mediaId);
response.setStatus(HttpServletResponse.SC_OK);
} catch (Exception e) {
e.printStackTrace();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
private void addUploadedFilesToPhotoAlbum(HttpServletRequest request,
HttpServletResponse response) throws IOException {
ServletFileUpload uploadHandler = new ServletFileUpload(
new DiskFileItemFactory());
// The userId and albumId are sent along with the request
String userHash = null;
String albumId = null;
Map<FileItem, FileDTO> cachedFiles = new HashMap<FileItem, FileDTO>();
Map<File, String> fileAndMimeTypeMap = new HashMap<File, String>();
try {
@SuppressWarnings("unchecked")
List<FileItem> items = uploadHandler.parseRequest(request);
for (FileItem item : items) {
if (item.isFormField()) {
String fieldName = item.getFieldName();
if (fieldName.equalsIgnoreCase("user"))
userHash = item.getString();
else if (fieldName.equalsIgnoreCase("albumId"))
albumId = item.getString();
} else {
File f = new File(item.getName());
item.write(f);
cachedFiles.put(item, new FileDTO(f));
fileAndMimeTypeMap.put(f, item.getContentType());
item.delete();
}
}
} catch (Exception e) {
e.printStackTrace();
}
List<String> hashes = MediaController.getSingleton()
.addMediaItemsToAlbum(userHash, albumId, fileAndMimeTypeMap);
int i = 0;
for (Entry<FileItem, FileDTO> entry : cachedFiles.entrySet()) {
entry.getValue().setHash(hashes.get(i));
++i;
}
// Send a Json message to the imageGalleryUploader control
// containing the file's data
sendImageUploaderJsonReply(cachedFiles, response, albumId, userHash);
}
private void createNewPhotoAlbum(HttpServletRequest request) {
// Obtaining the current user
String user = request.getParameter("user");
try {
String galleryName = request.getParameter("galleryname");
if (galleryName != null) {
// Gallery creation
MediaController.getSingleton().createPhotoAlbum(user,
galleryName);
}
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println(e.getStackTrace());
}
}
private void sendImageUploaderJsonReply(Map<FileItem, FileDTO> cachedFiles,
HttpServletResponse response, String albumId, String userId)
throws IOException {
response.setContentType("application/json");
for (Entry<FileItem, FileDTO> entry : cachedFiles.entrySet()) {
List<String> stringEntry = new ArrayList<String>();
stringEntry.add(CACHE_RELATIVE_URL + entry.getValue().getHash());
String jsonAnswer = toJSON(stringEntry, albumId, userId);
response.getWriter().write(jsonAnswer);
}
}
private String toJSON(Collection<String> fileNames, String albumId,
String userId) throws IOException {
JSONArray array = new JSONArray();
try {
for (String fileName : fileNames) {
JSONObject json = new JSONObject();
File currentFile = new File(fileName);
System.out.println(fileName);
json.put("name", "");
json.put("size", String.valueOf(currentFile.length()));
json.put("url", fileName);
json.put("thumbnail_url", fileName);
json.put("delete_url", String.format(SERVLET_RELATIVE_URL
+ "?mediaId=%s&albumId=%s&userId=%s",
fileName.substring(CACHE_RELATIVE_URL.length()),
albumId, userId));
json.put("delete_type", "DELETE");
array.put(json);
}
} catch (JSONException e) {
e.printStackTrace();
}
return array.toString();
}
/***
* Auxiliary Data Transfer Object which keeps the File and its bittorrent
* hash string information
*
*/
public class FileDTO {
public FileDTO(File associatedFile) {
this.file = associatedFile;
}
public File getFile() {
return file;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
protected File file;
protected String hash;
public Entry<File, String> toEntry() {
return new AbstractMap.SimpleEntry<File, String>(this.file,
this.hash);
}
}
}