2 * Copyright (C) 2009 The Android Open Source Project
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
17 package com.android.sdklib.internal.repository;
\r
19 import com.android.sdklib.IAndroidTarget;
\r
20 import com.android.sdklib.ISdkLog;
\r
21 import com.android.sdklib.SdkConstants;
\r
22 import com.android.sdklib.SdkManager;
\r
23 import com.android.sdklib.internal.repository.Archive.Arch;
\r
24 import com.android.sdklib.internal.repository.Archive.Os;
\r
26 import java.io.File;
\r
27 import java.io.FileInputStream;
\r
28 import java.io.IOException;
\r
29 import java.util.ArrayList;
\r
30 import java.util.HashSet;
\r
31 import java.util.Properties;
\r
32 import java.util.Set;
\r
35 * Scans a local SDK to find which packages are currently installed.
\r
37 public class LocalSdkParser {
\r
39 static final String SOURCE_PROPERTIES = "source.properties"; //$NON-NLS-1$
\r
40 private Package[] mPackages;
\r
42 public LocalSdkParser() {
\r
47 * Returns the packages found by the last call to {@link #parseSdk(String, SdkManager, ISdkLog)}.
\r
49 public Package[] getPackages() {
\r
54 * Clear the internal packages list. After this call, {@link #getPackages()} will return
\r
55 * null till {@link #parseSdk(String, SdkManager, ISdkLog)} is called.
\r
57 public void clearPackages() {
\r
62 * Scan the give SDK to find all the packages already installed at this location.
\r
64 * Store the packages internally. You can use {@link #getPackages()} to retrieve them
\r
65 * at any time later.
\r
67 * @param osSdkRoot The path to the SDK folder.
\r
68 * @param sdkManager An existing SDK manager to list current platforms and addons.
\r
69 * @param log An SDK logger object.
\r
70 * @return The packages found. Can be retrieved later using {@link #getPackages()}.
\r
72 public Package[] parseSdk(String osSdkRoot, SdkManager sdkManager, ISdkLog log) {
\r
73 ArrayList<Package> packages = new ArrayList<Package>();
\r
74 HashSet<File> visited = new HashSet<File>();
\r
76 File dir = new File(osSdkRoot, SdkConstants.FD_DOCS);
\r
77 Package pkg = scanDoc(dir, log);
\r
83 dir = new File(osSdkRoot, SdkConstants.FD_TOOLS);
\r
84 pkg = scanTools(dir, log);
\r
90 // for platforms and add-ons, rely on the SdkManager parser
\r
91 for(IAndroidTarget target : sdkManager.getTargets()) {
\r
93 Properties props = parseProperties(new File(target.getLocation(), SOURCE_PROPERTIES));
\r
96 if (target.isPlatform()) {
\r
97 pkg = new PlatformPackage(target, props);
\r
99 pkg = new AddonPackage(target, props);
\r
101 } catch (Exception e) {
\r
102 log.error(e, null);
\r
107 visited.add(new File(target.getLocation()));
\r
111 scanExtra(osSdkRoot, visited, packages, log);
\r
113 mPackages = packages.toArray(new Package[packages.size()]);
\r
118 * Find any other directory what we haven't successfully visited and
\r
119 * assume they contain extra packages.
\r
122 private void scanExtra(String osSdkRoot,
\r
123 HashSet<File> visited,
\r
124 ArrayList<Package> packages,
\r
126 File root = new File(osSdkRoot);
\r
127 for (File dir : root.listFiles()) {
\r
128 if (dir.isDirectory() && !visited.contains(dir)) {
\r
130 Properties props = parseProperties(new File(dir, SOURCE_PROPERTIES));
\r
131 if (props != null) {
\r
133 ExtraPackage pkg = new ExtraPackage(
\r
135 props, //properties
\r
136 dir.getName(), //path
\r
139 "Tools", //description
\r
141 Os.getCurrentOs(), //archiveOs
\r
142 Arch.getCurrentArch(), //archiveArch
\r
143 dir.getPath() //archiveOsPath
\r
146 // We only accept this as an extra package if it has a valid local path.
\r
147 if (pkg.isPathValid()) {
\r
150 } catch (Exception e) {
\r
151 log.error(e, null);
\r
159 * Try to find a tools package at the given location.
\r
160 * Returns null if not found.
\r
162 private Package scanTools(File toolFolder, ISdkLog log) {
\r
163 // Can we find some properties?
\r
164 Properties props = parseProperties(new File(toolFolder, SOURCE_PROPERTIES));
\r
166 // We're not going to check that all tools are present. At the very least
\r
167 // we should expect to find adb, android and an emulator adapted to the current OS.
\r
168 Set<String> names = new HashSet<String>();
\r
169 for (File file : toolFolder.listFiles()) {
\r
170 names.add(file.getName());
\r
172 if (!names.contains(SdkConstants.FN_ADB) ||
\r
173 !names.contains(SdkConstants.androidCmdName()) ||
\r
174 !names.contains(SdkConstants.FN_EMULATOR)) {
\r
178 // Create are package. use the properties if we found any.
\r
180 ToolPackage pkg = new ToolPackage(
\r
182 props, //properties
\r
185 "Tools", //description
\r
187 Os.getCurrentOs(), //archiveOs
\r
188 Arch.getCurrentArch(), //archiveArch
\r
189 toolFolder.getPath() //archiveOsPath
\r
193 } catch (Exception e) {
\r
194 log.error(e, null);
\r
200 * Try to find a docs package at the given location.
\r
201 * Returns null if not found.
\r
203 private Package scanDoc(File docFolder, ISdkLog log) {
\r
204 // Can we find some properties?
\r
205 Properties props = parseProperties(new File(docFolder, SOURCE_PROPERTIES));
\r
207 // To start with, a doc folder should have an "index.html" to be acceptable.
\r
208 // We don't actually check the content of the file.
\r
209 if (new File(docFolder, "index.html").isFile()) {
\r
211 DocPackage pkg = new DocPackage(
\r
213 props, //properties
\r
218 null, //description
\r
220 Os.getCurrentOs(), //archiveOs
\r
221 Arch.getCurrentArch(), //archiveArch
\r
222 docFolder.getPath() //archiveOsPath
\r
226 } catch (Exception e) {
\r
227 log.error(e, null);
\r
235 * Parses the given file as properties file if it exists.
\r
236 * Returns null if the file does not exist, cannot be parsed or has no properties.
\r
238 private Properties parseProperties(File propsFile) {
\r
239 FileInputStream fis = null;
\r
241 if (propsFile.exists()) {
\r
242 fis = new FileInputStream(propsFile);
\r
244 Properties props = new Properties();
\r
247 // To be valid, there must be at least one property in it.
\r
248 if (props.size() > 0) {
\r
253 } catch (IOException e) {
\r
254 e.printStackTrace();
\r
259 } catch (IOException e) {
\r