OSDN Git Service

ca78b0b3214c5222840a41981fc2c51964c8182c
[android-x86/sdk.git] / sdkmanager / libs / sdklib / src / com / android / sdklib / internal / repository / LocalSdkParser.java
1 /*\r
2  * Copyright (C) 2009 The Android Open Source Project\r
3  *\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
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\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
15  */\r
16 \r
17 package com.android.sdklib.internal.repository;\r
18 \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
25 \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
33 \r
34 /**\r
35  * Scans a local SDK to find which packages are currently installed.\r
36  */\r
37 public class LocalSdkParser {\r
38 \r
39     static final String SOURCE_PROPERTIES = "source.properties";  //$NON-NLS-1$\r
40     private Package[] mPackages;\r
41 \r
42     public LocalSdkParser() {\r
43         // pass\r
44     }\r
45 \r
46     /**\r
47      * Returns the packages found by the last call to {@link #parseSdk(String, SdkManager, ISdkLog)}.\r
48      */\r
49     public Package[] getPackages() {\r
50         return mPackages;\r
51     }\r
52 \r
53     /**\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
56      */\r
57     public void clearPackages() {\r
58         mPackages = null;\r
59     }\r
60 \r
61     /**\r
62      * Scan the give SDK to find all the packages already installed at this location.\r
63      * <p/>\r
64      * Store the packages internally. You can use {@link #getPackages()} to retrieve them\r
65      * at any time later.\r
66      *\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
71      */\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
75 \r
76         File dir = new File(osSdkRoot, SdkConstants.FD_DOCS);\r
77         Package pkg = scanDoc(dir, log);\r
78         if (pkg != null) {\r
79             packages.add(pkg);\r
80             visited.add(dir);\r
81         }\r
82 \r
83         dir = new File(osSdkRoot, SdkConstants.FD_TOOLS);\r
84         pkg = scanTools(dir, log);\r
85         if (pkg != null) {\r
86             packages.add(pkg);\r
87             visited.add(dir);\r
88         }\r
89 \r
90         // for platforms and add-ons, rely on the SdkManager parser\r
91         for(IAndroidTarget target : sdkManager.getTargets()) {\r
92 \r
93             Properties props = parseProperties(new File(target.getLocation(), SOURCE_PROPERTIES));\r
94 \r
95             try {\r
96                 if (target.isPlatform()) {\r
97                     pkg = new PlatformPackage(target, props);\r
98                 } else {\r
99                     pkg = new AddonPackage(target, props);\r
100                 }\r
101             } catch (Exception e) {\r
102                 log.error(e, null);\r
103             }\r
104 \r
105             if (pkg != null) {\r
106                 packages.add(pkg);\r
107                 visited.add(new File(target.getLocation()));\r
108             }\r
109         }\r
110 \r
111         scanExtra(osSdkRoot, visited, packages, log);\r
112 \r
113         mPackages = packages.toArray(new Package[packages.size()]);\r
114         return mPackages;\r
115     }\r
116 \r
117     /**\r
118      * Find any other directory what we haven't successfully visited and\r
119      * assume they contain extra packages.\r
120      * @param log\r
121      */\r
122     private void scanExtra(String osSdkRoot,\r
123             HashSet<File> visited,\r
124             ArrayList<Package> packages,\r
125             ISdkLog log) {\r
126         File root = new File(osSdkRoot);\r
127         for (File dir : root.listFiles()) {\r
128             if (dir.isDirectory() && !visited.contains(dir)) {\r
129 \r
130                 Properties props = parseProperties(new File(dir, SOURCE_PROPERTIES));\r
131                 if (props != null) {\r
132                     try {\r
133                         ExtraPackage pkg = new ExtraPackage(\r
134                                 null,                       //source\r
135                                 props,                      //properties\r
136                                 dir.getName(),              //path\r
137                                 0,                          //revision\r
138                                 null,                       //license\r
139                                 "Tools",                    //description\r
140                                 null,                       //descUrl\r
141                                 Os.getCurrentOs(),          //archiveOs\r
142                                 Arch.getCurrentArch(),      //archiveArch\r
143                                 dir.getPath()               //archiveOsPath\r
144                                 );\r
145 \r
146                         // We only accept this as an extra package if it has a valid local path.\r
147                         if (pkg.isPathValid()) {\r
148                             packages.add(pkg);\r
149                         }\r
150                     } catch (Exception e) {\r
151                         log.error(e, null);\r
152                     }\r
153                 }\r
154             }\r
155         }\r
156     }\r
157 \r
158     /**\r
159      * Try to find a tools package at the given location.\r
160      * Returns null if not found.\r
161      */\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
165 \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
171         }\r
172         if (!names.contains(SdkConstants.FN_ADB) ||\r
173                 !names.contains(SdkConstants.androidCmdName()) ||\r
174                 !names.contains(SdkConstants.FN_EMULATOR)) {\r
175             return null;\r
176         }\r
177 \r
178         // Create are package. use the properties if we found any.\r
179         try {\r
180             ToolPackage pkg = new ToolPackage(\r
181                     null,                       //source\r
182                     props,                      //properties\r
183                     0,                          //revision\r
184                     null,                       //license\r
185                     "Tools",                    //description\r
186                     null,                       //descUrl\r
187                     Os.getCurrentOs(),          //archiveOs\r
188                     Arch.getCurrentArch(),      //archiveArch\r
189                     toolFolder.getPath()        //archiveOsPath\r
190                     );\r
191 \r
192             return pkg;\r
193         } catch (Exception e) {\r
194             log.error(e, null);\r
195         }\r
196         return null;\r
197     }\r
198 \r
199     /**\r
200      * Try to find a docs package at the given location.\r
201      * Returns null if not found.\r
202      */\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
206 \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
210             try {\r
211                 DocPackage pkg = new DocPackage(\r
212                         null,                       //source\r
213                         props,                      //properties\r
214                         0,                          //apiLevel\r
215                         null,                       //codename\r
216                         0,                          //revision\r
217                         null,                       //license\r
218                         null,                       //description\r
219                         null,                       //descUrl\r
220                         Os.getCurrentOs(),          //archiveOs\r
221                         Arch.getCurrentArch(),      //archiveArch\r
222                         docFolder.getPath()         //archiveOsPath\r
223                         );\r
224 \r
225                 return pkg;\r
226             } catch (Exception e) {\r
227                 log.error(e, null);\r
228             }\r
229         }\r
230 \r
231         return null;\r
232     }\r
233 \r
234     /**\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
237      */\r
238     private Properties parseProperties(File propsFile) {\r
239         FileInputStream fis = null;\r
240         try {\r
241             if (propsFile.exists()) {\r
242                 fis = new FileInputStream(propsFile);\r
243 \r
244                 Properties props = new Properties();\r
245                 props.load(fis);\r
246 \r
247                 // To be valid, there must be at least one property in it.\r
248                 if (props.size() > 0) {\r
249                     return props;\r
250                 }\r
251             }\r
252 \r
253         } catch (IOException e) {\r
254             e.printStackTrace();\r
255         } finally {\r
256             if (fis != null) {\r
257                 try {\r
258                     fis.close();\r
259                 } catch (IOException e) {\r
260                 }\r
261             }\r
262         }\r
263         return null;\r
264     }\r
265 }\r