podd.resources.TabImportResource.java Source code

Java tutorial

Introduction

Here is the source code for podd.resources.TabImportResource.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;

import static podd.model.audit.AuditLog.ERROR;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.json.JSONException;
import org.json.JSONObject;
import org.restlet.data.Form;
import org.restlet.data.MediaType;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.representation.Variant;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ResourceException;

import podd.client.PoddWebServiceException;
import podd.resources.util.CreateObjectHelper;
import podd.resources.util.FileUploadHelper;
import podd.resources.util.TabImporterFactory;
import podd.tab.PoddTabException;
import podd.tab.Tab;
import podd.tab.TabImporter;
import podd.util.FormHandler;

/**
 * 
 * Import TAB file format
 * 
 * @author Philip Wu
 *
 */
public class TabImportResource extends PoddFreemarkerResource {

    protected static final String STOP_REFRESH_KEY = "stopRefresh";
    public static final String INPUT_TAB_FILE = "tabFile";
    public static final String INPUT_ACTION = "action";

    public static final String ACTION_SUBMIT = "submit";
    public static final String ACTION_RESET = "reset";
    public static final String ACTION_REMOVE_FILE = "removeFile";
    public static final String ACTION_CACHE_TAB_FILE = "cacheTabFile";
    public static final String ACTION_STATUS = "status";

    public static final String GET_ACTION_COMPLETED = "completed";

    protected FormHandler formHandler;
    protected CreateObjectHelper createObjectHelper;
    protected TabImporter tabImporter;
    protected boolean alreadyInitialized;

    public void setFormHandler(FormHandler formHandler) {
        this.formHandler = formHandler;
    }

    public FormHandler getFormHandler() {
        return formHandler;
    }

    public CreateObjectHelper getCreateObjectHelper() {
        return createObjectHelper;
    }

    public void setCreateObjectHelper(CreateObjectHelper createObjectHelper) {
        this.createObjectHelper = createObjectHelper;
    }

    public void doInit() throws ResourceException {
        dataModel = new HashMap<String, Object>();
        dataModel.put("stopRefreshKey", STOP_REFRESH_KEY);
        exceptionHandler.setDataModel(dataModel);
        setContentTemplateName("tabImport.html.ftl");
        super.doInit();
    }

    @Override
    protected boolean authoriseGet() {
        // Any authenticated user can upload
        // However, not all users can create all objects. This is handled at the TAB import level
        if (authenticatedUser != null)
            return true;
        else
            return false;
    }

    @Override
    protected void preGetAuthorisation() {
        super.preGetAuthorisation();
        //Form form = getRequest().getResourceRef().getQueryAsForm();
        String uploadedTabFile = getUploadedTabFile();

        if (null != uploadedTabFile) {
            alreadyInitialized = true;
            exceptionHandler.displayErrorOnScreen(
                    "A TAB file was previously attached. To restart click the 'Reset' button below");
        }
    }

    @Override
    @Get("html")
    public Representation doAuthenticatedGet(Variant variant) throws ResourceException {

        Form form = this.getRequest().getResourceRef().getQueryAsForm();
        String action = form.getFirstValue(INPUT_ACTION);
        if (_INFO) {
            LOGGER.info("action: " + action);
        }
        if (action != null && action.equals(GET_ACTION_COMPLETED)) {
            Representation representation = super.doAuthenticatedGet(variant);
            // Override the contentTemplate
            dataModel.put("contentTemplate", "tabImportResults.html.ftl"); // Restore the content template name

            // Load all the objects to be displayed
            List<URI> list = tabImporter.getProcessingOrder();
            dataModel.put("tabObjects", list);

            return representation;
        } else if (action != null && action.equals(ACTION_STATUS)) {
            JSONObject json = new JSONObject();
            // Return the status of the import
            if (_DEBUG) {
                LOGGER.debug("tabImporter=" + tabImporter);
            }

            if (tabImporter != null) {
                try {
                    json.put("numObjectsCompleted", tabImporter.getNumObjectsCompleted());
                    json.put("totalNumObjects", tabImporter.getTotalNumObjects());
                    if (tabImporter.getError() != null)
                        json.put("error", tabImporter.getError());

                } catch (JSONException e) {
                    final String msg = "Error creating JSON response: " + e.getMessage();
                    LOGGER.error(msg, e);
                    auditLogHelper.auditAction(ERROR, authenticatedUser, "TAB Import Resource: " + msg,
                            e.toString());
                }
            }

            if (_DEBUG) {
                LOGGER.debug("json=" + json);
            }

            // For some reason usin JsonRepresentation is being returned as a downloadable document (as in binary file)
            //JsonRepresentation representation = new JsonRepresentation(json);

            return new StringRepresentation(json.toString());
        } else { // Default Form page
            return getMainFormRepresentation(variant);
        }
    }

    /**
     * Returns the main representation to the form page
     * @param variant
     * @return
     * @throws ResourceException
     */
    protected Representation getMainFormRepresentation(Variant variant) throws ResourceException {
        dataModel.put("fileDescription", formHandler.getFirstFieldValue("file_description"));
        //dataModel.put("fileList", attachments);
        dataModel.put("attachedFileList", getAttachedFiles());
        if (tabImporter != null)
            dataModel.put("error", tabImporter.getError());
        if (null != formHandler.getInputErrors() && !formHandler.getInputErrors().isEmpty()) {
            exceptionHandler.displayErrorOnScreen("Invalid TAB file");
            displayFileErrorMessages(formHandler.getInputErrors());
            final Map<String, List<String>> inputErrors = formHandler.getInputErrors();
            for (String key : inputErrors.keySet()) {
                exceptionHandler.displayErrorOnScreen(key + "Error", inputErrors.get(key).get(0));
            }
        }
        // Provide the name of the tab file if it's already been uploaded
        String uploadedTabFile = getUploadedTabFile();
        dataModel.put("uploadedTabFile", uploadedTabFile);
        if (_DEBUG) {
            LOGGER.debug("uploadedTabFile: " + uploadedTabFile);
        }

        return super.doAuthenticatedGet(variant);
    }

