Package org.apache.ace.webui.vaadin

Source Code of org.apache.ace.webui.vaadin.UploadHelper$ArtifactDropHandler

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ace.webui.vaadin;

import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.ace.client.repository.object.ArtifactObject;
import org.apache.ace.client.repository.repository.ArtifactRepository;

import com.vaadin.event.Transferable;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptAll;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.terminal.StreamVariable;
import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable;
import com.vaadin.ui.Html5File;
import com.vaadin.ui.Upload;
import com.vaadin.ui.Upload.FailedEvent;
import com.vaadin.ui.Upload.FinishedEvent;
import com.vaadin.ui.Upload.SucceededEvent;

/**
* Provides convenience and utility methods for handling uploads of artifacts.
*/
public class UploadHelper {
    public static interface UploadHandle {
        void cleanup();

        Exception getFailureReason();

        File getFile();

        String getFilename();

        boolean isSuccessful();
    }

    /**
     * Provides a {@link DropHandler} implementation for handling dropped artifacts.
     */
    static final class ArtifactDropHandler implements DropHandler {
        private final GenericUploadHandler m_uploadHandler;

        ArtifactDropHandler(GenericUploadHandler uploadHandler) {
            m_uploadHandler = uploadHandler;
        }

        @Override
        public void drop(DragAndDropEvent dropEvent) {
            Transferable transferable = dropEvent.getTransferable();
            if (!(transferable instanceof WrapperTransferable)) {
                return;
            }

            // expecting this to be an html5 drag
            WrapperTransferable tr = (WrapperTransferable) transferable;
            Html5File[] files = tr.getFiles();
            if (files != null) {
                for (Html5File html5File : files) {
                    StreamVariable streamVar = m_uploadHandler.prepareUpload(html5File);

                    html5File.setStreamVariable(streamVar);
                }
            }
        }

        @Override
        public AcceptCriterion getAcceptCriterion() {
            return AcceptAll.get();
        }
    }

    /**
     * Provides a upload handler capable of handling "old school" uploads, and new HTML5-style uploads.
     */
    static abstract class GenericUploadHandler implements Upload.SucceededListener,
        Upload.FailedListener, Upload.Receiver, Upload.FinishedListener, Upload.ProgressListener {
        private final Map<String, UploadHandleImpl> m_uploads = new ConcurrentHashMap<String, UploadHandleImpl>();
        private final List<UploadHandle> m_completed = new CopyOnWriteArrayList<UploadHandle>();
        private final File m_sessionDir;

        /**
         * @param sessionDir
         *            the session directory to temporarily store uploaded artifacts in, cannot be <code>null</code>.
         */
        GenericUploadHandler(File sessionDir) {
            m_sessionDir = sessionDir;
        }

        /**
         * Install this upload handler for the given {@link Upload} component.
         *
         * @param upload
         *            the upload component to install this handler on, cannot be <code>null</code>.
         */
        public void install(Upload upload) {
            upload.setReceiver(this);
            upload.addListener((Upload.FailedListener) this);
            upload.addListener((Upload.FinishedListener) this);
            upload.addListener((Upload.ProgressListener) this);
            upload.addListener((Upload.SucceededListener) this);
        }

        @Override
        public final OutputStream receiveUpload(String filename, String MIMEType) {
            UploadHandleImpl handle = new UploadHandleImpl(this, new File(m_sessionDir, filename));
            m_uploads.put(filename, handle);
            handle.startUpload();
            uploadStarted(handle);
            return handle.m_fos;
        }

        @Override
        public final void uploadFailed(FailedEvent event) {
            handleUploadFailure(event.getFilename(), event.getReason());
        }

        @Override
        public final void uploadFinished(FinishedEvent event) {
            UploadHandleImpl handle = m_uploads.get(event.getFilename());
            if (handle != null) {
                silentlyClose(handle);
            }
        }

        @Override
        public final void uploadSucceeded(SucceededEvent event) {
            handleUploadSuccess(event.getFilename());
        }

        final void handleUploadFailure(String filename, Exception reason) {
            UploadHandleImpl handle = m_uploads.remove(filename);
            if (handle != null) {
                handle.uploadFailed(reason);

                silentlyClose(handle);

                m_completed.add(handle);
            }

            if (m_uploads.isEmpty()) {
                // All uploads are finished...
                artifactsUploaded(m_completed);
                m_completed.clear();
            }
        }

        final void handleUploadSuccess(String filename) {
            UploadHandleImpl handle = m_uploads.remove(filename);
            if (handle != null) {
                silentlyClose(handle);

                m_completed.add(handle);
            }

            if (m_uploads.isEmpty()) {
                // All uploads are finished...
                artifactsUploaded(m_completed);
                m_completed.clear();
            }
        }

        final UploadHandleImpl prepareUpload(Html5File file) {
            String fileName = file.getFileName();
            UploadHandleImpl uploadHandle = new UploadHandleImpl(this, new File(m_sessionDir, fileName));
            m_uploads.put(fileName, uploadHandle);
            return uploadHandle;
        }

        /**
         * Called when the upload is finished. The exact status (success or failure) can be determined by the given
         * {@link UploadHandle}.
         *
         * @param handles
         *            the uploaded artifacts to process, never <code>null</code>.
         */
        protected abstract void artifactsUploaded(List<UploadHandle> handles);

        /**
         * Called when the upload is started for an artifact.
         *
         * @param handle
         *            the handle to the upload that is started, never <code>null</code>.
         */
        protected void uploadStarted(UploadHandle handle) {
            // Nop
        }
    }

