* <p/>\r
* Packages are offered by a {@link SdkSource} (a download site).\r
*/\r
-public class Archive implements IDescription {\r
+public class Archive implements IDescription, Comparable<Archive> {\r
\r
public static final int NUM_MONITOR_INC = 100;\r
private static final String PROP_OS = "Archive.Os"; //$NON-NLS-1$\r
"chmod", "777", file.getAbsolutePath()\r
});\r
}\r
+\r
+ /**\r
+ * Archives are compared using their {@link Package} ordering.\r
+ *\r
+ * @see Package#compareTo(Package)\r
+ */\r
+ public int compareTo(Archive rhs) {\r
+ if (mPackage != null && rhs != null) {\r
+ return mPackage.compareTo(rhs.getParentPackage());\r
+ }\r
+ return 0;\r
+ }\r
}\r
\r
\r
/**\r
- * Returns an ordering like this:\r
- * - Tools.\r
- * - Platform-Tools.\r
- * - Docs.\r
- * - Platform n preview\r
- * - Platform n\r
- * - Platform n-1\r
- * - Samples packages.\r
- * - Add-on based on n preview\r
- * - Add-on based on n\r
- * - Add-on based on n-1\r
- * - Extra packages.\r
+ * Returns an ordering like this: <br/>\r
+ * - Tools <br/>\r
+ * - Platform-Tools <br/>\r
+ * - Docs. <br/>\r
+ * - Platform n preview <br/>\r
+ * - Platform n <br/>\r
+ * - Platform n-1 <br/>\r
+ * - Samples packages <br/>\r
+ * - Add-on based on n preview <br/>\r
+ * - Add-on based on n <br/>\r
+ * - Add-on based on n-1 <br/>\r
+ * - Extra packages <br/>\r
*/\r
public int compareTo(Package other) {\r
int s1 = this.sortingScore();\r
*\r
* @see ArchiveInfo#ArchiveInfo(Archive, Archive, ArchiveInfo[])\r
*/\r
-class ArchiveInfo implements IDescription {\r
+class ArchiveInfo implements IDescription, Comparable<ArchiveInfo> {\r
\r
private final Archive mNewArchive;\r
private final Archive mReplaced;\r
}\r
return super.toString();\r
}\r
+\r
+ /**\r
+ * ArchiveInfos are compared using ther "new archive" ordering.\r
+ *\r
+ * @see Archive#compareTo(Archive)\r
+ */\r
+ public int compareTo(ArchiveInfo rhs) {\r
+ if (mNewArchive != null && rhs != null) {\r
+ return mNewArchive.compareTo(rhs.getNewArchive());\r
+ }\r
+ return 0;\r
+ }\r
+\r
}\r
import java.io.PrintStream;\r
import java.util.ArrayList;\r
import java.util.Collection;\r
+import java.util.Collections;\r
import java.util.HashMap;\r
import java.util.HashSet;\r
import java.util.Iterator;\r
// TODO if selectedArchives is null and archives.len==0, find if there are\r
// any new platform we can suggest to install instead.\r
\r
+ Collections.sort(archives);\r
+\r
UpdateChooserDialog dialog = new UpdateChooserDialog(getWindowShell(), this, archives);\r
dialog.open();\r
\r
getLocalSdkParser().getPackages(),\r
includeObsoletes);\r
\r
+ Collections.sort(archives);\r
+\r
// Filter the selected archives to only keep the ones matching the filter\r
if (pkgFilter != null && pkgFilter.size() > 0 && archives != null && archives.size() > 0) {\r
// Map filter types to an SdkRepository Package type.\r
return new MissingPlatformArchiveInfo(new AndroidVersion(api, null /*codename*/));\r
}\r
\r
- /** Fetch all remote packages only if really needed. */\r
+ /**\r
+ * Fetch all remote packages only if really needed.\r
+ * <p/>\r
+ * This method takes a list of sources. Each source is only fetched once -- that is each\r
+ * source keeps the list of packages that we fetched from the remote XML file. If the list\r
+ * is null, it means this source has never been fetched so we'll do it once here. Otherwise\r
+ * we rely on the cached list of packages from this source.\r
+ * <p/>\r
+ * This method also takes a remote package list as input, which it will fill out.\r
+ * If a source has already been fetched, we'll add its packages to the remote package list\r
+ * if they are not already present. Otherwise, the source will be fetched and the packages\r
+ * added to the list.\r
+ *\r
+ * @param remotePkgs An in-out list of packages available from remote sources.\r
+ * This list must not be null.\r
+ * It can be empty or already contain some packages.\r
+ * @param remoteSources A list of available remote sources to fetch from.\r
+ */\r
protected void fetchRemotePackages(\r
final ArrayList<Package> remotePkgs,\r
final SdkSource[] remoteSources) {\r
// necessary.\r
boolean needsFetch = false;\r
for (final SdkSource remoteSrc : remoteSources) {\r
- needsFetch = remoteSrc.getPackages() == null;\r
- if (needsFetch) {\r
- break;\r
+ Package[] pkgs = remoteSrc.getPackages();\r
+ if (pkgs == null) {\r
+ // This source has never been fetched. We'll do it below.\r
+ needsFetch = true;\r
+ } else {\r
+ // This source has already been fetched and we know its package list.\r
+ // We still need to make sure all of its packages are present in the\r
+ // remotePkgs list.\r
+\r
+ nextPackage: for (Package pkg : pkgs) {\r
+ for (Archive a : pkg.getArchives()) {\r
+ // Only add a package if it contains at least one compatible archive\r
+ // and is not already in the remote package list.\r
+ if (a.isCompatible()) {\r
+ if (!remotePkgs.contains(pkg)) {\r
+ remotePkgs.add(pkg);\r
+ continue nextPackage;\r
+ }\r
+ }\r
+ }\r
+ }\r
}\r
}\r
\r
if (pkgs != null) {\r
nextPackage: for (Package pkg : pkgs) {\r
for (Archive a : pkg.getArchives()) {\r
- // Only add a package if it contains at least\r
- // one compatible archive\r
+ // Only add a package if it contains at least one compatible archive\r
+ // and is not already in the remote package list.\r
if (a.isCompatible()) {\r
- remotePkgs.add(pkg);\r
- continue nextPackage;\r
+ if (!remotePkgs.contains(pkg)) {\r
+ remotePkgs.add(pkg);\r
+ continue nextPackage;\r
+ }\r
}\r
}\r
}\r