podd.resources.services.PublishProjectService.java Source code

Java tutorial

Introduction

Here is the source code for podd.resources.services.PublishProjectService.java

Source

/*
 * 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());
        }
    }
}