Java tutorial
/* * Copyright (c) 2008-2011, Martijn Brinkers, Djigzo. * * This file is part of Djigzo email encryption. * * Djigzo is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License * version 3, 19 November 2007 as published by the Free Software * Foundation. * * Djigzo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public * License along with Djigzo. If not, see <http://www.gnu.org/licenses/> * * Additional permission under GNU AGPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or * combining it with saaj-api-1.3.jar, saaj-impl-1.3.jar, * wsdl4j-1.6.1.jar (or modified versions of these libraries), * containing parts covered by the terms of Common Development and * Distribution License (CDDL), Common Public License (CPL) the * licensors of this Program grant you additional permission to * convey the resulting work. */ package mitm.djigzo.web.pages.portal.pdf; import java.io.IOException; import java.io.InputStream; import java.util.LinkedList; import java.util.List; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import mitm.application.djigzo.DjigzoException; import mitm.common.cache.CacheEntry; import mitm.common.cache.CacheException; import mitm.common.cache.ContentCache; import mitm.common.cache.FileStreamCacheEntry; import mitm.common.properties.HierarchicalPropertiesException; import mitm.common.util.URLBuilderException; import mitm.common.ws.WebServiceCheckedException; import mitm.djigzo.web.asos.PDFReplyState; import mitm.djigzo.web.services.DisableHttpCache; import mitm.djigzo.web.utils.HttpServletUtils; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.io.FileUtils; import org.apache.tapestry5.Asset; import org.apache.tapestry5.PersistenceConstants; import org.apache.tapestry5.annotations.ApplicationState; import org.apache.tapestry5.annotations.BeginRender; import org.apache.tapestry5.annotations.Component; import org.apache.tapestry5.annotations.IncludeStylesheet; import org.apache.tapestry5.annotations.OnEvent; import org.apache.tapestry5.annotations.Path; import org.apache.tapestry5.annotations.Persist; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.corelib.components.Form; import org.apache.tapestry5.ioc.Messages; import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.ioc.annotations.Value; import org.apache.tapestry5.upload.components.Upload; import org.apache.tapestry5.upload.services.UploadEvents; import org.apache.tapestry5.upload.services.UploadedFile; @IncludeStylesheet({ "context:styles/style.css", "context:styles/pages/portal/pdf/pdfattachments.css" }) public class PDFAttachments { /* * The cache id used for the body. */ public static final String BODY_ATTACHMENT_ID = "body"; /* * Maximum number of attachments for a user */ @Inject @Value("${upload.max-attachments}") private int maxAttachments; /* * Maximum size of the file to upload */ @Inject @Value("${email.attachment.max-size}") private int emailMaxAttachmentSize; /* * Maximum size of the file upload request */ @Inject @Value("${upload.requestsize-max}") private int emailMaxRequestSize; @SuppressWarnings("unused") @Inject @Path("context:images/loading-small.gif") @Property private Asset loadingAsset; /* * 'Handle' to the uploaded attachment */ private UploadedFile uploadedFile; @Component(id = "form", parameters = { "clientValidation=false" }) private Form form; @Component(id = "upload", parameters = { "value=uploadedFile" }) private Upload upload; @SuppressWarnings("unused") @Inject @Path("context:icons/cross.png") @Property private Asset removeAttachmentAsset; /* * Cache which is used for storing uploaded files. */ @Inject private ContentCache cache; /* * We use the HttpServletRequest to get the session */ @Inject private HttpServletRequest httpRequest; @Inject private Messages messages; @ApplicationState private PDFReplyState replyState; @Persist(PersistenceConstants.FLASH) private boolean uploadError; @Persist(PersistenceConstants.FLASH) private String uploadErrorMessage; /* * Name of the attachment that gets set while looping over the attachments */ private String attachmentName; /* * The max size of the attachment (the smaller of max size and max request size) */ private int getMaxAttachmentSize() { return Math.min(emailMaxAttachmentSize, emailMaxRequestSize); } public String getMaxAttachmentSizeReadable() { return FileUtils.byteCountToDisplaySize(getMaxAttachmentSize()); } public boolean isUploadError() { return uploadError; } public String getUploadErrorMessage() { return uploadErrorMessage; } public UploadedFile getUploadedFile() { return uploadedFile; } public void setUploadedFile(UploadedFile uploadedFile) { this.uploadedFile = uploadedFile; } private Class<?> invalidateSessionAndRedirect(Class<?> redirectPage) throws IOException { HttpServletUtils.invalidateSession(httpRequest); return redirectPage; } private Class<?> handleInvalidRequest() throws IOException { return invalidateSessionAndRedirect(PDFInvalidRequest.class); } public Class<?> onActivate() throws IOException { if (!replyState.isValidRequest()) { return handleInvalidRequest(); } return null; } @BeginRender @DisableHttpCache public void beginRender() { // empty on purpose. We need beginRender to set @DisableHttpCache } /* * Returns a unique identifier for a message which will be used to identify the attachment in the cache. */ private String getCacheKey() { return httpRequest.getSession().getId() + replyState.getMessageKey(); } public List<String> getAttachmentNames() throws CacheException { List<CacheEntry> entries = cache.getAllEntries(getCacheKey()); List<String> attachmentNames = new LinkedList<String>(); for (CacheEntry entry : entries) { String id = entry.getId(); /* * An attachment with name BODY_ATTACHMENT is special because it is the body of the message and not * an attachment to the message. We should therefore skip body attachments */ if (!BODY_ATTACHMENT_ID.equals(id)) { attachmentNames.add(id); } } return attachmentNames; } public String getAttachmentName() { return attachmentName; } public void setAttachmentName(String attachmentName) { this.attachmentName = attachmentName; } /* * Returns the FileCacheEntry associates with the current attachmentName */ public CacheEntry getAttachment() throws CacheException { return getUniqueCacheEntry(attachmentName); } private CacheEntry getUniqueCacheEntry(String id) throws CacheException { CacheEntry entry = cache.getEntry(getCacheKey(), id); return entry; } public void onValidateFromUpload(UploadedFile file) { /* * Sanity check */ if (file != null) { if (file.getSize() > getMaxAttachmentSize()) { form.recordError(messages.format("attachment-max-size-exceeded", getMaxAttachmentSize())); } } } private void addAttachment(String id, String filename, InputStream input) throws IOException, CacheException { CacheEntry entry = getUniqueCacheEntry(id); if (entry == null) { entry = new FileStreamCacheEntry(id); entry.setObject(filename); cache.addEntry(getCacheKey(), entry); } entry.store(input); } private void AddUploadedAttachment() throws IOException, CacheException, DjigzoException { if (isUploadDisabled()) { form.recordError(upload, messages.get("attachment-not-allowed")); } else if (uploadedFile == null) { form.recordError(upload, messages.get("attachment-missing")); } else { /* * Generate a unique attachment name */ String name = UUID.randomUUID().toString(); addAttachment(name, uploadedFile.getFileName(), uploadedFile.getStream()); } } @OnEvent(component = "removeAttachment") protected void removeAttachment(String name) throws WebServiceCheckedException, DjigzoException { if (name != null) { try { cache.removeEntry(getCacheKey(), name); } catch (CacheException e) { throw new DjigzoException(e); } } } /* * Event handler that gets called when the uploaded file exceeds the maximum size */ @OnEvent(UploadEvents.UPLOAD_EXCEPTION) protected Object onUploadException(FileUploadException uploadException) { uploadError = true; uploadErrorMessage = uploadException.getMessage(); return PDFAttachments.class; } public Class<?> onValidateForm() throws WebServiceCheckedException, HierarchicalPropertiesException, URLBuilderException, IOException { if (!replyState.isValidRequest()) { return handleInvalidRequest(); } return null; } protected void onSuccess() throws IOException, CacheException, DjigzoException { AddUploadedAttachment(); } /* * getter called from .tml file */ public boolean isUploadDisabled() throws DjigzoException { /* * If maximum number of attachments exceeded we will disable the upload control */ int attachmentCount = 0; try { List<CacheEntry> entries = cache.getAllEntries(getCacheKey()); for (CacheEntry entry : entries) { if (!BODY_ATTACHMENT_ID.equals(entry.getId())) { attachmentCount++; } } } catch (CacheException e) { throw new DjigzoException(e); } if (attachmentCount >= maxAttachments) { return true; } return false; } }