gwtupload.server.gae.BlobstoreUploadAction Maven / Gradle / Ivy
/*
* Copyright 2010 Manuel Carrasco Moñino. (manuel_carrasco at
* users.sourceforge.net) http://code.google.com/p/gwtupload
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package gwtupload.server.gae;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static gwtupload.shared.UConsts.PARAM_BLOBKEY;
import static gwtupload.shared.UConsts.PARAM_CANCEL;
import static gwtupload.shared.UConsts.PARAM_ERROR;
import static gwtupload.shared.UConsts.PARAM_REDIRECT;
import static gwtupload.shared.UConsts.RESP_OK;
import static gwtupload.shared.UConsts.TAG_CANCELED;
import static gwtupload.shared.UConsts.TAG_ERROR;
import static gwtupload.shared.UConsts.TAG_FINISHED;
import static gwtupload.shared.UConsts.TAG_MESSAGE;
import gwtupload.server.AbstractUploadListener;
import gwtupload.server.UploadAction;
import gwtupload.server.exceptions.UploadActionException;
import gwtupload.server.exceptions.UploadCanceledException;
import gwtupload.server.gae.BlobstoreFileItemFactory.BlobstoreFileItem;
import gwtupload.shared.UConsts;
/**
*
* Upload servlet for the GwtUpload library's deployed in Google App-engine using blobstore.
*
*
*
* Constrains:
*
* - It seems that the redirected servlet path must be /upload because wildcards don't work.
* - After of blobstoring, our doPost receives a request size = -1.
* - If the upload fails, our doPost is never called.
*
*
* @author Manolo Carrasco Moñino
*
*/
public class BlobstoreUploadAction extends UploadAction {
private static final long serialVersionUID = -2569300604226532811L;
protected static BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
// See constrain 1
private String servletPath = "/upload";
@Override
public void checkRequest(HttpServletRequest request) {
logger.debug("BLOB-STORE-SERVLET: (" + request.getSession().getId() + ") procesing a request with size: " + request.getContentLength() + " bytes.");
}
@Override
public boolean isAppEngine() {
return true;
}
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
uploadDelay = 0;
useBlobstore = true;
logger.info("BLOB-STORE-SERVLET: init: maxSize=" + maxSize
+ ", slowUploads=" + uploadDelay + ", isAppEngine=" + isAppEngine()
+ ", useBlobstore=" + useBlobstore);
}
@SuppressWarnings("serial")
@Override
protected final AbstractUploadListener createNewListener(
HttpServletRequest request) {
return new MemCacheUploadListener(uploadDelay, request.getContentLength()) {
int cont = 1;
// In blobStore we cannot know the fileSize emulating progress
public long getBytesRead() {
return getContentLength() / (isFinished() ? 1 : 10 * (1+ (cont++ % 10)));
}
public long getContentLength() {
return 100;
}
};
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
if (request.getParameter(PARAM_BLOBKEY) != null) {
BlobKey blobKey = new BlobKey(request.getParameter("blob-key"));
blobstoreService.serve(blobKey, response);
try {
logger.info("BLOB-STORE-SERVLET: Serving blobstore file. " + request.getParameter(PARAM_BLOBKEY));
blobstoreService.serve(new BlobKey(request.getParameter(PARAM_BLOBKEY)), response);
} catch (Throwable e) {
logger.info("BLOB-STORE-SERVLET: Exception accessing blobStoreService:" + e.getMessage());
e.printStackTrace();
renderXmlResponse(request, response, "Error getting blob: " + e.getMessage() + " " + request.getParameter(PARAM_BLOBKEY));
}
} else if (request.getParameter(PARAM_REDIRECT) != null) {
perThreadRequest.set(request);
Map stat = new HashMap();
if (request.getParameter(PARAM_ERROR) != null) {
stat.put(TAG_ERROR, request.getParameter(PARAM_ERROR));
} else if (request.getParameter(PARAM_CANCEL) != null) {
stat.put(TAG_CANCELED, request.getParameter(PARAM_CANCEL));
} else {
try {
getFileItemsSummary(request, stat);
String message = executeAction(request, getMySessionFileItems(request));
stat.put(TAG_MESSAGE, message);
stat.put(TAG_FINISHED, RESP_OK);
} catch (UploadActionException e) {
logger.error("ExecuteUploadActionException: " + e);
stat.put(TAG_ERROR, e.getMessage());
}
}
String ret = statusToString(stat);
finish(request, ret);
logger.debug("BLOB-STORE-SERVLET: (" + request.getSession().getId() + ") redirect \n" + ret);
renderXmlResponse(request, response, ret, true);
perThreadRequest.set(null);
} else {
super.doGet(request, response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String error = null;
perThreadRequest.set(request);
try {
error = super.parsePostRequest(request, response);
} catch (UploadCanceledException e) {
redirect(response, PARAM_CANCEL + "=true");
return;
} catch (Exception e) {
logger.info("BLOB-STORE-SERVLET: Exception " + e);
error = e.getMessage();
} finally {
perThreadRequest.set(null);
}
if (error != null) {
removeSessionFileItems(request);
redirect(response, PARAM_ERROR + "=" + error);
perThreadRequest.set(null);
return;
}
List sessionFiles = getLastReceivedFileItems(request);
if (sessionFiles == null) {
sessionFiles = new ArrayList();
request.setAttribute(getSessionLastFilesKey(request), sessionFiles);
}
Map> blobs = blobstoreService.getUploads(request);
if (blobs != null && blobs.size() > 0) {
for (Entry> e: blobs.entrySet()) {
for (BlobKey blob: e.getValue()) {
BlobstoreFileItem bfi = null;
if (sessionFiles != null) {
for (FileItem i : sessionFiles) {
if (i.getFieldName().replaceFirst("-\\d+$", "").equals(e.getKey().replace(UConsts.MULTI_SUFFIX, ""))) {
bfi = (BlobstoreFileItem) i;
break;
}
}
}
if (bfi == null) {
bfi = new BlobstoreFileItem(e.getKey(), "unknown", false, "");
sessionFiles.add(bfi);
}
bfi.setKey(blob);
logger.info("BLOB-STORE-SERVLET: received file: " + e.getKey() + " " + bfi);
}
}
redirect(response, null);
} else {
redirect(response, PARAM_ERROR + "=" + getMessage("no_data"));
}
perThreadRequest.set(null);
}
/**
* User can override this for customization.
*/
public String executeAction(HttpServletRequest request, List sessionFiles)
throws UploadActionException {
// Let the user whether remove or not file items overriding this method
removeSessionFileItems(request, false);
return null;
}
protected void redirect(HttpServletResponse response, String params) throws IOException {
String url = servletPath + "?" + PARAM_REDIRECT + "=true" + (params != null ? "&" + params.replaceAll("[\n\r]+", " ") : "");
logger.info("BLOB-STORE-SERVLET: redirecting to -> : " + url);
response.sendRedirect(url);
}
protected String getBlobstorePath(HttpServletRequest request) {
String ret = blobstoreService.createUploadUrl(servletPath);
logger.info("BLOB-STORE-SERVLET: generated new upload-url -> " + servletPath + " : " + ret);
ret = ret.replaceFirst("^https?://[^/]+", "");
return ret;
}
@Override
protected final AbstractUploadListener getCurrentListener(
HttpServletRequest request) {
return MemCacheUploadListener.current(request.getSession().getId());
}
@Override
protected final FileItemFactory getFileItemFactory(long requestSize) {
return new BlobstoreFileItemFactory();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy