rename variables, move bundlehost instance, clean dead fileinstaller code

This commit is contained in:
Jason P. Leasure 2020-03-26 16:23:04 -04:00
parent 2e05da019f
commit ad897f263c
10 changed files with 80 additions and 122 deletions

View file

@ -1,7 +1,6 @@
MODULE FILE LICENSE: lib/biz.aQute.bndlib-5.0.0.jar Apache License 2.0
MODULE FILE LICENSE: lib/slf4j-api-1.7.25.jar MIT
MODULE FILE LICENSE: lib/org.apache.felix.main-6.0.3.jar Apache License 2.0
MODULE FILE LICENSE: lib/org.apache.felix.fileinstall-3.6.4.jar Apache License 2.0
MODULE FILE LICENSE: lib/org.apache.felix.framework-6.0.3.jar Apache License 2.0
MODULE FILE LICENSE: lib/animal-sniffer-annotations-1.9.jar MIT
MODULE FILE LICENSE: lib/org.osgi.core-5.0.0.jar Apache License 2.0

View file

@ -28,7 +28,6 @@ dependencies {
compile 'org.apache.felix:org.apache.felix.framework:6.0.3'
compile 'org.apache.felix:org.apache.felix.main:6.0.3'
compile 'org.apache.felix:org.apache.felix.fileinstall:3.6.4'
compile 'com.github.rotty3000:phidias:0.3.7'
compile 'biz.aQute.bnd:biz.aQute.bndlib:5.0.0'
compile 'org.slf4j:slf4j-api:1.7.25'

View file

@ -42,6 +42,7 @@ import generic.jar.ResourceFile;
import generic.util.Path;
import ghidra.app.plugin.core.script.osgi.*;
import ghidra.app.script.*;
import ghidra.app.script.osgi.BundleHost;
import ghidra.app.services.ConsoleService;
import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.ComponentProviderAdapter;
@ -71,7 +72,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
private GTree scriptCategoryTree;
private DraggableScriptTable scriptTable;
private GhidraScriptTableModel tableModel;
private BundleStatusProvider bundlePathManager;
private BundleStatusProvider bundleStatusProvider;
private TaskListener taskListener = new ScriptTaskListener();
private GhidraScriptActionManager actionManager;
private GhidraTableFilterPanel<ResourceFile> tableFilterPanel;
@ -119,7 +120,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
scriptTable.dispose();
tableFilterPanel.dispose();
actionManager.dispose();
bundlePathManager.dispose();
bundleStatusProvider.dispose();
}
GhidraScriptActionManager getActionManager() {
@ -131,11 +132,11 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
}
void showBundleStatusDialog() {
bundlePathManager.setVisible(true);
bundleStatusProvider.setVisible(true);
}
private void performRefresh() {
GhidraScriptUtil.setScriptDirectories(bundlePathManager.getPaths());
GhidraScriptUtil.setScriptDirectories(bundleStatusProvider.getPaths());
GhidraScriptUtil.clearMetadata();
refresh();
}
@ -340,12 +341,12 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
}
public List<BundlePath> getScriptDirectories() {
return bundlePathManager.getPaths().stream().filter(BundlePath::isDirectory).collect(
return bundleStatusProvider.getPaths().stream().filter(BundlePath::isDirectory).collect(
Collectors.toList());
}
public void enableScriptDirectory(ResourceFile scriptDir) {
if (bundlePathManager.enablePath(scriptDir)) {
if (bundleStatusProvider.enablePath(scriptDir)) {
Msg.showInfo(this, getComponent(), "Script Path Added/Enabled",
"The directory has been automatically enabled for use:\n" +
scriptDir.getAbsolutePath());
@ -396,7 +397,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
}
void runScript(String scriptName, TaskListener listener) {
List<BundlePath> dirPaths = bundlePathManager.getPaths();
List<BundlePath> dirPaths = bundleStatusProvider.getPaths();
for (Path dir : dirPaths) {
ResourceFile scriptSource = new ResourceFile(dir.getPath(), scriptName);
if (scriptSource.exists()) {
@ -536,7 +537,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
private void updateAvailableScriptFilesForAllPaths() {
List<ResourceFile> scriptsToRemove = tableModel.getScripts();
List<ResourceFile> scriptAccumulator = new ArrayList<>();
List<BundlePath> bundlePaths = bundlePathManager.getPaths();
List<BundlePath> bundlePaths = bundleStatusProvider.getPaths();
for (BundlePath bundlePath : bundlePaths) {
if (bundlePath.isDirectory()) {
updateAvailableScriptFilesForDirectory(scriptsToRemove, scriptAccumulator,
@ -732,12 +733,13 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
}
private void build() {
bundlePathManager =
new BundleStatusProvider(plugin.getTool(), plugin.getName());
bundlePathManager.setFileChooserProperties("Select Script Bundle",
bundleStatusProvider =
new BundleStatusProvider(plugin.getTool(), plugin.getName(), BundleHost.getInstance());
bundleStatusProvider.setFileChooserProperties("Select Script Bundle",
"LastGhidraScriptBundle");
bundlePathManager.addListener(new BundlePathManagerListener() {
bundleStatusProvider.addListener(new BundlePathManagerListener() {
@Override
public void bundlesChanged() {
plugin.getTool().setConfigChanged(true);
@ -1010,10 +1012,10 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
}
public void readConfigState(SaveState saveState) {
bundlePathManager.restoreState(saveState);
bundleStatusProvider.restoreState(saveState);
// pull in the just-loaded paths
List<BundlePath> paths = bundlePathManager.getPaths();
List<BundlePath> paths = bundleStatusProvider.getPaths();
GhidraScriptUtil.setScriptDirectories(paths);
actionManager.restoreUserDefinedKeybindings(saveState);
actionManager.restoreScriptsThatAreInTool(saveState);
@ -1037,7 +1039,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
}
public void writeConfigState(SaveState saveState) {
bundlePathManager.saveState(saveState);
bundleStatusProvider.saveState(saveState);
actionManager.saveUserDefinedKeybindings(saveState);
actionManager.saveScriptsThatAreInTool(saveState);

View file

@ -26,8 +26,6 @@ import ghidra.app.plugin.ProgramPlugin;
import ghidra.app.plugin.core.eclipse.EclipseConnection;
import ghidra.app.plugin.core.eclipse.EclipseIntegrationOptionsPlugin;
import ghidra.app.script.GhidraState;
import ghidra.app.script.osgi.BundleHost;
import ghidra.app.script.osgi.OSGiException;
import ghidra.app.services.*;
import ghidra.framework.options.SaveState;
import ghidra.framework.options.ToolOptions;
@ -50,22 +48,6 @@ import ghidra.util.task.TaskListener;
//@formatter:on
public class GhidraScriptMgrPlugin extends ProgramPlugin implements GhidraScriptService {
// XXX embedded OSGi should be a service, but ScriptProviders don't have any way to access services
static private BundleHost _bundle_host;
static public BundleHost getBundleHost() {
if (_bundle_host == null) {
_bundle_host = new BundleHost();
try {
_bundle_host.startFelix();
}
catch (OSGiException | IOException e) {
throw new RuntimeException(e);
}
}
return _bundle_host;
}
private GhidraScriptComponentProvider provider;
public GhidraScriptMgrPlugin(PluginTool tool) {

View file

@ -108,14 +108,13 @@ class BundleStatusModel extends AbstractSortedTableModel<BundlePath> {
}
}
private BundleStatusProvider mgr;
private BundleStatusProvider provider;
private List<BundlePath> paths = new ArrayList<>();
BundleStatusModel(BundleStatusProvider mgr) {
BundleStatusModel(BundleStatusProvider provider) {
super();
this.mgr = mgr;
List<BundlePath> paths=GhidraScriptUtil.getDefaultScriptBundles();
this.paths.addAll(dedupPaths(paths));
this.provider = provider;
this.paths.addAll(dedupPaths(GhidraScriptUtil.getDefaultScriptBundles()));
fireTableDataChanged();
}
@ -176,7 +175,7 @@ class BundleStatusModel extends AbstractSortedTableModel<BundlePath> {
paths.remove(path);
}
else {
List<BundlePathManagerListener> listeners = mgr.getListeners();
List<BundlePathManagerListener> listeners = provider.getListeners();
for (BundlePathManagerListener listener : listeners) {
listener.pathMessage("Unable to remove path.");
}
@ -194,7 +193,7 @@ class BundleStatusModel extends AbstractSortedTableModel<BundlePath> {
paths.remove(path);
}
else {
List<BundlePathManagerListener> listeners = mgr.getListeners();
List<BundlePathManagerListener> listeners = provider.getListeners();
for (BundlePathManagerListener listener : listeners) {
listener.pathMessage("Unable to remove path.");
}
@ -267,7 +266,7 @@ class BundleStatusModel extends AbstractSortedTableModel<BundlePath> {
BundlePath path = paths.get(rowIndex);
COLUMN.val(columnIndex).setValue(path, aValue);
fireTableDataChanged();
mgr.fireBundlePathChanged(path);
provider.fireBundlePathChanged(path);
}
@Override

View file

@ -29,6 +29,7 @@ import docking.widgets.filechooser.GhidraFileChooser;
import docking.widgets.filechooser.GhidraFileChooserMode;
import docking.widgets.table.*;
import generic.jar.ResourceFile;
import ghidra.app.script.osgi.BundleHost;
import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.ComponentProviderAdapter;
import ghidra.framework.plugintool.PluginTool;
@ -43,7 +44,7 @@ import resources.ResourceManager;
public class BundleStatusProvider extends ComponentProviderAdapter {
private JPanel panel;
private GTable bundlePathTable;
private BundleStatusModel bundlePathModel;
private BundleStatusModel bundleStatusModel;
private TableModelListener bundlePathModelListener;
private JButton addButton;
private JButton removeButton;
@ -54,8 +55,11 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
private GhidraFileFilter filter;
private ArrayList<BundlePathManagerListener> listeners = new ArrayList<>();
public BundleStatusProvider(PluginTool tool, String owner) {
private BundleHost bundleHost;
public BundleStatusProvider(PluginTool tool, String owner, BundleHost bundleHost) {
super(tool, "Bundle Status Manager", "my owner");
this.bundleHost = bundleHost;
build();
addToTool();
}
@ -89,7 +93,7 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
* @return enabled paths
*/
public List<BundlePath> getPaths() {
return bundlePathModel.getPaths();
return bundleStatusModel.getPaths();
}
/**
@ -99,11 +103,11 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
*/
public boolean enablePath(ResourceFile file) {
ResourceFile dir = file.isDirectory() ? file : file.getParentFile();
for (BundlePath path : bundlePathModel.getAllPaths()) {
for (BundlePath path : bundleStatusModel.getAllPaths()) {
if (path.getPath().equals(dir)) {
if (!path.isEnabled()) {
path.setEnabled(true);
bundlePathModel.fireTableDataChanged();
bundleStatusModel.fireTableDataChanged();
fireBundlesChanged();
return true;
}
@ -112,21 +116,21 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
}
BundlePath p = new BundlePath(dir);
p.setEnabled(true);
bundlePathModel.addPath(p);
bundleStatusModel.addPath(p);
Preferences.setProperty(preferenceForLastSelectedBundle, dir.getAbsolutePath());
fireBundlesChanged();
return true;
}
public void setPaths(List<BundlePath> paths) {
bundlePathModel.setPaths(paths);
bundleStatusModel.setPaths(paths);
}
/**
* Clear the paths in the table.
*/
public void clear() {
bundlePathModel.clear();
bundleStatusModel.clear();
}
public void addListener(BundlePathManagerListener listener) {
@ -187,10 +191,10 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
fireBundlesChanged();
};
bundlePathModel = new BundleStatusModel(this);
bundlePathModel.addTableModelListener(bundlePathModelListener);
bundleStatusModel = new BundleStatusModel(this);
bundleStatusModel.addTableModelListener(bundlePathModelListener);
bundlePathTable = new GTable(bundlePathModel);
bundlePathTable = new GTable(bundleStatusModel);
bundlePathTable.setName("BUNDLEPATH_TABLE");
bundlePathTable.setSelectionBackground(selectionColor);
bundlePathTable.setSelectionForeground(Color.BLACK);
@ -205,22 +209,19 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
column.setMaxWidth(skinnyWidth);
column.setWidth(skinnyWidth);
column =
bundlePathTable.getColumnModel().getColumn(BundleStatusModel.COLUMN.Active.index);
column = bundlePathTable.getColumnModel().getColumn(BundleStatusModel.COLUMN.Active.index);
column.setPreferredWidth(skinnyWidth);
column.setMinWidth(skinnyWidth);
column.setMaxWidth(skinnyWidth);
column.setWidth(skinnyWidth);
column =
bundlePathTable.getColumnModel().getColumn(BundleStatusModel.COLUMN.Type.index);
column = bundlePathTable.getColumnModel().getColumn(BundleStatusModel.COLUMN.Type.index);
FontMetrics fontmetrics = panel.getFontMetrics(panel.getFont());
column.setMaxWidth(10 +
SwingUtilities.computeStringWidth(fontmetrics, BundlePath.Type.SourceDir.toString()));
column =
bundlePathTable.getColumnModel().getColumn(BundleStatusModel.COLUMN.Path.index);
column = bundlePathTable.getColumnModel().getColumn(BundleStatusModel.COLUMN.Path.index);
column.setCellRenderer(new GTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(GTableCellRenderingData data) {
@ -235,7 +236,7 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
});
GTableFilterPanel<BundlePath> filterPanel =
new GTableFilterPanel<>(bundlePathTable, bundlePathModel);
new GTableFilterPanel<>(bundlePathTable, bundleStatusModel);
JScrollPane scrollPane = new JScrollPane(bundlePathTable);
scrollPane.getViewport().setBackground(bundlePathTable.getBackground());
@ -267,12 +268,12 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
if (selectedRows == null) {
return;
}
bundlePathModel.remove(selectedRows);
bundleStatusModel.remove(selectedRows);
// select the next row based on what was selected
Arrays.sort(selectedRows);
int row = selectedRows[selectedRows.length - 1] + 1 - selectedRows.length;
int count = bundlePathModel.getRowCount();
int count = bundleStatusModel.getRowCount();
if (row >= count) {
row = count - 1;
}
@ -323,7 +324,7 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
files.get(0).getAbsolutePath());
for (File element : files) {
BundlePath p = new BundlePath(element);
bundlePathModel.addPath(p);
bundleStatusModel.addPath(p);
}
}
}
@ -342,7 +343,7 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
* @param ss the SaveState object
*/
public void saveState(SaveState ss) {
List<BundlePath> paths = bundlePathModel.getAllPaths();
List<BundlePath> paths = bundleStatusModel.getAllPaths();
String[] pathArr = new String[paths.size()];
boolean[] enableArr = new boolean[paths.size()];
@ -379,15 +380,15 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
* Temporarily remove the listener to prevent too many
* notifications from being sent.
*/
bundlePathModel.removeTableModelListener(bundlePathModelListener);
bundleStatusModel.removeTableModelListener(bundlePathModelListener);
boolean[] enableArr =
ss.getBooleans("BundleManagerPanel_ENABLE", new boolean[pathArr.length]);
boolean[] editArr = ss.getBooleans("BundleManagerPanel_EDIT", new boolean[pathArr.length]);
boolean[] readArr = ss.getBooleans("BundleManagerPanel_READ", new boolean[pathArr.length]);
List<BundlePath> oldPaths = bundlePathModel.getAllPaths();
bundlePathModel.clear();
List<BundlePath> oldPaths = bundleStatusModel.getAllPaths();
bundleStatusModel.clear();
for (int i = 0; i < pathArr.length; i++) {
BundlePath path = new BundlePath(pathArr[i], enableArr[i], editArr[i], readArr[i]);
@ -405,19 +406,19 @@ public class BundleStatusProvider extends ComponentProviderAdapter {
// This is needed to thin-out old default entries
continue;
}
bundlePathModel.addPath(path);
bundleStatusModel.addPath(path);
}
for (BundlePath path : oldPaths) {
if (!path.isEditable()) {
bundlePathModel.addPath(path);
bundleStatusModel.addPath(path);
}
}
/*
* Reinstall the listener then fire the update.
*/
bundlePathModel.addTableModelListener(bundlePathModelListener);
bundleStatusModel.addTableModelListener(bundlePathModelListener);
fireBundlesChanged();
}

View file

@ -22,7 +22,6 @@ import org.osgi.framework.Bundle;
import generic.io.NullPrintWriter;
import generic.jar.ResourceFile;
import ghidra.app.plugin.core.script.GhidraScriptMgrPlugin;
import ghidra.app.script.osgi.*;
import ghidra.util.Msg;
@ -32,7 +31,7 @@ public class JavaScriptProvider extends GhidraScriptProvider {
if (sourceDir == null) {
return null;
}
return GhidraScriptMgrPlugin.getBundleHost().getSourceBundleInfo(sourceDir);
return BundleHost.getInstance().getSourceBundleInfo(sourceDir);
}
@Override
@ -50,7 +49,7 @@ public class JavaScriptProvider extends GhidraScriptProvider {
Bundle b = getBundleInfoForSource(sourceFile).getBundle();
if (b != null) {
try {
GhidraScriptMgrPlugin.getBundleHost().synchronousUninstall(b);
BundleHost.getInstance().synchronousUninstall(b);
}
catch (GhidraBundleException | InterruptedException e) {
e.printStackTrace();
@ -127,7 +126,7 @@ public class JavaScriptProvider extends GhidraScriptProvider {
needsBundleActivate |= needsCompile;
BundleHost bundle_host = GhidraScriptMgrPlugin.getBundleHost();
BundleHost bundle_host = BundleHost.getInstance();
if (needsBundleActivate) {
writer.printf("%s has %d new/updated %d failed in previous build(s)%s\n",
bi.getSourceDir().toString(), newSourcecount, failing,
@ -166,7 +165,7 @@ public class JavaScriptProvider extends GhidraScriptProvider {
Class<?> clazz = b.loadClass(classname); // throws ClassNotFoundException
return clazz;
}
public static ResourceFile getSourceDirectoryContaining(ResourceFile sourceFile) {
String sourcePath = sourceFile.getAbsolutePath();
for (ResourceFile sourceDir : GhidraScriptUtil.getScriptSourceDirectories()) {

View file

@ -42,6 +42,22 @@ import ghidra.util.task.*;
// XXX this class should be part of a service/plugin
public class BundleHost {
// XXX embedded OSGi should be a service, but ScriptProviders don't have any way to access services
static private BundleHost _instance;
static public BundleHost getInstance() {
if (_instance == null) {
_instance = new BundleHost();
try {
_instance.startFelix();
}
catch (OSGiException | IOException e) {
throw new RuntimeException(e);
}
}
return _instance;
}
static public String getSymbolicNameFromSourceDir(ResourceFile sourceDir) {
return Integer.toHexString(sourceDir.getAbsolutePath().hashCode());
}
@ -214,10 +230,6 @@ public class BundleHost {
config.setProperty("ds.showtrace", "true");
config.setProperty("ds.showerrors", "true");
config.setProperty("felix.fileinstall.dir", getWatchedBundleDirs());
// config.setProperty("felix.fileinstall.log.level", "999");
// config.setProperty("felix.fileinstall.log.default", "jul"); // stdout
config.setProperty("felix.fileinstall.bundles.new.start", "true"); // autostart bundles
config.put(FelixConstants.LOG_LEVEL_PROP, "999");// was 4
config.put(FelixConstants.LOG_LOGGER_PROP, new FelixLogger());
@ -301,9 +313,6 @@ public class BundleHost {
catch (BundleException e) {
throw new OSGiException("starting felix OSGi framework", e);
}
// fileinstall_bundle = installFromPath(findJarForClass(FileInstall.class));
// fileinstall_bundle.start();
}
private String makeCacheDir() throws IOException {
@ -312,11 +321,6 @@ public class BundleHost {
return cache_dir.toAbsolutePath().toString();
}
/** comma separated list of directories watched for bundles by fileinstaller */
private String getWatchedBundleDirs() {
return GhidraScriptUtil.getCompiledBundlesDir().toAbsolutePath().toString();
}
public Bundle getBundle(String bundleLoc) {
return bc.getBundle(bundleLoc);
}
@ -399,39 +403,12 @@ public class BundleHost {
return felix;
}
public boolean stopBundleWatcher() {
if (fileinstall_bundle != null) {
try {
fileinstall_bundle.stop();
return true;
}
catch (BundleException e) {
e.printStackTrace();
}
}
return false;
}
public boolean startBundleWatcher() {
if (fileinstall_bundle != null) {
try {
fileinstall_bundle.start();
return true;
}
catch (BundleException e) {
e.printStackTrace();
}
}
return false;
}
public interface NewSourceCallback {
public interface DiscrepencyCallback {
void found(ResourceFile source_file, Collection<Path> class_files) throws Throwable;
}
public static void visitDiscrepencies(ResourceFile srcdir, Path bindir,
NewSourceCallback new_source_cb) {
DiscrepencyCallback new_source_cb) {
try {
// delete class files for which java is either newer, or no longer exists
Deque<ResourceFile> stack = new ArrayDeque<>();

View file

@ -978,9 +978,9 @@ public abstract class AbstractGhidraScriptMgrPluginTest
String myTestName = super.testName.getMethodName();
// destroy any NewScriptxxx files...and Temp ones too
BundleStatusProvider pathManager =
BundleStatusProvider bundleStatusProvider =
(BundleStatusProvider) TestUtils.getInstanceField("bundlePathManager", provider);
List<BundlePath> paths = pathManager.getPaths();
List<BundlePath> paths = bundleStatusProvider.getPaths();
for (BundlePath path : paths) {
File file = path.getPath().getFile(false);
File[] listFiles = file.listFiles();

View file

@ -116,11 +116,11 @@ public class GhidraScriptMgrPluginScreenShots extends GhidraScreenShotGenerator
paths.add(new BundlePath("$GHIDRA_HOME/Features/Base/ghidra_scripts"));
paths.add(new BundlePath("/User/defined/invalid/directory"));
BundleStatusProvider bundleStatus = showProvider(BundleStatusProvider.class);
bundleStatus.setPaths(paths);
BundleStatusProvider bundleStatusProvider = showProvider(BundleStatusProvider.class);
bundleStatusProvider.setPaths(paths);
waitForComponentProvider(BundleStatusProvider.class);
captureComponent(bundleStatus.getComponent());
captureComponent(bundleStatusProvider.getComponent());
}
@Test