From 470ef71ba8f18ece2828f1489badcdb1a8c81e07 Mon Sep 17 00:00:00 2001 From: ghidra1 Date: Thu, 11 Mar 2021 14:47:57 -0500 Subject: [PATCH] Improve ApplicationLayout use for standalone apps --- .../framework/DockingApplicationLayout.java | 55 ++++++++----- .../plugintool/StandAloneApplication.java | 80 +++++++++++-------- 2 files changed, 80 insertions(+), 55 deletions(-) diff --git a/Ghidra/Framework/Docking/src/main/java/docking/framework/DockingApplicationLayout.java b/Ghidra/Framework/Docking/src/main/java/docking/framework/DockingApplicationLayout.java index 7e0975539c..21758d2c8c 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/framework/DockingApplicationLayout.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/framework/DockingApplicationLayout.java @@ -16,12 +16,12 @@ package docking.framework; import java.io.FileNotFoundException; -import java.util.ArrayList; -import java.util.Objects; +import java.util.*; import generic.jar.ResourceFile; import ghidra.framework.ApplicationProperties; import ghidra.util.SystemUtilities; +import util.CollectionUtils; import utility.application.ApplicationLayout; import utility.application.ApplicationUtilities; import utility.module.ModuleUtilities; @@ -34,16 +34,6 @@ public class DockingApplicationLayout extends ApplicationLayout { private static final String NO_RELEASE_NAME = "NO_RELEASE"; - /** - * Constructs a new docking application layout object with the given name. - * - * @param name The name of the application. - * @throws FileNotFoundException if there was a problem getting a user directory. - */ - public DockingApplicationLayout(String name) throws FileNotFoundException { - this(name, "0.1"); - } - /** * Constructs a new docking application layout object with the given name and version. * @@ -57,24 +47,31 @@ public class DockingApplicationLayout extends ApplicationLayout { /** * Constructs a new docking application layout object with the given set of application - * properties. + * properties. The default Ghidra application root directory(s) will be used. * * @param applicationProperties The properties object that will be read system properties. * @throws FileNotFoundException if there was a problem getting a user directory. */ public DockingApplicationLayout(ApplicationProperties applicationProperties) throws FileNotFoundException { + this(getDefaultApplicationRootDirs(), applicationProperties); + } + + /** + * Constructs a new docking application layout object with the given set of application + * properties. + * + * @param applicationRootDirs list of application root directories which should be + * used to idenitfy modules and resources. The first entry will be treated as the + * installation root. + * @param applicationProperties The properties object that will be read system properties. + * @throws FileNotFoundException if there was a problem getting a user directory. + */ + public DockingApplicationLayout(Collection applicationRootDirs, + ApplicationProperties applicationProperties) throws FileNotFoundException { this.applicationProperties = Objects.requireNonNull(applicationProperties); - - // Application root directories - if (SystemUtilities.isInDevelopmentMode()) { - applicationRootDirs = ApplicationUtilities.findDefaultApplicationRootDirs(); - } - else { - applicationRootDirs = new ArrayList<>(); - applicationRootDirs.add(new ResourceFile(System.getProperty("user.dir"))); - } + this.applicationRootDirs = applicationRootDirs; // Application installation directory applicationInstallationDir = applicationRootDirs.iterator().next().getParentFile(); @@ -97,4 +94,18 @@ public class DockingApplicationLayout extends ApplicationLayout { applicationInstallationDir); } + /** + * Get the default list of Application directories. In repo-based + * development mode this includes the root Ghidra directory within each repo. + * When not in development mode, the requirement is that the current working + * directory correspond to the installation root. The first entry will be + * the primary root in both cases. + * @return root directories + */ + public static Collection getDefaultApplicationRootDirs() { + if (SystemUtilities.isInDevelopmentMode()) { + return ApplicationUtilities.findDefaultApplicationRootDirs(); + } + return CollectionUtils.asList(new ResourceFile(System.getProperty("user.dir"))); + } } diff --git a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/StandAloneApplication.java b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/StandAloneApplication.java index 1d5e24c673..a66fb1f0d0 100644 --- a/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/StandAloneApplication.java +++ b/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/StandAloneApplication.java @@ -33,7 +33,6 @@ import ghidra.framework.model.ToolServices; import ghidra.util.Msg; import ghidra.util.SystemUtilities; import ghidra.util.classfinder.ClassSearcher; -import ghidra.util.exception.AssertException; import ghidra.util.exception.CancelledException; import ghidra.util.xml.GenericXMLOutputter; import ghidra.util.xml.XmlUtilities; @@ -52,7 +51,6 @@ public abstract class StandAloneApplication implements GenericStandAloneApplicat /** * Creates a new application using the given properties filename. The * filename is expected reside in the current working directory. - * *

* The given properties file is expected to have the * {@link ApplicationProperties#APPLICATION_NAME_PROPERTY} and @@ -60,43 +58,59 @@ public abstract class StandAloneApplication implements GenericStandAloneApplicat * set. * * @param propertiesFilename the name of the properties file. + * @throws IOException error causing application initialization failure */ - public StandAloneApplication(String propertiesFilename) { - - try { - ApplicationProperties properties = ApplicationProperties.fromFile(propertiesFilename); - String name = properties.getProperty(ApplicationProperties.APPLICATION_NAME_PROPERTY); - if (name == null) { - Msg.error(this, - "The application.name property is not set in " + propertiesFilename); - } - - String version = - properties.getProperty(ApplicationProperties.APPLICATION_VERSION_PROPERTY); - if (version == null) { - Msg.error(this, - "The application.name property is not set in " + propertiesFilename); - } - - ApplicationLayout applicationLayout = new DockingApplicationLayout(properties); - init(applicationLayout); - } - catch (IOException e) { - throw new AssertException(e); - } + public StandAloneApplication(String propertiesFilename) throws IOException { + this(new DockingApplicationLayout(readApplicationProperties(propertiesFilename))); } - public StandAloneApplication(String name, String version) { + /** + * Creates a new application using the specified application name + * and version. + * @param name application name + * @param version application version + * @throws IOException error causing application initialization failure + */ + public StandAloneApplication(String name, String version) throws IOException { + this(new DockingApplicationLayout(name, version)); + } - // Setup application layout - try { - ApplicationLayout applicationLayout = new DockingApplicationLayout(name, version); - init(applicationLayout); - } - catch (IOException e) { - throw new AssertException(e); + /** + * reates a new application using the given application layout + * and associated application properties. + * @param applicationLayout application layout + */ + public StandAloneApplication(ApplicationLayout applicationLayout) { + init(applicationLayout); + } + + /** + * Read {@link ApplicationProperties} from the specified file path relative + * to the current working directory. + *

+ * The given properties file is expected to have the + * {@link ApplicationProperties#APPLICATION_NAME_PROPERTY} and + * {@link ApplicationProperties#APPLICATION_VERSION_PROPERTY} properties + * set. + * @param propertiesFilename the name of the properties file. + * @return application properties + * @throws IOException if file read error occurs + */ + public static ApplicationProperties readApplicationProperties(String propertiesFilename) + throws IOException { + ApplicationProperties properties = ApplicationProperties.fromFile(propertiesFilename); + String name = properties.getProperty(ApplicationProperties.APPLICATION_NAME_PROPERTY); + if (name == null) { + Msg.error(StandAloneApplication.class, + "The application.name property is not set in " + propertiesFilename); } + String version = properties.getProperty(ApplicationProperties.APPLICATION_VERSION_PROPERTY); + if (version == null) { + Msg.error(StandAloneApplication.class, + "The application.name property is not set in " + propertiesFilename); + } + return properties; } private void init(ApplicationLayout applicationLayout) {