All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.android.sdklib.internal.repository.packages.BuildToolPackage Maven / Gradle / Ivy

There is a newer version: 25.3.0
Show newest version
/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.sdklib.internal.repository.packages;

import com.android.SdkConstants;
import com.android.annotations.VisibleForTesting;
import com.android.annotations.VisibleForTesting.Visibility;
import com.android.sdklib.SdkManager;
import com.android.sdklib.internal.repository.IDescription;
import com.android.sdklib.internal.repository.archives.Archive.Arch;
import com.android.sdklib.internal.repository.archives.Archive.Os;
import com.android.sdklib.internal.repository.sources.SdkSource;
import com.android.sdklib.repository.FullRevision;
import com.android.sdklib.repository.PkgProps;
import com.android.sdklib.repository.FullRevision.PreviewComparison;

import org.w3c.dom.Node;

import java.io.File;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * Represents a build-tool XML node in an SDK repository.
 */
public class BuildToolPackage extends FullRevisionPackage {

    /** The base value returned by {@link BuildToolPackage#installId()}. */
    private static final String INSTALL_ID_BASE = SdkConstants.FD_BUILD_TOOLS + '-';

    /**
     * Creates a new build-tool package from the attributes and elements of the given XML node.
     * This constructor should throw an exception if the package cannot be created.
     *
     * @param source The {@link SdkSource} where this is loaded from.
     * @param packageNode The XML element being parsed.
     * @param nsUri The namespace URI of the originating XML document, to be able to deal with
     *          parameters that vary according to the originating XML schema.
     * @param licenses The licenses loaded from the XML originating document.
     */
    public BuildToolPackage(
            SdkSource source,
            Node packageNode,
            String nsUri,
            Map licenses) {
        super(source, packageNode, nsUri, licenses);
    }

