Improve ApplicationLayout use for standalone apps

This commit is contained in:
ghidra1 2021-03-11 14:47:57 -05:00
parent b428631bf4
commit 470ef71ba8
2 changed files with 80 additions and 55 deletions

View file

@ -16,12 +16,12 @@
package docking.framework; package docking.framework;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.util.ArrayList; import java.util.*;
import java.util.Objects;
import generic.jar.ResourceFile; import generic.jar.ResourceFile;
import ghidra.framework.ApplicationProperties; import ghidra.framework.ApplicationProperties;
import ghidra.util.SystemUtilities; import ghidra.util.SystemUtilities;
import util.CollectionUtils;
import utility.application.ApplicationLayout; import utility.application.ApplicationLayout;
import utility.application.ApplicationUtilities; import utility.application.ApplicationUtilities;
import utility.module.ModuleUtilities; import utility.module.ModuleUtilities;
@ -34,16 +34,6 @@ public class DockingApplicationLayout extends ApplicationLayout {
private static final String NO_RELEASE_NAME = "NO_RELEASE"; 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. * 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 * 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. * @param applicationProperties The properties object that will be read system properties.
* @throws FileNotFoundException if there was a problem getting a user directory. * @throws FileNotFoundException if there was a problem getting a user directory.
*/ */
public DockingApplicationLayout(ApplicationProperties applicationProperties) public DockingApplicationLayout(ApplicationProperties applicationProperties)
throws FileNotFoundException { 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<ResourceFile> applicationRootDirs,
ApplicationProperties applicationProperties) throws FileNotFoundException {
this.applicationProperties = Objects.requireNonNull(applicationProperties); this.applicationProperties = Objects.requireNonNull(applicationProperties);
this.applicationRootDirs = applicationRootDirs;
// Application root directories
if (SystemUtilities.isInDevelopmentMode()) {
applicationRootDirs = ApplicationUtilities.findDefaultApplicationRootDirs();
}
else {
applicationRootDirs = new ArrayList<>();
applicationRootDirs.add(new ResourceFile(System.getProperty("user.dir")));
}
// Application installation directory // Application installation directory
applicationInstallationDir = applicationRootDirs.iterator().next().getParentFile(); applicationInstallationDir = applicationRootDirs.iterator().next().getParentFile();
@ -97,4 +94,18 @@ public class DockingApplicationLayout extends ApplicationLayout {
applicationInstallationDir); 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<ResourceFile> getDefaultApplicationRootDirs() {
if (SystemUtilities.isInDevelopmentMode()) {
return ApplicationUtilities.findDefaultApplicationRootDirs();
}
return CollectionUtils.asList(new ResourceFile(System.getProperty("user.dir")));
}
} }

View file

@ -33,7 +33,6 @@ import ghidra.framework.model.ToolServices;
import ghidra.util.Msg; import ghidra.util.Msg;
import ghidra.util.SystemUtilities; import ghidra.util.SystemUtilities;
import ghidra.util.classfinder.ClassSearcher; import ghidra.util.classfinder.ClassSearcher;
import ghidra.util.exception.AssertException;
import ghidra.util.exception.CancelledException; import ghidra.util.exception.CancelledException;
import ghidra.util.xml.GenericXMLOutputter; import ghidra.util.xml.GenericXMLOutputter;
import ghidra.util.xml.XmlUtilities; 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 * Creates a new application using the given properties filename. The
* filename is expected reside in the current working directory. * filename is expected reside in the current working directory.
*
* <p> * <p>
* <b>The given properties file is expected to have the * <b>The given properties file is expected to have the
* {@link ApplicationProperties#APPLICATION_NAME_PROPERTY} and * {@link ApplicationProperties#APPLICATION_NAME_PROPERTY} and
@ -60,43 +58,59 @@ public abstract class StandAloneApplication implements GenericStandAloneApplicat
* set.</b> * set.</b>
* *
* @param propertiesFilename the name of the properties file. * @param propertiesFilename the name of the properties file.
* @throws IOException error causing application initialization failure
*/ */
public StandAloneApplication(String propertiesFilename) { public StandAloneApplication(String propertiesFilename) throws IOException {
this(new DockingApplicationLayout(readApplicationProperties(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 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 { * reates a new application using the given application layout
ApplicationLayout applicationLayout = new DockingApplicationLayout(name, version); * and associated application properties.
init(applicationLayout); * @param applicationLayout application layout
} */
catch (IOException e) { public StandAloneApplication(ApplicationLayout applicationLayout) {
throw new AssertException(e); init(applicationLayout);
}
/**
* Read {@link ApplicationProperties} from the specified file path relative
* to the current working directory.
* <p>
* <b>The given properties file is expected to have the
* {@link ApplicationProperties#APPLICATION_NAME_PROPERTY} and
* {@link ApplicationProperties#APPLICATION_VERSION_PROPERTY} properties
* set.</b>
* @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) { private void init(ApplicationLayout applicationLayout) {