com.android.ide.eclipse.adt.internal.project.CompatibilityLibraryHelper.java Source code

Java tutorial

Introduction

Here is the source code for com.android.ide.eclipse.adt.internal.project.CompatibilityLibraryHelper.java

Source

/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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.ide.eclipse.adt.internal.project;

import static com.android.ide.common.layout.LayoutConstants.FQCN_GRID_LAYOUT;
import static com.android.ide.common.layout.LayoutConstants.FQCN_GRID_LAYOUT_V7;
import static com.android.ide.common.layout.LayoutConstants.FQCN_SPACE;
import static com.android.ide.common.layout.LayoutConstants.FQCN_SPACE_V7;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.actions.AddCompatibilityJarAction;
import com.android.ide.eclipse.adt.internal.editors.manifest.ManifestInfo;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState.LibraryState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;

import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;

/**
 * Helper class for the Android Support Library. The support library provides
 * (for example) a backport of GridLayout, which must be used as a library
 * project rather than a jar library since it has resources. This class provides
 * support for finding the library project, or downloading and installing it on
 * demand if it does not, as well as translating tags such as
 * {@code <GridLayout>} into {@code <com.android.support.v7.GridLayout>} if it
 * does not.
 */
public class CompatibilityLibraryHelper {
    /**
     * Returns the correct tag to use for the given view tag. This is normally
     * the same as the tag itself. However, for some views which are not available
     * on all platforms, this will:
     * <ul>
     *  <li> Check if the view is available in the compatibility library,
     *       and if so, if the support library is not installed, will offer to
     *       install it via the SDK manager.
     *  <li> (The tool may also offer to adjust the minimum SDK of the project
     *       up to a level such that the given tag is supported directly, and then
     *       this method will return the original tag.)
     *  <li> Check whether the compatibility library is included in the project, and
     *       if not, offer to copy it into the workspace and add a library dependency.
     *  <li> Return the alternative tag. For example, for "GridLayout", it will
     *       (if the minimum SDK is less than 14) return "com.android.support.v7.GridLayout"
     *       instead.
     * </ul>
     *
     * @param project the project to add the dependency into
     * @param tag the tag to look up, such as "GridLayout"
     * @return the tag to use in the layout, normally the same as the input tag but possibly
     *      an equivalent compatibility library tag instead.
     */
    @NonNull
    public static String getTagFor(@NonNull IProject project, @NonNull String tag) {
        boolean isGridLayout = tag.equals(FQCN_GRID_LAYOUT);
        boolean isSpace = tag.equals(FQCN_SPACE);
        if (isGridLayout || isSpace) {
            int minSdk = ManifestInfo.get(project).getMinSdkVersion();
            if (minSdk < 14) {
                // See if the support library is installed in the SDK area
                // See if there is a local project in the workspace providing the
                // project
                IProject supportProject = getSupportProjectV7();
                if (supportProject != null) {
                    // Make sure I have a dependency on it
                    ProjectState state = Sdk.getProjectState(project);
                    if (state != null) {
                        for (LibraryState library : state.getLibraries()) {
                            if (supportProject.equals(library.getProjectState().getProject())) {
                                // Found it: you have the compatibility library and have linked
                                // to it: use the alternative tag
                                return isGridLayout ? FQCN_GRID_LAYOUT_V7 : FQCN_SPACE_V7;
                            }
                        }
                    }
                }

                // Ask user to install it
                String message = String.format("%1$s requires API level 14 or higher, or a compatibility "
                        + "library for older versions.\n\n" + " Do you want to install the compatibility library?",
                        tag);
                MessageDialog dialog = new MessageDialog(Display.getCurrent().getActiveShell(), "Warning", null,
                        message, MessageDialog.QUESTION, new String[] { "Install", "Cancel" },
                        1 /* default button: Cancel */);
                int answer = dialog.open();
                if (answer == 0) {
                    if (supportProject != null) {
                        // Just add library dependency
                        if (!AddCompatibilityJarAction.addLibraryDependency(supportProject, project,
                                true /* waitForFinish */)) {
                            return tag;
                        }
                    } else {
                        // Install library AND add dependency
                        if (!AddCompatibilityJarAction.installLibrary(project, true /* waitForFinish */)) {
                            return tag;
                        }
                    }

                    return isGridLayout ? FQCN_GRID_LAYOUT_V7 : FQCN_SPACE_V7;
                }
            }
        }

        return tag;
    }

    /** Cache for {@link #getSupportProjectV7()} */
    private static IProject sCachedProject;

    /**
     * Finds and returns the support project in the workspace, if any.
     *
     * @return the android support library project, or null if not found
     */
    @Nullable
    public static IProject getSupportProjectV7() {
        if (sCachedProject != null) {
            if (sCachedProject.isAccessible()) {
                return sCachedProject;
            } else {
                sCachedProject = null;
            }
        }

        sCachedProject = findSupportProjectV7();
        return sCachedProject;
    }

    @Nullable
    private static IProject findSupportProjectV7() {
        for (IJavaProject javaProject : AdtUtils.getOpenAndroidProjects()) {
            IProject project = javaProject.getProject();
            ProjectState state = Sdk.getProjectState(project);
            if (state.isLibrary()) {
                ManifestInfo manifestInfo = ManifestInfo.get(project);
                if (manifestInfo.getPackage().equals("android.support.v7.gridlayout")) { //$NON-NLS-1$
                    return project;
                }
            }
        }

        return null;
    }
}