    /**
     * Creates either a valid {@link BuildToolPackage} or a {@link BrokenPackage}.
     * 

* If the build-tool directory contains valid properties, * this creates a new {@link BuildToolPackage} with the reversion listed in the properties. * Otherwise returns a new {@link BrokenPackage} with some explanation on what failed. *

* Note that the folder name is not enforced. A build-tool directory must have a * a source.props with a revision property and a few expected binaries inside to be * valid. * * @param buildToolDir The SDK/build-tool/revision folder * @param props The properties located in {@code buildToolDir} or null if not found. * @return A new {@link BuildToolPackage} or a new {@link BrokenPackage}. */ public static Package create(File buildToolDir, Properties props) { String error = null; // Try to load the reversion from the sources.props. // If we don't find them, the package is broken. if (props == null) { error = String.format("Missing file %1$s in build-tool/%2$s", SdkConstants.FN_SOURCE_PROP, buildToolDir.getName()); } // Check we can find the revision in the source properties FullRevision rev = null; if (error == null) { String revStr = getProperty(props, PkgProps.PKG_REVISION, null); if (revStr != null) { try { rev = FullRevision.parseRevision(revStr); } catch (NumberFormatException ignore) {} } if (rev == null) { error = String.format("Missing revision property in %1$s", SdkConstants.FN_SOURCE_PROP); } } if (error == null) { // Check the directory contains the expected binaries. if (!buildToolDir.isDirectory()) { error = String.format("build-tool/%1$s folder is missing", buildToolDir.getName()); } else { File[] files = buildToolDir.listFiles(); if (files == null || files.length == 0) { error = String.format("build-tool/%1$s folder is empty", buildToolDir.getName()); } else { Set names = new HashSet(); for (File file : files) { names.add(file.getName()); } for (String name : new String[] { SdkConstants.FN_AAPT, SdkConstants.FN_AIDL, SdkConstants.FN_DX } ) { if (!names.contains(name)) { if (error == null) { error = String.format("build-tool/%1$s folder is missing ", buildToolDir.getName()); } else { error += ", "; } error += name; } } } } } if (error == null && rev != null) { return new BuildToolPackage( null, //source props, 0, //revision (extracted from props) null, //license null, //description null, //descUrl Os.getCurrentOs(), //archiveOs Arch.getCurrentArch(), //archiveArch buildToolDir.getAbsolutePath()); } StringBuilder sb = new StringBuilder("Broken Build-Tools Package"); if (rev != null) { sb.append(String.format(", revision %1$s", rev.toShortString())); } String shortDesc = sb.toString(); if (error != null) { sb.append('\n').append(error); } String longDesc = sb.toString(); return new BrokenPackage(props, shortDesc, longDesc, IMinApiLevelDependency.MIN_API_LEVEL_NOT_SPECIFIED, IExactApiLevelDependency.API_LEVEL_INVALID, buildToolDir.getAbsolutePath()); } @VisibleForTesting(visibility=Visibility.PRIVATE) protected BuildToolPackage( SdkSource source, Properties props, int revision, String license, String description, String descUrl, Os archiveOs, Arch archiveArch, String archiveOsPath) { super(source, props, revision, license, description, descUrl, archiveOs, archiveArch, archiveOsPath); } /** * Returns a string identifier to install this package from the command line. * For build-tools, we use "build-tools-" followed by the full revision string * where spaces are changed to underscore to be more script-friendly. *

* {@inheritDoc} */ @Override public String installId() { return INSTALL_ID_BASE + getRevision().toString().replace(' ', '_'); } /** * Returns a description of this package that is suitable for a list display. *

* {@inheritDoc} */ @Override public String getListDescription() { return String.format("Android SDK Build-tools%1$s", isObsolete() ? " (Obsolete)" : ""); } /** * Returns a short description for an {@link IDescription}. */ @Override public String getShortDescription() { return String.format("Android SDK Build-tools, revision %1$s%2$s", getRevision().toShortString(), isObsolete() ? " (Obsolete)" : ""); } /** Returns a long description for an {@link IDescription}. */ @Override public String getLongDescription() { String s = getDescription(); if (s == null || s.length() == 0) { s = getShortDescription(); } if (s.indexOf("revision") == -1) { s += String.format("\nRevision %1$s%2$s", getRevision().toShortString(), isObsolete() ? " (Obsolete)" : ""); } return s; } /** * Computes a potential installation folder if an archive of this package were * to be installed right away in the given SDK root. *

* A build-tool package is typically installed in SDK/build-tools/revision. * Revision spaces are replaced by underscores for ease of use in command-line. * * @param osSdkRoot The OS path of the SDK root folder. * @param sdkManager An existing SDK manager to list current platforms and addons. * @return A new {@link File} corresponding to the directory to use to install this package. */ @Override public File getInstallFolder(String osSdkRoot, SdkManager sdkManager) { File folder = new File(osSdkRoot, SdkConstants.FD_BUILD_TOOLS); folder = new File(folder, getRevision().toString().replace(' ', '_')); return folder; } /** * Check whether 2 platform-tool packages are the same and have the * same preview bit. */ @Override public boolean sameItemAs(Package pkg) { // Implementation note: here we don't want to care about the preview number // so we ignore the preview when calling sameItemAs(); however we do care // about both packages being either previews or not previews (i.e. the type // must match but the preview number doesn't need to.) // The end result is that a package such as "1.2 rc 4" will be an update for "1.2 rc 3". return sameItemAs(pkg, PreviewComparison.COMPARE_TYPE); } @Override public boolean sameItemAs(Package pkg, PreviewComparison comparePreview) { // Contrary to other package types, build-tools do not "update themselves" // so 2 build tools with 2 different revisions are not the same item. if (pkg instanceof BuildToolPackage) { BuildToolPackage rhs = (BuildToolPackage) pkg; return rhs.getRevision().compareTo(getRevision(), comparePreview) == 0; } return false; } /** * For build-tool package use their revision number like version numbers and * we want them sorted from higher to lower. To do that, insert a fake revision * number using 9999-value into the sorting key. *

* {@inheritDoc} */ @Override protected String comparisonKey() { String s = super.comparisonKey(); int pos = s.indexOf("|r:"); //$NON-NLS-1$ assert pos > 0; FullRevision rev = getRevision(); String reverseSort = String.format("|rr:%1$04d.%2$04d.%3$04d.", //$NON-NLS-1$ 9999 - rev.getMajor(), 9999 - rev.getMinor(), 9999 - rev.getMicro()); s = s.substring(0, pos) + reverseSort + s.substring(pos); return s; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy