From 87c4b19b84afce306c2132c023585f0c68eb1ce0 Mon Sep 17 00:00:00 2001 From: Ryan Kurtz Date: Mon, 24 Mar 2025 14:05:20 -0400 Subject: [PATCH] GP-5458: Fixing repetitive project lock dialogs --- .../Base/src/main/java/ghidra/GhidraRun.java | 12 ++---- .../ghidra/framework/store/LockException.java | 12 +----- .../framework/data/DefaultProjectData.java | 27 ++++++------- .../framework/data/DomainObjectAdapter.java | 2 +- .../framework/main/FileActionManager.java | 39 +++++++------------ .../project/DefaultProjectManager.java | 2 - 6 files changed, 33 insertions(+), 61 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/GhidraRun.java b/Ghidra/Features/Base/src/main/java/ghidra/GhidraRun.java index ba86f3b449..b0237bb0d5 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/GhidraRun.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/GhidraRun.java @@ -4,9 +4,9 @@ * Licensed 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. @@ -189,9 +189,6 @@ public class GhidraRun implements GhidraLaunchable { try { ProjectManager pm = tool.getProjectManager(); Project activeProject = pm.openProject(projectLocator, true, false); - if (activeProject == null) { - return; - } tool.setActiveProject(activeProject); @@ -210,10 +207,7 @@ public class GhidraRun implements GhidraLaunchable { catch (Throwable t) { if (t instanceof UsrException) { if (t instanceof LockException) { - Msg.showInfo(GhidraRun.class, null, "Project is Locked", - "Can't open project: " + projectLocator.toString() + - "\nProject is already locked"); - + Msg.showInfo(GhidraRun.class, null, "Project is Locked", t.getMessage()); } else { Msg.showInfo(GhidraRun.class, null, "Project Open Failed", diff --git a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/LockException.java b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/LockException.java index f1aec437b4..278b3eb3c5 100644 --- a/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/LockException.java +++ b/Ghidra/Framework/FileSystem/src/main/java/ghidra/framework/store/LockException.java @@ -1,13 +1,12 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed 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. @@ -22,13 +21,6 @@ import ghidra.util.exception.UsrException; * Indicates a failure to obtain a required lock. */ public class LockException extends UsrException { - - /** - * Construct a new LockException - */ - public LockException() { - super("Operation requires exclusive access to object."); - } /** * Construct a new LockException with the given message diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DefaultProjectData.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DefaultProjectData.java index e0c60f03a5..f9023969ed 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DefaultProjectData.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DefaultProjectData.java @@ -4,9 +4,9 @@ * Licensed 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. @@ -321,9 +321,6 @@ public class DefaultProjectData implements ProjectData { private void initLock(boolean creatingProject) throws LockException, IOException { this.projectLock = getProjectLock(localStorageLocator, !creatingProject); - if (projectLock == null) { - throw new LockException("Unable to lock project! " + localStorageLocator); - } if (!properties.exists()) { owner = getUserName(); @@ -339,28 +336,31 @@ public class DefaultProjectData implements ProjectData { * @param locator the project locator * @param allowInteractiveForce if true, when a lock cannot be obtained, the * user will be prompted - * @return A locked ProjectLock or null if lock fails + * @return A locked ProjectLock + * @throws LockException if the lock fails */ - private ProjectLock getProjectLock(ProjectLocator locator, boolean allowInteractiveForce) { + private ProjectLock getProjectLock(ProjectLocator locator, boolean allowInteractiveForce) + throws LockException { ProjectLock lock = new ProjectLock(locator); if (lock.lock()) { return lock; } + String defaultMsg = "Unable to lock project! " + locator; + // in headless mode, just spit out an error if (!allowInteractiveForce || SystemUtilities.isInHeadlessMode()) { - return null; + throw new LockException(defaultMsg); } String projectStr = "Project: " + HTMLUtilities.escapeHTML(locator.getLocation()) + System.getProperty("file.separator") + HTMLUtilities.escapeHTML(locator.getName()); String lockInformation = lock.getExistingLockFileInformation(); if (!lock.canForceLock()) { - Msg.showInfo(getClass(), null, "Project Locked", - "Project is locked. You have another instance of Ghidra
" + + String msg = "Project is locked. You have another instance of Ghidra
" + "already running with this project open (locally or remotely).

" + - projectStr + "

" + "Lock information: " + lockInformation); - return null; + projectStr + "

" + "Lock information: " + lockInformation; + throw new LockException(msg); } int userChoice = OptionDialog.showOptionDialog(null, "Project Locked - Delete Lock?", @@ -377,7 +377,8 @@ public class DefaultProjectData implements ProjectData { Msg.showError(this, null, "Error", "Attempt to force lock failed! " + locator); } - return null; + + throw new LockException(defaultMsg); } /** diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DomainObjectAdapter.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DomainObjectAdapter.java index 803cddf95d..2e5e1c832c 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DomainObjectAdapter.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/data/DomainObjectAdapter.java @@ -347,7 +347,7 @@ public abstract class DomainObjectAdapter implements DomainObject { public void checkExclusiveAccess() throws LockException { if (!hasExclusiveAccess()) { - throw new LockException(); + throw new LockException("Operation requires exclusive access to object."); } } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FileActionManager.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FileActionManager.java index 86cdb79d01..4d24d55083 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FileActionManager.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/main/FileActionManager.java @@ -247,9 +247,7 @@ class FileActionManager { * @return true if the project was opened */ final boolean doOpenProject(ProjectLocator projectLocator) { - String status = "Opened project: " + projectLocator.getName(); Project project = null; - boolean openStatus = false; try { // first close the active project (if there is one) // but if user cancels operation, don't continue @@ -258,49 +256,38 @@ class FileActionManager { } ProjectManager pm = plugin.getProjectManager(); project = pm.openProject(projectLocator, true, false); - if (project == null) { - status = "Error opening project: " + projectLocator.toString(); - } - else { - firingProjectOpened = true; - tool.setActiveProject(project); - openProjectAndNotify(project); - openStatus = true; - firingProjectOpened = false; - } + firingProjectOpened = true; + tool.setActiveProject(project); + openProjectAndNotify(project); + firingProjectOpened = false; + Msg.info(this, "Opened project: " + projectLocator.getName()); } catch (NotFoundException nfe) { - status = "Project not found for " + projectLocator.toString(); - Msg.showInfo(getClass(), tool.getToolFrame(), "Error Opening Project", status); + String msg = "Project not found for " + projectLocator; + Msg.showInfo(getClass(), tool.getToolFrame(), "Error Opening Project", msg); + Msg.error(this, msg); } catch (NotOwnerException e) { - status = "Cannot open project: " + e.getMessage(); Msg.showError(this, null, "Not Project Owner", "Cannot open project " + projectLocator + "\n" + e.getMessage() + "\n \nEach user must create their own project. If needed, another user's project may be viewed\n" + "and files copied, using the View Other action from your own open project. Alternatively, \n" + "creating a \"Shared Project\" will allow a group of users to use a shared server-based repository."); + Msg.error(this, "Cannot open project: " + e.getMessage()); } catch (LockException e) { - status = "Project is already open for update: " + projectLocator.toString(); - Msg.showError(this, null, "Open Project Failed", status); + Msg.showInfo(this, null, "Open Project Failed", e.getMessage()); } catch (Exception e) { - status = "Error opening project: " + projectLocator.toString(); - Msg.showError(this, null, "Open Project Failed", status, e); + Msg.showError(this, null, "Open Project Failed", + "Error opening project: " + projectLocator, e); } finally { // update our list of recent projects plugin.rebuildRecentMenus(); } - if (!openStatus) { - Msg.error(this, status); - } - else { - Msg.info(this, status); - } - return openStatus; + return project != null; } /** diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/DefaultProjectManager.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/DefaultProjectManager.java index c438c4595c..bb9afd9b80 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/DefaultProjectManager.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/project/DefaultProjectManager.java @@ -151,8 +151,6 @@ public class DefaultProjectManager implements ProjectManager { return currentProject; } catch (LockException e) { - Msg.showError(LOG, null, "Locked Project!", - "Cannot open locked project: " + projectLocator, e); throw e; } catch (ReadOnlyException e) {