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.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
25 import org.w3c.dom.Node;
\r
27 import java.io.File;
\r
28 import java.util.Map;
\r
29 import java.util.Properties;
\r
32 * Represents a extra XML node in an SDK repository.
\r
34 public class ExtraPackage extends Package {
\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
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
45 private final String mPath;
\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
51 private final int mMinToolsRevision;
\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
57 public static final int MIN_TOOLS_REV_NOT_SPECIFIED = 0;
\r
60 * Creates a new tool package from the attributes and elements of the given XML node.
\r
62 * This constructor should throw an exception if the package cannot be created.
\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
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
76 ExtraPackage(RepoSource source,
\r
85 String 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
98 mMinToolsRevision = Integer.parseInt(getProperty(props, PROP_MIN_TOOLS_REV,
\r
99 Integer.toString(MIN_TOOLS_REV_NOT_SPECIFIED)));
\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
107 void saveProperties(Properties props) {
\r
108 super.saveProperties(props);
\r
110 props.setProperty(PROP_PATH, mPath);
\r
112 if (mMinToolsRevision != MIN_TOOLS_REV_NOT_SPECIFIED) {
\r
113 props.setProperty(PROP_MIN_TOOLS_REV, Integer.toString(mMinToolsRevision));
\r
118 * Static helper to check if a given path is acceptable for an "extra" package.
\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
127 return mPath != null && mPath.indexOf('/') == -1 && mPath.indexOf('\\') == -1;
\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
136 public String getPath() {
\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
144 public int getMinToolsRevision() {
\r
145 return mMinToolsRevision;
\r
148 /** Returns a short description for an {@link IDescription}. */
\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
155 name = name.replaceAll("[ _\t\f-]+", " "); //$NON-NLS-1$ //$NON-NLS-2$
\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
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
169 name = new String(chars);
\r
173 String s = String.format("%1$s package, revision %2$d",
\r
177 if (mMinToolsRevision != MIN_TOOLS_REV_NOT_SPECIFIED) {
\r
178 s += String.format(" (tools rev: %1$d)", mMinToolsRevision);
\r
184 /** Returns a long description for an {@link IDescription}. */
\r
186 public String getLongDescription() {
\r
187 String s = String.format("Extra %1$s package, revision %2$d",
\r
191 if (mMinToolsRevision != MIN_TOOLS_REV_NOT_SPECIFIED) {
\r
192 s += String.format(" (min tools rev.: %1$d)", mMinToolsRevision);
\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
204 * A "tool" package should always be located in SDK/tools.
\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
213 public File getInstallFolder(String osSdkRoot, String suggestedDir, SdkManager sdkManager) {
\r
214 return new File(osSdkRoot, getPath());
\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