podd.resources.services.ExternalFileUploadAttachmentService.java Source code

Java tutorial

Introduction

Here is the source code for podd.resources.services.ExternalFileUploadAttachmentService.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/>.
 */
/*
 * 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 static org.restlet.data.Status.CLIENT_ERROR_BAD_REQUEST;
import static org.restlet.data.Status.SERVER_ERROR_INTERNAL;
import static podd.model.audit.AuditLog.ERROR;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.apache.commons.fileupload.FileItem;
import org.json.JSONObject;
import org.restlet.representation.Representation;

import podd.exception.DataAccessException;
import podd.exception.EntityException;
import podd.exception.MimeTypeHandlingException;
import podd.exception.RawDataHandlingException;

/**
 * 
 * Attaches external files by uploading them to the remote datastore
 * 
 * @author Yuan-Fang Li
 * @version $Id$
 */
public class ExternalFileUploadAttachmentService extends AbstractExternalFileAttachmentService {

    protected Map<Integer, FileItem> fileMap;

    /**
     * Attach the files by uploading
     */
    protected void handleRemoteFileAttachment()
            throws DataAccessException, RawDataHandlingException, EntityException, MimeTypeHandlingException {

        attachAndTransferRedirectFiles();

    }

    protected void attachAndTransferRedirectFiles()
            throws DataAccessException, RawDataHandlingException, EntityException, MimeTypeHandlingException {
        try {
            // note: we used the loaded datastore when transferring the file, as it has more information than can be supplied by the user
            remoteFileHelper.attachRedirectFiles(dbLoadedDatastore, poddObject, fileMap, fileDescMap,
                    authenticatedUser.getUserName());

            final HashMap<String, String> transferErrorMap = remoteFileHelper.uploadFiles(dbLoadedDatastore,
                    poddObject);
            if (!transferErrorMap.isEmpty()) {
                // errors transferring some or all of the files, ensure the user gets the error messages back
                getResponse().setStatus(SERVER_ERROR_INTERNAL);
                errorMap.putAll(transferErrorMap);
                // rollback any changes to the object
                objectDao.refresh(poddObject);
            }

        } catch (IOException e) {
            final String msg = "Error transferring files to server - " + dbLoadedDatastore.getAddress()
                    + " directory - " + dbLoadedDatastore.getDefaultDirectory();
            errorMap.put("errorMessage", msg);
            LOGGER.error(msg, e);
            auditLogHelper.auditAction(ERROR, authenticatedUser, "External File Attachment Service: " + msg,
                    e.toString());
            objectDao.refresh(poddObject);
        }
    }

    @Override
    protected JSONObject getJSONObject() {
        return getAttachedFileURLs(fileMap);
    }

    private JSONObject getAttachedFileURLs(Map<Integer, FileItem> fileMap) {
        Map<Integer, String> filenameMap = new HashMap<Integer, String>();
        for (Integer idx : fileMap.keySet()) {
            FileItem item = fileMap.get(idx);
            filenameMap.put(idx, item.getName());
        }

        return super.getAttachedFileURLsAsJSONObject(filenameMap);
    }

    @Override
    protected Set<String> validateNoDuplicateFilenames(Map<String, String> errorMap) {

        final Set<String> fileNames = new HashSet<String>();
        for (FileItem item : fileMap.values()) {
            if (fileNames.contains(item.getName())) {
                getResponse().setStatus(CLIENT_ERROR_BAD_REQUEST);
                errorMap.put("duplicate file name", "Duplicate file attached: " + item.getName());
            } else {
                fileNames.add(item.getName());
            }
        }

        return fileNames;
    }

    @Override
    protected void validateDescriptions(Map<String, String> errorMap) {
        if (!fileDescMap.keySet().equals(fileMap.keySet())) {
            getResponse().setStatus(CLIENT_ERROR_BAD_REQUEST);
            errorMap.put("description error", "Files and descriptions not matching.");
        }

    }

    @Override
    protected void loadFormData(Representation entity) {
        fileMap = new LinkedHashMap<Integer, FileItem>();
        super.loadFormData(entity);
    }

    @Override
    protected boolean handleFormDataItem(FileItem item) {
        final String fieldName = item.getFieldName().trim();
        if (!item.isFormField()) {
            String intString = getFirstGroupMatched(FILE_NAME_PATTERN, fieldName);
            if (null != intString) {
                fileMap.put(Integer.parseInt(intString), item);
                return true;
            }
        }
        return false;
    }

}