1
0
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:
Federico Fissore 2015-08-04 11:35:29 +02:00
parent dc93bb93d0
commit 2daf330c09
6 changed files with 50 additions and 74 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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";
}
}

View File

@ -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;
}

View File

@ -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) {