OSDN Git Service

BUG 1922588: SDK Updater, Needs better license display
[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\r
48      * {@link #parseSdk(String, SdkManager, ISdkLog)}.\r
49      * <p/>\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
52      */\r
53     public Package[] getPackages() {\r
54         return mPackages;\r
55     }\r
56 \r
57     /**\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
60      */\r
61     public void clearPackages() {\r
62         mPackages = null;\r
63     }\r
64 \r
65     /**\r
66      * Scan the give SDK to find all the packages already installed at this location.\r
67      * <p/>\r
68      * Store the packages internally. You can use {@link #getPackages()} to retrieve them\r
69      * at any time later.\r
70      *\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
75      */\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
79 \r
80         File dir = new File(osSdkRoot, SdkConstants.FD_DOCS);\r
81         Package pkg = scanDoc(dir, log);\r
82         if (pkg != null) {\r
83             packages.add(pkg);\r
84             visited.add(dir);\r
85         }\r
86 \r
87         dir = new File(osSdkRoot, SdkConstants.FD_TOOLS);\r
88         pkg = scanTools(dir, log);\r
89         if (pkg != null) {\r
90             packages.add(pkg);\r
91             visited.add(dir);\r
92         }\r
93 \r
94         // for platforms and add-ons, rely on the SdkManager parser\r
95         for(IAndroidTarget target : sdkManager.getTargets()) {\r
96 \r
97             Properties props = parseProperties(new File(target.getLocation(), SOURCE_PROPERTIES));\r
98 \r
99             try {\r
100                 if (target.isPlatform()) {\r
101                     pkg = new PlatformPackage(target, props);\r
102                 } else {\r
103                     pkg = new AddonPackage(target, props);\r
104                 }\r
105             } catch (Exception e) {\r
106                 log.error(e, null);\r
107             }\r
108 \r
109             if (pkg != null) {\r
110                 packages.add(pkg);\r
111                 visited.add(new File(target.getLocation()));\r
112             }\r
113         }\r
114 \r
115         scanExtra(osSdkRoot, visited, packages, log);\r
116 \r
117         mPackages = packages.toArray(new Package[packages.size()]);\r
118         return mPackages;\r
119     }\r
120 \r
121     /**\r
122      * Find any other directory what we haven't successfully visited and\r
123      * assume they contain extra packages.\r
124      * @param log\r
125      */\r
126     private void scanExtra(String osSdkRoot,\r
127             HashSet<File> visited,\r
128             ArrayList<Package> packages,\r
129             ISdkLog log) {\r
130         File root = new File(osSdkRoot);\r
131         for (File dir : root.listFiles()) {\r
132             if (dir.isDirectory() && !visited.contains(dir)) {\r
133 \r
134                 Properties props = parseProperties(new File(dir, SOURCE_PROPERTIES));\r
135                 if (props != null) {\r
136                     try {\r
137                         ExtraPackage pkg = new ExtraPackage(\r
138                                 null,                       //source\r
139                                 props,                      //properties\r
140                                 dir.getName(),              //path\r
141                                 0,                          //revision\r
142                                 null,                       //license\r
143                                 "Tools",                    //description\r
144                                 null,                       //descUrl\r
145                                 Os.getCurrentOs(),          //archiveOs\r
146                                 Arch.getCurrentArch(),      //archiveArch\r
147                                 dir.getPath()               //archiveOsPath\r
148                                 );\r
149 \r
150                         // We only accept this as an extra package if it has a valid local path.\r
151                         if (pkg.isPathValid()) {\r
152                             packages.add(pkg);\r
153                         }\r
154                     } catch (Exception e) {\r
155                         log.error(e, null);\r
156                     }\r
157                 }\r
158             }\r
159         }\r
160     }\r
161 \r
162     /**\r
163      * Try to find a tools package at the given location.\r
164      * Returns null if not found.\r
165      */\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
169 \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
175         }\r
176         if (!names.contains(SdkConstants.FN_ADB) ||\r
177                 !names.contains(SdkConstants.androidCmdName()) ||\r
178                 !names.contains(SdkConstants.FN_EMULATOR)) {\r
179             return null;\r
180         }\r
181 \r
182         // Create are package. use the properties if we found any.\r
183         try {\r
184             ToolPackage pkg = new ToolPackage(\r
185                     null,                       //source\r
186                     props,                      //properties\r
187                     0,                          //revision\r
188                     null,                       //license\r
189                     "Tools",                    //description\r
190                     null,                       //descUrl\r
191                     Os.getCurrentOs(),          //archiveOs\r
192                     Arch.getCurrentArch(),      //archiveArch\r
193                     toolFolder.getPath()        //archiveOsPath\r
194                     );\r
195 \r
196             return pkg;\r
197         } catch (Exception e) {\r
198             log.error(e, null);\r
199         }\r
200         return null;\r
201     }\r
202 \r
203     /**\r
204      * Try to find a docs package at the given location.\r
205      * Returns null if not found.\r
206      */\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
210 \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
214             try {\r
215                 DocPackage pkg = new DocPackage(\r
216                         null,                       //source\r
217                         props,                      //properties\r
218                         0,                          //apiLevel\r
219                         null,                       //codename\r
220                         0,                          //revision\r
221                         null,                       //license\r
222                         null,                       //description\r
223                         null,                       //descUrl\r
224                         Os.getCurrentOs(),          //archiveOs\r
225                         Arch.getCurrentArch(),      //archiveArch\r
226                         docFolder.getPath()         //archiveOsPath\r
227                         );\r
228 \r
229                 return pkg;\r
230             } catch (Exception e) {\r
231                 log.error(e, null);\r
232             }\r
233         }\r
234 \r
235         return null;\r
236     }\r
237 \r
238     /**\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
241      */\r
242     private Properties parseProperties(File propsFile) {\r
243         FileInputStream fis = null;\r
244         try {\r
245             if (propsFile.exists()) {\r
246                 fis = new FileInputStream(propsFile);\r
247 \r
248                 Properties props = new Properties();\r
249                 props.load(fis);\r
250 \r
251                 // To be valid, there must be at least one property in it.\r
252                 if (props.size() > 0) {\r
253                     return props;\r
254                 }\r
255             }\r
256 \r
257         } catch (IOException e) {\r
258             e.printStackTrace();\r
259         } finally {\r
260             if (fis != null) {\r
261                 try {\r
262                     fis.close();\r
263                 } catch (IOException e) {\r
264                 }\r
265             }\r
266         }\r
267         return null;\r
268     }\r
269 }\r