From 4bea93b0b64c026281277c65b80b6ee020a6cce4 Mon Sep 17 00:00:00 2001 From: Yuriy Artamonov Date: Fri, 21 Dec 2012 13:10:27 +0000 Subject: [PATCH] Refs #1744 [Desktop] Show progress window during file upload --- .../components/DesktopFileUploadField.java | 61 +++++++---------- .../impl/DesktopBackgroundWorker.java | 5 +- .../BackgroundWorkProgressWindow.java | 2 - .../cuba/gui/components/FileUploadField.java | 20 +++--- .../gui/executors/impl/TaskHandlerImpl.java | 17 ++--- ...ty.java => FileStorageProgressEntity.java} | 9 ++- .../cuba/gui/upload/FileUploading.java | 28 +++++--- .../cuba/gui/upload/FileUploadingAPI.java | 4 +- .../gui/components/WebFileUploadField.java | 68 ++++++++----------- 9 files changed, 97 insertions(+), 117 deletions(-) rename modules/gui/src/com/haulmont/cuba/gui/upload/{FileStorageEntity.java => FileStorageProgressEntity.java} (77%) diff --git a/modules/desktop/src/com/haulmont/cuba/desktop/gui/components/DesktopFileUploadField.java b/modules/desktop/src/com/haulmont/cuba/desktop/gui/components/DesktopFileUploadField.java index 375ff76830..409c5f75ed 100644 --- a/modules/desktop/src/com/haulmont/cuba/desktop/gui/components/DesktopFileUploadField.java +++ b/modules/desktop/src/com/haulmont/cuba/desktop/gui/components/DesktopFileUploadField.java @@ -7,11 +7,8 @@ package com.haulmont.cuba.desktop.gui.components; import com.haulmont.cuba.client.ClientConfig; -import com.haulmont.cuba.core.global.AppBeans; -import com.haulmont.cuba.core.global.ConfigProvider; -import com.haulmont.cuba.core.global.FileStorageException; -import com.haulmont.cuba.core.global.MessageProvider; -import com.haulmont.cuba.core.sys.AppContext; +import com.haulmont.cuba.core.entity.FileDescriptor; +import com.haulmont.cuba.core.global.*; import com.haulmont.cuba.gui.AppConfig; import com.haulmont.cuba.gui.components.FileUploadField; import com.haulmont.cuba.gui.components.IFrame; @@ -37,10 +34,11 @@ public class DesktopFileUploadField extends DesktopAbstractComponent im private static final int BYTES_IN_MEGABYTE = 1048576; protected FileUploadingAPI fileUploading; + protected Messages messages; + + protected volatile boolean isUploadingState = false; - protected boolean isUploadingState = false; protected String fileName; - protected byte[] bytes; protected String description; @@ -54,7 +52,7 @@ public class DesktopFileUploadField extends DesktopAbstractComponent im fileUploading = AppBeans.get(FileUploadingAPI.NAME); final JFileChooser fileChooser = new JFileChooser(); - String caption = MessageProvider.getMessage(getClass(), "export.selectFile"); + String caption = messages.getMessage(getClass(), "export.selectFile"); impl = new JButton(); impl.setAction(new AbstractAction(caption) { @Override @@ -67,11 +65,11 @@ public class DesktopFileUploadField extends DesktopAbstractComponent im } private void uploadFile(File file) { - final Integer maxUploadSizeMb = ConfigProvider.getConfig(ClientConfig.class).getMaxUploadSizeMb(); + final Integer maxUploadSizeMb = AppBeans.get(Configuration.class).getConfig(ClientConfig.class).getMaxUploadSizeMb(); final long maxSize = maxUploadSizeMb * BYTES_IN_MEGABYTE; if (file.length() > maxSize) { - String warningMsg = MessageProvider.getMessage(AppConfig.getMessagesPack(), "upload.fileTooBig.message"); + String warningMsg = messages.getMessage(AppConfig.getMessagesPack(), "upload.fileTooBig.message"); getFrame().showNotification(warningMsg, IFrame.NotificationType.WARNING); } else { boolean succcess = true; @@ -135,11 +133,6 @@ public class DesktopFileUploadField extends DesktopAbstractComponent im } } - @Override - public String getFilePath() { - return fileName; - } - @Override public String getFileName() { String[] strings = fileName.split("[/\\\\]"); @@ -147,24 +140,26 @@ public class DesktopFileUploadField extends DesktopAbstractComponent im } @Override - public boolean isUploading() { - return isUploadingState; + public FileDescriptor getFileDescriptor() { + if (fileId != null) + return fileUploading.getFileDescriptor(fileId, fileName); + else + return null; } @Override public byte[] getBytes() { - if (bytes == null) { - try { - if (fileId != null) { - File file = fileUploading.getFile(fileId); - FileInputStream fileInputStream = new FileInputStream(file); - ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(); - IOUtils.copy(fileInputStream, byteOutput); - bytes = byteOutput.toByteArray(); - } - } catch (Exception e) { - throw new RuntimeException(e); + byte[] bytes = null; + try { + if (fileId != null) { + File file = fileUploading.getFile(fileId); + FileInputStream fileInputStream = new FileInputStream(file); + ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(); + IOUtils.copy(fileInputStream, byteOutput); + bytes = byteOutput.toByteArray(); } + } catch (Exception e) { + throw new RuntimeException(e); } return bytes; @@ -175,16 +170,6 @@ public class DesktopFileUploadField extends DesktopAbstractComponent im return fileId; } - @Override - public long getBytesRead() { - return 0; - } - - @Override - public void release() { - bytes = null; - } - @Override public void addListener(Listener listener) { if (!listeners.contains(listener)) listeners.add(listener); diff --git a/modules/desktop/src/com/haulmont/cuba/desktop/gui/executors/impl/DesktopBackgroundWorker.java b/modules/desktop/src/com/haulmont/cuba/desktop/gui/executors/impl/DesktopBackgroundWorker.java index 100d070580..8d2ea257d9 100644 --- a/modules/desktop/src/com/haulmont/cuba/desktop/gui/executors/impl/DesktopBackgroundWorker.java +++ b/modules/desktop/src/com/haulmont/cuba/desktop/gui/executors/impl/DesktopBackgroundWorker.java @@ -6,7 +6,8 @@ package com.haulmont.cuba.desktop.gui.executors.impl; -import com.haulmont.cuba.core.global.UserSessionProvider; +import com.haulmont.cuba.core.global.AppBeans; +import com.haulmont.cuba.core.global.UserSessionSource; import com.haulmont.cuba.gui.executors.*; import com.haulmont.cuba.gui.executors.impl.TaskExecutor; import com.haulmont.cuba.gui.executors.impl.TaskHandlerImpl; @@ -69,7 +70,7 @@ public class DesktopBackgroundWorker implements BackgroundWorker { private DesktopTaskExecutor(BackgroundTask runnableTask) { this.runnableTask = runnableTask; - userId = UserSessionProvider.getUserSession().getId(); + userId = AppBeans.get(UserSessionSource.class).getUserSession().getId(); //noinspection unchecked this.params = runnableTask.getParams(); diff --git a/modules/gui/src/com/haulmont/cuba/gui/backgroundwork/BackgroundWorkProgressWindow.java b/modules/gui/src/com/haulmont/cuba/gui/backgroundwork/BackgroundWorkProgressWindow.java index 957fac1e5f..3d3d4b86e3 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/backgroundwork/BackgroundWorkProgressWindow.java +++ b/modules/gui/src/com/haulmont/cuba/gui/backgroundwork/BackgroundWorkProgressWindow.java @@ -39,9 +39,7 @@ import java.util.Map; * @author ovchinnikov * @version $Id$ */ -@SuppressWarnings("unused") public class BackgroundWorkProgressWindow extends AbstractWindow { - private static final long serialVersionUID = -3073224246530486376L; @Inject private Label text; diff --git a/modules/gui/src/com/haulmont/cuba/gui/components/FileUploadField.java b/modules/gui/src/com/haulmont/cuba/gui/components/FileUploadField.java index 2484490ed4..b040a636e3 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/components/FileUploadField.java +++ b/modules/gui/src/com/haulmont/cuba/gui/components/FileUploadField.java @@ -9,6 +9,8 @@ */ package com.haulmont.cuba.gui.components; +import com.haulmont.cuba.core.entity.FileDescriptor; + import java.util.UUID; public interface FileUploadField @@ -60,10 +62,13 @@ public interface FileUploadField } } - String getFilePath(); + /** + * Get id for uploaded file in {@link com.haulmont.cuba.gui.upload.FileUploading} + * @return File Id + */ + UUID getFileId(); String getFileName(); - - boolean isUploading(); + FileDescriptor getFileDescriptor(); /** * Get content bytes for uploaded file @@ -72,15 +77,6 @@ public interface FileUploadField */ byte[] getBytes(); - /** - * Get id for uploaded file in {@link com.haulmont.cuba.gui.upload.FileUploading} - * @return File Id - */ - UUID getFileId(); - - long getBytesRead(); - void release(); - void addListener(Listener listener); void removeListener(Listener listener); } diff --git a/modules/gui/src/com/haulmont/cuba/gui/executors/impl/TaskHandlerImpl.java b/modules/gui/src/com/haulmont/cuba/gui/executors/impl/TaskHandlerImpl.java index d6e17f81e8..abd15715fa 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/executors/impl/TaskHandlerImpl.java +++ b/modules/gui/src/com/haulmont/cuba/gui/executors/impl/TaskHandlerImpl.java @@ -6,8 +6,9 @@ package com.haulmont.cuba.gui.executors.impl; -import com.haulmont.cuba.core.global.TimeProvider; -import com.haulmont.cuba.core.global.UserSessionProvider; +import com.haulmont.cuba.core.global.AppBeans; +import com.haulmont.cuba.core.global.TimeSource; +import com.haulmont.cuba.core.global.UserSessionSource; import com.haulmont.cuba.core.sys.AppContext; import com.haulmont.cuba.gui.components.Window; import com.haulmont.cuba.gui.executors.BackgroundTask; @@ -44,7 +45,7 @@ public class TaskHandlerImpl implements BackgroundTaskHandler { public TaskHandlerImpl(TaskExecutor taskExecutor, WatchDog watchDog) { this.taskExecutor = taskExecutor; this.watchDog = watchDog; - this.userSession = UserSessionProvider.getUserSession(); + this.userSession = AppBeans.get(UserSessionSource.class).getUserSession(); BackgroundTask task = taskExecutor.getTask(); if (task.getOwnerWindow() != null) { @@ -70,7 +71,7 @@ public class TaskHandlerImpl implements BackgroundTaskHandler { UUID userId = getUserSession().getId(); Window ownerWindow = getTask().getOwnerWindow(); String windowClass = ownerWindow.getClass().getCanonicalName(); - log.debug("Window closed. User: " + userId + " Window: " + windowClass); + log.trace("Window closed. User: " + userId + " Window: " + windowClass); taskExecutor.cancelExecution(); } @@ -82,12 +83,12 @@ public class TaskHandlerImpl implements BackgroundTaskHandler { this.started = true; - this.startTimeStamp = TimeProvider.currentTimestamp().getTime(); + this.startTimeStamp = AppBeans.get(TimeSource.class).currentTimestamp().getTime(); this.watchDog.manageTask(this); UUID userId = getUserSession().getId(); - log.debug("Run task. User: " + userId); + log.trace("Run task. User: " + userId); taskExecutor.startExecution(); } @@ -149,9 +150,9 @@ public class TaskHandlerImpl implements BackgroundTaskHandler { if (ownerWindow != null) { String windowClass = ownerWindow.getClass().getCanonicalName(); - log.debug("Task killed. User: " + userId + " Window: " + windowClass); + log.trace("Task killed. User: " + userId + " Window: " + windowClass); } else - log.debug("Task killed. User: " + userId); + log.trace("Task killed. User: " + userId); } taskExecutor.cancelExecution(); diff --git a/modules/gui/src/com/haulmont/cuba/gui/upload/FileStorageEntity.java b/modules/gui/src/com/haulmont/cuba/gui/upload/FileStorageProgressEntity.java similarity index 77% rename from modules/gui/src/com/haulmont/cuba/gui/upload/FileStorageEntity.java rename to modules/gui/src/com/haulmont/cuba/gui/upload/FileStorageProgressEntity.java index 8d63e50b52..0660d625c3 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/upload/FileStorageEntity.java +++ b/modules/gui/src/com/haulmont/cuba/gui/upload/FileStorageProgressEntity.java @@ -17,14 +17,14 @@ import static com.google.common.base.Preconditions.checkNotNull; * @author artamonov * @version $Id$ */ -public class FileStorageEntity extends FileEntity { +public class FileStorageProgressEntity extends FileEntity { private final long size; private final UUID fileId; private final FileUploadingAPI.UploadToStorageProgressListener listener; - public FileStorageEntity(File file, String contentType, UUID fileId, - FileUploadingAPI.UploadToStorageProgressListener listener) { + public FileStorageProgressEntity(File file, String contentType, UUID fileId, + FileUploadingAPI.UploadToStorageProgressListener listener) { super(file, contentType); this.listener = listener; @@ -47,6 +47,9 @@ public class FileStorageEntity extends FileEntity { byte[] tmp = new byte[4096]; int readedBytes; while ((readedBytes = instream.read(tmp)) != -1) { + if (Thread.currentThread().isInterrupted()) + throw new InterruptedIOException(); + outstream.write(tmp, 0, readedBytes); transferredBytes += readedBytes; diff --git a/modules/gui/src/com/haulmont/cuba/gui/upload/FileUploading.java b/modules/gui/src/com/haulmont/cuba/gui/upload/FileUploading.java index ea14dd467f..2bbf59cdb2 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/upload/FileUploading.java +++ b/modules/gui/src/com/haulmont/cuba/gui/upload/FileUploading.java @@ -214,14 +214,14 @@ public class FileUploading implements FileUploadingAPI, FileUploadingMBean { if (file.exists()) { boolean res = file.delete(); if (!res) - throw new FileStorageException(FileStorageException.Type.IO_EXCEPTION, file.getAbsolutePath()); + log.warn("Could not delete temp file " + file.getAbsolutePath()); } } } @Override public void deleteFileLink(String fileName) { - Map clonedFileMap = new ConcurrentHashMap<>(tempFiles); + Map clonedFileMap = new HashMap<>(tempFiles); Iterator> iterator = clonedFileMap.entrySet().iterator(); UUID forDelete = null; while ((iterator.hasNext()) && (forDelete == null)) { @@ -236,13 +236,18 @@ public class FileUploading implements FileUploadingAPI, FileUploadingMBean { @Override public void putFileIntoStorage(UUID fileId, FileDescriptor fileDescr) throws FileStorageException { - uploadFileIntoStorage(fileId, fileDescr, null); + try { + uploadFileIntoStorage(fileId, fileDescr, null); + } catch (InterruptedIOException e) { + throw new FileStorageException(FileStorageException.Type.IO_EXCEPTION, fileDescr.getFileName()); + } deleteFile(fileId); } private void uploadFileIntoStorage(UUID fileId, FileDescriptor fileDescr, - @Nullable UploadToStorageProgressListener listener) throws FileStorageException { + @Nullable UploadToStorageProgressListener listener) + throws FileStorageException, InterruptedIOException { File file = getFile(fileId); for (Iterator iterator = clusterInvocationSupport.getUrlList().iterator(); iterator.hasNext(); ) { @@ -254,7 +259,7 @@ public class FileUploading implements FileUploadingAPI, FileUploadingMBean { HttpPost method = new HttpPost(url); FileEntity entity; if (listener != null) - entity = new FileStorageEntity(file, "application/octet-stream", fileId, listener); + entity = new FileStorageProgressEntity(file, "application/octet-stream", fileId, listener); else entity = new FileEntity(file, "application/octet-stream"); @@ -272,6 +277,9 @@ public class FileUploading implements FileUploadingAPI, FileUploadingMBean { else throw new FileStorageException(FileStorageException.Type.fromHttpStatus(statusCode), fileDescr.getName()); } + } catch (InterruptedIOException e) { + log.trace("Uploading has been interrupted"); + throw e; } catch (IOException e) { log.debug("Unable to upload file to " + url + "\n" + e); if (iterator.hasNext()) @@ -285,7 +293,9 @@ public class FileUploading implements FileUploadingAPI, FileUploadingMBean { } @Override - public FileDescriptor putFileIntoStorage(final TaskLifeCycle taskLifeCycle) throws FileStorageException { + public FileDescriptor putFileIntoStorage(final TaskLifeCycle taskLifeCycle) + throws FileStorageException, InterruptedIOException { + checkNotNull(taskLifeCycle); UUID fileId = (UUID) taskLifeCycle.getParams().get("fileId"); @@ -337,10 +347,8 @@ public class FileUploading implements FileUploadingAPI, FileUploadingMBean { @Override public String showTempFiles() { StringBuilder builder = new StringBuilder(); - Map clonedFileMap = new ConcurrentHashMap<>(tempFiles); - Iterator> iterator = clonedFileMap.entrySet().iterator(); - while ((iterator.hasNext())) { - Map.Entry fileEntry = iterator.next(); + Map clonedFileMap = new HashMap<>(tempFiles); + for (Map.Entry fileEntry : clonedFileMap.entrySet()) { builder.append(fileEntry.getKey().toString()).append(" | "); Date lastModified = new Date(fileEntry.getValue().lastModified()); DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); diff --git a/modules/gui/src/com/haulmont/cuba/gui/upload/FileUploadingAPI.java b/modules/gui/src/com/haulmont/cuba/gui/upload/FileUploadingAPI.java index 69ad6a7019..7f907a5b42 100644 --- a/modules/gui/src/com/haulmont/cuba/gui/upload/FileUploadingAPI.java +++ b/modules/gui/src/com/haulmont/cuba/gui/upload/FileUploadingAPI.java @@ -12,6 +12,7 @@ import com.haulmont.cuba.gui.executors.TaskLifeCycle; import java.io.File; import java.io.FileNotFoundException; import java.io.InputStream; +import java.io.InterruptedIOException; import java.util.UUID; /** @@ -68,5 +69,6 @@ public interface FileUploadingAPI { * @return file descriptor * @throws FileStorageException */ - FileDescriptor putFileIntoStorage(TaskLifeCycle taskLifeCycle) throws FileStorageException; + FileDescriptor putFileIntoStorage(TaskLifeCycle taskLifeCycle) + throws FileStorageException, InterruptedIOException; } \ No newline at end of file diff --git a/modules/web/src/com/haulmont/cuba/web/gui/components/WebFileUploadField.java b/modules/web/src/com/haulmont/cuba/web/gui/components/WebFileUploadField.java index e2009d4d06..522b3e5d66 100644 --- a/modules/web/src/com/haulmont/cuba/web/gui/components/WebFileUploadField.java +++ b/modules/web/src/com/haulmont/cuba/web/gui/components/WebFileUploadField.java @@ -6,10 +6,11 @@ package com.haulmont.cuba.web.gui.components; import com.haulmont.cuba.client.ClientConfig; +import com.haulmont.cuba.core.entity.FileDescriptor; import com.haulmont.cuba.core.global.AppBeans; -import com.haulmont.cuba.core.global.ConfigProvider; +import com.haulmont.cuba.core.global.Configuration; import com.haulmont.cuba.core.global.FileStorageException; -import com.haulmont.cuba.core.global.MessageProvider; +import com.haulmont.cuba.core.global.Messages; import com.haulmont.cuba.gui.AppConfig; import com.haulmont.cuba.gui.components.FileUploadField; import com.haulmont.cuba.gui.components.IFrame; @@ -34,9 +35,9 @@ public class WebFileUploadField extends WebAbstractComponent implements private static final int BYTES_IN_MEGABYTE = 1048576; protected FileUploadingAPI fileUploading; + protected Messages messages; protected String fileName; - protected byte[] bytes; protected UUID fileId; @@ -49,7 +50,7 @@ public class WebFileUploadField extends WebAbstractComponent implements public WebFileUploadField() { fileUploading = AppBeans.get(FileUploadingAPI.NAME); - String caption = MessageProvider.getMessage(AppConfig.getMessagesPack(), "Upload"); + String caption = messages.getMessage(AppConfig.getMessagesPack(), "Upload"); component = new Upload( /* Fixes caption rendering. * If caption == "", the VerticalLayout reserves an empty space */ @@ -75,14 +76,13 @@ public class WebFileUploadField extends WebAbstractComponent implements component.addListener(new Upload.StartedListener() { @Override public void uploadStarted(Upload.StartedEvent event) { - final Integer maxUploadSizeMb = ConfigProvider.getConfig(ClientConfig.class).getMaxUploadSizeMb(); + final Integer maxUploadSizeMb = AppBeans.get(Configuration.class).getConfig(ClientConfig.class).getMaxUploadSizeMb(); final long maxSize = maxUploadSizeMb * BYTES_IN_MEGABYTE; if (event.getContentLength() > maxSize) { component.interruptUpload(); - String warningMsg = MessageProvider.getMessage(AppConfig.getMessagesPack(), "upload.fileTooBig.message"); + String warningMsg = messages.getMessage(AppConfig.getMessagesPack(), "upload.fileTooBig.message"); getFrame().showNotification(warningMsg, IFrame.NotificationType.WARNING); } else { - bytes = null; final Listener.Event e = new Listener.Event(event.getFilename()); for (Listener listener : listeners) { listener.uploadStarted(e); @@ -144,12 +144,7 @@ public class WebFileUploadField extends WebAbstractComponent implements } } }); - component.setButtonCaption(MessageProvider.getMessage(AppConfig.getMessagesPack(), "upload.submit")); - } - - @Override - public String getFilePath() { - return fileName; + component.setButtonCaption(messages.getMessage(AppConfig.getMessagesPack(), "upload.submit")); } @Override @@ -158,22 +153,6 @@ public class WebFileUploadField extends WebAbstractComponent implements return strings[strings.length - 1]; } - @Override - public boolean isUploading() { - return component.isUploading(); - } - - @Override - public long getBytesRead() { - return component.getBytesRead(); - } - - @Override - public void release() { - outputStream = null; - bytes = null; - } - @Override public void addListener(Listener listener) { if (!listeners.contains(listener)) listeners.add(listener); @@ -192,18 +171,17 @@ public class WebFileUploadField extends WebAbstractComponent implements */ @Deprecated public byte[] getBytes() { - if (bytes == null) { - try { - if (fileId != null) { - File file = fileUploading.getFile(fileId); - FileInputStream fileInputStream = new FileInputStream(file); - ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(); - IOUtils.copy(fileInputStream, byteOutput); - bytes = byteOutput.toByteArray(); - } - } catch (Exception e) { - throw new RuntimeException(e); + byte[] bytes = null; + try { + if (fileId != null) { + File file = fileUploading.getFile(fileId); + FileInputStream fileInputStream = new FileInputStream(file); + ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(); + IOUtils.copy(fileInputStream, byteOutput); + bytes = byteOutput.toByteArray(); } + } catch (Exception e) { + throw new RuntimeException(e); } return bytes; @@ -244,4 +222,12 @@ public class WebFileUploadField extends WebAbstractComponent implements public UUID getFileId() { return fileId; } -} + + @Override + public FileDescriptor getFileDescriptor() { + if (fileId != null) + return fileUploading.getFileDescriptor(fileId, fileName); + else + return null; + } +} \ No newline at end of file