*/
package mircoders.localizer.basic;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
-import java.util.Vector;
import mir.config.MirPropertiesConfiguration;
import mir.log.LoggerWrapper;
import mir.session.SessionHandler;
import mir.session.UploadedFile;
import mir.session.ValidationError;
-import mir.session.ValidationHelper;
-import mir.storage.StorageObject;
+import mir.storage.Database;
import mir.util.ExceptionFunctions;
+import mir.util.FileFunctions;
import mircoders.global.MirGlobal;
-import mircoders.module.ModuleMediaType;
+import mircoders.media.UnsupportedMediaTypeExc;
/**
- *
- * <p>Title: Experimental session handler for comment postings </p>
- * <p>Description: </p>
- * <p>Copyright: Copyright (c) 2003</p>
- * <p>Company: </p>
- * @author not attributable
- * @version 1.0
+ * Extensible handler for open postings.
+ * Behaviour can be altered by overriding methods.
*/
-
public abstract class MirBasicPostingSessionHandler implements SessionHandler {
- protected LoggerWrapper logger;
- protected MirPropertiesConfiguration configuration;
+ protected static LoggerWrapper logger = new LoggerWrapper("Localizer.OpenPosting");
+ protected MirPropertiesConfiguration configuration = MirPropertiesConfiguration.instance();;
+
+ /** Previously uploaded files */
+ protected List attachments;
+ /** counter to generate unique field names for uploaded files */
+ protected int uploadedFileIndex = 0;
private String normalResponseGenerator;
private String dupeResponseGenerator;
private String unsupportedMediaTypeResponseGenerator;
private String finalResponseGenerator;
+ private boolean persistentUploadedFiles;
- public MirBasicPostingSessionHandler() {
- logger = new LoggerWrapper("Localizer.OpenPosting");
- try {
- configuration = MirPropertiesConfiguration.instance();
- }
- catch (Throwable t) {
- logger.fatal("Cannot load configuration: " + t.toString());
-
- throw new RuntimeException("Cannot load configuration: " + t.toString());
- }
+ public MirBasicPostingSessionHandler(boolean aPersistentUploadedFiles) {
+ attachments = new ArrayList();
+ persistentUploadedFiles = aPersistentUploadedFiles;
}
protected void setNormalResponseGenerator(String aGenerator) {
normalResponseGenerator = aGenerator;
}
- protected void setResponseGenerators(String aNormalResponseGenerator, String aDupeResponseGenerator,
- String anUnsupportedMediaTypeResponseGenerator, String aFinalResponseGenerator) {
+ protected void setResponseGenerators(String aNormalResponseGenerator,
+ String aDupeResponseGenerator, String anUnsupportedMediaTypeResponseGenerator,
+ String aFinalResponseGenerator) {
setNormalResponseGenerator(aNormalResponseGenerator);
dupeResponseGenerator = aDupeResponseGenerator;
unsupportedMediaTypeResponseGenerator = anUnsupportedMediaTypeResponseGenerator;
makeInitialResponse(aRequest, aSession, aResponse);
}
+ protected void processAttachments(Request aRequest, Session aSession, Response aResponse) {
+ Iterator i = attachments.iterator();
+ while (i.hasNext()) {
+ Attachment attachment = (Attachment) i.next();
+ try{
+ processAttachment(aRequest, aSession, attachment);
+ }
+ catch (Throwable t) {
+ try {
+ processAttachmentError(aRequest, aSession, attachment, t);
+ }
+ catch (Throwable u) {
+ }
+ }
+ }
+ }
+
public void subsequentRequest(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
try {
-
try {
- List validationErrors = new Vector();
+ List validationErrors = new ArrayList();
+
+ preprocessPreviousAttachments(aRequest, aSession);
+ preProcessNewAttachments(aRequest, aSession);
if (!shouldProcessRequest(aRequest, aSession, validationErrors)) {
initializeResponseData(aRequest, aSession, aResponse);
}
else {
preProcessRequest(aRequest, aSession);
- Iterator i = aRequest.getUploadedFiles().iterator();
- while (i.hasNext()) {
- processUploadedFile(aRequest, aSession, (UploadedFile) i.next());
- }
+
+ processAttachments(aRequest, aSession, aResponse);
postProcessRequest(aRequest, aSession);
initializeResponseData(aRequest, aSession, aResponse);
makeFinalResponse(aRequest, aSession, aResponse);
}
}
+ /**
+ * Initializes a session.
+ * This may happen in the case of a new session being initiated, but also
+ * when an older session gets re-initiated after a session timeout.
+ */
protected void initializeSession(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
if (MirGlobal.abuse().getOpenPostingPassword()) {
String password = (String) aSession.getAttribute("password");
aSession.deleteAttribute("password");
}
- logger.debug("referrer = " + aRequest.getHeader("Referer"));
-
aSession.setAttribute("referer", aRequest.getHeader("Referer"));
- aSession.setAttribute("nrmediaitems",
- new Integer(configuration.getInt("ServletModule.OpenIndy.DefaultMediaUploadItems")));
}
+ /**
+ * Called every time a response is being prepared.
+ * This may be at the initial response, or on a subsequent one.
+ */
protected void initializeResponseData(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
- int nrMediaItems = ((Integer) aSession.getAttribute("nrmediaitems")).intValue();
- List mediaItems = new Vector();
- int i=0;
+ int nrMediaItems = configuration.getInt("ServletModule.OpenIndy.DefaultMediaUploadItems", 5);
- while (i<nrMediaItems) {
- i++;
+ if (aSession.getAttribute("nrmediaitems")!=null) {
+ nrMediaItems = ((Integer) aSession.getAttribute("nrmediaitems")).intValue();
+ }
+
+ try {
+ nrMediaItems = Math.min(configuration.getInt("ServletModule.OpenIndy.MaxMediaUploadItems"), Integer.parseInt(aRequest.getParameter("nrmediaitems")));
+ }
+ catch (Throwable t) {
+ }
+
+ aSession.setAttribute("nrmediaitems", new Integer(nrMediaItems));
+
+ List mediaItems = new ArrayList();
+ for (int i=1; i<=nrMediaItems; i++) {
mediaItems.add(new Integer(i));
}
aResponse.setResponseValue("password", aSession.getAttribute("password"));
aResponse.setResponseValue("referer", aSession.getAttribute("referer"));
aResponse.setResponseValue("errors", null);
+
+ if (configuration.getBoolean("Localizer.OpenSession.AllowFTPUploads", false)) {
+ aResponse.setResponseValue("ftpfiles",
+ FileFunctions.getDirectoryContentsAsList(configuration.getFile("Localizer.OpenSession.FTPDirectory"),
+ new FilenameFilter() {
+ public boolean accept(File aDir, String aName) {
+ return !(new File(aDir, aName).isDirectory());
+ }
+ }));
+ }
+ else {
+ aResponse.setResponseValue("ftpfiles", null);
+ }
+
+ initializeAttachmentResponseData(aRequest, aSession, aResponse);
+ }
+
+ /**
+ * Process possible changes to previously uploaded files
+ */
+ protected void initializeAttachmentResponseData(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
+ List result = new ArrayList();
+ if (persistentUploadedFiles) {
+ Iterator i = attachments.iterator();
+ while (i.hasNext()) {
+ Attachment attachment = (Attachment) i.next();
+ Map attachmentData = new HashMap();
+ attachmentData.putAll(attachment.getAllAttributes());
+ attachmentData.put("fieldname", attachment.getFieldName());
+ attachmentData.put("filename", attachment.getFileName());
+ result.add(attachmentData);
+ }
+ }
+
+ aResponse.setResponseValue("attachments", result);
+ }
+
+ /**
+ * Process possible changes to previously uploaded files
+ */
+ protected void preprocessPreviousAttachments(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
+ synchronized (attachments) {
+ List previouslyUploadedFiles = new ArrayList(attachments);
+ attachments.clear();
+
+ if (persistentUploadedFiles) {
+ Iterator i = previouslyUploadedFiles.iterator();
+ while (i.hasNext()) {
+ Attachment uploadedFile = (Attachment) i.next();
+ if (!(aRequest.getParameter(uploadedFile.getFieldName()+"_cancel")!=null)) {
+ addAttachment(aRequest, aSession, uploadedFile, uploadedFile.getFieldName());
+ }
+ }
+ }
+ }
+ }
+
+ protected void addAttachment(Request aRequest, Session aSession, Attachment anAttachment, String aFieldName) throws SessionExc, SessionFailure {
+ List parameters = aRequest.getPrefixedParameterNames(aFieldName+"_");
+ Iterator j = parameters.iterator();
+ while (j.hasNext()) {
+ String parameter = ((String) j.next());
+ anAttachment.setAttribute(
+ parameter.substring(aFieldName.length()+1),
+ aRequest.getParameter(parameter));
+ }
+ attachments.add(anAttachment);
+ }
+
+ public void preprocessNewAttachment(Request aRequest, Session aSession, UploadedFile aFile) throws SessionExc, SessionFailure {
+ Attachment uploadedFile =
+ new Attachment(aFile, aFile.getFileName(), "attachment"+ ++uploadedFileIndex, aFile.getContentType());
+
+ addAttachment(aRequest, aSession, uploadedFile, aFile.getFieldName());
+ }
+
+
+ /**
+ * Process newly uploaded files
+ */
+ protected void preProcessNewAttachments(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
+ Iterator i = aRequest.getUploadedFiles().iterator();
+ while (i.hasNext()) {
+ preprocessNewAttachment(aRequest, aSession, (UploadedFile) i.next());
+ }
+
+ if (configuration.getBoolean("Localizer.OpenSession.AllowFTPUploads", false)) {
+ File FTPDirectory = configuration.getFile("Localizer.OpenSession.FTPDirectory");
+
+ List ftpUploads = aRequest.getPrefixedParameterNames("ftpupload");
+ i = ftpUploads.iterator();
+ while (i.hasNext()) {
+ final String fieldName = (String) i.next();
+
+ if (fieldName.indexOf("_")<0) {
+ final String fileName = aRequest.getParameter(fieldName);
+
+ if (fileName!=null && fileName.trim().length()>0) {
+ final File sourceFile = new File(FTPDirectory, fileName);
+
+ if (sourceFile.getParentFile().equals(FTPDirectory)) {
+ preprocessNewAttachment(aRequest, aSession, new UploadedFile() {
+ public void writeToFile(File aFile) throws SessionFailure {
+ try {
+ FileFunctions.move(sourceFile, aFile);
+ }
+ catch (IOException e) {
+ throw new SessionFailure(e);
+ }
+ }
+
+ public InputStream getInputStream() throws SessionFailure {
+ try {
+ return new FileInputStream(sourceFile);
+ }
+ catch (IOException e) {
+ throw new SessionFailure(e);
+ }
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ public String getContentType() {
+ return null;
+ }
+ });
+ }
+ }
+ }
+ }
+ }
}
protected void makeInitialResponse(Request aRequest, Session aSession, Response aResponse) throws SessionExc, SessionFailure {
};
protected void makeErrorResponse(Request aRequest, Session aSession, Response aResponse, Throwable anError) throws SessionExc, SessionFailure {
- anError.printStackTrace();
Throwable rootCause = ExceptionFunctions.traceCauseException(anError);
if (rootCause instanceof DuplicatePostingExc)
aResponse.setResponseGenerator(dupeResponseGenerator);
- if (rootCause instanceof ModuleMediaType.UnsupportedMimeTypeExc) {
- aResponse.setResponseValue("mimetype", ((ModuleMediaType.UnsupportedMimeTypeExc) rootCause).getMimeType());
+ if (rootCause instanceof UnsupportedMediaTypeExc) {
+ aResponse.setResponseValue("mimetype", ((UnsupportedMediaTypeExc) rootCause).getMimeType());
aResponse.setResponseGenerator(unsupportedMediaTypeResponseGenerator);
}
else {
- aResponse.setResponseValue("errorstring", anError.getMessage());
- aResponse.setResponseGenerator(configuration.getString("Localizer.OpenSession.ErrorTemplate"));
+ List errors = new ArrayList();
+ errors.add(new ValidationError("", "general.unexpectederror",
+ new Object[] {anError.getMessage()}));
+ makeResponse(aRequest, aSession, aResponse, errors);
}
};
aResponse.setResponseGenerator(configuration.getString("ServletModule.OpenIndy.PostingDisabledTemplate"));
}
+ /**
+ *
+ */
protected void preProcessRequest(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
};
- public void processUploadedFile(Request aRequest, Session aSession, UploadedFile aFile) throws SessionExc, SessionFailure {
+ public void processAttachment(Request aRequest, Session aSession, Attachment aFile) throws SessionExc, SessionFailure {
+ };
+ public void processAttachmentError(Request aRequest, Session aSession, Attachment aFile, Throwable anError) {
};
protected void postProcessRequest(Request aRequest, Session aSession) throws SessionExc, SessionFailure {
};
+ /**
+ * Determine whether the request shoudl be processed: that is, the validate,
+ * preprocess, postprocess methods should be called to perform validations,
+ * store data, etc
+ */
protected boolean shouldProcessRequest(Request aRequest, Session aSession, List aValidationErrors) throws SessionExc, SessionFailure {
- int nrMediaItems = ((Integer) aSession.getAttribute("nrmediaitems")).intValue();
- try {
- nrMediaItems = Math.min(configuration.getInt("ServletModule.OpenIndy.MaxMediaUploadItems"), Integer.parseInt(aRequest.getParameter("nrmediaitems")));
- }
- catch (Throwable t) {
- }
-
- aSession.setAttribute("nrmediaitems", new Integer(nrMediaItems));
-
if (aRequest.getParameter("post")==null)
return false;
else {
}
}
+ /**
+ * Method used to validate user input.
+ * Multiple {@link ValidationError}s may be added to the
+ * <code>aResults</code> parameter.
+ * The request is considered validated if, after calling this method,
+ * <code>aResults</code> is empty.
+ */
protected void validate(List aResults, Request aRequest, Session aSession) throws SessionExc, SessionFailure {
String password = (String) aSession.getAttribute("password");
*
* @return a password, to be used once
*/
-
protected String generateOnetimePassword() {
Random r = new Random();
int random = r.nextInt();
return returnString.substring(5);
}
-
/**
- *
- * @param aRequest
- * @param aStorage
- * @return
- * @throws SessionExc
- * @throws SessionFailure
+ * Method to filter the attributes and their values of a request
+ * based on the fields of a database object.
*/
-
- protected static final Map getIntersectingValues(Request aRequest, StorageObject aStorage) throws SessionExc, SessionFailure {
+ protected static final Map getIntersectingValues(Request aRequest, Database aStorage) throws SessionFailure {
Map result = new HashMap();
- Iterator i = aStorage.getFields().iterator();
+ Iterator i = aStorage.getFieldNames().iterator();
while (i.hasNext()) {
String fieldName = (String) i.next();
return result;
}
+ /**
+ * Exception to be thrown when an article or comment was already posted
+ */
protected static class DuplicatePostingExc extends SessionExc {
public DuplicatePostingExc(String aMessage) {
super(aMessage);
}
}
+ /**
+ * A file that has been attached to a session
+ */
+ protected static class Attachment implements UploadedFile {
+ private UploadedFile uploadedFile;
+ private String filename;
+ private String fieldName;
+ private String contentType;
+ private Map attributes;
+
+ public Attachment(UploadedFile anUploadedFile, String aFilename, String aFieldName, String aContentType) {
+ attributes = new HashMap();
+ filename = aFilename;
+ fieldName = aFieldName;
+ contentType = aContentType;
+ uploadedFile = anUploadedFile;
+ }
+
+ public void writeToFile(File aFile) throws SessionExc, SessionFailure {
+ uploadedFile.writeToFile(aFile);
+ }
+
+ public InputStream getInputStream() throws SessionExc, SessionFailure {
+ return uploadedFile.getInputStream();
+ }
+
+ public String getFileName() {
+ return filename;
+ }
+
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ public String getContentType() {
+ return contentType;
+ }
+
+ public String getAttribute(String anAttribute) {
+ return (String) attributes.get(anAttribute);
+ }
+
+ public void setAttribute(String anAttribute, String aValue) {
+ attributes.put(anAttribute, aValue);
+ }
+
+ public Map getAllAttributes() {
+ return Collections.unmodifiableMap(attributes);
+ }
+ }
}
+