GP-3616 corrected DomainFileProxy.getSharedProjectURL

This commit is contained in:
ghidra1 2023-07-07 18:34:11 -04:00
parent 75fb5bf79b
commit f661d684f6
4 changed files with 173 additions and 19 deletions

View File

@ -132,6 +132,21 @@ public class ClientUtil {
return rsa;
}
/**
* Determine if a connected {@link RepositoryServerAdapter} already exists for the specified server.
* @param host server name or address
* @param port server port, 0 indicates that default port applies.
* @return true if connection already exists, else false
*/
public static boolean isConnected(String host, int port) {
if (port <= 0) {
port = GhidraServerHandle.DEFAULT_PORT;
}
ServerInfo server = new ServerInfo(host, port);
RepositoryServerAdapter rsa = serverHandles.get(server);
return rsa != null && rsa.isConnected();
}
/**
* Eliminate the specified repository server from the connection cache
* @param host host name or IP address

View File

@ -23,8 +23,10 @@ import java.util.*;
import javax.swing.Icon;
import ghidra.framework.client.*;
import ghidra.framework.model.*;
import ghidra.framework.protocol.ghidra.GhidraURL;
import ghidra.framework.remote.RepositoryItem;
import ghidra.framework.store.ItemCheckoutStatus;
import ghidra.framework.store.Version;
import ghidra.framework.store.db.PackedDatabase;
@ -114,25 +116,81 @@ public class DomainFileProxy implements DomainFile {
return parentPath + DomainFolder.SEPARATOR + getName();
}
private URL getSharedFileURL(URL sharedProjectURL) {
try {
// Direct URL construction done so that ghidra protocol
// extension may be supported
String urlStr = sharedProjectURL.toExternalForm();
if (urlStr.endsWith("/")) {
urlStr = urlStr.substring(0, urlStr.length() - 1);
}
urlStr += getPathname();
return new URL(urlStr);
}
catch (MalformedURLException e) {
// ignore
}
return null;
}
private URL getSharedFileURL(Properties properties) {
if (properties == null) {
return null;
}
String serverName = properties.getProperty(ProjectFileManager.SERVER_NAME);
String repoName = properties.getProperty(ProjectFileManager.REPOSITORY_NAME);
if (serverName == null || repoName == null) {
return null;
}
int port = Integer.parseInt(properties.getProperty(ProjectFileManager.PORT_NUMBER, "0"));
if (!ClientUtil.isConnected(serverName, port)) {
return null; // avoid initiating a server connection.
}
RepositoryAdapter repository = null;
try {
RepositoryServerAdapter repositoryServer =
ClientUtil.getRepositoryServer(serverName, port);
Set<String> repoNames = Set.of(repositoryServer.getRepositoryNames());
if (!repoNames.contains(repoName)) {
return null; // only consider repos which user has access to
}
repository = repositoryServer.getRepository(repoName);
if (repository == null) {
return null;
}
repository.connect();
RepositoryItem item = repository.getItem(parentPath, name);
if (item == null || !Objects.equals(item.getFileID(), fileID)) {
return null;
}
ServerInfo serverInfo = repository.getServerInfo();
return GhidraURL.makeURL(serverInfo.getServerName(),
serverInfo.getPortNumber(), repository.getName(),
item.getPathName());
}
catch (IOException e) {
// ignore
}
finally {
if (repository != null) {
repository.disconnect();
}
}
return null;
}
@Override
public URL getSharedProjectURL() {
if (projectLocation != null && version == DomainFile.DEFAULT_VERSION) {
URL projectURL = projectLocation.getURL();
if (GhidraURL.isServerRepositoryURL(projectURL)) {
try {
// Direct URL construction done so that ghidra protocol
// extension may be supported
String urlStr = projectURL.toExternalForm();
if (urlStr.endsWith("/")) {
urlStr = urlStr.substring(0, urlStr.length() - 1);
}
urlStr += getPathname();
return new URL(urlStr);
}
catch (MalformedURLException e) {
// ignore
}
return getSharedFileURL(projectURL);
}
Properties properties =
ProjectFileManager.readProjectProperties(projectLocation.getProjectDir());
return getSharedFileURL(properties);
}
return null;
}

View File

@ -49,10 +49,11 @@ public class ProjectFileManager implements ProjectData {
private static final String TEST_REPOSITORY_PATH = System.getProperty("Repository");
private static final String SERVER_NAME = "SERVER";
private static final String PORT_NUMBER = "PORT_NUMBER";
private static final String REPOSITORY_NAME = "REPOSITORY_NAME";
private static final String OWNER = "OWNER";
public static final String SERVER_NAME = "SERVER";
public static final String PORT_NUMBER = "PORT_NUMBER";
public static final String REPOSITORY_NAME = "REPOSITORY_NAME";
public static final String OWNER = "OWNER";
private static final String PROPERTY_FILENAME = "project";
private static final int USER_DATA_RECONCILE_DELAY_MS = 5 * 60 * 1000; // 5-minutes
@ -204,6 +205,38 @@ public class ProjectFileManager implements ProjectData {
}
}
/**
* Read the contents of the project properties file to include the following values if relavent:
* {@value #OWNER}, {@value #SERVER_NAME}, {@value #REPOSITORY_NAME}, {@value #PORT_NUMBER}
* @param projectDir project directory (*.rep)
* @return project properties or null if invalid project directory specified
*/
public static Properties readProjectProperties(File projectDir) {
try {
PropertyFile pf =
new PropertyFile(projectDir, PROPERTY_FILENAME, "/", PROPERTY_FILENAME);
if (pf.exists()) {
Properties properties = new Properties();
properties.setProperty(OWNER, pf.getString(OWNER, null));
String serverName = pf.getString(SERVER_NAME, null);
String repoName = pf.getString(REPOSITORY_NAME, null);
int port = pf.getInt(PORT_NUMBER, 0);
if (serverName != null && repoName != null) {
properties.setProperty(SERVER_NAME, serverName);
properties.setProperty(REPOSITORY_NAME, repoName);
properties.setProperty(PORT_NUMBER, Integer.toString(port));
}
return properties;
}
}
catch (IOException e) {
// ignore
}
return null;
}
private void init(boolean create, boolean isInWritableProject)
throws IOException, LockException {

View File

@ -22,8 +22,8 @@ import db.DBConstants;
import generic.jar.ResourceFile;
import ghidra.framework.store.db.PackedDBHandle;
import ghidra.framework.store.db.PackedDatabase;
import ghidra.program.model.lang.CompilerSpec;
import ghidra.program.model.lang.Language;
import ghidra.program.model.lang.*;
import ghidra.program.util.DefaultLanguageService;
import ghidra.util.InvalidNameException;
import ghidra.util.UniversalID;
import ghidra.util.exception.*;
@ -98,6 +98,54 @@ public class FileDataTypeManager extends StandAloneDataTypeManager
}
}
/**
* Create a new data-type file archive using the default data organization
* @param packedDbfile archive file (filename must end with DataTypeFileManager.SUFFIX)
* @return data-type manager backed by specified packedDbFile
* @throws IOException if an IO error occurs
*/
public static FileDataTypeManager createFileArchive(File packedDbfile, LanguageID languageId,
CompilerSpecID compilerSpecId)
throws LanguageNotFoundException, CompilerSpecNotFoundException, IOException {
try {
FileDataTypeManager dtm =
new FileDataTypeManager(new ResourceFile(packedDbfile), DBConstants.CREATE,
TaskMonitor.DUMMY);
LanguageService languageService = DefaultLanguageService.getLanguageService();
Language language = languageService.getLanguage(languageId);
CompilerSpec compilerSpec = language.getCompilerSpecByID(compilerSpecId);
//dtm.setProgramArchitecture()
return dtm;
}
catch (CancelledException e) {
throw new AssertException(e); // unexpected without task monitor use
}
}
/**
* Create a new data-type file archive using the default data organization
* @param packedDbfile archive file (filename must end with DataTypeFileManager.SUFFIX)
* @return data-type manager backed by specified packedDbFile
* @throws IOException if an IO error occurs
*/
public static FileDataTypeManager createFileArchive(File packedDbfile, String languageId,
String compilerSpecId) throws IOException {
try {
FileDataTypeManager dtm =
new FileDataTypeManager(new ResourceFile(packedDbfile), DBConstants.CREATE,
TaskMonitor.DUMMY);
//dtm.setProgramArchitecture()
return dtm;
}
catch (CancelledException e) {
throw new AssertException(e); // unexpected without task monitor use
}
}
/**
* Open an existing data-type file archive using the default data organization.
* <p>