mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Merge remote-tracking branch 'origin/GP-2903_ghidra1_ImmutableDomainObjects--SQUASHED'
This commit is contained in:
commit
b707c2ea6b
11 changed files with 226 additions and 256 deletions
|
@ -169,18 +169,7 @@ public class OpenProgramTask extends Task {
|
|||
String path = url != null ? url.toString() : domainFile.getPathname();
|
||||
Object obj = null;
|
||||
try {
|
||||
|
||||
obj = domainFile.getReadOnlyDomainObject(consumer, version, taskMonitor);
|
||||
|
||||
if (obj == null) {
|
||||
String errorMessage = "Can't open " + contentType + " - \"" + path + "\"";
|
||||
if (version != DomainFile.DEFAULT_VERSION) {
|
||||
errorMessage += " version " + version;
|
||||
}
|
||||
|
||||
Msg.showError(this, null, "File Not Found", errorMessage);
|
||||
}
|
||||
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// we don't care, the task has been cancelled
|
||||
|
|
|
@ -100,13 +100,17 @@ public class OpenVersionedFileDialog<T extends DomainObject> extends DataTreeDia
|
|||
/**
|
||||
* Get the selected domain object for read-only or immutable use.
|
||||
* If an existing open object is selected its original mode applies but consumer will
|
||||
* be added.
|
||||
* @param consumer consumer
|
||||
* @param readOnly true if the domain object should be opened read only, versus immutable
|
||||
* @return null if a file was not selected
|
||||
* be added. The caller/consumer is responsible for releasing the returned domain object
|
||||
* when done using it (see {@link DomainObject#release(Object)}).
|
||||
* @param consumer domain object consumer
|
||||
* @param immutable true if the domain object should be opened immutable, else false for
|
||||
* read-only. Immutable mode should not be used for content that will be modified. If
|
||||
* read-only indicated an upgrade will always be performed if required.
|
||||
* @return opened domain object or null if a file was not selected or if open failed to
|
||||
* complete.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // relies on content class filter
|
||||
public T getDomainObject(Object consumer, boolean readOnly) {
|
||||
public T getDomainObject(Object consumer, boolean immutable) {
|
||||
T dobj = null;
|
||||
if (usingOpenProgramList()) {
|
||||
dobj = getSelectedOpenDomainObject();
|
||||
|
@ -115,20 +119,19 @@ public class OpenVersionedFileDialog<T extends DomainObject> extends DataTreeDia
|
|||
}
|
||||
return dobj;
|
||||
}
|
||||
int version = DomainFile.DEFAULT_VERSION;
|
||||
if (historyPanel != null) {
|
||||
dobj = (T) historyPanel.getSelectedVersion(consumer, readOnly);
|
||||
version = historyPanel.getSelectedVersionNumber();
|
||||
}
|
||||
if (dobj == null) {
|
||||
|
||||
DomainFile domainFile = getDomainFile();
|
||||
if (domainFile != null) {
|
||||
GetVersionedObjectTask task =
|
||||
new GetVersionedObjectTask(consumer, domainFile, DomainFile.DEFAULT_VERSION,
|
||||
readOnly);
|
||||
GetDomainObjectTask task =
|
||||
new GetDomainObjectTask(consumer, domainFile, version, immutable);
|
||||
tool.execute(task, 1000);
|
||||
return (T) task.getVersionedObject();
|
||||
return (T) task.getDomainObject();
|
||||
}
|
||||
}
|
||||
return dobj;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,7 +17,6 @@ package ghidra.app.plugin.core.diff;
|
|||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
@ -51,6 +50,7 @@ import ghidra.app.util.viewer.format.FormatManager;
|
|||
import ghidra.app.util.viewer.listingpanel.*;
|
||||
import ghidra.app.util.viewer.util.AddressIndexMap;
|
||||
import ghidra.app.util.viewer.util.FieldNavigator;
|
||||
import ghidra.framework.main.GetDomainObjectTask;
|
||||
import ghidra.framework.main.OpenVersionedFileDialog;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.options.*;
|
||||
|
@ -60,7 +60,8 @@ import ghidra.program.model.address.*;
|
|||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.util.*;
|
||||
import ghidra.util.*;
|
||||
import ghidra.util.exception.*;
|
||||
import ghidra.util.exception.AssertException;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.task.*;
|
||||
import help.Help;
|
||||
import help.HelpService;
|
||||
|
@ -1143,7 +1144,7 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
|||
tool.clearStatusInfo();
|
||||
JComponent component = dialog.getComponent();
|
||||
|
||||
Program dobj = dialog.getDomainObject(ProgramDiffPlugin.this, false);
|
||||
Program dobj = dialog.getDomainObject(ProgramDiffPlugin.this, true);
|
||||
if (dobj != null) {
|
||||
if (openSecondProgram(dobj, component)) {
|
||||
dialog.close();
|
||||
|
@ -1151,9 +1152,6 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
displayStatus(component, "Can't Open Selected Program",
|
||||
"Please select a file, not a folder.", OptionDialog.INFORMATION_MESSAGE);
|
||||
});
|
||||
dialog.showComponent();
|
||||
}
|
||||
|
@ -1531,17 +1529,20 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
|||
}
|
||||
|
||||
private boolean openSecondProgram(DomainFile df) {
|
||||
if (!Program.class.isAssignableFrom(df.getDomainObjectClass())) {
|
||||
Msg.error(this, "Failed to launch Diff for non-Program file: " + df.getName());
|
||||
return false;
|
||||
}
|
||||
|
||||
OpenSecondProgramTask task = new OpenSecondProgramTask(df);
|
||||
GetDomainObjectTask task =
|
||||
new GetDomainObjectTask(this, df, DomainFile.DEFAULT_VERSION, true);
|
||||
new TaskLauncher(task, tool.getToolFrame(), 500);
|
||||
// block until the task completes
|
||||
|
||||
if (!task.wasCanceled()) {
|
||||
Program newProgram = task.getDiffProgram();
|
||||
Program newProgram = (Program) task.getDomainObject();
|
||||
if (newProgram != null) {
|
||||
return openSecondProgram(newProgram, null);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1851,71 +1852,6 @@ public class ProgramDiffPlugin extends ProgramPlugin
|
|||
}
|
||||
}
|
||||
|
||||
private class OpenSecondProgramTask extends Task {
|
||||
private DomainFile domainFile;
|
||||
private Program diffProgram;
|
||||
private TaskMonitor monitor;
|
||||
|
||||
OpenSecondProgramTask(DomainFile domainFile) {
|
||||
super("Opening Program for Diff", true, true, true);
|
||||
this.domainFile = domainFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(TaskMonitor tm) {
|
||||
this.monitor = tm;
|
||||
try {
|
||||
try {
|
||||
monitor.setMessage("Waiting on program file...");
|
||||
diffProgram =
|
||||
(Program) domainFile.getImmutableDomainObject(ProgramDiffPlugin.this,
|
||||
DomainFile.DEFAULT_VERSION, monitor);
|
||||
}
|
||||
catch (VersionException e) {
|
||||
if (e.isUpgradable()) {
|
||||
try {
|
||||
diffProgram =
|
||||
(Program) domainFile.getReadOnlyDomainObject(ProgramDiffPlugin.this,
|
||||
DomainFile.DEFAULT_VERSION, monitor);
|
||||
}
|
||||
catch (VersionException exc) {
|
||||
Msg.showError(this, null, "Error Getting Diff Program",
|
||||
"Getting read only file failed");
|
||||
}
|
||||
catch (IOException exc) {
|
||||
if (!monitor.isCancelled()) {
|
||||
Msg.showError(this, null, "Error Getting Diff Program",
|
||||
"Getting read only file failed", exc);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Msg.showError(this, null, "Error Getting Diff Program",
|
||||
"File cannot be upgraded.");
|
||||
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
Msg.showError(this, null, "Error Getting Diff Program",
|
||||
"Getting read only file failed", e);
|
||||
}
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// For now do nothing if user cancels
|
||||
}
|
||||
|
||||
monitor.setMessage("");
|
||||
}
|
||||
|
||||
boolean wasCanceled() {
|
||||
return monitor.isCancelled();
|
||||
}
|
||||
|
||||
Program getDiffProgram() {
|
||||
return diffProgram;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void domainObjectChanged(DomainObjectChangedEvent event) {
|
||||
if (secondaryDiffProgram != null && diffDetailsProvider != null) {
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.net.MalformedURLException;
|
|||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.help.UnsupportedOperationException;
|
||||
import javax.swing.Icon;
|
||||
|
||||
import generic.theme.GIcon;
|
||||
|
@ -45,9 +44,6 @@ import ghidra.util.task.TaskMonitor;
|
|||
*/
|
||||
public abstract class LinkHandler<T extends DomainObjectAdapterDB> extends DBContentHandler<T> {
|
||||
|
||||
// TODO: Need to improve by making this meta data on file instead of database content.
|
||||
// Metadata use would eliminate need for DB but we lack support for non-DB files.
|
||||
|
||||
public static final String URL_METADATA_KEY = "link.url";
|
||||
|
||||
// 16x16 link icon where link is placed in lower-left corner
|
||||
|
@ -76,15 +72,29 @@ public abstract class LinkHandler<T extends DomainObjectAdapterDB> extends DBCon
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final T getReadOnlyObject(FolderItem item, int version, boolean okToUpgrade,
|
||||
Object consumer, TaskMonitor monitor)
|
||||
throws IOException, VersionException, CancelledException {
|
||||
|
||||
if (!okToUpgrade) {
|
||||
throw new IllegalArgumentException("okToUpgrade must be true");
|
||||
throw new UnsupportedOperationException("okToUpgrade must be true for link-file");
|
||||
}
|
||||
return getObject(item, version, consumer, monitor, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getImmutableObject(FolderItem item, Object consumer, int version, int minChangeVersion,
|
||||
TaskMonitor monitor) throws IOException, CancelledException, VersionException {
|
||||
if (minChangeVersion != -1) {
|
||||
throw new UnsupportedOperationException("minChangeVersion must be -1 for link-file");
|
||||
}
|
||||
return getObject(item, version, consumer, monitor, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private T getObject(FolderItem item, int version, Object consumer, TaskMonitor monitor,
|
||||
boolean immutable)
|
||||
throws IOException, VersionException, CancelledException {
|
||||
|
||||
URL url = getURL(item);
|
||||
|
||||
|
@ -112,10 +122,11 @@ public abstract class LinkHandler<T extends DomainObjectAdapterDB> extends DBCon
|
|||
DomainFile linkedFile = (DomainFile) content;
|
||||
if (!getDomainObjectClass().isAssignableFrom(linkedFile.getDomainObjectClass())) {
|
||||
throw new BadLinkException(
|
||||
"Excepted " + getDomainObjectClass() + " but linked to " +
|
||||
"Expected " + getDomainObjectClass() + " but linked to " +
|
||||
linkedFile.getDomainObjectClass());
|
||||
}
|
||||
return (T) linkedFile.getReadOnlyDomainObject(consumer, version, monitor);
|
||||
return immutable ? (T) linkedFile.getImmutableDomainObject(consumer, version, monitor)
|
||||
: (T) linkedFile.getReadOnlyDomainObject(consumer, version, monitor);
|
||||
}
|
||||
finally {
|
||||
if (content != null) {
|
||||
|
@ -128,16 +139,8 @@ public abstract class LinkHandler<T extends DomainObjectAdapterDB> extends DBCon
|
|||
public final T getDomainObject(FolderItem item, FileSystem userfs, long checkoutId,
|
||||
boolean okToUpgrade, boolean okToRecover, Object consumer, TaskMonitor monitor)
|
||||
throws IOException, CancelledException, VersionException {
|
||||
// Always upgrade if needed for read-only object
|
||||
return getReadOnlyObject(item, DomainFile.DEFAULT_VERSION, true, consumer, monitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getImmutableObject(FolderItem item, Object consumer, int version, int minChangeVersion,
|
||||
TaskMonitor monitor) throws IOException, CancelledException, VersionException {
|
||||
//throw new UnsupportedOperationException("link-file does not support getImmutableObject");
|
||||
// See GP-2903
|
||||
return getReadOnlyObject(item, version, true, consumer, monitor);
|
||||
// getReadOnlyObject or getImmutableObject should be used
|
||||
throw new UnsupportedOperationException("link-file does not support getDomainObject");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.framework.main;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import docking.widgets.OptionDialog;
|
||||
import ghidra.framework.client.ClientUtil;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.model.DomainObject;
|
||||
import ghidra.util.VersionExceptionHandler;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.VersionException;
|
||||
import ghidra.util.task.Task;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* A modal task that gets a domain object for a specified version.
|
||||
* Object is either open read-only or immutable.
|
||||
*
|
||||
* NOTE: This task is not intended to open a domain file for modification and saving back
|
||||
* to a project.
|
||||
*
|
||||
* A file open for read-only use will be upgraded if needed and is possible. Once open it is
|
||||
* important that the specified consumer be released from the domain object when done using
|
||||
* the open object (see {@link DomainObject#release(Object)}).
|
||||
*/
|
||||
public class GetDomainObjectTask extends Task {
|
||||
|
||||
private Object consumer;
|
||||
private DomainFile domainFile;
|
||||
private int versionNumber;
|
||||
private boolean immutable;
|
||||
|
||||
private DomainObject versionedObj;
|
||||
|
||||
/**
|
||||
* Construct task open specified domainFile read only.
|
||||
* An upgrade is performed if needed and is possible.
|
||||
* @param consumer consumer of the domain object
|
||||
* @param domainFile domain file
|
||||
* @param versionNumber version
|
||||
*/
|
||||
public GetDomainObjectTask(Object consumer, DomainFile domainFile, int versionNumber) {
|
||||
this(consumer, domainFile, versionNumber, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct task open specified domainFile read only or immutable. Immutable mode should not
|
||||
* be used for content that will be modified.
|
||||
* If read-only an upgrade is performed if needed, if immutable the user will be prompted
|
||||
* if an upgrade should be performed if possible in which case it will open read-only.
|
||||
* @param consumer consumer of the domain object
|
||||
* @param domainFile domain file
|
||||
* @param versionNumber version
|
||||
* @param immutable true if the object should be open immutable, else read-only.
|
||||
*/
|
||||
public GetDomainObjectTask(Object consumer, DomainFile domainFile, int versionNumber,
|
||||
boolean immutable) {
|
||||
super("Get Versioned Domain Object", true, false, true);
|
||||
this.consumer = consumer;
|
||||
this.domainFile = domainFile;
|
||||
this.versionNumber = versionNumber;
|
||||
this.immutable = immutable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(TaskMonitor monitor) {
|
||||
String contentType = domainFile.getContentType();
|
||||
try {
|
||||
monitor.setMessage("Getting Version " + versionNumber + " for " + domainFile.getName());
|
||||
if (immutable) {
|
||||
versionedObj =
|
||||
domainFile.getImmutableDomainObject(consumer, versionNumber, monitor);
|
||||
}
|
||||
else {
|
||||
// Upgrade will be performed if required
|
||||
versionedObj = domainFile.getReadOnlyDomainObject(consumer, versionNumber, monitor);
|
||||
}
|
||||
}
|
||||
catch (CancelledException e) {
|
||||
// ignore
|
||||
}
|
||||
catch (IOException e) {
|
||||
ClientUtil.handleException(AppInfo.getActiveProject().getRepository(), e,
|
||||
contentType + " Open", null);
|
||||
} catch (VersionException e) {
|
||||
if (immutable && e.isUpgradable()) {
|
||||
String detailMessage =
|
||||
e.getDetailMessage() == null ? "" : "\n" + e.getDetailMessage();
|
||||
String title = "Upgrade " + contentType + " Data? " + domainFile.getName();
|
||||
String message = "The " + contentType + " file you are attempting to open" +
|
||||
" is an older version." + detailMessage + "\n \n" +
|
||||
"Would you like to Upgrade it now?";
|
||||
int rc = OptionDialog.showOptionDialog(null, title, message, "Upgrade",
|
||||
OptionDialog.QUESTION_MESSAGE);
|
||||
if (rc == OptionDialog.OPTION_ONE) {
|
||||
// try again as read-only
|
||||
immutable = false;
|
||||
run(monitor);
|
||||
}
|
||||
return;
|
||||
}
|
||||
VersionExceptionHandler.showVersionError(null, domainFile.getName(),
|
||||
domainFile.getContentType(), contentType + " Open", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the domain object instance.
|
||||
* @return domain object which was opened or null if task cancelled or failed
|
||||
*/
|
||||
public DomainObject getDomainObject() {
|
||||
return versionedObj;
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
/* ###
|
||||
* 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.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.framework.main;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import ghidra.framework.client.ClientUtil;
|
||||
import ghidra.framework.model.DomainFile;
|
||||
import ghidra.framework.model.DomainObject;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.exception.CancelledException;
|
||||
import ghidra.util.exception.VersionException;
|
||||
import ghidra.util.task.Task;
|
||||
import ghidra.util.task.TaskMonitor;
|
||||
|
||||
/**
|
||||
* A modal task that gets a domain object for a specific version.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class GetVersionedObjectTask extends Task {
|
||||
|
||||
private Object consumer;
|
||||
private DomainFile domainFile;
|
||||
private int versionNumber;
|
||||
private DomainObject versionedObj;
|
||||
|
||||
/**
|
||||
* Constructor; task will get a read only domain object
|
||||
* @param consumer consumer of the domain object
|
||||
* @param domainFile domain file
|
||||
* @param versionNumber version
|
||||
*/
|
||||
public GetVersionedObjectTask(Object consumer, DomainFile domainFile,
|
||||
int versionNumber) {
|
||||
this(consumer, domainFile, versionNumber, true);
|
||||
}
|
||||
/**
|
||||
* Constructor
|
||||
* @param consumer consumer of the domain object
|
||||
* @param domainFile domain file
|
||||
* @param versionNumber version
|
||||
* @param readOnly true if the object should be read only versus
|
||||
* immutable
|
||||
*/
|
||||
public GetVersionedObjectTask(Object consumer, DomainFile domainFile,
|
||||
int versionNumber, boolean readOnly) {
|
||||
|
||||
super("Get Versioned Domain Object", true, false, true);
|
||||
this.consumer = consumer;
|
||||
this.domainFile = domainFile;
|
||||
this.versionNumber = versionNumber;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see ghidra.util.task.Task#run(ghidra.util.task.TaskMonitor)
|
||||
*/
|
||||
@Override
|
||||
public void run(TaskMonitor monitor) {
|
||||
try {
|
||||
monitor.setMessage("Getting Version " + versionNumber +
|
||||
" for " + domainFile.getName());
|
||||
versionedObj =
|
||||
domainFile.getReadOnlyDomainObject(consumer, versionNumber,
|
||||
monitor);
|
||||
}catch (CancelledException e) {
|
||||
}catch (IOException e) {
|
||||
if (domainFile.isInWritableProject()) {
|
||||
ClientUtil.handleException(AppInfo.getActiveProject().getRepository(), e,
|
||||
"Get Versioned Object", null);
|
||||
}
|
||||
else {
|
||||
Msg.showError(this, null,
|
||||
"Error Getting Versioned Object", "Could not get version " + versionNumber +
|
||||
" for " + domainFile.getName() + ": " + e, e);
|
||||
}
|
||||
} catch (VersionException e) {
|
||||
Msg.showError(this,
|
||||
null,
|
||||
"Error Getting Versioned Object", "Could not get version " + versionNumber +
|
||||
" for " + domainFile.getName() + ": " + e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return the versioned domain object.
|
||||
*/
|
||||
public DomainObject getVersionedObject() {
|
||||
return versionedObj;
|
||||
}
|
||||
}
|
|
@ -370,9 +370,9 @@ class ToolButton extends EmptyBorderButton implements Draggable, Droppable {
|
|||
}
|
||||
|
||||
private DomainObject getVersionedObject(DomainFile file, int versionNumber) {
|
||||
GetVersionedObjectTask task = new GetVersionedObjectTask(this, file, versionNumber);
|
||||
GetDomainObjectTask task = new GetDomainObjectTask(this, file, versionNumber);
|
||||
plugin.getTool().execute(task, 250);
|
||||
return task.getVersionedObject();
|
||||
return task.getDomainObject();
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
|
|
@ -22,7 +22,7 @@ import java.io.IOException;
|
|||
import docking.widgets.tree.GTreeNode;
|
||||
import ghidra.app.util.FileOpenDataFlavorHandler;
|
||||
import ghidra.framework.client.*;
|
||||
import ghidra.framework.main.GetVersionedObjectTask;
|
||||
import ghidra.framework.main.GetDomainObjectTask;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.util.task.TaskLauncher;
|
||||
|
@ -35,17 +35,20 @@ public final class LocalVersionInfoHandler
|
|||
VersionInfo info = (VersionInfo) obj;
|
||||
|
||||
DomainFile file = tool.getProject().getProjectData().getFile(info.getDomainFilePath());
|
||||
GetVersionedObjectTask task =
|
||||
new GetVersionedObjectTask(this, file, info.getVersionNumber());
|
||||
GetDomainObjectTask task =
|
||||
new GetDomainObjectTask(this, file, info.getVersionNumber());
|
||||
tool.execute(task, 250);
|
||||
DomainObject versionedObj = task.getVersionedObject();
|
||||
|
||||
DomainObject versionedObj = task.getDomainObject();
|
||||
if (versionedObj != null) {
|
||||
try {
|
||||
DomainFile vfile = versionedObj.getDomainFile();
|
||||
tool.acceptDomainFiles(new DomainFile[] { vfile });
|
||||
}
|
||||
finally {
|
||||
versionedObj.release(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PluginTool tool, DataTree dataTree, GTreeNode destinationNode,
|
||||
|
|
|
@ -38,7 +38,7 @@ import docking.widgets.OptionDialog;
|
|||
import docking.widgets.table.*;
|
||||
import ghidra.app.util.GenericHelpTopics;
|
||||
import ghidra.framework.client.ClientUtil;
|
||||
import ghidra.framework.main.GetVersionedObjectTask;
|
||||
import ghidra.framework.main.GetDomainObjectTask;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.framework.plugintool.PluginTool;
|
||||
import ghidra.framework.store.ItemCheckoutStatus;
|
||||
|
@ -143,31 +143,36 @@ public class VersionHistoryPanel extends JPanel implements Draggable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the domain object for the selected version.
|
||||
* @param consumer the consumer
|
||||
* @param readOnly true if read only
|
||||
* @return null if there is no selection
|
||||
* Get the selected {@link Version}.
|
||||
* @return selected {@link Version} or null if no selection
|
||||
*/
|
||||
public DomainObject getSelectedVersion(Object consumer, boolean readOnly) {
|
||||
public Version getSelectedVersion() {
|
||||
int row = table.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
Version version = tableModel.getVersionAt(row);
|
||||
return getVersionedObject(consumer, version.getVersion(), readOnly);
|
||||
return tableModel.getVersionAt(row);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a version selection has been made.
|
||||
* @return true if version selection has been made, esle false
|
||||
*/
|
||||
public boolean isVersionSelected() {
|
||||
return !table.getSelectionModel().isSelectionEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selected version number or {@link DomainFile#DEFAULT_VERSION} if no selection.
|
||||
* @return selected version number
|
||||
*/
|
||||
public int getSelectedVersionNumber() {
|
||||
int row = table.getSelectedRow();
|
||||
if (row >= 0) {
|
||||
Version version = tableModel.getVersionAt(row);
|
||||
return version.getVersion();
|
||||
}
|
||||
return -1;
|
||||
return DomainFile.DEFAULT_VERSION;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -260,11 +265,11 @@ public class VersionHistoryPanel extends JPanel implements Draggable {
|
|||
dragSource.createDefaultDragGestureRecognizer(table, dragAction, dragGestureAdapter);
|
||||
}
|
||||
|
||||
private DomainObject getVersionedObject(Object consumer, int versionNumber, boolean readOnly) {
|
||||
GetVersionedObjectTask task =
|
||||
new GetVersionedObjectTask(consumer, domainFile, versionNumber, readOnly);
|
||||
private DomainObject getVersionedObject(Object consumer, int versionNumber, boolean immutable) {
|
||||
GetDomainObjectTask task =
|
||||
new GetDomainObjectTask(consumer, domainFile, versionNumber, immutable);
|
||||
tool.execute(task, 1000);
|
||||
return task.getVersionedObject();
|
||||
return task.getDomainObject();
|
||||
}
|
||||
|
||||
private void delete() {
|
||||
|
@ -337,15 +342,19 @@ public class VersionHistoryPanel extends JPanel implements Draggable {
|
|||
Version version = tableModel.getVersionAt(row);
|
||||
DomainObject versionedObj = getVersionedObject(this, version.getVersion(), true);
|
||||
if (versionedObj != null) {
|
||||
try {
|
||||
if (toolName != null) {
|
||||
tool.getToolServices().launchTool(toolName, versionedObj.getDomainFile());
|
||||
}
|
||||
else {
|
||||
tool.getToolServices().launchDefaultTool(versionedObj.getDomainFile());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
versionedObj.release(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void open() {
|
||||
openWith(null);
|
||||
|
|
|
@ -187,6 +187,9 @@ public interface DomainFile extends Comparable<DomainFile> {
|
|||
|
||||
/**
|
||||
* Returns a new DomainObject that cannot be changed or saved to its original file.
|
||||
* NOTE: The use of this method should generally be avoided since it can't
|
||||
* handle version changes that may have occured and require a data upgrade
|
||||
* (e.g., DB schema change).
|
||||
* @param consumer consumer of the domain object which is responsible for
|
||||
* releasing it after use.
|
||||
* @param version the domain object version requested. DEFAULT_VERSION should be
|
||||
|
|
|
@ -145,7 +145,6 @@ public class ProgramContentHandler extends DBWithUserDataContentHandler<ProgramD
|
|||
}
|
||||
catch (Throwable t) {
|
||||
Msg.error(this, "getReadOnlyObject failed", t);
|
||||
t.printStackTrace();
|
||||
String msg = t.getMessage();
|
||||
if (msg == null) {
|
||||
msg = t.toString();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue