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
\r
48 * {@link #parseSdk(String, SdkManager, ISdkLog)}.
\r
50 * This returns initially returns null.
\r
51 * Once the parseSdk() method has been called, this returns a possibly empty but non-null array.
\r
53 public Package[] getPackages() {
\r
58 * Clear the internal packages list. After this call, {@link #getPackages()} will return
\r
59 * null till {@link #parseSdk(String, SdkManager, ISdkLog)} is called.
\r
61 public void clearPackages() {
\r
66 * Scan the give SDK to find all the packages already installed at this location.
\r
68 * Store the packages internally. You can use {@link #getPackages()} to retrieve them
\r
69 * at any time later.
\r
71 * @param osSdkRoot The path to the SDK folder.
\r
72 * @param sdkManager An existing SDK manager to list current platforms and addons.
\r
73 * @param log An SDK logger object.
\r
74 * @return The packages found. Can be retrieved later using {@link #getPackages()}.
\r
76 public Package[] parseSdk(String osSdkRoot, SdkManager sdkManager, ISdkLog log) {
\r
77 ArrayList<Package> packages = new ArrayList<Package>();
\r
78 HashSet<File> visited = new HashSet<File>();
\r
80 File dir = new File(osSdkRoot, SdkConstants.FD_DOCS);
\r
81 Package pkg = scanDoc(dir, log);
\r
87 dir = new File(osSdkRoot, SdkConstants.FD_TOOLS);
\r
88 pkg = scanTools(dir, log);
\r
94 // for platforms and add-ons, rely on the SdkManager parser
\r
95 for(IAndroidTarget target : sdkManager.getTargets()) {
\r
97 Properties props = parseProperties(new File(target.getLocation(), SOURCE_PROPERTIES));
\r
100 if (target.isPlatform()) {
\r
101 pkg = new PlatformPackage(target, props);
\r
103 pkg = new AddonPackage(target, props);
\r
105 } catch (Exception e) {
\r
106 log.error(e, null);
\r
111 visited.add(new File(target.getLocation()));
\r
115 scanExtra(osSdkRoot, visited, packages, log);
\r
117 mPackages = packages.toArray(new Package[packages.size()]);
\r
122 * Find any other directory what we haven't successfully visited and
\r
123 * assume they contain extra packages.
\r
126 private void scanExtra(String osSdkRoot,
\r
127 HashSet<File> visited,
\r
128 ArrayList<Package> packages,
\r
130 File root = new File(osSdkRoot);
\r
131 for (File dir : root.listFiles()) {
\r
132 if (dir.isDirectory() && !visited.contains(dir)) {
\r
134 Properties props = parseProperties(new File(dir, SOURCE_PROPERTIES));
\r
135 if (props != null) {
\r
137 ExtraPackage pkg = new ExtraPackage(
\r
139 props, //properties
\r
140 dir.getName(), //path
\r
143 "Tools", //description
\r
145 Os.getCurrentOs(), //archiveOs
\r
146 Arch.getCurrentArch(), //archiveArch
\r
147 dir.getPath() //archiveOsPath
\r
150 // We only accept this as an extra package if it has a valid local path.
\r
151 if (pkg.isPathValid()) {
\r
154 } catch (Exception e) {
\r
155 log.error(e, null);
\r
163 * Try to find a tools package at the given location.
\r
164 * Returns null if not found.
\r
166 private Package scanTools(File toolFolder, ISdkLog log) {
\r
167 // Can we find some properties?
\r
168 Properties props = parseProperties(new File(toolFolder, SOURCE_PROPERTIES));
\r
170 // We're not going to check that all tools are present. At the very least
\r
171 // we should expect to find adb, android and an emulator adapted to the current OS.
\r
172 Set<String> names = new HashSet<String>();
\r
173 for (File file : toolFolder.listFiles()) {
\r
174 names.add(file.getName());
\r
176 if (!names.contains(SdkConstants.FN_ADB) ||
\r
177 !names.contains(SdkConstants.androidCmdName()) ||
\r
178 !names.contains(SdkConstants.FN_EMULATOR)) {
\r
182 // Create are package. use the properties if we found any.
\r
184 ToolPackage pkg = new ToolPackage(
\r
186 props, //properties
\r
189 "Tools", //description
\r
191 Os.getCurrentOs(), //archiveOs
\r
192 Arch.getCurrentArch(), //archiveArch
\r
193 toolFolder.getPath() //archiveOsPath
\r
197 } catch (Exception e) {
\r
198 log.error(e, null);
\r
204 * Try to find a docs package at the given location.
\r
205 * Returns null if not found.
\r
207 private Package scanDoc(File docFolder, ISdkLog log) {
\r
208 // Can we find some properties?
\r
209 Properties props = parseProperties(new File(docFolder, SOURCE_PROPERTIES));
\r
211 // To start with, a doc folder should have an "index.html" to be acceptable.
\r
212 // We don't actually check the content of the file.
\r
213 if (new File(docFolder, "index.html").isFile()) {
\r
215 DocPackage pkg = new DocPackage(
\r
217 props, //properties
\r
222 null, //description
\r
224 Os.getCurrentOs(), //archiveOs
\r
225 Arch.getCurrentArch(), //archiveArch
\r
226 docFolder.getPath() //archiveOsPath
\r
230 } catch (Exception e) {
\r
231 log.error(e, null);
\r
239 * Parses the given file as properties file if it exists.
\r
240 * Returns null if the file does not exist, cannot be parsed or has no properties.
\r
242 private Properties parseProperties(File propsFile) {
\r
243 FileInputStream fis = null;
\r
245 if (propsFile.exists()) {
\r
246 fis = new FileInputStream(propsFile);
\r
248 Properties props = new Properties();
\r
251 // To be valid, there must be at least one property in it.
\r
252 if (props.size() > 0) {
\r
257 } catch (IOException e) {
\r
258 e.printStackTrace();
\r
263 } catch (IOException e) {
\r