    private static class UploadHandleImpl implements StreamVariable, Closeable, UploadHandle {
        private final GenericUploadHandler m_handler;
        private final String m_filename;
        private final File m_file;

        private FileOutputStream m_fos = null;
        private Exception m_failureReason = null;

        /**
         * Creates a new {@link UploadHandleImpl} instance.
         */
        public UploadHandleImpl(GenericUploadHandler handler, File file) {
            m_handler = handler;
            m_filename = file.getName();
            m_file = file;
            m_fos = null;
        }

        @Override
        public void cleanup() {
            m_file.delete();
            silentlyClose(m_fos);
            m_fos = null;
        }

        @Override
        public void close() throws IOException {
            if (m_fos != null) {
                m_fos.close();
            }
        }

        @Override
        public Exception getFailureReason() {
            return m_failureReason;
        }

        @Override
        public File getFile() {
            return m_file;
        }

        @Override
        public String getFilename() {
            return m_filename;
        }

        @Override
        public OutputStream getOutputStream() {
            return m_fos;
        }

        @Override
        public boolean isInterrupted() {
            return (m_fos == null);
        }

        @Override
        public boolean isSuccessful() {
            return (m_failureReason == null);
        }

        @Override
        public boolean listenProgress() {
            return true;
        }

        @Override
        public void onProgress(StreamingProgressEvent event) {
            m_handler.updateProgress(event.getBytesReceived(), event.getContentLength());
        }

        @Override
        public void streamingFailed(StreamingErrorEvent event) {
            uploadFailed(event.getException());
            m_handler.handleUploadFailure(m_filename, event.getException());
        }

        @Override
        public void streamingFinished(StreamingEndEvent event) {
            m_handler.handleUploadSuccess(m_filename);
        }

        @Override
        public void streamingStarted(StreamingStartEvent event) {
            startUpload();

            if (m_fos != null) {
                m_handler.uploadStarted(this);
            }
        }

        /**
         * Starts the upload by creating an output stream to the temporary file.
         */
        void startUpload() {
            try {
                m_fos = new FileOutputStream(m_file);
            }
            catch (FileNotFoundException exception) {
                // This can only happen in theory...
                m_failureReason = exception;
                m_fos = null;
            }
        }

        void uploadFailed(Exception reason) {
            m_failureReason = reason;
        }
    }

    /**
     * Imports a local bundle (already contained in the OBR) bundle.
     *
     * @param artifactURL
     *            the URL of the artifact to import, cannot be <code>null</code>.
     * @return the imported artifact object, never <code>null</code>.
     * @throws IOException
     *             in case an I/O exception has occurred.
     */
    public static ArtifactObject importLocalBundle(ArtifactRepository artifactRepository, File artifact) throws IOException {
        URL url = artifact.toURI().toURL();
        if (!artifactRepository.recognizeArtifact(url)) {
            throw new IOException("Artifact " + artifact.getName() + " not recognized!");
        }
        return importLocalBundle(artifactRepository, url);
    }

    /**
     * Imports a local bundle (already contained in the OBR) bundle.
     *
     * @param artifactURL
     *            the URL of the artifact to import, cannot be <code>null</code>.
     * @return the imported artifact object, never <code>null</code>.
     * @throws IOException
     *             in case an I/O exception has occurred.
     */
    public static ArtifactObject importLocalBundle(ArtifactRepository artifactRepository, URL url) throws IOException {
        return artifactRepository.importArtifact(url, false /* upload */);
    }

    /**
     * Imports a remote bundle by uploading it to the OBR.
     *
     * @param artifactURL
     *            the URL of the artifact to import, cannot be <code>null</code>.
     * @return the imported artifact object, never <code>null</code>.
     * @throws IOException
     *             in case an I/O exception has occurred.
     */
    public static ArtifactObject importRemoteBundle(ArtifactRepository artifactRepository, File artifact) throws IOException {
        URL url = artifact.toURI().toURL();
        if (!artifactRepository.recognizeArtifact(url)) {
            throw new IOException("Artifact " + artifact.getName() + " not recognized!");
        }
        return artifactRepository.importArtifact(url, true /* upload */);
    }

    /**
     * Silently closes the given {@link Closeable} implementation, ignoring any errors that come out of the
     * {@link Closeable#close()} method.
     *
     * @param closable
     *            the closeable to close, can be <code>null</code>.
     */
    private static void silentlyClose(Closeable closable) {
        if (closable != null) {
            try {
                closable.close();
            }
            catch (IOException e) {
                // Best effort; nothing we can (or want) do about this...
            }
        }
    }

}
TOP

Related Classes of org.apache.ace.webui.vaadin.UploadHelper$ArtifactDropHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.