|
30 | 30 | import processing.app.Platform;
|
31 | 31 | import processing.app.Preferences;
|
32 | 32 | import processing.app.ui.Toolkit;
|
| 33 | +import processing.core.PApplet; |
33 | 34 |
|
34 | 35 | import javax.swing.*;
|
35 | 36 | import javax.swing.border.EmptyBorder;
|
@@ -223,88 +224,133 @@ private SDKUrlHolder getDownloadUrls(String repositoryUrl, String requiredHostOs
|
223 | 224 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
224 | 225 | DocumentBuilder db = dbf.newDocumentBuilder();
|
225 | 226 | Document doc = db.parse(new URL(repositoryUrl).openStream());
|
226 |
| - |
227 |
| - // platform |
228 |
| - String platformDescription = "Android SDK Platform " + PLATFORM_API_LEVEL; |
229 |
| - NodeList platformList = doc.getElementsByTagName("sdk:platform"); |
230 |
| - for (int i = 0; i < platformList.getLength(); i++) { |
231 |
| - Node platform = platformList.item(i); |
| 227 | + Node archiveListItem; |
| 228 | + NodeList archiveList; |
| 229 | + Node archiveItem; |
| 230 | + |
| 231 | + // ----------------------------------------------------------------------- |
| 232 | + // platform |
| 233 | + Node platform = getLatestPlatform(doc.getElementsByTagName("sdk:platform")); |
| 234 | + if (platform != null) { |
232 | 235 | NodeList version = ((Element) platform).getElementsByTagName("sdk:version");
|
233 |
| - NodeList level = ((Element) platform).getElementsByTagName("sdk:api-level"); |
234 |
| - NodeList desc = ((Element) platform).getElementsByTagName("sdk:description"); |
235 |
| - // API level and platform description are both used to avoid ambiguity with |
236 |
| - // preview versions, which might share the API level with the earlier stable |
237 |
| - // platform, but use the letter codename in their description. |
238 |
| - if (level.item(0).getTextContent().equals(PLATFORM_API_LEVEL) && |
239 |
| - desc.item(0).getTextContent().equals(platformDescription)) { |
240 |
| - Node archiveListItem = ((Element) platform).getElementsByTagName("sdk:archives").item(0); |
241 |
| - Node archiveItem = ((Element) archiveListItem).getElementsByTagName("sdk:archive").item(0); |
242 |
| - urlHolder.platformVersion = version.item(0).getTextContent(); |
243 |
| - urlHolder.platformUrl = ((Element) archiveItem).getElementsByTagName("sdk:url").item(0).getTextContent(); |
244 |
| - urlHolder.platformFilename = urlHolder.platformUrl.split("/")[urlHolder.platformUrl.split("/").length-1]; |
245 |
| - urlHolder.totalSize += Integer.parseInt(((Element) archiveItem).getElementsByTagName("sdk:size").item(0).getTextContent()); |
246 |
| - } |
| 236 | + archiveListItem = ((Element) platform).getElementsByTagName("sdk:archives").item(0); |
| 237 | + archiveItem = ((Element) archiveListItem).getElementsByTagName("sdk:archive").item(0); |
| 238 | + urlHolder.platformVersion = version.item(0).getTextContent(); |
| 239 | + urlHolder.platformUrl = ((Element) archiveItem).getElementsByTagName("sdk:url").item(0).getTextContent(); |
| 240 | + urlHolder.platformFilename = urlHolder.platformUrl.split("/")[urlHolder.platformUrl.split("/").length-1]; |
| 241 | + urlHolder.totalSize += Integer.parseInt(((Element) archiveItem).getElementsByTagName("sdk:size").item(0).getTextContent()); |
247 | 242 | }
|
248 | 243 |
|
| 244 | + // Difference between platform tools, build tools, and SDK tools: |
| 245 | + // http://stackoverflow.com/questions/19911762/what-is-android-sdk-build-tools-and-which-version-should-be-used |
| 246 | + // Always get the latest! |
| 247 | + |
| 248 | + // ----------------------------------------------------------------------- |
249 | 249 | // platform-tools
|
250 |
| - Node platformToolItem = doc.getElementsByTagName("sdk:platform-tool").item(0); |
251 |
| - Node archiveListItem = ((Element) platformToolItem).getElementsByTagName("sdk:archives").item(0); |
252 |
| - NodeList archiveList = ((Element) archiveListItem).getElementsByTagName("sdk:archive"); |
253 |
| - for (int i = 0; i < archiveList.getLength(); i++) { |
254 |
| - Node archive = archiveList.item(i); |
255 |
| - String hostOs = ((Element) archive).getElementsByTagName("sdk:host-os").item(0).getTextContent(); |
256 |
| - if (hostOs.equals(requiredHostOs)) { |
257 |
| - urlHolder.platformToolsFilename = (((Element) archive).getElementsByTagName("sdk:url").item(0).getTextContent()); |
258 |
| - urlHolder.platformToolsUrl = URL_REPOSITORY_FOLDER + urlHolder.platformToolsFilename; |
259 |
| - urlHolder.totalSize += Integer.parseInt(((Element) archive).getElementsByTagName("sdk:size").item(0).getTextContent()); |
260 |
| - break; |
| 250 | + Node platformToolsItem = getLatestToolItem(doc.getElementsByTagName("sdk:platform-tool")); |
| 251 | + if (platformToolsItem != null) { |
| 252 | + archiveListItem = ((Element) platformToolsItem).getElementsByTagName("sdk:archives").item(0); |
| 253 | + archiveList = ((Element) archiveListItem).getElementsByTagName("sdk:archive"); |
| 254 | + for (int i = 0; i < archiveList.getLength(); i++) { |
| 255 | + Node archive = archiveList.item(i); |
| 256 | + String hostOs = ((Element) archive).getElementsByTagName("sdk:host-os").item(0).getTextContent(); |
| 257 | + if (hostOs.equals(requiredHostOs)) { |
| 258 | + urlHolder.platformToolsFilename = (((Element) archive).getElementsByTagName("sdk:url").item(0).getTextContent()); |
| 259 | + urlHolder.platformToolsUrl = URL_REPOSITORY_FOLDER + urlHolder.platformToolsFilename; |
| 260 | + urlHolder.totalSize += Integer.parseInt(((Element) archive).getElementsByTagName("sdk:size").item(0).getTextContent()); |
| 261 | + break; |
| 262 | + } |
261 | 263 | }
|
262 | 264 | }
|
263 | 265 |
|
| 266 | + // ----------------------------------------------------------------------- |
264 | 267 | // build-tools
|
265 |
| - NodeList buildToolList = doc.getElementsByTagName("sdk:build-tool"); |
266 |
| - for (int i = 0; i < buildToolList.getLength(); i++) { |
267 |
| - Node buildTool = buildToolList.item(i); |
268 |
| - NodeList revision = ((Element) buildTool).getElementsByTagName("sdk:revision"); |
269 |
| - NodeList major = ((Element) revision).getElementsByTagName("sdk:major"); |
270 |
| - NodeList minor = ((Element) revision).getElementsByTagName("sdk:minor"); |
271 |
| - NodeList micro = ((Element) revision).getElementsByTagName("sdk:micro"); |
272 |
| - |
273 |
| - |
274 |
| - } |
275 |
| - |
276 |
| - Node buildToolsItem = doc.getElementsByTagName("sdk:build-tool").item(doc.getElementsByTagName("sdk:build-tool").getLength()-1); |
277 |
| - archiveListItem = ((Element) buildToolsItem).getElementsByTagName("sdk:archives").item(0); |
278 |
| - archiveList = ((Element) archiveListItem).getElementsByTagName("sdk:archive"); |
279 |
| - for (int i = 0; i < archiveList.getLength(); i++) { |
280 |
| - Node archive = archiveList.item(i); |
281 |
| - String hostOs = ((Element) archive).getElementsByTagName("sdk:host-os").item(0).getTextContent(); |
282 |
| - if (hostOs.equals(requiredHostOs)) { |
283 |
| - urlHolder.buildToolsFilename = (((Element) archive).getElementsByTagName("sdk:url").item(0).getTextContent()); |
284 |
| - urlHolder.buildToolsUrl = URL_REPOSITORY_FOLDER + urlHolder.buildToolsFilename; |
285 |
| - urlHolder.totalSize += Integer.parseInt(((Element) archive).getElementsByTagName("sdk:size").item(0).getTextContent()); |
286 |
| - break; |
| 268 | + Node buildToolsItem = getLatestToolItem(doc.getElementsByTagName("sdk:build-tool")); |
| 269 | + if (buildToolsItem != null) { |
| 270 | + archiveListItem = ((Element) buildToolsItem).getElementsByTagName("sdk:archives").item(0); |
| 271 | + archiveList = ((Element) archiveListItem).getElementsByTagName("sdk:archive"); |
| 272 | + for (int i = 0; i < archiveList.getLength(); i++) { |
| 273 | + Node archive = archiveList.item(i); |
| 274 | + String hostOs = ((Element) archive).getElementsByTagName("sdk:host-os").item(0).getTextContent(); |
| 275 | + if (hostOs.equals(requiredHostOs)) { |
| 276 | + urlHolder.buildToolsFilename = (((Element) archive).getElementsByTagName("sdk:url").item(0).getTextContent()); |
| 277 | + urlHolder.buildToolsUrl = URL_REPOSITORY_FOLDER + urlHolder.buildToolsFilename; |
| 278 | + urlHolder.totalSize += Integer.parseInt(((Element) archive).getElementsByTagName("sdk:size").item(0).getTextContent()); |
| 279 | + break; |
| 280 | + } |
287 | 281 | }
|
288 | 282 | }
|
289 |
| - |
| 283 | + |
| 284 | + // ----------------------------------------------------------------------- |
290 | 285 | // tools
|
291 |
| - Node toolsItem = doc.getElementsByTagName("sdk:tool").item(0); |
292 |
| - archiveListItem = ((Element) toolsItem).getElementsByTagName("sdk:archives").item(0); |
293 |
| - archiveList = ((Element) archiveListItem).getElementsByTagName("sdk:archive"); |
294 |
| - for (int i = 0; i < archiveList.getLength(); i++) { |
295 |
| - Node archive = archiveList.item(i); |
296 |
| - String hostOs = ((Element) archive).getElementsByTagName("sdk:host-os").item(0).getTextContent(); |
297 |
| - if (hostOs.equals(requiredHostOs)) { |
298 |
| - urlHolder.toolsFilename = (((Element) archive).getElementsByTagName("sdk:url").item(0).getTextContent()); |
299 |
| - urlHolder.toolsUrl = URL_REPOSITORY_FOLDER + urlHolder.toolsFilename; |
300 |
| - urlHolder.totalSize += Integer.parseInt(((Element) archive).getElementsByTagName("sdk:size").item(0).getTextContent()); |
301 |
| - break; |
| 286 | + Node toolsItem = getLatestToolItem(doc.getElementsByTagName("sdk:tool")); |
| 287 | + if (toolsItem != null) { |
| 288 | + archiveListItem = ((Element) toolsItem).getElementsByTagName("sdk:archives").item(0); |
| 289 | + archiveList = ((Element) archiveListItem).getElementsByTagName("sdk:archive"); |
| 290 | + for (int i = 0; i < archiveList.getLength(); i++) { |
| 291 | + Node archive = archiveList.item(i); |
| 292 | + String hostOs = ((Element) archive).getElementsByTagName("sdk:host-os").item(0).getTextContent(); |
| 293 | + if (hostOs.equals(requiredHostOs)) { |
| 294 | + urlHolder.toolsFilename = (((Element) archive).getElementsByTagName("sdk:url").item(0).getTextContent()); |
| 295 | + urlHolder.toolsUrl = URL_REPOSITORY_FOLDER + urlHolder.toolsFilename; |
| 296 | + urlHolder.totalSize += Integer.parseInt(((Element) archive).getElementsByTagName("sdk:size").item(0).getTextContent()); |
| 297 | + break; |
| 298 | + } |
302 | 299 | }
|
303 | 300 | }
|
304 |
| - |
| 301 | + |
305 | 302 | return urlHolder;
|
306 | 303 | }
|
307 | 304 | }
|
| 305 | + |
| 306 | + private Node getLatestPlatform(NodeList platformList) { |
| 307 | + Node latest = null; |
| 308 | + int maxRevision = -1; |
| 309 | + String platformDescription = "Android SDK Platform " + PLATFORM_API_LEVEL; |
| 310 | + for (int i = 0; i < platformList.getLength(); i++) { |
| 311 | + Node platform = platformList.item(i); |
| 312 | + |
| 313 | + NodeList level = ((Element) platform).getElementsByTagName("sdk:api-level"); |
| 314 | + NodeList desc = ((Element) platform).getElementsByTagName("sdk:description"); |
| 315 | + NodeList revision = ((Element) platform).getElementsByTagName("sdk:revision"); |
| 316 | + // API level and platform description are both used to avoid ambiguity with |
| 317 | + // preview versions, which might share the API level with the earlier stable |
| 318 | + // platform, but use the letter codename in their description. |
| 319 | + if (level.item(0).getTextContent().equals(PLATFORM_API_LEVEL) && |
| 320 | + desc.item(0).getTextContent().equals(platformDescription)) { |
| 321 | + int intRevision = PApplet.parseInt(revision.item(0).getTextContent()); |
| 322 | + if (maxRevision < intRevision) { |
| 323 | + latest = platform; |
| 324 | + maxRevision = intRevision; |
| 325 | + } |
| 326 | + } |
| 327 | + } |
| 328 | + return latest; |
| 329 | + } |
| 330 | + |
| 331 | + private Node getLatestToolItem(NodeList list) { |
| 332 | + Node latest = null; |
| 333 | + int maxMajor = -1; |
| 334 | + int maxMinor = -1; |
| 335 | + int maxMicro = -1; |
| 336 | + for (int i = 0; i < list.getLength(); i++) { |
| 337 | + Node item = list.item(i); |
| 338 | + Node revision = ((Element)item).getElementsByTagName("sdk:revision").item(0); |
| 339 | + NodeList major = ((Element)revision).getElementsByTagName("sdk:major"); |
| 340 | + NodeList minor = ((Element)revision).getElementsByTagName("sdk:minor"); |
| 341 | + NodeList micro = ((Element)revision).getElementsByTagName("sdk:micro"); |
| 342 | + int intMajor = PApplet.parseInt(major.item(0).getTextContent()); |
| 343 | + int intMinor = PApplet.parseInt(minor.item(0).getTextContent()); |
| 344 | + int intMicro = PApplet.parseInt(micro.item(0).getTextContent()); |
| 345 | + if (maxMajor <= intMajor && maxMinor <= intMinor && maxMicro <= intMicro) { |
| 346 | + latest = item; |
| 347 | + maxMajor = intMajor; |
| 348 | + maxMinor = intMinor; |
| 349 | + maxMicro = intMicro; |
| 350 | + } |
| 351 | + } |
| 352 | + return latest; |
| 353 | + } |
308 | 354 |
|
309 | 355 | @Override
|
310 | 356 | public void propertyChange(PropertyChangeEvent evt) {
|
|
0 commit comments