    @Override
    @Post("html")
    protected Representation doAuthenticatedPost(Representation entity, Variant variant) throws ResourceException {

        Representation resultRepresentation = null;
        boolean validformdata = false;
        if (_DEBUG) {
            LOGGER.debug("mediaType: " + entity.getMediaType().getName());
        }

        if (entity.getMediaType().getName().equals(MediaType.APPLICATION_WWW_FORM.getName())) {
            validformdata = formHandler.saveForm(this.getRequest().getEntityAsForm());
        } else {
            validformdata = formHandler.saveFieldValues(entity);
        }

        if (_DEBUG) {
            LOGGER.debug("validFormData: " + validformdata);
        }
        boolean hasError = false;
        if (validformdata) {
            try {
                // add currently selected file to the Map of files to be attached when PODD object is saved          
                formHandler.addFile(false);

                String submitAction = formHandler.getFirstFieldValue(INPUT_ACTION);
                if (_DEBUG) {
                    LOGGER.debug("submitAction: " + submitAction);
                }

                if (submitAction != null && submitAction.trim().length() != 0) {
                    if (submitAction.equals(ACTION_SUBMIT)) {// Submitting

                        // Store all the parameters in a Tab object
                        Tab tab = new Tab();
                        for (Iterator<FileItem> it = formHandler.getFileIterator(); it.hasNext();) {
                            FileItem item = it.next();
                            if (_DEBUG) {
                                LOGGER.debug("adding file name: " + item.getName() + " fieldName: "
                                        + item.getFieldName() + " in memory: " + item.isInMemory());
                            }

                            DiskFileItem diskFileItem = (DiskFileItem) item;

                            if (!item.getFieldName().equals(INPUT_TAB_FILE)) {
                                // If the file is not on disk, force to disk
                                File copiedFile = FileUploadHelper.writeToDisk(diskFileItem, authenticatedUser);
                                if (copiedFile != null) {
                                    if (copiedFile.exists())
                                        tab.addAttachment(copiedFile.getName(), copiedFile);
                                    else {
                                        String msg = "File attachment failed to copy: "
                                                + copiedFile.getAbsolutePath();
                                        LOGGER.error(msg);
                                        auditLogHelper.auditAction(ERROR, authenticatedUser,
                                                "TAB Import Resource: " + msg, "");
                                        throw new ResourceException(new PoddTabException(msg));
                                    }
                                }
                            } else {
                                tab.setTabStream(item.getInputStream());
                            }
                        }

                        tabImporter = TabImporterFactory.getInstance().createTabImporter(this.getRequest(), tab);

                        // Run in a separate thread so that we can get a response back right away
                        Thread t = new Thread() {

                            public void run() {
                                // Now that we have all the parameters, import the TAB file                         
                                try {
                                    tabImporter.importTab();
                                } catch (PoddTabException e) {
                                    LOGGER.error("Found PODD Tab exception", e);
                                    tabImporter.rollbackCreatedObjects();
                                } catch (PoddWebServiceException e) {
                                    LOGGER.error("Found PODD Web Service exception", e);
                                    tabImporter.rollbackCreatedObjects();
                                }
                                formHandler.resetAllFields();
                            }
                        };

                        t.start();
                        // Hack: so that Javascript can invoke the redirection in the Freemarker templates
                        /*
                        try {
                           Thread.sleep(4000);
                        } catch (InterruptedException e) {
                           LOGGER.error(e);
                           e.printStackTrace();
                        }*/

                        // Return back to the same page and indicate that the page should check the status of the import
                        /*
                        String redirectUrl = this.getRequest().getOriginalRef().toString() + "?" + INPUT_ACTION + "=" + GET_ACTION_COMPLETED;
                        LOGGER.debug("redirectUrl: " + redirectUrl);
                        getResponse().redirectPermanent(redirectUrl);                  
                        return super.doAuthenticatedGet(variant);
                        */

                        // Indicate to the page that the tab file has been submitted
                        dataModel.put("submitted", Boolean.TRUE);
                        resultRepresentation = getMainFormRepresentation(variant);

                    } else if (submitAction.equals(ACTION_RESET)) {
                        tabImporter.reset();
                        formHandler.resetAllFields();
                        resultRepresentation = get(variant);
                    } else if (submitAction.equals(ACTION_CACHE_TAB_FILE)) {
                        resultRepresentation = doAuthenticatedGet(variant);
                    } else {
                        resultRepresentation = doAuthenticatedGet(variant);
                    }
                } else if (formHandler.fieldExists("removeFile")) {
                    formHandler.removeFile();
                    resultRepresentation = doAuthenticatedGet(variant);
                } else { // File attachment most likely
                    resultRepresentation = doAuthenticatedGet(variant);
                }
            } catch (IOException e) {
                final String msg = "Exception reading file item: " + e.getMessage();
                exceptionHandler.handleException(e, true, msg);
                auditLogHelper.auditAction(ERROR, authenticatedUser, "TAB Import Resource: " + msg, e.toString());
                hasError = true;
            }

            // If there's an error go back to the originating page
            if (hasError) {
                LOGGER.error("There was an error. Redirecting to originating page to display error messages");
                // Rollback            
                tabImporter.rollbackCreatedObjects();

                resultRepresentation = getMainFormRepresentation(variant);
            }
        }
        if (_DEBUG) {
            LOGGER.debug("resultRepresentation: " + resultRepresentation);
        }
        return resultRepresentation;
    }

    /**
     * Check to see if the file has already been uploaded
     * @return
     */
    private String getUploadedTabFile() {

        for (Iterator<FileItem> it = formHandler.getFileIterator(); it.hasNext();) {

            FileItem item = it.next();
            if (item.getFieldName().equals(INPUT_TAB_FILE)) {
                if (item.getSize() > 0)
                    return item.getName();
                else
                    return null;
            }
        }
        return null;
    }

    /**
     * Gets a list of attached files
     * @return
     */
    private List<String> getAttachedFiles() {

        List<String> attachments = new ArrayList<String>();
        for (Iterator<FileItem> it = formHandler.getFileIterator(); it.hasNext();) {

            FileItem item = it.next();
            String fieldname = item.getFieldName();
            if (fieldname.equals("File0")) {
                attachments.add(item.getName());
            }
        }
        return attachments;
    }
}