diff --git a/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java b/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java index 05259cdfd..d21acdd5e 100644 --- a/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java +++ b/arduino-core/src/cc/arduino/contributions/packages/ContributionInstaller.java @@ -244,7 +244,8 @@ public class ContributionInstaller { String statusText = _("Downloading platforms index..."); URL url = new URL(PACKAGE_INDEX_URL); - File outputFile = indexer.getIndexFile(); + String[] urlPathParts = url.getFile().split("/"); + File outputFile = indexer.getIndexFile(urlPathParts[urlPathParts.length - 1]); File tmpFile = new File(outputFile.getAbsolutePath() + ".tmp"); downloader.download(url, tmpFile, progress, statusText); progress.stepDone(); diff --git a/arduino-core/src/cc/arduino/contributions/packages/ContributionsIndex.java b/arduino-core/src/cc/arduino/contributions/packages/ContributionsIndex.java index 6cb4391f6..ecb8fad64 100644 --- a/arduino-core/src/cc/arduino/contributions/packages/ContributionsIndex.java +++ b/arduino-core/src/cc/arduino/contributions/packages/ContributionsIndex.java @@ -137,10 +137,12 @@ public abstract class ContributionsIndex { } } - public ContributedPackage getPackage(String packager) { - for (ContributedPackage pack : getPackages()) - if (pack.getName().equals(packager)) + public ContributedPackage getPackage(String packageName) { + for (ContributedPackage pack : getPackages()) { + if (pack.getName().equals(packageName)) { return pack; + } + } return null; } diff --git a/arduino-core/src/cc/arduino/contributions/packages/ContributionsIndexer.java b/arduino-core/src/cc/arduino/contributions/packages/ContributionsIndexer.java index 6e7326162..a4aeb8c8f 100644 --- a/arduino-core/src/cc/arduino/contributions/packages/ContributionsIndexer.java +++ b/arduino-core/src/cc/arduino/contributions/packages/ContributionsIndexer.java @@ -44,26 +44,25 @@ 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.io.*; import java.util.*; import static processing.app.helpers.filefilters.OnlyDirs.ONLY_DIRS; public class ContributionsIndexer { + private static final String DEFAULT_INDEX_FILE_NAME = "package_index.json"; + private static final List PROTECTED_PACKAGE_NAMES = Arrays.asList("arduino", "Intel"); + private final File packagesFolder; private final File stagingFolder; - private final File indexFile; + private final File preferencesFolder; private ContributionsIndex index; public ContributionsIndexer(File preferencesFolder) { + this.preferencesFolder = preferencesFolder; packagesFolder = new File(preferencesFolder, "packages"); - stagingFolder = new File(preferencesFolder, "staging" + File.separator + - "packages"); - indexFile = new File(preferencesFolder, "package_index.json"); + stagingFolder = new File(preferencesFolder, "staging" + File.separator + "packages"); } // public static void main(String args[]) throws Exception { @@ -81,8 +80,19 @@ public class ContributionsIndexer { // } public void parseIndex() throws IOException { - // Parse index file - parseIndex(indexFile); + index = parseIndex(getIndexFile(DEFAULT_INDEX_FILE_NAME)); + + File[] indexFiles = preferencesFolder.listFiles(new FilenameFilter() { + @Override + public boolean accept(File file, String name) { + return !DEFAULT_INDEX_FILE_NAME.equals(name) && name.startsWith("package_") && name.endsWith("_index.json"); + } + }); + + for (File indexFile : indexFiles) { + ContributionsIndex contributionsIndex = parseIndex(indexFile); + mergeContributions(contributionsIndex, indexFile); + } List packages = index.getPackages(); for (ContributedPackage pack : packages) { @@ -98,14 +108,58 @@ public class ContributionsIndexer { index.fillCategories(); } - private void parseIndex(File indexFile) throws IOException { + private void mergeContributions(ContributionsIndex contributionsIndex, File indexFile) { + for (ContributedPackage contributedPackage : contributionsIndex.getPackages()) { + ContributedPackage targetPackage = index.getPackage(contributedPackage.getName()); + + if (targetPackage == null) { + index.getPackages().add(contributedPackage); + } else { + if (mergeAllowed(contributedPackage, indexFile)) { + List platforms = contributedPackage.getPlatforms(); + if (platforms == null) { + platforms = new LinkedList(); + } + for (ContributedPlatform contributedPlatform : platforms) { + ContributedPlatform platform = targetPackage.findPlatform(contributedPlatform.getArchitecture(), contributedPlatform.getVersion()); + if (platform != null) { + targetPackage.getPlatforms().remove(platform); + } + targetPackage.getPlatforms().add(contributedPlatform); + } + List tools = contributedPackage.getTools(); + if (tools == null) { + tools = new LinkedList(); + } + for (ContributedTool contributedTool : tools) { + ContributedTool tool = targetPackage.findTool(contributedTool.getName(), contributedTool.getVersion()); + if (tool != null) { + targetPackage.getTools().remove(tool); + } + targetPackage.getTools().add(contributedTool); + } + } + } + } + } + + private boolean mergeAllowed(ContributedPackage contributedPackage, File indexFile) { + return !PROTECTED_PACKAGE_NAMES.contains(contributedPackage.getName()) || isSigned(indexFile); + } + + //TODO stub implementation + private boolean isSigned(File indexFile) { + return true; + } + + private ContributionsIndex parseIndex(File indexFile) throws IOException { InputStream indexIn = new FileInputStream(indexFile); ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new MrBeanModule()); mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); mapper.configure(DeserializationFeature.EAGER_DESERIALIZER_FETCH, true); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - index = mapper.readValue(indexIn, ContributionsIndex.class); + return mapper.readValue(indexIn, ContributionsIndex.class); } public void syncWithFilesystem(File hardwareFolder) throws IOException { @@ -295,8 +349,8 @@ public class ContributionsIndexer { return stagingFolder; } - public File getIndexFile() { - return indexFile; + public File getIndexFile(String name) { + return new File(preferencesFolder, name); } } diff --git a/arduino-core/src/processing/app/BaseNoGui.java b/arduino-core/src/processing/app/BaseNoGui.java index 285ab1ba6..3c89ed50f 100644 --- a/arduino-core/src/processing/app/BaseNoGui.java +++ b/arduino-core/src/processing/app/BaseNoGui.java @@ -577,7 +577,7 @@ public class BaseNoGui { static public void initPackages() throws Exception { indexer = new ContributionsIndexer(BaseNoGui.getSettingsFolder()); - File indexFile = indexer.getIndexFile(); + File indexFile = indexer.getIndexFile("package_index.json"); File defaultPackageJsonFile = new File(getContentFile("dist"), "package_index.json"); if (!indexFile.isFile() || (defaultPackageJsonFile.isFile() && defaultPackageJsonFile.lastModified() > indexFile.lastModified())) { FileUtils.copyFile(defaultPackageJsonFile, indexFile);