You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2019/09/12 13:24:21 UTC

[cayenne] 01/02: CAY-2616 Modeler: Wrong handling of path with spaces

This is an automated email from the ASF dual-hosted git repository.

ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit dca7e03afc152a9073e24aa58f441d0b4aab88bc
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Thu Sep 12 11:37:17 2019 +0300

    CAY-2616 Modeler: Wrong handling of path with spaces
---
 RELEASE-NOTES.txt                                  |   1 +
 .../cayenne/modeler/CayenneModelerController.java  | 110 ++++++-------------
 .../cayenne/modeler/ProjectFileChangeTracker.java  | 121 +++++++++++----------
 3 files changed, 96 insertions(+), 136 deletions(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 5ece547..bd2f1c5 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -95,6 +95,7 @@ CAY-2605 Modeler: Unable to save - java.nio.file.InvalidPathException
 CAY-2606 Can't resolve obj path with embeddable component
 CAY-2608 CayenneModeler: NPE when reverse engineering with an auto-adapter DataSource
 CAY-2609 Modeler: can't close dbImport result dialog window
+CAY-2616 Modeler: Wrong handling of path with spaces
 
 ----------------------------------
 Release: 4.1.B1
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java
index 1e242c5..094a77e 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/CayenneModelerController.java
@@ -47,6 +47,7 @@ import java.awt.event.ActionEvent;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.io.File;
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -67,7 +68,8 @@ public class CayenneModelerController extends CayenneController {
 
 	private DbImportController dbImportController;
 
-    public CayenneModelerController(){}
+    public CayenneModelerController(){
+    }
 
     public CayenneModelerController(Application application) {
         super(application);
@@ -115,12 +117,7 @@ public class CayenneModelerController extends CayenneController {
         // Register a hook to save the window position when quit via the app menu.
         // This is in Mac OSX only.
         if (System.getProperty("os.name").startsWith("Mac OS")) {
-            Runnable runner = new Runnable() {
-                @Override
-                public void run() {
-                    PROJECT_STATE_UTIL.saveLastState(projectController);
-                }
-            };
+            Runnable runner = () -> PROJECT_STATE_UTIL.saveLastState(projectController);
             Runtime.getRuntime().addShutdownHook(new Thread(runner, "Window Prefs Hook"));
         }
 
@@ -148,8 +145,7 @@ public class CayenneModelerController extends CayenneController {
         }
 
         if (fileList != null) {
-
-        File transferFile = fileList.get(0);
+            File transferFile = fileList.get(0);
             if (transferFile.isFile()) {
                 FileFilter filter = FileFilters.getApplicationFilter();
                 if (filter.accept(transferFile)) {
@@ -224,13 +220,14 @@ public class CayenneModelerController extends CayenneController {
             frame.setTitle("[New Project]");
         } else {
             updateStatus("Project opened...");
-            frame.setTitle(project.getConfigurationResource().getURL().getPath());
-        }
-
-        // update preferences
-        if (project.getConfigurationResource() != null) {
-            getLastDirectory().setDirectory(new File(project.getConfigurationResource().getURL().getPath()));
-            frame.fireRecentFileListChanged();
+            try {
+                File file = new File(project.getConfigurationResource().getURL().toURI());
+                frame.setTitle(file.toString());
+                // update preferences
+                getLastDirectory().setDirectory(file);
+                frame.fireRecentFileListChanged();
+            } catch (URISyntaxException ignore) {
+            }
         }
 
         PROJECT_STATE_UTIL.fireLastState(projectController);
@@ -262,15 +259,11 @@ public class CayenneModelerController extends CayenneController {
 
 	/** Adds path to the list of last opened projects in preferences. */
     public void addToLastProjListAction(File file) {
-
         Preferences prefLastProjFiles = ModelerPreferences.getLastProjFilesPref();
         List<File> arr = ModelerPreferences.getLastProjFiles();
-        // Add proj path to the preferences
-        // Prevent duplicate entries.
-        if (arr.contains(file)) {
-            arr.remove(file);
-        }
 
+        // Add proj path to the preferences
+        arr.remove(file);
         arr.add(0, file);
         while (arr.size() > ModelerPreferences.LAST_PROJ_FILES_SIZE) {
             arr.remove(arr.size() - 1);
@@ -288,16 +281,32 @@ public class CayenneModelerController extends CayenneController {
         }
     }
 
+    public void changePathInLastProjListAction(File oldFile, File newFile) {
+        ModelerPreferences.getLastProjFiles().remove(oldFile);
+
+        addToLastProjListAction(newFile);
+
+        getLastDirectory().setDirectory(newFile);
+        frame.fireRecentFileListChanged();
+    }
+
     /**
-     * Performs status bar update with a message. Message will dissappear in 6 seconds.
+     * Performs status bar update with a message. Message will disappear in 6 seconds.
      */
     public void updateStatus(String message) {
         frame.getStatus().setText(message);
 
         // start message cleanup thread that would remove the message after X seconds
         if (message != null && message.trim().length() > 0) {
-            Thread cleanup = new ExpireThread(message, 6);
-            cleanup.start();
+            new Thread(() -> {
+                try {
+                    Thread.sleep(6 * 10000);
+                } catch (InterruptedException ignore){
+                }
+                if (message.equals(frame.getStatus().getText())) {
+                    updateStatus(null);
+                }
+            }).start();
         }
     }
 
@@ -305,55 +314,4 @@ public class CayenneModelerController extends CayenneController {
         return dbImportController;
     }
 
-    class ExpireThread extends Thread {
-
-        int seconds;
-        protected String message;
-
-        ExpireThread(String message, int seconds) {
-            this.seconds = seconds;
-            this.message = message;
-        }
-
-        @Override
-        public void run() {
-            try {
-                sleep(seconds * 1000);
-            } catch (InterruptedException e) {
-                // ignore exception
-            }
-
-            if (message.equals(frame.getStatus().getText())) {
-                updateStatus(null);
-            }
-        }
-    }
-
-    public void changePathInLastProjListAction(File oldFile, File newFile) {
-        Preferences frefLastProjFiles = ModelerPreferences.getLastProjFilesPref();
-        List<File> arr = ModelerPreferences.getLastProjFiles();
-
-        // Add proj path to the preferences
-        arr.remove(oldFile);
-        arr.remove(newFile);
-        arr.add(0, newFile);
-        while (arr.size() > ModelerPreferences.LAST_PROJ_FILES_SIZE) {
-            arr.remove(arr.size() - 1);
-        }
-
-        try {
-            frefLastProjFiles.clear();
-        } catch (BackingStoreException e) {
-            // ignore exception
-        }
-
-        int size = arr.size();
-        for (int i = 0; i < size; i++) {
-            frefLastProjFiles.put(String.valueOf(i), arr.get(i).getAbsolutePath());
-        }
-
-        getLastDirectory().setDirectory(newFile);
-        frame.fireRecentFileListChanged();
-    }
-	
 }
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectFileChangeTracker.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectFileChangeTracker.java
index 59fd435..856f561 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectFileChangeTracker.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ProjectFileChangeTracker.java
@@ -19,6 +19,8 @@
 package org.apache.cayenne.modeler;
 
 import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -26,6 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import javax.swing.JOptionPane;
 import javax.swing.SwingUtilities;
 
+import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.configuration.DataChannelDescriptor;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.modeler.action.OpenProjectAction;
@@ -42,7 +45,7 @@ import org.slf4j.LoggerFactory;
  */
 public class ProjectFileChangeTracker extends Thread {
 
-    private static final Logger log = LoggerFactory.getLogger(ProjectFileChangeTracker.class);
+    private static final Logger LOGGER = LoggerFactory.getLogger(ProjectFileChangeTracker.class);
 
     /**
      * The default delay between every file modification check
@@ -52,16 +55,16 @@ public class ProjectFileChangeTracker extends Thread {
     /**
      * The names of the files to observe for changes.
      */
-    protected Map<String, FileInfo> files;
+    protected final Map<URI, FileInfo> files;
+    protected final ProjectController mediator;
+
     protected boolean paused;
     protected boolean isShownChangeDialog;
     protected boolean isShownRemoveDialog;
-    protected ProjectController mediator;
-    public ProjectFileChangeTracker(ProjectController mediator) {
 
+    public ProjectFileChangeTracker(ProjectController mediator) {
         this.files = new ConcurrentHashMap<>();
         this.mediator = mediator;
-
         setName("cayenne-modeler-file-change-tracker");
     }
 
@@ -78,18 +81,18 @@ public class ProjectFileChangeTracker extends Thread {
 
         // check if project exists and has been saved at least once.
         if (project != null && project.getConfigurationResource() != null) {
-            String projectPath = project.getConfigurationResource().getURL().getPath() + File.separator;
-            addFile(projectPath);
-
-            Iterator<DataMap> it = ((DataChannelDescriptor) project.getRootNode()).getDataMaps().iterator();
-            while (it.hasNext()) {
-                DataMap dm = it.next();
-                if(dm.getConfigurationSource() != null) {
-                    // if DataMap is in separate file, monitor it
-                    addFile(dm.getConfigurationSource().getURL().getPath());
+            try {
+                addFile(project.getConfigurationResource().getURL().toURI());
+
+                for (DataMap dm : ((DataChannelDescriptor) project.getRootNode()).getDataMaps()) {
+                    if (dm.getConfigurationSource() != null) {
+                        // if DataMap is in separate file, monitor it
+                        addFile(dm.getConfigurationSource().getURL().toURI());
+                    }
                 }
+            } catch (URISyntaxException ex) {
+                throw new CayenneRuntimeException("Unable to start change tracker", ex);
             }
-
         }
 
         resumeWatching();
@@ -97,48 +100,47 @@ public class ProjectFileChangeTracker extends Thread {
 
     protected void doOnChange() {
 
-        SwingUtilities.invokeLater(new Runnable() {
-
-            public void run() {
-                isShownChangeDialog = true;
-                if (showConfirmation("One or more project files were changed by external program. "
-                        + "Do you want to load the changes?")) {
-
-                    // Currently we are reloading all project
-                    if (mediator.getProject() != null) {
-
-                        File fileDirectory = new File(mediator.getProject().getConfigurationResource().getURL()
-                                .getPath());
-                        Application.getInstance().getActionManager().getAction(OpenProjectAction.class)
-                                .openProject(fileDirectory);
+        SwingUtilities.invokeLater(() -> {
+            isShownChangeDialog = true;
+            if (showConfirmation("One or more project files were changed by external program. "
+                    + "Do you want to load the changes?")) {
+
+                // Currently we are reloading all project
+                if (mediator.getProject() != null) {
+                    File fileDirectory;
+                    try {
+                        fileDirectory = new File(mediator.getProject().getConfigurationResource().getURL().toURI());
+                    } catch (URISyntaxException e) {
+                        throw new CayenneRuntimeException("Unable to open project %s",
+                                e, mediator.getProject().getConfigurationResource().getURL());
                     }
-                } else {
-                    mediator.setDirty(true);
+                    Application.getInstance().getActionManager()
+                            .getAction(OpenProjectAction.class)
+                            .openProject(fileDirectory);
                 }
-                isShownChangeDialog = false;
+            } else {
+                mediator.setDirty(true);
             }
+            isShownChangeDialog = false;
         });
     }
 
     protected void doOnRemove() {
         if (mediator.getProject() != null) {
 
-            SwingUtilities.invokeLater(new Runnable() {
-
-                public void run() {
-                    isShownRemoveDialog = true;
-                    FileDeletedDialog dialog = new FileDeletedDialog(Application.getFrame());
-                    dialog.show();
+            SwingUtilities.invokeLater(() -> {
+                isShownRemoveDialog = true;
+                FileDeletedDialog dialog = new FileDeletedDialog(Application.getFrame());
+                dialog.show();
 
-                    if (dialog.shouldSave()) {
-                        Application.getInstance().getActionManager().getAction(SaveAction.class).performAction(null);
-                    } else if (dialog.shouldClose()) {
-                        Application.getInstance().getFrameController().projectClosedAction();
-                    } else {
-                        mediator.setDirty(true);
-                    }
-                    isShownRemoveDialog = false;
+                if (dialog.shouldSave()) {
+                    Application.getInstance().getActionManager().getAction(SaveAction.class).performAction(null);
+                } else if (dialog.shouldClose()) {
+                    Application.getInstance().getFrameController().projectClosedAction();
+                } else {
+                    mediator.setDirty(true);
                 }
+                isShownRemoveDialog = false;
             });
         }
     }
@@ -157,11 +159,11 @@ public class ProjectFileChangeTracker extends Thread {
      * @param location
      *            path of file
      */
-    public void addFile(String location) {
+    public void addFile(URI location) {
         try {
             files.put(location, new FileInfo(location));
         } catch (SecurityException e) {
-            log.error("SecurityException adding file " + location, e);
+            LOGGER.error("SecurityException adding file " + location, e);
         }
     }
 
@@ -172,7 +174,7 @@ public class ProjectFileChangeTracker extends Thread {
      *            path of file
      */
     public void removeFile(String location) {
-        files.remove(location);
+        files.remove(URI.create(location));
     }
 
     /**
@@ -197,7 +199,7 @@ public class ProjectFileChangeTracker extends Thread {
             try {
                 fileExists = fi.getFile().exists();
             } catch (SecurityException e) {
-                log.error("SecurityException checking file " + fi.getFile().getPath(), e);
+                LOGGER.error("SecurityException checking file " + fi.getFile().getPath(), e);
 
                 // we still process with other files
                 continue;
@@ -211,9 +213,8 @@ public class ProjectFileChangeTracker extends Thread {
                     fi.setLastModified(l);
                     hasChanges = true;
                 }
-            }
-            // the file has been removed
-            else if (fi.getLastModified() != -1) {
+            } else if (fi.getLastModified() != -1) {
+                // the file has been removed
                 hasDeletions = true;
                 it.remove(); // no point to watch the file now
             }
@@ -257,17 +258,17 @@ public class ProjectFileChangeTracker extends Thread {
      * Class to store information about files (last modification time & File
      * pointer)
      */
-    protected class FileInfo {
+    protected static class FileInfo {
 
         /**
          * Exact java.io.File object, may not be null
          */
-        File file;
+        private final File file;
 
         /**
          * Time the file was modified
          */
-        long lastModified;
+        private long lastModified;
 
         /**
          * Creates new object
@@ -275,20 +276,20 @@ public class ProjectFileChangeTracker extends Thread {
          * @param location
          *            the file path
          */
-        public FileInfo(String location) {
+        protected FileInfo(URI location) {
             file = new File(location);
             lastModified = file.exists() ? file.lastModified() : -1;
         }
 
-        public File getFile() {
+        protected File getFile() {
             return file;
         }
 
-        public long getLastModified() {
+        protected long getLastModified() {
             return lastModified;
         }
 
-        public void setLastModified(long l) {
+        protected void setLastModified(long l) {
             lastModified = l;
         }
     }