Java tutorial
/* * Copyright (c) 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.components; import java.util.Collections; import java.util.HashSet; import java.util.Set; import mitm.application.djigzo.admin.FactoryRoles; import mitm.application.djigzo.ws.BinaryDTO; import mitm.application.djigzo.ws.MailRepositoryItemDTO; import mitm.application.djigzo.ws.MailRepositoryWS; import mitm.application.djigzo.ws.ReleaseProcessor; import mitm.common.mail.repository.MailRepositorySearchField; import mitm.common.ws.WebServiceCheckedException; import mitm.djigzo.web.common.ContentTypes; import mitm.djigzo.web.common.MailFilterBy; import mitm.djigzo.web.common.streamresponse.InputStreamFileResponse; import mitm.djigzo.web.grid.MailRepositoryGridDataSource; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.commons.lang.mutable.MutableObject; import org.apache.tapestry5.Asset; import org.apache.tapestry5.ComponentEventCallback; import org.apache.tapestry5.ComponentResources; import org.apache.tapestry5.Link; import org.apache.tapestry5.PersistenceConstants; import org.apache.tapestry5.StreamResponse; import org.apache.tapestry5.annotations.Component; import org.apache.tapestry5.annotations.IncludeJavaScriptLibrary; 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.SetupRender; import org.apache.tapestry5.beaneditor.BeanModel; import org.apache.tapestry5.corelib.components.Grid; import org.apache.tapestry5.grid.GridDataSource; import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.ioc.annotations.Value; import org.apache.tapestry5.json.JSONObject; import org.apache.tapestry5.services.BeanModelSource; import org.apache.tapestry5.services.Request; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.annotation.Secured; @Secured({ FactoryRoles.ROLE_ADMIN, FactoryRoles.ROLE_DLP_MANAGER, FactoryRoles.ROLE_QUARANTINE_MANAGER }) @IncludeStylesheet("context:styles/components/quarantineManager.css") @IncludeJavaScriptLibrary("quarantineManager.js") public class QuarantineManager { private final static Logger logger = LoggerFactory.getLogger(QuarantineManager.class); public static final String VIEW_MIME_CLICKED_EVENT = "QuarantineManager-viewMIME-clicked"; private static final String DOWNLOAD_EMAIL_EVENT = "downloadEmail"; @Inject private MailRepositoryWS mailRepository; @Inject private Request request; @Inject private BeanModelSource beanModelSource; @Inject private ComponentResources resources; @Inject @Value("${quarantineManager.rowsPerPage}") private int defaultRowsPerPage; @Persist private Integer rowsPerPage; /* * Set of the selected ID's */ @Persist private Set<String> selected; @Inject @Path("context:icons/cross.png") private Asset deleteAsset; /* * True if and error has occurred */ @Persist(PersistenceConstants.FLASH) private boolean error; /* * Error message if an error has occurred */ @Persist(PersistenceConstants.FLASH) private String errorMessage; /* * The field to filter on */ @Persist private MailFilterBy filterBy; /* * The search value to filter on */ @Persist private String searchKey; /* * The MailRepositoryItem that's currrently drawn in the grid */ private MailRepositoryItemDTO mailRepositoryItem; @SuppressWarnings("unused") @Component(parameters = { "source = source", "model = model", "row = mailRepositoryItem", "volatile = true", "reorder = select,delete, id, fromHeader, subject, recipients, policyViolations, info ", "rowsPerPage = prop:rowsPerPage" }) private Grid grid; @SetupRender @Secured({ FactoryRoles.ROLE_ADMIN, FactoryRoles.ROLE_DLP_MANAGER, FactoryRoles.ROLE_QUARANTINE_MANAGER }) protected void setupRender() { if (selected == null) { selected = Collections.synchronizedSet(new HashSet<String>()); } else { selected.clear(); } if (filterBy == null) { filterBy = MailFilterBy.NO_FILTER; } } public BeanModel<MailRepositoryItemDTO> getModel() { BeanModel<MailRepositoryItemDTO> model = beanModelSource.createDisplayModel(MailRepositoryItemDTO.class, resources.getMessages()); model.add("delete", null); model.add("select", null); model.add("recipients", null); model.add("policyViolations", null); model.exclude("repository"); /* * Disable all sorting */ for (String column : model.getPropertyNames()) { model.get(column).sortable(false); } return model; } public void setFilterBy(MailFilterBy filterBy) { this.filterBy = filterBy; } public MailFilterBy getFilterBy() { return filterBy; } public MailRepositorySearchField getSearchField() { MailRepositorySearchField result = null; if (filterBy != null) { switch (filterBy) { case ID: result = MailRepositorySearchField.ID; break; case MESSAGE_ID: result = MailRepositorySearchField.MESSAGE_ID; break; case SUBJECT: result = MailRepositorySearchField.SUBJECT; break; case RECIPIENTS: result = MailRepositorySearchField.RECIPIENTS; break; case SENDER: result = MailRepositorySearchField.SENDER; break; case FROM: result = MailRepositorySearchField.FROM; break; } } return result; } public void setSearchKey(String searchKey) { this.searchKey = searchKey; } public String getSearchKey() { return searchKey; } public boolean isFilterDisabled() { return filterBy == null || filterBy == MailFilterBy.NO_FILTER; } public GridDataSource getSource() { return new MailRepositoryGridDataSource(mailRepository, getSearchField(), getSearchKey()); } @OnEvent(component = "deleteEntry") protected void deleteEntry(String id) { try { mailRepository.deleteItem(id); } catch (WebServiceCheckedException e) { logger.error("Error deleteEntry", e); error = true; errorMessage = ExceptionUtils.getRootCauseMessage(e); } } /* * Event handler called when the checkbox is clicked. */ public void onCheckboxEvent() { String data = request.getParameter("data"); if (StringUtils.isEmpty(data)) { throw new IllegalArgumentException("data is missing."); } JSONObject json = new JSONObject(data); String element = json.getString("element"); boolean checked = json.getBoolean("checked"); if (checked) { selected.add(element); } else { selected.remove(element); } } @OnEvent(component = "deleteSelected") protected void deleteSelected() { try { /* * Note: we need to clone the set to make sure that concurrent modifications * are possible. */ String[] ids = selected.toArray(new String[] {}); for (String id : ids) { mailRepository.deleteItem(id); } } catch (WebServiceCheckedException e) { logger.error("Error deleteSelected", e); error = true; errorMessage = ExceptionUtils.getRootCauseMessage(e); } } protected void releaseSelected(ReleaseProcessor processor) { try { /* * Note: we need to clone the set to make sure that concurrent modifications * are possible. */ String[] ids = selected.toArray(new String[] {}); for (String id : ids) { mailRepository.releaseMessage(id, processor); } } catch (WebServiceCheckedException e) { logger.error("Error releaseSelected", e); error = true; errorMessage = ExceptionUtils.getRootCauseMessage(e); } } @OnEvent(component = "releaseSelected") protected void releaseSelected() { releaseSelected(ReleaseProcessor.DEFAULT); } @OnEvent(component = "releaseEncryptSelected") protected void releaseEncryptSelected() { releaseSelected(ReleaseProcessor.ENCRYPT); } @OnEvent(component = "releaseAsIsSelected") protected void releaseAsIsSelected() { releaseSelected(ReleaseProcessor.AS_IS); } @OnEvent(DOWNLOAD_EMAIL_EVENT) protected StreamResponse downloadEmail(String id) { StreamResponse result = null; try { BinaryDTO backup = mailRepository.getMimeMessage(id); result = new InputStreamFileResponse(backup.getDataHandler().getInputStream(), ContentTypes.X_DOWNLOAD, id + ".eml"); } catch (Exception e) { logger.error("Error downloading email", e); error = true; errorMessage = ExceptionUtils.getRootCauseMessage(e); } return result; } public void setMailRepositoryItem(MailRepositoryItemDTO mailRepositoryItem) { this.mailRepositoryItem = mailRepositoryItem; } public MailRepositoryItemDTO getMailRepositoryItem() { return mailRepositoryItem; } public String getRecipients() { /* * The recipients are stored as list so they must be converted to a string */ return StringUtils.join(mailRepositoryItem.getRecipients(), ", "); } public String getPolicyViolations() { /* * The PolicyViolations is stored as list so they must be converted to a string */ return StringUtils.join(mailRepositoryItem.getPolicyViolations(), ", "); } public boolean getSelect() { return selected.contains(mailRepositoryItem.getId()); } public void setSelect(boolean value) { /* * Ignored. Checkbox values will be handled using EventCheckbox (see onCheckboxClick) */ } public Asset getDeleteAsset() { return deleteAsset; } public int getRowsPerPage() { return rowsPerPage != null ? rowsPerPage : defaultRowsPerPage; } public void setRowsPerPage(int rowsPerPage) { this.rowsPerPage = rowsPerPage; } public boolean isError() { return error; } public String getErrorMessage() { return StringUtils.isNotBlank(errorMessage) ? errorMessage : "No details."; } public Link getDownloadEmailLink() { return resources.createEventLink(DOWNLOAD_EMAIL_EVENT, mailRepositoryItem.getId()); } public Link getViewMIMELink() { final MutableObject mutableLink = new MutableObject(); ComponentEventCallback<Link> callback = new ComponentEventCallback<Link>() { @Override public boolean handleResult(Link link) { mutableLink.setValue(link); return true; } }; resources.triggerEvent(VIEW_MIME_CLICKED_EVENT, new Object[] { mailRepositoryItem.getId() }, callback); return (Link) mutableLink.getValue(); } public MailFilterBy getNoFilterEnumValue() { return MailFilterBy.NO_FILTER; } public MailFilterBy getIdEnumValue() { return MailFilterBy.ID; } public MailFilterBy getMessageIdEnumValue() { return MailFilterBy.MESSAGE_ID; } public MailFilterBy getSubjectEnumValue() { return MailFilterBy.SUBJECT; } public MailFilterBy getRecipientsEnumValue() { return MailFilterBy.RECIPIENTS; } public MailFilterBy getSenderEnumValue() { return MailFilterBy.SENDER; } public MailFilterBy getFromEnumValue() { return MailFilterBy.FROM; } }