OSDN Git Service

merge from donut
[android-x86/development.git] / tools / sdkmanager / libs / sdklib / src / com / android / sdklib / internal / repository / ExtraPackage.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.SdkConstants;\r
20 import com.android.sdklib.SdkManager;\r
21 import com.android.sdklib.internal.repository.Archive.Arch;\r
22 import com.android.sdklib.internal.repository.Archive.Os;\r
23 import com.android.sdklib.repository.SdkRepository;\r
24 \r
25 import org.w3c.dom.Node;\r
26 \r
27 import java.io.File;\r
28 import java.util.Map;\r
29 import java.util.Properties;\r
30 \r
31 /**\r
32  * Represents a extra XML node in an SDK repository.\r
33  */\r
34 public class ExtraPackage extends Package {\r
35 \r
36     private static final String PROP_PATH          = "Extra.Path";         //$NON-NLS-1$\r
37     private static final String PROP_MIN_TOOLS_REV = "Extra.MinToolsRev";  //$NON-NLS-1$\r
38 \r
39     /**\r
40      * The install folder name. It must be a single-segment path.\r
41      * The paths "add-ons", "platforms", "tools" and "docs" are reserved and cannot be used.\r
42      * This limitation cannot be written in the XML Schema and must be enforced here by using\r
43      * the method {@link #isPathValid()} *before* installing the package.\r
44      */\r
45     private final String mPath;\r
46 \r
47     /**\r
48      * The minimal revision of the tools package required by this extra package, if > 0,\r
49      * or {@link #MIN_TOOLS_REV_NOT_SPECIFIED} if there is no such requirement.\r
50      */\r
51     private final int mMinToolsRevision;\r
52 \r
53     /**\r
54      * The value of {@link #mMinToolsRevision} when the {@link SdkRepository#NODE_MIN_TOOLS_REV}\r
55      * was not specified in the XML source.\r
56      */\r
57     public static final int MIN_TOOLS_REV_NOT_SPECIFIED = 0;\r
58 \r
59     /**\r
60      * Creates a new tool package from the attributes and elements of the given XML node.\r
61      * <p/>\r
62      * This constructor should throw an exception if the package cannot be created.\r
63      */\r
64     ExtraPackage(RepoSource source, Node packageNode, Map<String,String> licenses) {\r
65         super(source, packageNode, licenses);\r
66         mPath = XmlParserUtils.getXmlString(packageNode, SdkRepository.NODE_PATH);\r
67         mMinToolsRevision = XmlParserUtils.getXmlInt(packageNode, SdkRepository.NODE_MIN_TOOLS_REV,\r
68                 MIN_TOOLS_REV_NOT_SPECIFIED);\r
69     }\r
70 \r
71     /**\r
72      * Manually create a new package with one archive and the given attributes or properties.\r
73      * This is used to create packages from local directories in which case there must be\r
74      * one archive which URL is the actual target location.\r
75      */\r
76     ExtraPackage(RepoSource source,\r
77             Properties props,\r
78             String path,\r
79             int revision,\r
80             String license,\r
81             String description,\r
82             String descUrl,\r
83             Os archiveOs,\r
84             Arch archiveArch,\r
85             String archiveOsPath) {\r
86         super(source,\r
87                 props,\r
88                 revision,\r
89                 license,\r
90                 description,\r
91                 descUrl,\r
92                 archiveOs,\r
93                 archiveArch,\r
94                 archiveOsPath);\r
95         // The path argument comes before whatever could be in the properties\r
96         mPath = path != null ? path : getProperty(props, PROP_PATH, path);\r
97 \r
98         mMinToolsRevision = Integer.parseInt(getProperty(props, PROP_MIN_TOOLS_REV,\r
99                 Integer.toString(MIN_TOOLS_REV_NOT_SPECIFIED)));\r
100     }\r
101 \r
102     /**\r
103      * Save the properties of the current packages in the given {@link Properties} object.\r
104      * These properties will later be give the constructor that takes a {@link Properties} object.\r
105      */\r
106     @Override\r
107     void saveProperties(Properties props) {\r
108         super.saveProperties(props);\r
109 \r
110         props.setProperty(PROP_PATH, mPath);\r
111 \r
112         if (mMinToolsRevision != MIN_TOOLS_REV_NOT_SPECIFIED) {\r
113             props.setProperty(PROP_MIN_TOOLS_REV, Integer.toString(mMinToolsRevision));\r
114         }\r
115     }\r
116 \r
117     /**\r
118      * Static helper to check if a given path is acceptable for an "extra" package.\r
119      */\r
120     public boolean isPathValid() {\r
121         if (SdkConstants.FD_ADDONS.equals(mPath) ||\r
122                 SdkConstants.FD_PLATFORMS.equals(mPath) ||\r
123                 SdkConstants.FD_TOOLS.equals(mPath) ||\r
124                 SdkConstants.FD_DOCS.equals(mPath)) {\r
125             return false;\r
126         }\r
127         return mPath != null && mPath.indexOf('/') == -1 && mPath.indexOf('\\') == -1;\r
128     }\r
129 \r
130     /**\r
131      * The install folder name. It must be a single-segment path.\r
132      * The paths "add-ons", "platforms", "tools" and "docs" are reserved and cannot be used.\r
133      * This limitation cannot be written in the XML Schema and must be enforced here by using\r
134      * the method {@link #isPathValid()} *before* installing the package.\r
135      */\r
136     public String getPath() {\r
137         return mPath;\r
138     }\r
139 \r
140     /**\r
141      * The minimal revision of the tools package required by this extra package, if > 0,\r
142      * or {@link #MIN_TOOLS_REV_NOT_SPECIFIED} if there is no such requirement.\r
143      */\r
144     public int getMinToolsRevision() {\r
145         return mMinToolsRevision;\r
146     }\r
147 \r
148     /** Returns a short description for an {@link IDescription}. */\r
149     @Override\r
150     public String getShortDescription() {\r
151         String name = getPath();\r
152         if (name != null) {\r
153             // Uniformize all spaces in the name and upper case words.\r
154 \r
155             name = name.replaceAll("[ _\t\f-]+", " ");     //$NON-NLS-1$ //$NON-NLS-2$\r
156 \r
157             // Look at all lower case characters in range [1..n-1] and replace them by an upper\r
158             // case if they are preceded by a space. Also upper cases the first character of the\r
159             // string.\r
160             boolean changed = false;\r
161             char[] chars = name.toCharArray();\r
162             for (int n = chars.length - 1, i = 0; i < n; i++) {\r
163                 if (Character.isLowerCase(chars[i]) && (i == 0 || chars[i - 1] == ' ')) {\r
164                     chars[i] = Character.toUpperCase(chars[i]);\r
165                     changed = true;\r
166                 }\r
167             }\r
168             if (changed) {\r
169                 name = new String(chars);\r
170             }\r
171         }\r
172 \r
173         String s = String.format("%1$s package, revision %2$d",\r
174                 name,\r
175                 getRevision());\r
176 \r
177         if (mMinToolsRevision != MIN_TOOLS_REV_NOT_SPECIFIED) {\r
178             s += String.format(" (tools rev: %1$d)", mMinToolsRevision);\r
179         }\r
180 \r
181         return s;\r
182     }\r
183 \r
184     /** Returns a long description for an {@link IDescription}. */\r
185     @Override\r
186     public String getLongDescription() {\r
187         String s = String.format("Extra %1$s package, revision %2$d",\r
188                 getPath(),\r
189                 getRevision());\r
190 \r
191         if (mMinToolsRevision != MIN_TOOLS_REV_NOT_SPECIFIED) {\r
192             s += String.format(" (min tools rev.: %1$d)", mMinToolsRevision);\r
193         }\r
194 \r
195         s += ".";\r
196 \r
197         return s;\r
198     }\r
199 \r
200     /**\r
201      * Computes a potential installation folder if an archive of this package were\r
202      * to be installed right away in the given SDK root.\r
203      * <p/>\r
204      * A "tool" package should always be located in SDK/tools.\r
205      *\r
206      * @param osSdkRoot The OS path of the SDK root folder.\r
207      * @param suggestedDir A suggestion for the installation folder name, based on the root\r
208      *                     folder used in the zip archive.\r
209      * @param sdkManager An existing SDK manager to list current platforms and addons.\r
210      * @return A new {@link File} corresponding to the directory to use to install this package.\r
211      */\r
212     @Override\r
213     public File getInstallFolder(String osSdkRoot, String suggestedDir, SdkManager sdkManager) {\r
214         return new File(osSdkRoot, getPath());\r
215     }\r
216 \r
217     @Override\r
218     public boolean sameItemAs(Package pkg) {\r
219         // Extra packages are similar if they have the same path.\r
220         return pkg instanceof ExtraPackage && ((ExtraPackage)pkg).mPath.equals(mPath);\r
221     }\r
222 }\r