2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.sdklib;
20 import java.io.FileFilter;
21 import java.util.Arrays;
22 import java.util.HashSet;
24 import java.util.Map.Entry;
27 * Represents an add-on target in the SDK.
28 * An add-on extends a standard {@link PlatformTarget}.
30 final class AddOnTarget implements IAndroidTarget {
32 * String to compute hash for add-on targets.
33 * Format is vendor:name:apiVersion
35 private final static String ADD_ON_FORMAT = "%s:%s:%s"; //$NON-NLS-1$
37 private final static class OptionalLibrary implements IOptionalLibrary {
38 private final String mJarName;
39 private final String mJarPath;
40 private final String mName;
41 private final String mDescription;
43 OptionalLibrary(String jarName, String jarPath, String name, String description) {
47 mDescription = description;
50 public String getJarName() {
54 public String getJarPath() {
58 public String getName() {
62 public String getDescription() {
67 private final String mLocation;
68 private final PlatformTarget mBasePlatform;
69 private final String mName;
70 private final String mVendor;
71 private final int mRevision;
72 private final String mDescription;
73 private String[] mSkins;
74 private String mDefaultSkin;
75 private IOptionalLibrary[] mLibraries;
76 private int mVendorId = NO_USB_ID;
79 * Creates a new add-on
80 * @param location the OS path location of the add-on
81 * @param name the name of the add-on
82 * @param vendor the vendor name of the add-on
83 * @param revision the revision of the add-on
84 * @param description the add-on description
85 * @param libMap A map containing the optional libraries. The map key is the fully-qualified
86 * library name. The value is a 2 string array with the .jar filename, and the description.
87 * @param basePlatform the platform the add-on is extending.
89 AddOnTarget(String location, String name, String vendor, int revision, String description,
90 Map<String, String[]> libMap, PlatformTarget basePlatform) {
91 if (location.endsWith(File.separator) == false) {
92 location = location + File.separator;
99 mDescription = description;
100 mBasePlatform = basePlatform;
102 // handle the optional libraries.
103 if (libMap != null) {
104 mLibraries = new IOptionalLibrary[libMap.size()];
106 for (Entry<String, String[]> entry : libMap.entrySet()) {
107 String jarFile = entry.getValue()[0];
108 String desc = entry.getValue()[1];
109 mLibraries[index++] = new OptionalLibrary(jarFile,
110 mLocation + SdkConstants.OS_ADDON_LIBS_FOLDER + jarFile,
111 entry.getKey(), desc);
116 public String getLocation() {
120 public String getName() {
124 public String getVendor() {
128 public String getFullName() {
129 return String.format("%1$s (%2$s)", mName, mVendor);
132 public String getClasspathName() {
133 return String.format("%1$s [%2$s]", mName, mBasePlatform.getName());
136 public String getDescription() {
140 public AndroidVersion getVersion() {
141 // this is always defined by the base platform
142 return mBasePlatform.getVersion();
145 public String getVersionName() {
146 return mBasePlatform.getVersionName();
149 public int getRevision() {
153 public boolean isPlatform() {
157 public IAndroidTarget getParent() {
158 return mBasePlatform;
161 public String getPath(int pathId) {
164 return mLocation + SdkConstants.OS_IMAGES_FOLDER;
166 return mLocation + SdkConstants.OS_SKINS_FOLDER;
168 return mLocation + SdkConstants.FD_DOCS + File.separator
169 + SdkConstants.FD_DOCS_REFERENCE;
171 // only return the add-on samples folder if there is actually a sample (or more)
172 File sampleLoc = new File(mLocation, SdkConstants.FD_SAMPLES);
173 if (sampleLoc.isDirectory()) {
174 File[] files = sampleLoc.listFiles(new FileFilter() {
175 public boolean accept(File pathname) {
176 return pathname.isDirectory();
180 if (files != null && files.length > 0) {
181 return sampleLoc.getAbsolutePath();
184 // INTENDED FALL-THROUGH
186 return mBasePlatform.getPath(pathId);
190 public String[] getSkins() {
194 public String getDefaultSkin() {
198 public IOptionalLibrary[] getOptionalLibraries() {
203 * Returns the list of libraries of the underlying platform.
207 public String[] getPlatformLibraries() {
208 return mBasePlatform.getPlatformLibraries();
211 public int getUsbVendorId() {
215 public boolean isCompatibleBaseFor(IAndroidTarget target) {
217 if (target == this) {
222 * The method javadoc indicates:
223 * Returns whether the given target is compatible with the receiver.
224 * <p/>A target is considered compatible if applications developed for the receiver can
225 * run on the given target.
228 // The receiver is an add-on. There are 2 big use cases: The add-on has libraries
229 // or the add-on doesn't (in which case we consider it a platform).
230 if (mLibraries.length == 0) {
231 return mBasePlatform.isCompatibleBaseFor(target);
233 // the only targets that can run the receiver are the same add-on in the same or later
235 // first check: vendor/name
236 if (mVendor.equals(target.getVendor()) == false ||
237 mName.equals(target.getName()) == false) {
241 // now check the version. At this point since we checked the add-on part,
242 // we can revert to the basic check on version/codename which are done by the
243 // base platform already.
244 return mBasePlatform.isCompatibleBaseFor(target);
249 public String hashString() {
250 return String.format(ADD_ON_FORMAT, mVendor, mName,
251 mBasePlatform.getVersion().getApiString());
255 public int hashCode() {
256 return hashString().hashCode();
260 public boolean equals(Object obj) {
261 if (obj instanceof AddOnTarget) {
262 AddOnTarget addon = (AddOnTarget)obj;
264 return mVendor.equals(addon.mVendor) && mName.equals(addon.mName) &&
265 mBasePlatform.getVersion().equals(addon.mBasePlatform.getVersion());
272 * Always return +1 if the object we compare to is a platform.
273 * Otherwise, do vendor then name then api version comparison.
275 * @see java.lang.Comparable#compareTo(java.lang.Object)
277 public int compareTo(IAndroidTarget target) {
278 if (target.isPlatform()) {
283 int value = mVendor.compareTo(target.getVendor());
285 // if same vendor, compare name
287 value = mName.compareTo(target.getName());
290 // if same vendor/name, compare version
292 if (getVersion().isPreview() == true) {
293 value = target.getVersion().isPreview() == true ?
294 getVersion().getApiString().compareTo(target.getVersion().getApiString()) :
295 +1; // put the preview at the end.
297 value = target.getVersion().isPreview() == true ?
298 -1 : // put the preview at the end :
299 getVersion().getApiLevel() - target.getVersion().getApiLevel();
306 // ---- local methods.
308 void setSkins(String[] skins, String defaultSkin) {
309 mDefaultSkin = defaultSkin;
311 // we mix the add-on and base platform skins
312 HashSet<String> skinSet = new HashSet<String>();
313 skinSet.addAll(Arrays.asList(skins));
314 skinSet.addAll(Arrays.asList(mBasePlatform.getSkins()));
316 mSkins = skinSet.toArray(new String[skinSet.size()]);
320 * Sets the USB vendor id in the add-on.
322 void setUsbVendorId(int vendorId) {
324 throw new IllegalArgumentException( "VendorId must be > 0");
327 mVendorId = vendorId;