diff --git a/app/lib/java-semver-0.8.0.jar b/app/lib/java-semver-0.8.0.jar new file mode 100644 index 000000000..967f0d154 Binary files /dev/null and b/app/lib/java-semver-0.8.0.jar differ diff --git a/app/lib/java-semver.LICENSE.MIT.txt b/app/lib/java-semver.LICENSE.MIT.txt new file mode 100644 index 000000000..e69de29bb diff --git a/app/src/cc/arduino/contributions/libraries/filters/BuiltInPredicate.java b/app/src/cc/arduino/contributions/libraries/filters/BuiltInPredicate.java deleted file mode 100644 index f9c816462..000000000 --- a/app/src/cc/arduino/contributions/libraries/filters/BuiltInPredicate.java +++ /dev/null @@ -1,17 +0,0 @@ -package cc.arduino.contributions.libraries.filters; - -import cc.arduino.contributions.libraries.ContributedLibrary; -import com.google.common.base.Predicate; - -public class BuiltInPredicate implements Predicate { - - @Override - public boolean apply(ContributedLibrary input) { - return input.isReadOnly(); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof BuiltInPredicate; - } -} diff --git a/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCell.java b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCell.java index 35bdf6558..15c03c06d 100644 --- a/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCell.java +++ b/app/src/cc/arduino/contributions/libraries/ui/ContributedLibraryTableCell.java @@ -29,15 +29,16 @@ package cc.arduino.contributions.libraries.ui; import cc.arduino.contributions.VersionComparator; +import cc.arduino.contributions.VersionHelper; import cc.arduino.contributions.filters.InstalledPredicate; import cc.arduino.contributions.libraries.ContributedLibrary; import cc.arduino.contributions.libraries.ContributedLibraryComparator; -import cc.arduino.contributions.libraries.filters.BuiltInPredicate; -import cc.arduino.contributions.libraries.filters.InstalledLibraryPredicate; +import cc.arduino.contributions.filters.BuiltInPredicate; import cc.arduino.contributions.libraries.filters.OnlyUpstreamReleasePredicate; import cc.arduino.contributions.ui.InstallerTableCell; import cc.arduino.contributions.ui.listeners.DelegatingKeyListener; import cc.arduino.utils.ReverseComparator; +import com.github.zafarkhaja.semver.Version; import com.google.common.base.Function; import com.google.common.base.Predicates; import com.google.common.collect.Collections2; @@ -66,7 +67,6 @@ import static processing.app.I18n.format; @SuppressWarnings("serial") public class ContributedLibraryTableCell extends InstallerTableCell { - private final LibraryManagerUI indexer; private JPanel panel; private JButton installButton; private Component installButtonPlaceholder; @@ -77,9 +77,7 @@ public class ContributedLibraryTableCell extends InstallerTableCell { private JPanel inactiveButtonsPanel; private JLabel statusLabel; - public ContributedLibraryTableCell(LibraryManagerUI indexer) { - this.indexer = indexer; - + public ContributedLibraryTableCell() { { installButton = new JButton(_("Install")); installButton.addActionListener(new ActionListener() { @@ -359,7 +357,7 @@ public class ContributedLibraryTableCell extends InstallerTableCell { // ...version. if (installed != null) { - String installedVer = installed.getVersion(); + Version installedVer = VersionHelper.valueOf(installed.getVersion()); if (installedVer == null) { desc += " " + _("Version unknown"); } else { diff --git a/app/src/cc/arduino/contributions/libraries/ui/DropdownBuiltInLibrariesItem.java b/app/src/cc/arduino/contributions/libraries/ui/DropdownBuiltInLibrariesItem.java index ef5181b60..0c10e62d6 100644 --- a/app/src/cc/arduino/contributions/libraries/ui/DropdownBuiltInLibrariesItem.java +++ b/app/src/cc/arduino/contributions/libraries/ui/DropdownBuiltInLibrariesItem.java @@ -1,20 +1,20 @@ package cc.arduino.contributions.libraries.ui; -import cc.arduino.contributions.libraries.ContributedLibrary; -import cc.arduino.contributions.libraries.filters.BuiltInPredicate; +import cc.arduino.contributions.filters.BuiltInPredicate; +import cc.arduino.contributions.packages.DownloadableContribution; import cc.arduino.contributions.ui.DropdownItem; import com.google.common.base.Predicate; import static processing.app.I18n._; -public class DropdownBuiltInLibrariesItem implements DropdownItem { +public class DropdownBuiltInLibrariesItem implements DropdownItem { public String toString() { return _("Built-in"); } @Override - public Predicate getFilterPredicate() { + public Predicate getFilterPredicate() { return new BuiltInPredicate(); } } diff --git a/app/src/cc/arduino/contributions/libraries/ui/LibrariesIndexTableModel.java b/app/src/cc/arduino/contributions/libraries/ui/LibrariesIndexTableModel.java index 384e1cedc..2ad94c7e7 100644 --- a/app/src/cc/arduino/contributions/libraries/ui/LibrariesIndexTableModel.java +++ b/app/src/cc/arduino/contributions/libraries/ui/LibrariesIndexTableModel.java @@ -28,16 +28,22 @@ */ package cc.arduino.contributions.libraries.ui; -import cc.arduino.contributions.VersionComparator; +import cc.arduino.contributions.DownloadableContributionBuiltInAtTheBottomComparator; +import cc.arduino.contributions.VersionHelper; +import cc.arduino.contributions.filters.InstalledPredicate; import cc.arduino.contributions.libraries.ContributedLibrary; import cc.arduino.contributions.libraries.LibrariesIndexer; import cc.arduino.contributions.packages.ContributedPlatform; import cc.arduino.contributions.ui.FilteredAbstractTableModel; +import com.github.zafarkhaja.semver.Version; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.Collections2; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; @SuppressWarnings("serial") public class LibrariesIndexTableModel extends FilteredAbstractTableModel { @@ -45,13 +51,18 @@ public class LibrariesIndexTableModel extends FilteredAbstractTableModel { + public final String name; - public final List releases = new ArrayList(); - public final List versions = new ArrayList(); - public ContributedLibrary selected = null; + public final List releases; + public final List versions; + + public ContributedLibrary selected; public ContributedLibraryReleases(ContributedLibrary library) { - name = library.getName(); + this.name = library.getName(); + this.versions = new LinkedList(); + this.releases = new LinkedList(); + this.selected = null; add(library); } @@ -61,40 +72,28 @@ public class LibrariesIndexTableModel extends FilteredAbstractTableModel installedReleases = new LinkedList(Collections2.filter(releases, new Predicate() { - @Override - public boolean apply(ContributedLibrary contributedLibrary) { - return contributedLibrary.isInstalled(); - } - })); + List installedReleases = new LinkedList(Collections2.filter(releases, new InstalledPredicate())); + Collections.sort(installedReleases, new DownloadableContributionBuiltInAtTheBottomComparator()); - return getLatestOf(installedReleases); + if (installedReleases.isEmpty()) { + return null; + } + + return installedReleases.get(0); } public ContributedLibrary getLatest() { return getLatestOf(releases); } - private ContributedLibrary getLatestOf(List libs) { - Collections.sort(new LinkedList(libs), new Comparator() { - @Override - public int compare(ContributedLibrary lib1, ContributedLibrary lib2) { - return VersionComparator.VERSION_COMPARATOR.compare(lib1.getVersion(), lib2.getVersion()); - } - }); - - if (libs.isEmpty()) { - return null; - } - - return libs.get(libs.size() - 1); - } - public ContributedLibrary getSelected() { return selected; } @@ -223,7 +222,7 @@ public class LibrariesIndexTableModel extends FilteredAbstractTableModel getReleasesVersions(int row) { + public List getReleasesVersions(int row) { return contributions.get(row).versions; } diff --git a/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java b/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java index 39dd31e84..84ed30333 100644 --- a/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java +++ b/app/src/cc/arduino/contributions/libraries/ui/LibraryManagerUI.java @@ -61,12 +61,12 @@ public class LibraryManagerUI extends InstallerJDialog { @Override protected InstallerTableCell createCellRenderer() { - return new ContributedLibraryTableCell(this); + return new ContributedLibraryTableCell(); } @Override protected InstallerTableCell createCellEditor() { - return new ContributedLibraryTableCell(this) { + return new ContributedLibraryTableCell() { @Override protected void onInstall(ContributedLibrary selectedLibrary, ContributedLibrary installedLibrary) { if (selectedLibrary.isReadOnly()) { diff --git a/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCell.java b/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCell.java index 881f27e8d..0cb2d1796 100644 --- a/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCell.java +++ b/app/src/cc/arduino/contributions/packages/ui/ContributedPlatformTableCell.java @@ -29,7 +29,9 @@ package cc.arduino.contributions.packages.ui; import cc.arduino.contributions.VersionComparator; +import cc.arduino.contributions.VersionHelper; import cc.arduino.contributions.filters.InstalledPredicate; +import cc.arduino.contributions.filters.BuiltInPredicate; import cc.arduino.contributions.packages.ContributedBoard; import cc.arduino.contributions.packages.ContributedPlatform; import cc.arduino.contributions.packages.ContributedPlatformComparator; @@ -263,7 +265,7 @@ public class ContributedPlatformTableCell extends InstallerTableCell { java.util.List releases = new LinkedList(editorValue.releases); java.util.List uninstalledReleases = new LinkedList(Collections2.filter(releases, Predicates.not(new InstalledPredicate()))); - java.util.List installedBuiltIn = new LinkedList(); + java.util.List installedBuiltIn = new LinkedList(Collections2.filter(releases, Predicates.and(new InstalledPredicate(), new BuiltInPredicate()))); if (installed != null && !installedBuiltIn.contains(installed)) { uninstalledReleases.addAll(installedBuiltIn); @@ -330,8 +332,7 @@ public class ContributedPlatformTableCell extends InstallerTableCell { upgradable = false; } else { installable = false; - //removable = !installed.isReadOnly() && !hasBuiltInRelease; - removable = !hasBuiltInRelease; + removable = !installed.isReadOnly() && !hasBuiltInRelease; upgradable = new ContributedPlatformComparator().compare(selected, installed) > 0; } if (installable) { @@ -352,17 +353,18 @@ public class ContributedPlatformTableCell extends InstallerTableCell { if (author != null && !author.isEmpty()) { desc += " " + format("by {0}", author); } - if (removable) { - desc += " " + format(_("version {0}"), installed.getVersion()) + " INSTALLED"; + if (installed != null) { + desc += " " + format(_("version {0}"), VersionHelper.valueOf(installed.getVersion())) + " INSTALLED"; } desc += "
"; desc += _("Boards included in this package:") + "
"; - for (ContributedBoard board : selected.getBoards()) - desc += format("{0}, ", board.getName()); + for (ContributedBoard board : selected.getBoards()) { + desc += board.getName() + ", "; + } desc = desc.substring(0, desc.lastIndexOf(',')) + ".
"; - if (author != null && !author.isEmpty()) { + if (url != null && !url.isEmpty()) { desc += " " + format("More info", url); } diff --git a/app/src/cc/arduino/contributions/packages/ui/ContributionIndexTableModel.java b/app/src/cc/arduino/contributions/packages/ui/ContributionIndexTableModel.java index ca364be06..06089f6eb 100644 --- a/app/src/cc/arduino/contributions/packages/ui/ContributionIndexTableModel.java +++ b/app/src/cc/arduino/contributions/packages/ui/ContributionIndexTableModel.java @@ -28,34 +28,40 @@ */ package cc.arduino.contributions.packages.ui; +import cc.arduino.contributions.DownloadableContributionBuiltInAtTheBottomComparator; +import cc.arduino.contributions.VersionHelper; +import cc.arduino.contributions.filters.InstalledPredicate; import cc.arduino.contributions.packages.ContributedPackage; import cc.arduino.contributions.packages.ContributedPlatform; import cc.arduino.contributions.packages.ContributionsIndex; import cc.arduino.contributions.ui.FilteredAbstractTableModel; +import com.github.zafarkhaja.semver.Version; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import com.google.common.collect.Collections2; import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedList; import java.util.List; -import static processing.app.I18n._; - @SuppressWarnings("serial") public class ContributionIndexTableModel extends FilteredAbstractTableModel { public final static int DESCRIPTION_COL = 0; public static class ContributedPlatformReleases { - public ContributedPackage packager; - public String arch; - public List releases = new ArrayList(); - public List versions = new ArrayList(); + public final ContributedPackage packager; + public final String arch; + public final List releases; + public final List versions; public ContributedPlatform selected = null; public ContributedPlatformReleases(ContributedPlatform platform) { - packager = platform.getParentPackage(); - arch = platform.getArchitecture(); + this.packager = platform.getParentPackage(); + this.arch = platform.getArchitecture(); + this.releases = new LinkedList(); + this.versions = new LinkedList(); add(platform); } @@ -67,39 +73,26 @@ public class ContributionIndexTableModel extends FilteredAbstractTableModel installedPlatforms = new LinkedList(); - for (ContributedPlatform platform : releases) { - if (platform.isInstalled()) { - installedPlatforms.add(platform); - } + List installedReleases = new LinkedList(Collections2.filter(releases, new InstalledPredicate())); + Collections.sort(installedReleases, new DownloadableContributionBuiltInAtTheBottomComparator()); + + if (installedReleases.isEmpty()) { + return null; } - if (installedPlatforms.size() > 1) { - throw new IllegalStateException(_("More than one platform is currently installed! Only one can be installed at any given time")); - } - - if (!installedPlatforms.isEmpty()) { - return installedPlatforms.get(0); - } - - return null; + return installedReleases.get(0); } public ContributedPlatform getLatest() { - ContributedPlatform latest = null; - for (ContributedPlatform plat : releases) { - if (latest == null) - latest = plat; - // TODO a better version compare - if (plat.getVersion().compareTo(latest.getVersion()) > 0) - latest = plat; - } - return latest; + return getLatestOf(releases); } public ContributedPlatform getSelected() { @@ -224,7 +217,7 @@ public class ContributionIndexTableModel extends FilteredAbstractTableModel getReleasesVersions(int row) { + public List getReleasesVersions(int row) { return contributions.get(row).versions; } diff --git a/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java b/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java index fafc67a5c..e003a7a19 100644 --- a/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java +++ b/app/src/cc/arduino/contributions/packages/ui/ContributionManagerUI.java @@ -66,13 +66,17 @@ public class ContributionManagerUI extends InstallerJDialog { protected InstallerTableCell createCellEditor() { return new ContributedPlatformTableCell() { @Override - protected void onInstall(ContributedPlatform selectedPlatform, ContributedPlatform installed) { - onInstallPressed(selectedPlatform, installed); + protected void onInstall(ContributedPlatform selected, ContributedPlatform installed) { + if (selected.isReadOnly()) { + onRemovePressed(installed, false); + } else { + onInstallPressed(selected, installed); + } } @Override protected void onRemove(ContributedPlatform installedPlatform) { - onRemovePressed(installedPlatform); + onRemovePressed(installedPlatform, true); } }; } @@ -157,7 +161,7 @@ public class ContributionManagerUI extends InstallerJDialog { try { setProgressVisible(true, _("Installing...")); installer.install(platformToInstall); - if (platformToRemove != null) { + if (platformToRemove != null && !platformToRemove.isReadOnly()) { installer.remove(platformToRemove); } onIndexesUpdated(); @@ -172,12 +176,14 @@ public class ContributionManagerUI extends InstallerJDialog { installerThread.start(); } - public void onRemovePressed(final ContributedPlatform platform) { + public void onRemovePressed(final ContributedPlatform platform, boolean showWarning) { clearErrorMessage(); - int chosenOption = JOptionPane.showConfirmDialog(getParent(), I18n.format(_("Do you want to remove {0}?\nIf you do so you won't be able to use {0} any more."), platform.getName()), _("Please confirm boards deletion"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); - if (chosenOption != JOptionPane.YES_OPTION) { - return; + if (showWarning) { + int chosenOption = JOptionPane.showConfirmDialog(getParent(), I18n.format(_("Do you want to remove {0}?\nIf you do so you won't be able to use {0} any more."), platform.getName()), _("Please confirm boards deletion"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + if (chosenOption != JOptionPane.YES_OPTION) { + return; + } } installerThread = new Thread(new Runnable() { diff --git a/app/src/cc/arduino/contributions/ui/FilteredAbstractTableModel.java b/app/src/cc/arduino/contributions/ui/FilteredAbstractTableModel.java index e09cfb2a7..05999ad37 100644 --- a/app/src/cc/arduino/contributions/ui/FilteredAbstractTableModel.java +++ b/app/src/cc/arduino/contributions/ui/FilteredAbstractTableModel.java @@ -28,12 +28,34 @@ */ package cc.arduino.contributions.ui; +import cc.arduino.contributions.VersionComparator; +import cc.arduino.contributions.packages.DownloadableContribution; import com.google.common.base.Predicate; import javax.swing.table.AbstractTableModel; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; public abstract class FilteredAbstractTableModel extends AbstractTableModel { abstract public void updateIndexFilter(String[] filters, Predicate... additionalFilters); + protected static T getLatestOf(List contribs) { + contribs = new LinkedList(contribs); + Collections.sort(contribs, new Comparator() { + @Override + public int compare(T contrib1, T contrib2) { + return VersionComparator.VERSION_COMPARATOR.compare(contrib1.getVersion(), contrib2.getVersion()); + } + }); + + if (contribs.isEmpty()) { + return null; + } + + return contribs.get(contribs.size() - 1); + } + } diff --git a/app/src/processing/app/debug/TargetPackageStub.java b/app/src/processing/app/debug/TargetPackageStub.java index b3dcd1d0e..d564a9e4e 100644 --- a/app/src/processing/app/debug/TargetPackageStub.java +++ b/app/src/processing/app/debug/TargetPackageStub.java @@ -30,4 +30,9 @@ public class TargetPackageStub implements TargetPackage { public TargetPlatform get(String platform) { return null; } + + @Override + public boolean hasPlatform(TargetPlatform platform) { + return false; + } } diff --git a/app/test/cc/arduino/packages/contributions/HostDependentDownloadableContributionStub.java b/app/test/cc/arduino/packages/contributions/HostDependentDownloadableContributionStub.java index 3178e00f1..effa9f31b 100644 --- a/app/test/cc/arduino/packages/contributions/HostDependentDownloadableContributionStub.java +++ b/app/test/cc/arduino/packages/contributions/HostDependentDownloadableContributionStub.java @@ -3,6 +3,12 @@ package cc.arduino.packages.contributions; import cc.arduino.contributions.packages.HostDependentDownloadableContribution; public class HostDependentDownloadableContributionStub extends HostDependentDownloadableContribution { + + @Override + public String getVersion() { + return null; + } + @Override public String getHost() { return null; diff --git a/arduino-core/src/cc/arduino/contributions/DownloadableContributionBuiltInAtTheBottomComparator.java b/arduino-core/src/cc/arduino/contributions/DownloadableContributionBuiltInAtTheBottomComparator.java new file mode 100644 index 000000000..8c9d8e61d --- /dev/null +++ b/arduino-core/src/cc/arduino/contributions/DownloadableContributionBuiltInAtTheBottomComparator.java @@ -0,0 +1,16 @@ +package cc.arduino.contributions; + +import cc.arduino.contributions.packages.DownloadableContribution; + +import java.util.Comparator; + +public class DownloadableContributionBuiltInAtTheBottomComparator implements Comparator { + @Override + public int compare(DownloadableContribution p1, DownloadableContribution p2) { + if (p1.isReadOnly() == p2.isReadOnly()) { + return 0; + } + + return p1.isReadOnly() ? 1 : -1; + } +} diff --git a/arduino-core/src/cc/arduino/contributions/VersionComparator.java b/arduino-core/src/cc/arduino/contributions/VersionComparator.java index 156f078e8..a1f0961b5 100644 --- a/arduino-core/src/cc/arduino/contributions/VersionComparator.java +++ b/arduino-core/src/cc/arduino/contributions/VersionComparator.java @@ -47,8 +47,8 @@ public class VersionComparator implements Comparator { if (b == null) return 1; - Version versionA = valueOf(a); - Version versionB = valueOf(b); + Version versionA = VersionHelper.valueOf(a); + Version versionB = VersionHelper.valueOf(b); return versionA.compareTo(versionB); } @@ -65,26 +65,10 @@ public class VersionComparator implements Comparator { return true; } - Version versionA = valueOf(a); - Version versionB = valueOf(b); + Version versionA = VersionHelper.valueOf(a); + Version versionB = VersionHelper.valueOf(b); return versionA.greaterThan(versionB); } - private Version valueOf(String ver) { - if (ver.endsWith("b")) { - ver = ver.substring(0, ver.lastIndexOf("b")) + ".1"; - } - String[] verParts = ver.split("\\."); - if (verParts.length < 3) { - if (verParts.length == 2) { - return Version.forIntegers(Integer.valueOf(verParts[0]), Integer.valueOf(verParts[1])); - } else { - return Version.forIntegers(Integer.valueOf(verParts[0])); - } - } else { - return Version.valueOf(ver); - } - } - } diff --git a/arduino-core/src/cc/arduino/contributions/VersionHelper.java b/arduino-core/src/cc/arduino/contributions/VersionHelper.java new file mode 100644 index 000000000..10d64af84 --- /dev/null +++ b/arduino-core/src/cc/arduino/contributions/VersionHelper.java @@ -0,0 +1,23 @@ +package cc.arduino.contributions; + +import com.github.zafarkhaja.semver.Version; + +public class VersionHelper { + + public static Version valueOf(String ver) { + if (ver == null) { + return null; + } + String[] verParts = ver.split("\\."); + if (verParts.length < 3) { + if (verParts.length == 2) { + return Version.forIntegers(Integer.valueOf(verParts[0]), Integer.valueOf(verParts[1])); + } else { + return Version.forIntegers(Integer.valueOf(verParts[0])); + } + } else { + return Version.valueOf(ver); + } + } + +} diff --git a/arduino-core/src/cc/arduino/contributions/filters/BuiltInPredicate.java b/arduino-core/src/cc/arduino/contributions/filters/BuiltInPredicate.java new file mode 100644 index 000000000..76962079d --- /dev/null +++ b/arduino-core/src/cc/arduino/contributions/filters/BuiltInPredicate.java @@ -0,0 +1,17 @@ +package cc.arduino.contributions.filters; + +import cc.arduino.contributions.packages.DownloadableContribution; +import com.google.common.base.Predicate; + +public class BuiltInPredicate implements Predicate { + + @Override + public boolean apply(DownloadableContribution input) { + return input.isReadOnly(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof BuiltInPredicate; + } +} diff --git a/app/src/cc/arduino/contributions/filters/InstalledPredicate.java b/arduino-core/src/cc/arduino/contributions/filters/InstalledPredicate.java similarity index 100% rename from app/src/cc/arduino/contributions/filters/InstalledPredicate.java rename to arduino-core/src/cc/arduino/contributions/filters/InstalledPredicate.java diff --git a/arduino-core/src/cc/arduino/contributions/libraries/ContributedLibrary.java b/arduino-core/src/cc/arduino/contributions/libraries/ContributedLibrary.java index b67329762..bec9873e1 100644 --- a/arduino-core/src/cc/arduino/contributions/libraries/ContributedLibrary.java +++ b/arduino-core/src/cc/arduino/contributions/libraries/ContributedLibrary.java @@ -40,8 +40,6 @@ public abstract class ContributedLibrary extends DownloadableContribution { public abstract String getName(); - public abstract String getVersion(); - public abstract String getMaintainer(); public abstract String getAuthor(); @@ -64,16 +62,6 @@ public abstract class ContributedLibrary extends DownloadableContribution { public abstract List getRequires(); - private boolean readOnly; - - public boolean isReadOnly() { - return readOnly; - } - - public void setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - } - public static final Comparator CASE_INSENSITIVE_ORDER = new Comparator() { @Override public int compare(ContributedLibrary o1, ContributedLibrary o2) { diff --git a/arduino-core/src/cc/arduino/contributions/packages/ContributedPlatform.java b/arduino-core/src/cc/arduino/contributions/packages/ContributedPlatform.java index f790bb064..ce8460d70 100644 --- a/arduino-core/src/cc/arduino/contributions/packages/ContributedPlatform.java +++ b/arduino-core/src/cc/arduino/contributions/packages/ContributedPlatform.java @@ -37,8 +37,6 @@ public abstract class ContributedPlatform extends DownloadableContribution { public abstract String getName(); - public abstract String getVersion(); - public abstract String getCategory(); public abstract String getArchitecture(); diff --git a/arduino-core/src/cc/arduino/contributions/packages/ContributedTargetPackage.java b/arduino-core/src/cc/arduino/contributions/packages/ContributedTargetPackage.java index a04c5d79f..1a481a5a2 100644 --- a/arduino-core/src/cc/arduino/contributions/packages/ContributedTargetPackage.java +++ b/arduino-core/src/cc/arduino/contributions/packages/ContributedTargetPackage.java @@ -73,6 +73,11 @@ public class ContributedTargetPackage implements TargetPackage { return platforms.get(platform); } + @Override + public boolean hasPlatform(TargetPlatform platform) { + return platforms.containsKey(platform.getId()); + } + @Override public String toString() { return "TargetPackage: " + getId(); diff --git a/arduino-core/src/cc/arduino/contributions/packages/ContributionsIndexer.java b/arduino-core/src/cc/arduino/contributions/packages/ContributionsIndexer.java index a5a069c0f..6e7326162 100644 --- a/arduino-core/src/cc/arduino/contributions/packages/ContributionsIndexer.java +++ b/arduino-core/src/cc/arduino/contributions/packages/ContributionsIndexer.java @@ -28,21 +28,27 @@ */ package cc.arduino.contributions.packages; +import cc.arduino.contributions.DownloadableContributionBuiltInAtTheBottomComparator; +import cc.arduino.contributions.filters.BuiltInPredicate; +import cc.arduino.contributions.filters.InstalledPredicate; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.module.mrbean.MrBeanModule; +import com.google.common.base.Function; +import com.google.common.base.Predicates; +import com.google.common.collect.Collections2; +import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.Multimaps; import processing.app.debug.TargetPackage; import processing.app.debug.TargetPlatform; import processing.app.debug.TargetPlatformException; +import processing.app.helpers.PreferencesMap; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import static processing.app.helpers.filefilters.OnlyDirs.ONLY_DIRS; @@ -102,7 +108,47 @@ public class ContributionsIndexer { index = mapper.readValue(indexIn, ContributionsIndex.class); } - public void syncWithFilesystem() { + public void syncWithFilesystem(File hardwareFolder) throws IOException { + syncBuiltInHardwareFolder(hardwareFolder); + + syncLocalPackagesFolder(); + } + + public void syncBuiltInHardwareFolder(File hardwareFolder) throws IOException { + for (File folder : hardwareFolder.listFiles(ONLY_DIRS)) { + ContributedPackage pack = index.findPackage(folder.getName()); + if (pack != null) { + syncBuiltInPackageWithFilesystem(pack, folder); + + File toolsFolder = new File(hardwareFolder, "tools"); + if (toolsFolder.isDirectory()) { + for (File toolFolder : toolsFolder.listFiles(ONLY_DIRS)) { + File builtInToolsMetadata = new File(toolFolder, "builtin_tools_versions.txt"); + if (builtInToolsMetadata.isFile()) { + PreferencesMap toolsMetadata = new PreferencesMap(builtInToolsMetadata).subTree(pack.getName()); + for (Map.Entry toolMetadata : toolsMetadata.entrySet()) { + syncToolWithFilesystem(pack, toolFolder, toolMetadata.getKey(), toolMetadata.getValue()); + } + } + } + } + } + } + } + + private void syncBuiltInPackageWithFilesystem(ContributedPackage pack, File hardwareFolder) throws IOException { + // Scan all hardware folders and mark as installed all the tools found. + for (File platformFolder : hardwareFolder.listFiles(ONLY_DIRS)) { + File platformTxt = new File(platformFolder, "platform.txt"); + String version = new PreferencesMap(platformTxt).get("version"); + ContributedPlatform platform = syncHardwareWithFilesystem(pack, platformFolder, platformFolder.getName(), version); + if (platform != null) { + platform.setReadOnly(true); + } + } + } + + public void syncLocalPackagesFolder() { if (!packagesFolder.isDirectory()) return; @@ -110,8 +156,9 @@ public class ContributionsIndexer { // platforms found. for (File folder : packagesFolder.listFiles(ONLY_DIRS)) { ContributedPackage pack = index.findPackage(folder.getName()); - if (pack != null) + if (pack != null) { syncPackageWithFilesystem(pack, folder); + } } } @@ -120,8 +167,9 @@ public class ContributionsIndexer { File hardwareFolder = new File(root, "hardware"); if (hardwareFolder.isDirectory()) { for (File platformFolder : hardwareFolder.listFiles(ONLY_DIRS)) { - for (File versionFolder : platformFolder.listFiles(ONLY_DIRS)) - syncHardwareWithFilesystem(pack, platformFolder, versionFolder); + for (File versionFolder : platformFolder.listFiles(ONLY_DIRS)) { + syncHardwareWithFilesystem(pack, versionFolder, platformFolder.getName(), versionFolder.getName()); + } } } @@ -129,39 +177,35 @@ public class ContributionsIndexer { File toolsFolder = new File(root, "tools"); if (toolsFolder.isDirectory()) { for (File toolFolder : toolsFolder.listFiles(ONLY_DIRS)) { - for (File versionFolder : toolFolder.listFiles(ONLY_DIRS)) - syncToolWithFilesystem(pack, toolFolder, versionFolder); + for (File versionFolder : toolFolder.listFiles(ONLY_DIRS)) { + syncToolWithFilesystem(pack, versionFolder, toolFolder.getName(), versionFolder.getName()); + } } } } - private void syncToolWithFilesystem(ContributedPackage pack, File toolFolder, - File versionFolder) { - ContributedTool tool = pack.findTool(toolFolder.getName(), - versionFolder.getName()); - if (tool == null) + private void syncToolWithFilesystem(ContributedPackage pack, File installationFolder, String toolName, String version) { + ContributedTool tool = pack.findTool(toolName, version); + if (tool == null) { return; + } DownloadableContribution contrib = tool.getDownloadableContribution(); if (contrib == null) { - System.err.println(tool + - " seems to have no downloadable contributions for your " + - "operating system, but it is installed in\n" + versionFolder); + System.err.println(tool + " seems to have no downloadable contributions for your operating system, but it is installed in\n" + installationFolder); return; } contrib.setInstalled(true); - contrib.setInstalledFolder(versionFolder); + contrib.setInstalledFolder(installationFolder); } - private void syncHardwareWithFilesystem(ContributedPackage pack, - File platformFolder, - File versionFolder) { - String architecture = platformFolder.getName(); - String version = versionFolder.getName(); + private ContributedPlatform syncHardwareWithFilesystem(ContributedPackage pack, File installationFolder, String architecture, String version) { ContributedPlatform platform = pack.findPlatform(architecture, version); if (platform != null) { platform.setInstalled(true); - platform.setInstalledFolder(versionFolder); + platform.setReadOnly(false); + platform.setInstalledFolder(installationFolder); } + return platform; } @Override @@ -170,28 +214,29 @@ public class ContributionsIndexer { } public List createTargetPackages() throws TargetPlatformException { - List res = new ArrayList(); + List packages = new ArrayList(); - for (ContributedPackage pack : index.getPackages()) { - ContributedTargetPackage targetPackage; - targetPackage = new ContributedTargetPackage(pack.getName()); + for (ContributedPackage aPackage : index.getPackages()) { + ContributedTargetPackage targetPackage = new ContributedTargetPackage(aPackage.getName()); - for (ContributedPlatform platform : pack.getPlatforms()) { - if (!platform.isInstalled()) - continue; + List platforms = new LinkedList(Collections2.filter(aPackage.getPlatforms(), new InstalledPredicate())); + Collections.sort(platforms, new DownloadableContributionBuiltInAtTheBottomComparator()); + for (ContributedPlatform platform : platforms) { String arch = platform.getArchitecture(); File folder = platform.getInstalledFolder(); - TargetPlatform targetPlatform; - targetPlatform = new ContributedTargetPlatform(arch, folder, targetPackage, index); - targetPackage.addPlatform(targetPlatform); + TargetPlatform targetPlatform = new ContributedTargetPlatform(arch, folder, targetPackage, index); + if (!targetPackage.hasPlatform(targetPlatform)) { + targetPackage.addPlatform(targetPlatform); + } } - if (targetPackage.hasPlatforms()) - res.add(targetPackage); + if (targetPackage.hasPlatforms()) { + packages.add(targetPackage); + } } - return res; + return packages; } /** @@ -217,11 +262,21 @@ public class ContributionsIndexer { public Set getInstalledTools() { Set tools = new HashSet(); for (ContributedPackage pack : index.getPackages()) { - for (ContributedPlatform platform : pack.getPlatforms()) { - if (!platform.isInstalled()) - continue; - for (ContributedTool tool : platform.getResolvedTools()) { - tools.add(tool); + Collection platforms = Collections2.filter(pack.getPlatforms(), new InstalledPredicate()); + ImmutableListMultimap platformsByName = Multimaps.index(platforms, new Function() { + @Override + public String apply(ContributedPlatform contributedPlatform) { + return contributedPlatform.getName(); + } + }); + + for (Map.Entry> entry : platformsByName.asMap().entrySet()) { + Collection platformsWithName = entry.getValue(); + if (platformsWithName.size() > 1) { + platformsWithName = Collections2.filter(platformsWithName, Predicates.not(new BuiltInPredicate())); + } + for (ContributedPlatform platform : platformsWithName) { + tools.addAll(platform.getResolvedTools()); } } } diff --git a/arduino-core/src/cc/arduino/contributions/packages/DownloadableContribution.java b/arduino-core/src/cc/arduino/contributions/packages/DownloadableContribution.java index dc10306ef..79e092cd1 100644 --- a/arduino-core/src/cc/arduino/contributions/packages/DownloadableContribution.java +++ b/arduino-core/src/cc/arduino/contributions/packages/DownloadableContribution.java @@ -40,6 +40,8 @@ public abstract class DownloadableContribution { public abstract String getUrl(); + public abstract String getVersion(); + public abstract String getChecksum(); public abstract long getSize(); @@ -78,6 +80,16 @@ public abstract class DownloadableContribution { this.installedFolder = installedFolder; } + private boolean readOnly; + + public boolean isReadOnly() { + return readOnly; + } + + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + @Override public String toString() { String res = ""; diff --git a/arduino-core/src/processing/app/BaseNoGui.java b/arduino-core/src/processing/app/BaseNoGui.java index 9bd0c62de..4c6736612 100644 --- a/arduino-core/src/processing/app/BaseNoGui.java +++ b/arduino-core/src/processing/app/BaseNoGui.java @@ -578,12 +578,11 @@ public class BaseNoGui { static public void initPackages() throws Exception { indexer = new ContributionsIndexer(BaseNoGui.getSettingsFolder()); File indexFile = indexer.getIndexFile(); - File avrCoreFolder = FileUtils.newFile(indexFile.getParentFile(), "packages", "arduino", "hardware", "avr"); - if (!indexFile.isFile() || !(avrCoreFolder.exists() && avrCoreFolder.isDirectory())) { - File distFile = findDefaultPackageFile(); - if (distFile != null) { - new ArchiveExtractor(getPlatform()).extract(distFile, BaseNoGui.getSettingsFolder(), 0, true); - } else if (!indexFile.isFile()) { + if (!indexFile.isFile()) { + File defaultPackageJsonFile = new File(getContentFile("dist"), "package_index.json"); + if (defaultPackageJsonFile.isFile()) { + FileUtils.copyFile(defaultPackageJsonFile, indexFile); + } else { // Otherwise create an empty packages index FileOutputStream out = null; try { @@ -598,7 +597,7 @@ public class BaseNoGui { } } indexer.parseIndex(); - indexer.syncWithFilesystem(); + indexer.syncWithFilesystem(getHardwareFolder()); packages = new HashMap(); loadHardware(getHardwareFolder()); @@ -626,18 +625,6 @@ public class BaseNoGui { librariesIndexer.parseIndex(); } - private static File findDefaultPackageFile() { - File distFolder = getContentFile("dist"); - if (!distFolder.exists()) { - return null; - } - File[] files = distFolder.listFiles(new OnlyFilesWithExtension("tar.bz2", "zip", "tar.gz", "tar")); - if (files.length > 1) { - throw new IllegalStateException("More than one file in " + distFolder); - } - return files[0]; - } - static protected void initPlatform() { try { Class platformClass = Class.forName("processing.app.Platform"); @@ -697,7 +684,7 @@ public class BaseNoGui { try { packages.put(target, new LegacyTargetPackage(target, subfolder)); } catch (TargetPlatformException e) { - System.out.println("WARNING: Error loading hardware folder " + target); + System.out.println("WARNING: Error loading hardware folder " + new File(folder, target)); System.out.println(" " + e.getMessage()); } } @@ -777,12 +764,9 @@ public class BaseNoGui { PreferencesData.removeAllKeysWithPrefix(prefix); for (ContributedTool tool : indexer.getInstalledTools()) { - String path = tool.getDownloadableContribution().getInstalledFolder() - .getAbsolutePath(); - String toolId = tool.getName(); - PreferencesData.set(prefix + toolId + ".path", path); - toolId += "-" + tool.getVersion(); - PreferencesData.set(prefix + toolId + ".path", path); + String path = tool.getDownloadableContribution().getInstalledFolder().getAbsolutePath(); + PreferencesData.set(prefix + tool.getName() + ".path", path); + PreferencesData.set(prefix + tool.getName() + "-" + tool.getVersion() + ".path", path); } } diff --git a/arduino-core/src/processing/app/debug/LegacyTargetPackage.java b/arduino-core/src/processing/app/debug/LegacyTargetPackage.java index 8d381706c..42d6b0730 100644 --- a/arduino-core/src/processing/app/debug/LegacyTargetPackage.java +++ b/arduino-core/src/processing/app/debug/LegacyTargetPackage.java @@ -77,6 +77,11 @@ public class LegacyTargetPackage implements TargetPackage { return platforms.get(platform); } + @Override + public boolean hasPlatform(TargetPlatform platform) { + return platforms.containsKey(platform.getId()); + } + @Override public String getId() { return id; diff --git a/arduino-core/src/processing/app/debug/TargetPackage.java b/arduino-core/src/processing/app/debug/TargetPackage.java index 5644272d0..2df6880b0 100644 --- a/arduino-core/src/processing/app/debug/TargetPackage.java +++ b/arduino-core/src/processing/app/debug/TargetPackage.java @@ -25,12 +25,13 @@ import java.util.Map; public interface TargetPackage { - public String getId(); - - public Map getPlatforms(); + String getId(); - public Collection platforms(); + Map getPlatforms(); - public TargetPlatform get(String platform); - + Collection platforms(); + + TargetPlatform get(String platform); + + boolean hasPlatform(TargetPlatform platform); } diff --git a/build/build.xml b/build/build.xml index 62ad948e3..732d5d4b7 100644 --- a/build/build.xml +++ b/build/build.xml @@ -160,9 +160,10 @@ - - - + + + + @@ -348,8 +349,6 @@ - - @@ -368,33 +367,17 @@ - + - - + + - - - - - - - - - - - - - - - - @@ -629,40 +612,20 @@ - + - - - - - - - - - - - + - - - - - - - - - - @@ -875,8 +838,6 @@ - - @@ -904,20 +865,12 @@ - + - - - - - - - - - - + - - + + - + + - - + + - - - + + + + + + + + + + + + + + + + + + + + + +