Java tutorial
/* * Copyright (c) 2009 - 2010. School of Information Technology and Electrical * Engineering, The University of Queensland. This software is being developed * for the "Phenomics Ontoogy Driven Data Management Project (PODD)" project. * PODD is a National e-Research Architecture Taskforce (NeAT) project * co-funded by ANDS and ARCS. * * PODD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * PODD 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PODD. If not, see <http://www.gnu.org/licenses/>. */ package podd.resources.services; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.restlet.ext.fileupload.RestletFileUpload; import org.restlet.ext.json.JsonRepresentation; import org.restlet.representation.Representation; import org.restlet.representation.Variant; import org.restlet.resource.ResourceException; import podd.dataaccess.PoddObjectDAO; import podd.exception.DataAccessException; import podd.exception.EntityConsolidationException; import podd.model.entity.PoddObject; import podd.resources.AccessControlledResource; import podd.resources.services.util.JsonHelper; import podd.resources.util.error.SerivceErrorHandler; import java.net.URI; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.mail.MessagingException; import static org.restlet.data.Status.CLIENT_ERROR_BAD_REQUEST; import static org.restlet.data.Status.CLIENT_ERROR_NOT_FOUND; import static org.restlet.data.Status.CLIENT_ERROR_PRECONDITION_FAILED; import static org.restlet.data.Status.CLIENT_ERROR_FORBIDDEN; import static org.restlet.data.Status.CLIENT_ERROR_UNAUTHORIZED; import static org.restlet.data.Status.SERVER_ERROR_INTERNAL; import static org.restlet.data.Status.SUCCESS_OK; import static podd.model.audit.AuditLog.ERROR; import static podd.model.audit.AuditLog.INSUFFICIENT_ACCESS; import static podd.resources.services.ObjectService.GENERAL_MESSAGE_ID; import static podd.server.authz.UserAction.PUBLISH; import static podd.server.authz.UserAction.UNPUBLISH; import static podd.model.entity.ProjectStatus.COMPLETED; import podd.model.project.Project; import podd.model.user.User; import podd.resources.util.HandleServiceInvoker; import podd.util.EmailHandler; import podd.util.owl.PoddEntityConsolidator; public class PublishProjectService extends AccessControlledResource { private PoddObjectDAO objectDAO; private EmailHandler emailHandler; private HandleServiceInvoker handleInvoker; private PoddEntityConsolidator consolidator; private SerivceErrorHandler errorHandler; private Map<String, Map<String, List<String>>> errorMap; private JsonHelper jsonHelper; private URI objectURI; private Project project; private Boolean publish; private String baseUrl; public void setObjectDAO(PoddObjectDAO objectDAO) { this.objectDAO = objectDAO; } public void setEmailHandler(EmailHandler emailHandler) { this.emailHandler = emailHandler; } public void setHandleInvoker(HandleServiceInvoker handleInvoker) { this.handleInvoker = handleInvoker; } public void setConsolidator(PoddEntityConsolidator consolidator) { this.consolidator = consolidator; } public void setErrorHandler(SerivceErrorHandler errorHandler) { this.errorHandler = errorHandler; } public void setJsonHelper(JsonHelper jsonHelper) { this.jsonHelper = jsonHelper; } private void generateHandles() { handleInvoker.setParameters(project, baseUrl, authenticatedUser); //handleInvoker.run(); Thread thread = new Thread(handleInvoker); thread.start(); } private void sendNotificationEmail() { try { User pi = project.getPrincipalInvestigator(); Set<String> ccAddresses; if (pi.equals(authenticatedUser)) { ccAddresses = Collections.emptySet(); } else { ccAddresses = Collections.singleton(authenticatedUser.getEmail()); } emailHandler.send(authenticatedUser.getEmail(), pi.getEmail(), ccAddresses, "PODD: Project Published", "The following project has been published in PODD and is now publicly available. \n\n" + " ID: " + project.getPid() + "\n" + " Title: " + project.getLocalName() + "\n" + " Description: " + project.getLabel() + "\n\n" + "You should receive an email notifying you of the projects persistant URL shortly."); } catch (MessagingException e) { final String msg = "Error sending email to " + authenticatedUser.getEmail() + ": " + e.getMessage() + " "; LOGGER.error(msg, e); errorHandler.handleError(GENERAL_MESSAGE_ID, "Email Error", msg); auditLogHelper.auditAction(ERROR, authenticatedUser, "Publish Project Service: " + msg, e.toString()); } } private void updatePublicationStatus() { // set publication status if (publish) { project.setPublicationStatus(Project.ProjectPublicationStatus.PUBLISHED); } else { project.setPublicationStatus(Project.ProjectPublicationStatus.NOT_PUBLISHED); } } @Override protected void prePostAuthorisation(Representation entity) { LOGGER.debug("Publish Project Service"); errorMap = new HashMap<String, Map<String, List<String>>>(); errorHandler.setAllObjectsErrorMap(errorMap); PoddObject poddObject = null; project = null; publish = true; loadFormData(entity); if (null != objectURI) { try { poddObject = objectDAO.load(objectURI.getFragment()); if (null == poddObject) { getResponse().setStatus(CLIENT_ERROR_NOT_FOUND); final String msg = "No project can be found with the given URI: " + objectURI; errorHandler.handleError(GENERAL_MESSAGE_ID, "Invalid URI", msg); } else if (!poddObject.isProject()) { getResponse().setStatus(CLIENT_ERROR_NOT_FOUND); final String msg = "PODD Object with the given URI: " + objectURI + " is not a project"; errorHandler.handleError(GENERAL_MESSAGE_ID, "Not a Project", msg); } else { project = (Project) poddObject; if (publish) { if (!COMPLETED.equals(project.getProjectStatus())) { getResponse().setStatus(CLIENT_ERROR_PRECONDITION_FAILED); final String msg = "Project Status must be set to Completed before the project can be Published."; errorHandler.handleError(GENERAL_MESSAGE_ID, "Project Status Incorrect", msg); project = null; } } } } catch (DataAccessException e) { getResponse().setStatus(CLIENT_ERROR_BAD_REQUEST); final String msg = "Error loading PODD object with URI: " + objectURI + ". "; errorHandler.handleException(GENERAL_MESSAGE_ID, "Invalid URI", msg, e); auditLogHelper.auditAction(ERROR, authenticatedUser, "Publish Object Service: " + msg, e.toString()); } } else { getResponse().setStatus(CLIENT_ERROR_BAD_REQUEST); final String msg = "The object's URI must be sent in request with the key: URI"; errorHandler.handleError(GENERAL_MESSAGE_ID, "Invalid Parameters", msg); } } @Override protected Representation doAuthenticatedPost(Representation entity, Variant variant) throws ResourceException { Representation representation = null; if (null != project) { try { LOGGER.debug("pre updatePublicationStatus"); updatePublicationStatus(); consolidator.consolidate(project); objectDAO.update(project); if (publish) { LOGGER.info("Published project " + project.getObjectName() + " with pid: " + project.getPid()); generateHandles(); sendNotificationEmail(); getResponse().setStatus(SUCCESS_OK); } else { LOGGER.info( "Unpublished project " + project.getObjectName() + " with pid: " + project.getPid()); getResponse().setStatus(SUCCESS_OK); } } catch (DataAccessException e) { getResponse().setStatus(SERVER_ERROR_INTERNAL); final String msg = "An error occured while publishing project: " + project.getPid() + " "; errorHandler.handleException(project.getPid(), "Publishing Error", msg, e); auditLogHelper.auditAction(ERROR, authenticatedUser, "Publish Project Service: " + msg, e.toString()); } catch (EntityConsolidationException e) { getResponse().setStatus(SERVER_ERROR_INTERNAL); final String msg = "An error occured while consolidating project: " + project.getPid() + " "; errorHandler.handleException(project.getPid(), "Publishing Error", msg, e); auditLogHelper.auditAction(ERROR, authenticatedUser, "Publish Project Service: " + msg, e.toString()); } } if (!errorMap.isEmpty()) { representation = new JsonRepresentation(jsonHelper.convertErrorMap(errorMap)); } return representation; } @Override protected void preGetAuthorisation() { if (null == baseUrl) { baseUrl = getRequest().getRootRef().toString(); } } @Override protected Representation doAuthenticatedGet(Variant variant) throws ResourceException { auditLogHelper.auditAction(INSUFFICIENT_ACCESS, authenticatedUser, this.getRequest().getResourceRef().toString(), ""); return redirectErrorStatus(CLIENT_ERROR_FORBIDDEN); } @Override protected Representation doUnauthenticatedGet(Variant variant) throws ResourceException { if (null == authenticatedUser) { getResponse().setStatus(CLIENT_ERROR_UNAUTHORIZED); final String msg = "User must be authenticated to publish projects"; errorHandler.handleError(GENERAL_MESSAGE_ID, "errorMessage", msg); } if (!errorMap.isEmpty()) { return new JsonRepresentation(jsonHelper.convertErrorMap(errorMap)); } else { return redirectErrorStatus(CLIENT_ERROR_UNAUTHORIZED); } } @Override protected boolean authoriseGet() { if (null == project) { return true; } if (publish) { return manager.decide(authenticatedUser, project, PUBLISH); } else { return manager.decide(authenticatedUser, project, UNPUBLISH); } } private void loadFormData(Representation entity) { objectURI = null; RestletFileUpload upload = new RestletFileUpload(new DiskFileItemFactory()); try { List<FileItem> list = upload.parseRepresentation(entity); for (FileItem item : list) { if (item.getFieldName().equals("URI") && item.isFormField()) { objectURI = URI.create(item.getString().trim()); } } } catch (FileUploadException e) { getResponse().setStatus(SERVER_ERROR_INTERNAL); final String msg = "Error reading form data. "; errorHandler.handleException(GENERAL_MESSAGE_ID, "File Intialisation Error", msg, e); auditLogHelper.auditAction(ERROR, authenticatedUser, "Publish Object Service: " + msg, e.toString()); } } }