mirror of
https://github.com/arduino/Arduino.git
synced 2024-12-01 12:24:14 +01:00
LibraryInstaller and ContributionInstaller are now singletons: members of Base, they get passed to dependents, thus allowing a synchronized method execution, needed to avoid race conditions when accessing files
This commit is contained in:
parent
dc93bb93d0
commit
2daf330c09
@ -36,7 +36,6 @@ import cc.arduino.contributions.libraries.LibraryInstaller;
|
||||
import cc.arduino.contributions.libraries.LibraryTypeComparator;
|
||||
import cc.arduino.contributions.ui.*;
|
||||
import cc.arduino.utils.Progress;
|
||||
import processing.app.Platform;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@ -53,8 +52,8 @@ import static processing.app.I18n.tr;
|
||||
public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
|
||||
|
||||
private final JComboBox typeChooser;
|
||||
private final Platform platform;
|
||||
private LibrariesIndexer indexer;
|
||||
private final LibrariesIndexer indexer;
|
||||
private final LibraryInstaller installer;
|
||||
private Predicate<ContributedLibrary> typeFilter;
|
||||
|
||||
@Override
|
||||
@ -90,9 +89,10 @@ public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
|
||||
};
|
||||
}
|
||||
|
||||
public LibraryManagerUI(Frame parent, Platform platform) {
|
||||
public LibraryManagerUI(Frame parent, LibrariesIndexer indexer, LibraryInstaller installer) {
|
||||
super(parent, "Library Manager", Dialog.ModalityType.APPLICATION_MODAL, tr("Unable to reach Arduino.cc due to possible network issues."));
|
||||
this.platform = platform;
|
||||
this.indexer = indexer;
|
||||
this.installer = installer;
|
||||
|
||||
filtersContainer.add(new JLabel(tr("Topic")), 1);
|
||||
filtersContainer.remove(2);
|
||||
@ -130,9 +130,7 @@ public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
|
||||
super.updateIndexFilter(filters, additionalFilters);
|
||||
}
|
||||
|
||||
public void setIndexer(LibrariesIndexer indexer) {
|
||||
this.indexer = indexer;
|
||||
|
||||
public void updateUI() {
|
||||
DropdownItem<DownloadableContribution> previouslySelectedCategory = (DropdownItem<DownloadableContribution>) categoryChooser.getSelectedItem();
|
||||
DropdownItem<DownloadableContribution> previouslySelectedType = (DropdownItem<DownloadableContribution>) typeChooser.getSelectedItem();
|
||||
|
||||
@ -181,9 +179,6 @@ public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
|
||||
}
|
||||
|
||||
filterField.setEnabled(contribModel.getRowCount() > 0);
|
||||
|
||||
// Create LibrariesInstaller tied with the provided index
|
||||
installer = new LibraryInstaller(indexer, platform);
|
||||
}
|
||||
|
||||
public void selectDropdownItemByClassName(String dropdownItem) {
|
||||
@ -194,7 +189,6 @@ public class LibraryManagerUI extends InstallerJDialog<ContributedLibrary> {
|
||||
progressBar.setValue(progress);
|
||||
}
|
||||
|
||||
private LibraryInstaller installer;
|
||||
private Thread installerThread = null;
|
||||
|
||||
@Override
|
||||
|
@ -30,14 +30,12 @@
|
||||
package cc.arduino.contributions.packages.ui;
|
||||
|
||||
import cc.arduino.contributions.DownloadableContribution;
|
||||
import cc.arduino.contributions.GPGDetachedSignatureVerifier;
|
||||
import cc.arduino.contributions.packages.ContributedPlatform;
|
||||
import cc.arduino.contributions.packages.ContributionInstaller;
|
||||
import cc.arduino.contributions.packages.ContributionsIndexer;
|
||||
import cc.arduino.contributions.ui.*;
|
||||
import cc.arduino.utils.Progress;
|
||||
import processing.app.I18n;
|
||||
import processing.app.Platform;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@ -50,7 +48,8 @@ import static processing.app.I18n.tr;
|
||||
@SuppressWarnings("serial")
|
||||
public class ContributionManagerUI extends InstallerJDialog {
|
||||
|
||||
private final Platform platform;
|
||||
private final ContributionsIndexer indexer;
|
||||
private final ContributionInstaller installer;
|
||||
|
||||
@Override
|
||||
protected FilteredAbstractTableModel createContribModel() {
|
||||
@ -85,12 +84,13 @@ public class ContributionManagerUI extends InstallerJDialog {
|
||||
};
|
||||
}
|
||||
|
||||
public ContributionManagerUI(Frame parent, Platform platform) {
|
||||
public ContributionManagerUI(Frame parent, ContributionsIndexer indexer, ContributionInstaller installer) {
|
||||
super(parent, tr("Boards Manager"), Dialog.ModalityType.APPLICATION_MODAL, tr("Unable to reach Arduino.cc due to possible network issues."));
|
||||
this.platform = platform;
|
||||
this.indexer = indexer;
|
||||
this.installer = installer;
|
||||
}
|
||||
|
||||
public void setIndexer(ContributionsIndexer indexer) {
|
||||
public void updateUI() {
|
||||
DropdownItem<DownloadableContribution> previouslySelectedCategory = (DropdownItem<DownloadableContribution>) categoryChooser.getSelectedItem();
|
||||
|
||||
categoryChooser.removeActionListener(categoryChooserActionListener);
|
||||
@ -116,9 +116,6 @@ public class ContributionManagerUI extends InstallerJDialog {
|
||||
} else {
|
||||
categoryChooser.setSelectedIndex(0);
|
||||
}
|
||||
|
||||
// Create ConstributionInstaller tied with the provided index
|
||||
installer = new ContributionInstaller(indexer, platform, new GPGDetachedSignatureVerifier());
|
||||
}
|
||||
|
||||
public void setProgress(Progress progress) {
|
||||
@ -129,7 +126,6 @@ public class ContributionManagerUI extends InstallerJDialog {
|
||||
* Installer methods follows
|
||||
*/
|
||||
|
||||
private ContributionInstaller installer;
|
||||
private Thread installerThread = null;
|
||||
|
||||
@Override
|
||||
|
@ -92,6 +92,8 @@ public class Base {
|
||||
|
||||
public static SplashScreenHelper splashScreenHelper = new SplashScreenHelper(SplashScreen.getSplashScreen());
|
||||
public static Map<String, Object> FIND_DIALOG_STATE = new HashMap<String, Object>();
|
||||
private final ContributionInstaller contributionInstaller;
|
||||
private final LibraryInstaller libraryInstaller;
|
||||
private Timer selfCheckTimer;
|
||||
|
||||
// set to true after the first time the menu is built.
|
||||
@ -302,6 +304,9 @@ public class Base {
|
||||
this.pdeKeywords = new PdeKeywords();
|
||||
this.pdeKeywords.reload();
|
||||
|
||||
contributionInstaller = new ContributionInstaller(BaseNoGui.indexer, BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier());
|
||||
libraryInstaller = new LibraryInstaller(BaseNoGui.librariesIndexer, BaseNoGui.getPlatform());
|
||||
|
||||
parser.parseArgumentsPhase2();
|
||||
|
||||
for (String path : parser.getFilenames()) {
|
||||
@ -341,10 +346,9 @@ public class Base {
|
||||
if (parser.isInstallBoard()) {
|
||||
ContributionsIndexer indexer = new ContributionsIndexer(BaseNoGui.getSettingsFolder(), BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier());
|
||||
ProgressListener progressListener = new ConsoleProgressListener();
|
||||
ContributionInstaller installer = new ContributionInstaller(indexer, BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier());
|
||||
|
||||
List<String> downloadedPackageIndexFiles = installer.updateIndex(progressListener);
|
||||
installer.deleteUnknownFiles(downloadedPackageIndexFiles);
|
||||
List<String> downloadedPackageIndexFiles = contributionInstaller.updateIndex(progressListener);
|
||||
contributionInstaller.deleteUnknownFiles(downloadedPackageIndexFiles);
|
||||
indexer.parseIndex();
|
||||
indexer.syncWithFilesystem(BaseNoGui.getHardwareFolder());
|
||||
|
||||
@ -368,11 +372,11 @@ public class Base {
|
||||
ContributedPlatform installed = indexer.getInstalled(boardToInstallParts[0], boardToInstallParts[1]);
|
||||
|
||||
if (!selected.isReadOnly()) {
|
||||
installer.install(selected, progressListener);
|
||||
contributionInstaller.install(selected, progressListener);
|
||||
}
|
||||
|
||||
if (installed != null && !installed.isReadOnly()) {
|
||||
installer.remove(installed);
|
||||
contributionInstaller.remove(installed);
|
||||
}
|
||||
|
||||
System.exit(0);
|
||||
@ -380,12 +384,11 @@ public class Base {
|
||||
} else if (parser.isInstallLibrary()) {
|
||||
LibrariesIndexer indexer = new LibrariesIndexer(BaseNoGui.getSettingsFolder(), new ContributionsIndexer(BaseNoGui.getSettingsFolder(), BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier()));
|
||||
ProgressListener progressListener = new ConsoleProgressListener();
|
||||
LibraryInstaller installer = new LibraryInstaller(indexer, BaseNoGui.getPlatform());
|
||||
indexer.parseIndex();
|
||||
BaseNoGui.onBoardOrPortChange();
|
||||
indexer.setSketchbookLibrariesFolder(BaseNoGui.getSketchbookLibrariesFolder());
|
||||
indexer.setLibrariesFolders(BaseNoGui.getLibrariesPath());
|
||||
installer.updateIndex(progressListener);
|
||||
libraryInstaller.updateIndex(progressListener);
|
||||
|
||||
for (String library : parser.getLibraryToInstall().split(",")) {
|
||||
String[] libraryToInstallParts = library.split(":");
|
||||
@ -407,9 +410,9 @@ public class Base {
|
||||
|
||||
ContributedLibrary installed = indexer.getIndex().getInstalled(libraryToInstallParts[0]);
|
||||
if (selected.isReadOnly()) {
|
||||
installer.remove(installed, progressListener);
|
||||
libraryInstaller.remove(installed, progressListener);
|
||||
} else {
|
||||
installer.install(selected, installed, progressListener);
|
||||
libraryInstaller.install(selected, installed, progressListener);
|
||||
}
|
||||
}
|
||||
|
||||
@ -464,8 +467,6 @@ public class Base {
|
||||
new Thread(new BuiltInCoreIsNewerCheck(this)).start();
|
||||
|
||||
selfCheckTimer = new Timer(false);
|
||||
ContributionInstaller contributionInstaller = new ContributionInstaller(BaseNoGui.indexer, BaseNoGui.getPlatform(), new GPGDetachedSignatureVerifier());
|
||||
LibraryInstaller libraryInstaller = new LibraryInstaller(BaseNoGui.librariesIndexer, BaseNoGui.getPlatform());
|
||||
selfCheckTimer.schedule(new ContributionsSelfCheck(this, new UpdatableBoardsLibsFakeURLsHandler(this), BaseNoGui.indexer, contributionInstaller, BaseNoGui.librariesIndexer, libraryInstaller), Constants.BOARDS_LIBS_UPDATABLE_CHECK_START_PERIOD);
|
||||
|
||||
} else if (parser.isNoOpMode()) {
|
||||
@ -682,13 +683,6 @@ public class Base {
|
||||
"jul", "aug", "sep", "oct", "nov", "dec"
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle creating a sketch folder, return its base .pde file
|
||||
* or null if the operation was canceled.
|
||||
*
|
||||
* @param shift whether shift is pressed, which will invert prompt setting
|
||||
* @param noPrompt disable prompt, no matter the setting
|
||||
*/
|
||||
protected File createNewUntitled() throws IOException {
|
||||
File newbieDir = null;
|
||||
String newbieName = null;
|
||||
@ -791,20 +785,13 @@ public class Base {
|
||||
activeEditor.handleOpenInternal(file);
|
||||
activeEditor.untitled = true;
|
||||
}
|
||||
// return true;
|
||||
|
||||
} catch (IOException e) {
|
||||
activeEditor.statusError(e);
|
||||
// return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Open a sketch, replacing the sketch in the current window.
|
||||
*
|
||||
* @param path Location of the primary pde file for the sketch.
|
||||
*/
|
||||
public void handleOpenReplace(File file) {
|
||||
if (!activeEditor.checkModified()) {
|
||||
return; // sketch was modified, and user canceled
|
||||
@ -1245,21 +1232,21 @@ public class Base {
|
||||
selfCheckTimer.cancel();
|
||||
}
|
||||
@SuppressWarnings("serial")
|
||||
LibraryManagerUI managerUI = new LibraryManagerUI(activeEditor, BaseNoGui.getPlatform()) {
|
||||
LibraryManagerUI managerUI = new LibraryManagerUI(activeEditor, BaseNoGui.librariesIndexer, libraryInstaller) {
|
||||
@Override
|
||||
protected void onIndexesUpdated() throws Exception {
|
||||
BaseNoGui.initPackages();
|
||||
rebuildBoardsMenu();
|
||||
rebuildProgrammerMenu();
|
||||
onBoardOrPortChange();
|
||||
setIndexer(BaseNoGui.librariesIndexer);
|
||||
updateUI();
|
||||
if (StringUtils.isNotEmpty(dropdownItem)) {
|
||||
selectDropdownItemByClassName(dropdownItem);
|
||||
}
|
||||
}
|
||||
};
|
||||
managerUI.setLocationRelativeTo(activeEditor);
|
||||
managerUI.setIndexer(BaseNoGui.librariesIndexer);
|
||||
managerUI.updateUI();
|
||||
managerUI.setVisible(true);
|
||||
// Manager dialog is modal, waits here until closed
|
||||
|
||||
@ -1274,13 +1261,13 @@ public class Base {
|
||||
selfCheckTimer.cancel();
|
||||
}
|
||||
@SuppressWarnings("serial")
|
||||
ContributionManagerUI managerUI = new ContributionManagerUI(activeEditor, BaseNoGui.getPlatform()) {
|
||||
ContributionManagerUI managerUI = new ContributionManagerUI(activeEditor, BaseNoGui.indexer, contributionInstaller) {
|
||||
@Override
|
||||
protected void onIndexesUpdated() throws Exception {
|
||||
BaseNoGui.initPackages();
|
||||
rebuildBoardsMenu();
|
||||
rebuildProgrammerMenu();
|
||||
setIndexer(BaseNoGui.indexer);
|
||||
updateUI();
|
||||
if (StringUtils.isNotEmpty(dropdownItem)) {
|
||||
selectDropdownItemByClassName(dropdownItem);
|
||||
}
|
||||
@ -1290,7 +1277,7 @@ public class Base {
|
||||
}
|
||||
};
|
||||
managerUI.setLocationRelativeTo(activeEditor);
|
||||
managerUI.setIndexer(BaseNoGui.indexer);
|
||||
managerUI.updateUI();
|
||||
managerUI.setVisible(true);
|
||||
// Installer dialog is modal, waits here until closed
|
||||
|
||||
|
@ -47,6 +47,9 @@ public class Constants {
|
||||
public static final long BOARDS_LIBS_UPDATABLE_CHECK_START_PERIOD = 60000;
|
||||
public static final int NOTIFICATION_POPUP_AUTOCLOSE_DELAY = 10000;
|
||||
|
||||
public static final String LIBRARY_INDEX_URL;
|
||||
public static final String LIBRARY_INDEX_URL_GZ;
|
||||
|
||||
static {
|
||||
String extenalPackageIndexUrl = System.getProperty("PACKAGE_INDEX_URL");
|
||||
if (extenalPackageIndexUrl != null && !"".equals(extenalPackageIndexUrl)) {
|
||||
@ -54,6 +57,14 @@ public class Constants {
|
||||
} else {
|
||||
PACKAGE_INDEX_URL = "http://downloads.arduino.cc/packages/package_index.json";
|
||||
}
|
||||
|
||||
String externalLibraryIndexUrl = System.getProperty("LIBRARY_INDEX_URL");
|
||||
if (externalLibraryIndexUrl != null && !"".equals(externalLibraryIndexUrl)) {
|
||||
LIBRARY_INDEX_URL = externalLibraryIndexUrl;
|
||||
} else {
|
||||
LIBRARY_INDEX_URL = "http://downloads.arduino.cc/libraries/library_index.json";
|
||||
}
|
||||
LIBRARY_INDEX_URL_GZ = "http://downloads.arduino.cc/libraries/library_index.json.gz";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
package cc.arduino.contributions.libraries;
|
||||
|
||||
import cc.arduino.Constants;
|
||||
import cc.arduino.contributions.DownloadableContributionsDownloader;
|
||||
import cc.arduino.contributions.GZippedJsonDownloader;
|
||||
import cc.arduino.contributions.ProgressListener;
|
||||
@ -46,19 +47,6 @@ import static processing.app.I18n.tr;
|
||||
|
||||
public class LibraryInstaller {
|
||||
|
||||
private static final String LIBRARY_INDEX_URL;
|
||||
private static final String LIBRARY_INDEX_URL_GZ;
|
||||
|
||||
static {
|
||||
String externalLibraryIndexUrl = System.getProperty("LIBRARY_INDEX_URL");
|
||||
if (externalLibraryIndexUrl != null && !"".equals(externalLibraryIndexUrl)) {
|
||||
LIBRARY_INDEX_URL = externalLibraryIndexUrl;
|
||||
} else {
|
||||
LIBRARY_INDEX_URL = "http://downloads.arduino.cc/libraries/library_index.json";
|
||||
}
|
||||
LIBRARY_INDEX_URL_GZ = "http://downloads.arduino.cc/libraries/library_index.json.gz";
|
||||
}
|
||||
|
||||
private final LibrariesIndexer indexer;
|
||||
private final DownloadableContributionsDownloader downloader;
|
||||
private final Platform platform;
|
||||
@ -70,14 +58,14 @@ public class LibraryInstaller {
|
||||
downloader = new DownloadableContributionsDownloader(stagingFolder);
|
||||
}
|
||||
|
||||
public void updateIndex(ProgressListener progressListener) throws Exception {
|
||||
public synchronized void updateIndex(ProgressListener progressListener) throws Exception {
|
||||
final MultiStepProgress progress = new MultiStepProgress(2);
|
||||
|
||||
// Step 1: Download index
|
||||
File outputFile = indexer.getIndexFile();
|
||||
File tmpFile = new File(outputFile.getAbsolutePath() + ".tmp");
|
||||
try {
|
||||
GZippedJsonDownloader gZippedJsonDownloader = new GZippedJsonDownloader(downloader, new URL(LIBRARY_INDEX_URL), new URL(LIBRARY_INDEX_URL_GZ));
|
||||
GZippedJsonDownloader gZippedJsonDownloader = new GZippedJsonDownloader(downloader, new URL(Constants.LIBRARY_INDEX_URL), new URL(Constants.LIBRARY_INDEX_URL_GZ));
|
||||
gZippedJsonDownloader.download(tmpFile, progress, tr("Downloading libraries index..."), progressListener);
|
||||
} catch (InterruptedException e) {
|
||||
// Download interrupted... just exit
|
||||
@ -97,7 +85,7 @@ public class LibraryInstaller {
|
||||
rescanLibraryIndex(progress, progressListener);
|
||||
}
|
||||
|
||||
public void install(ContributedLibrary lib, ContributedLibrary replacedLib, ProgressListener progressListener) throws Exception {
|
||||
public synchronized void install(ContributedLibrary lib, ContributedLibrary replacedLib, ProgressListener progressListener) throws Exception {
|
||||
if (lib.isInstalled()) {
|
||||
System.out.println(I18n.format(tr("Library is already installed: {0} version {1}"), lib.getName(), lib.getParsedVersion()));
|
||||
return;
|
||||
@ -141,7 +129,7 @@ public class LibraryInstaller {
|
||||
rescanLibraryIndex(progress, progressListener);
|
||||
}
|
||||
|
||||
public void remove(ContributedLibrary lib, ProgressListener progressListener) throws IOException {
|
||||
public synchronized void remove(ContributedLibrary lib, ProgressListener progressListener) throws IOException {
|
||||
if (lib == null || lib.isReadOnly()) {
|
||||
return;
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public class ContributionInstaller {
|
||||
downloader = new DownloadableContributionsDownloader(stagingFolder);
|
||||
}
|
||||
|
||||
public List<String> install(ContributedPlatform contributedPlatform, ProgressListener progressListener) throws Exception {
|
||||
public synchronized List<String> install(ContributedPlatform contributedPlatform, ProgressListener progressListener) throws Exception {
|
||||
List<String> errors = new LinkedList<>();
|
||||
if (contributedPlatform.isInstalled()) {
|
||||
throw new Exception("Platform is already installed!");
|
||||
@ -229,7 +229,7 @@ public class ContributionInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> remove(ContributedPlatform contributedPlatform) {
|
||||
public synchronized List<String> remove(ContributedPlatform contributedPlatform) {
|
||||
if (contributedPlatform == null || contributedPlatform.isReadOnly()) {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
@ -269,7 +269,7 @@ public class ContributionInstaller {
|
||||
return errors;
|
||||
}
|
||||
|
||||
public List<String> updateIndex(ProgressListener progressListener) throws Exception {
|
||||
public synchronized List<String> updateIndex(ProgressListener progressListener) throws Exception {
|
||||
MultiStepProgress progress = new MultiStepProgress(1);
|
||||
|
||||
List<String> downloadedPackageIndexFilesAccumulator = new LinkedList<>();
|
||||
@ -323,7 +323,7 @@ public class ContributionInstaller {
|
||||
return outputFile;
|
||||
}
|
||||
|
||||
public void deleteUnknownFiles(List<String> downloadedPackageIndexFiles) throws IOException {
|
||||
public synchronized void deleteUnknownFiles(List<String> downloadedPackageIndexFiles) throws IOException {
|
||||
File preferencesFolder = indexer.getIndexFile(".").getParentFile();
|
||||
File[] additionalPackageIndexFiles = preferencesFolder.listFiles(new PackageIndexFilenameFilter(Constants.DEFAULT_INDEX_FILE_NAME));
|
||||
if (additionalPackageIndexFiles == null) {
|
||||
|
Loading…
Reference in New Issue
Block a user