aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2012-06-14 11:37:43 -0700
committerTor Norbye <tnorbye@google.com>2012-06-14 14:43:11 -0700
commitdd0a8b2ec052e0cc670cb8738b0f6ed7b292f122 (patch)
tree7b4f2b347426120d5cbb8160529902aacc4a7c95
parent7f10682cf646bcb3e761fbb6bcb2f645bd748c03 (diff)
downloadsdk-dd0a8b2ec052e0cc670cb8738b0f6ed7b292f122.zip
sdk-dd0a8b2ec052e0cc670cb8738b0f6ed7b292f122.tar.gz
sdk-dd0a8b2ec052e0cc670cb8738b0f6ed7b292f122.tar.bz2
Dependency support for the templates
Change-Id: Id6b0e5f65fc3a50b352423623332c47f7ab5085d
-rw-r--r--build/tools.atree2
-rwxr-xr-xeclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/AddCompatibilityJarAction.java115
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/CompatibilityLibraryHelper.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/welcome/WelcomeWizard.java6
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/InstallDependencyPage.java300
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewActivityWizard.java18
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java17
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java2
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizard.java17
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java24
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java35
-rw-r--r--templates/activities/BlankActivity/recipe.xml.ftl5
-rw-r--r--templates/activities/BlankActivity/template.xml1
-rw-r--r--templates/activities/MasterDetailFlow/recipe.xml.ftl3
-rw-r--r--templates/activities/MasterDetailFlow/template.xml1
-rw-r--r--templates/projects/NewAndroidApplication/template.xml1
-rw-r--r--templates/resources/android-support-v4.jar.binbin247894 -> 0 bytes
17 files changed, 514 insertions, 35 deletions
diff --git a/build/tools.atree b/build/tools.atree
index afdeb75..abd2127 100644
--- a/build/tools.atree
+++ b/build/tools.atree
@@ -153,7 +153,7 @@ sdk/templates/projects/NewAndroidApplication tools/templates/p
sdk/templates/activities/BlankActivity tools/templates/activities/BlankActivity
sdk/templates/activities/MasterDetailFlow tools/templates/activities/MasterDetailFlow
sdk/templates/other/CustomView tools/templates/other/CustomView
-sdk/templates/resources tools/templates/resources
+#sdk/templates/resources tools/templates/resources
# SDK Controller
sdk/apps/SdkController tools/apps/SdkController
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/AddCompatibilityJarAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/AddCompatibilityJarAction.java
index 7da3cc0..ebbd9f0 100755
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/AddCompatibilityJarAction.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/actions/AddCompatibilityJarAction.java
@@ -16,13 +16,16 @@
package com.android.ide.eclipse.adt.internal.actions;
+import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.sdk.AdtConsoleSdkLog;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
+import com.android.sdklib.NullSdkLog;
import com.android.sdklib.SdkConstants;
+import com.android.sdklib.SdkManager;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
import com.android.sdklib.internal.project.ProjectPropertiesWorkingCopy;
@@ -62,6 +65,7 @@ import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
+import java.util.Map;
/**
* An action to add the android-support-v4.jar compatibility library
@@ -74,6 +78,12 @@ import java.util.Iterator;
*/
public class AddCompatibilityJarAction implements IObjectActionDelegate {
+ private static final String FD_ANDROID = "android"; //$NON-NLS-1$
+ private static final String FD_SUPPORT = "support"; //$NON-NLS-1$
+ private static final String FD_GRIDLAYOUT = "gridlayout"; //$NON-NLS-1$
+ private static final String FD_V7 = "v7"; //$NON-NLS-1$
+ private static final String FD_V4 = "v4"; //$NON-NLS-1$
+ private static final String ANDROID_SUPPORT_V4_JAR = "android-support-v4.jar"; //$NON-NLS-1$
private ISelection mSelection;
/**
@@ -116,7 +126,7 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate {
* @return true if the installation was successful
*/
public static boolean install(final IProject project) {
- File jarPath = installSupport();
+ File jarPath = installSupport(-1);
if (jarPath != null) {
try {
return copyJarIntoProject(project, jarPath) != null;
@@ -128,7 +138,21 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate {
return false;
}
- private static File installSupport() {
+ /**
+ * Installs the Android Support library into the SDK extras/ folder. If a minimum
+ * revision number is specified, this method will check whether the package is already
+ * installed, and if the installed revision is at least as high as the requested revision,
+ * this method will exit without performing an update.
+ *
+ * @param minimumRevision a minimum revision, or -1 to upgrade
+ * unconditionally. Note that this does <b>NOT</b> specify which
+ * revision to install; the latest version will always be
+ * installed.
+ * @return the location of the support jar file, or null if something went
+ * wrong
+ */
+ @Nullable
+ public static File installSupport(int minimumRevision) {
final Sdk sdk = Sdk.getCurrent();
if (sdk == null) {
@@ -138,6 +162,18 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate {
return null;
}
+ String sdkLocation = sdk.getSdkLocation();
+ if (minimumRevision > 0) {
+ File path = getCompatJarFile();
+ if (path != null) {
+ assert path.exists(); // guaranteed by the getCompatJarFile call
+ int installedRevision = getInstalledRevision();
+ if (installedRevision != -1 && minimumRevision >= installedRevision) {
+ return path;
+ }
+ }
+ }
+
// TODO: For the generic action, check the library isn't in the project already.
// First call the package manager to make sure the package is installed
@@ -146,10 +182,10 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate {
AdtUpdateDialog window = new AdtUpdateDialog(
AdtPlugin.getDisplay().getActiveShell(),
new AdtConsoleSdkLog(),
- sdk.getSdkLocation());
+ sdkLocation);
Pair<Boolean, File> result = window.installExtraPackage(
- "android", "support"); //$NON-NLS-1$ //$NON-NLS-2$
+ FD_ANDROID, FD_SUPPORT);
// TODO: Make sure the version is at the required level; we know we need at least one
// containing the v7 support
@@ -163,8 +199,8 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate {
// vN/android-support-vN.jar. Eventually we'll want to rely on info from the
// package manifest anyway so this is irrelevant.
- File path = new File(result.getSecond(), "v4"); //$NON-NLS-1$
- final File jarPath = new File(path, "android-support-v4.jar"); //$NON-NLS-1$
+ File path = new File(result.getSecond(), FD_V4);
+ final File jarPath = new File(path, ANDROID_SUPPORT_V4_JAR);
if (!jarPath.isFile()) {
AdtPlugin.printErrorToConsole("Android Compatibility JAR not found:",
@@ -176,6 +212,27 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate {
}
/**
+ * Returns the installed revision number of the Android Compatibility
+ * library, or -1 if the package is not installed.
+ *
+ * @return the installed revision number, or -1
+ */
+ public static int getInstalledRevision() {
+ final Sdk sdk = Sdk.getCurrent();
+ if (sdk != null) {
+ String sdkLocation = sdk.getSdkLocation();
+ SdkManager manager = SdkManager.createManager(sdkLocation, new NullSdkLog());
+ Map<String, Integer> versions = manager.getExtrasVersions();
+ Integer version = versions.get("android/support"); //$NON-NLS-1$
+ if (version != null) {
+ return version.intValue();
+ }
+ }
+
+ return -1;
+ }
+
+ /**
* Similar to {@link #install}, but rather than copy a jar into the given
* project, it creates a new library project in the workspace for the
* compatibility library, and adds a library dependency on the newly
@@ -188,29 +245,23 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate {
* likely to be successful - e.g. the user has at least agreed to
* all installation prompts.)
*/
- public static boolean installLibrary(final IProject project, boolean waitForFinish) {
+ public static boolean installGridLayoutLibrary(final IProject project, boolean waitForFinish) {
final IJavaProject javaProject = JavaCore.create(project);
if (javaProject != null) {
- File sdk = new File(Sdk.getCurrent().getSdkLocation());
- File supportPath = new File(sdk,
- SdkConstants.FD_EXTRAS + File.separator
- + "android" + File.separator //$NON-NLS-1$
- + "support"); //$NON-NLS-1$
+ File supportPath = getCompatPackageDir();
if (!supportPath.isDirectory()) {
- File path = installSupport();
+ File path = installSupport(8); // GridLayout arrived in rev 7 and fixed in rev 8
if (path == null) {
return false;
}
assert path.equals(supportPath);
}
- File libraryPath = new File(supportPath,
- "v7" + File.separator //$NON-NLS-1$
- + "gridlayout"); //$NON-NLS-1$
+ File libraryPath = new File(supportPath, FD_V7 + File.separator + FD_GRIDLAYOUT);
if (!libraryPath.isDirectory()) {
// Upgrade support package: it's out of date. The SDK manager will
// perform an upgrade to the latest version if the package is already installed.
- File path = installSupport();
+ File path = installSupport(-1);
if (path == null) {
return false;
}
@@ -228,6 +279,36 @@ public class AddCompatibilityJarAction implements IObjectActionDelegate {
}
/**
+ * Returns the directory containing the support libraries (v4, v7, v13,
+ * ...), which may or may not exist
+ */
+ private static File getCompatPackageDir() {
+ File sdk = new File(Sdk.getCurrent().getSdkLocation());
+ File supportPath = new File(sdk,
+ SdkConstants.FD_EXTRAS + File.separator
+ + FD_ANDROID + File.separator
+ + FD_SUPPORT);
+ return supportPath;
+ }
+
+ /**
+ * Returns a path to the installed jar file for the compatibility library,
+ * or null if it does not exist
+ *
+ * @return a path to the library or null
+ */
+ @Nullable
+ public static File getCompatJarFile() {
+ File supportDir = getCompatPackageDir();
+ File path = new File(supportDir, FD_V4 + File.separator + ANDROID_SUPPORT_V4_JAR);
+ if (path.exists()) {
+ return path;
+ }
+
+ return null;
+ }
+
+ /**
* Creates a library project in the Eclipse workspace out of the grid layout project
* in the SDK tree.
*
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/CompatibilityLibraryHelper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/CompatibilityLibraryHelper.java
index 45590b7..d5f5c3c 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/CompatibilityLibraryHelper.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/project/CompatibilityLibraryHelper.java
@@ -121,7 +121,7 @@ public class CompatibilityLibraryHelper {
}
} else {
// Install library AND add dependency
- if (!AddCompatibilityJarAction.installLibrary(
+ if (!AddCompatibilityJarAction.installGridLayoutLibrary(
project,
true /* waitForFinish */)) {
return tag;
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/welcome/WelcomeWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/welcome/WelcomeWizard.java
index 5115385..8f5a3e1 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/welcome/WelcomeWizard.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/welcome/WelcomeWizard.java
@@ -173,6 +173,12 @@ public class WelcomeWizard extends Wizard {
// are required dependencies of any platform.
boolean result = updater.installNewSdk(apiLevels);
+ // TODO: Install extra package here as well since it is now core to most of
+ // the templates
+ // if (result) {
+ // updater.installExtraPackage(vendor, path);
+ // }
+
if (disposeShell) {
shell.dispose();
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/InstallDependencyPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/InstallDependencyPage.java
new file mode 100644
index 0000000..bdd53b8
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/InstallDependencyPage.java
@@ -0,0 +1,300 @@
+/*
+ * 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.wizards.templates;
+
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.internal.actions.AddCompatibilityJarAction;
+import com.android.util.Pair;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.browser.IWebBrowser;
+
+import java.io.File;
+import java.net.URL;
+import java.util.List;
+
+class InstallDependencyPage extends WizardPage implements SelectionListener {
+ /**
+ * The compatibility library. This is the only library the templates
+ * currently support. The appearance of any other dependency in this
+ * template will be flagged as a validation error (and the user encouraged
+ * to upgrade to a newer ADT
+ */
+ static final String SUPPORT_LIBRARY_NAME = "android-support-v4"; //$NON-NLS-1$
+
+ /** URL containing more info */
+ private static final String URL =
+ "http://developer.android.com/sdk/compatibility-library.html"; //$NON-NLS-1$
+
+ private Button mCheckButton;
+ private Button mInstallButton;
+ private Link mLink;
+ private TemplateMetadata mTemplate;
+
+ InstallDependencyPage() {
+ super("dependency"); //$NON-NLS-1$
+ setTitle("Install Dependencies");
+ }
+
+ void setTemplate(TemplateMetadata template) {
+ if (template != mTemplate) {
+ mTemplate = template;
+ if (getControl() != null) {
+ validatePage();
+ }
+ }
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ super.setVisible(visible);
+ if (visible) {
+ updateVersionLabels();
+ validatePage();
+ }
+ }
+
+ @Override
+ public void createControl(Composite parent) {
+ Composite container = new Composite(parent, SWT.NULL);
+ setControl(container);
+ container.setLayout(new GridLayout(2, false));
+ // Remaining contents are created lazily, since this page is always added to
+ // the page list, but typically not shown
+
+ Label dependLabel = new Label(container, SWT.WRAP);
+ GridData gd_dependLabel = new GridData(SWT.LEFT, SWT.TOP, true, false, 2, 1);
+ gd_dependLabel.widthHint = NewTemplatePage.WIZARD_PAGE_WIDTH - 50;
+ dependLabel.setLayoutData(gd_dependLabel);
+ dependLabel.setText("This template depends on the Android Support library, which is " +
+ "either not installed, or the template depends on a more recent version than " +
+ "the one you have installed.");
+
+ mLink = new Link(container, SWT.NONE);
+ mLink.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 2, 1));
+ mLink.setText("<a href=\"" + URL + "\">" + URL + "</a>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ mLink.addSelectionListener(this);
+
+ Label lblNewLabel_1 = new Label(container, SWT.NONE);
+ lblNewLabel_1.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
+
+ requiredLabel = new Label(container, SWT.NONE);
+ requiredLabel.setText("Required version:");
+
+ mRequiredVersion = new Label(container, SWT.NONE);
+ mRequiredVersion.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+
+ installedLabel = new Label(container, SWT.NONE);
+ installedLabel.setText("Installed version:");
+
+ mInstalledVersion = new Label(container, SWT.NONE);
+ mInstalledVersion.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
+
+ Label lblNewLabel = new Label(container, SWT.NONE);
+ lblNewLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
+
+ Label descLabel = new Label(container, SWT.WRAP);
+ GridData gd_descLabel = new GridData(SWT.LEFT, SWT.TOP, true, false, 2, 1);
+ gd_descLabel.widthHint = 550;
+ descLabel.setLayoutData(gd_descLabel);
+ descLabel.setText(
+ "You can install or upgrade it by clicking the Install button below, or " +
+ "alternatively, you can install it outside of Eclipse with the SDK Manager, " +
+ "then click on \"Check Again\" to proceed.");
+
+ mInstallButton = new Button(container, SWT.NONE);
+ mInstallButton.setText("Install/Upgrade");
+ mInstallButton.addSelectionListener(this);
+
+ mCheckButton = new Button(container, SWT.NONE);
+ mCheckButton.setText("Check Again");
+ mCheckButton.addSelectionListener(this);
+
+ mInstallButton.setFocus();
+ }
+
+ private void showNextPage() {
+ validatePage();
+ if (isPageComplete()) {
+ // Finish button will be enabled now
+ mInstallButton.setEnabled(false);
+ mCheckButton.setEnabled(false);
+
+ IWizard wizard = getWizard();
+ IWizardPage next = wizard.getNextPage(this);
+ if (next != null) {
+ wizard.getContainer().showPage(next);
+ }
+ }
+ }
+
+ @Override
+ public boolean isPageComplete() {
+ if (mTemplate == null) {
+ return true;
+ }
+
+ return super.isPageComplete() && isInstalled();
+ }
+
+ private boolean isInstalled() {
+ return isInstalled(mTemplate.getDependencies());
+ }
+
+ static String sCachedName;
+ static int sCachedVersion;
+ private Label requiredLabel;
+ private Label installedLabel;
+ private Label mRequiredVersion;
+ private Label mInstalledVersion;
+
+ public static boolean isInstalled(List<Pair<String, Integer>> dependencies) {
+ for (Pair<String, Integer> dependency : dependencies) {
+ String name = dependency.getFirst();
+ int required = dependency.getSecond();
+
+ int installed = -1;
+ if (SUPPORT_LIBRARY_NAME.equals(name)) {
+ installed = getInstalledSupportLibVersion();
+ }
+
+ if (installed == -1) {
+ return false;
+ }
+ if (required > installed) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private static int getInstalledSupportLibVersion() {
+ if (SUPPORT_LIBRARY_NAME.equals(sCachedName)) {
+ return sCachedVersion;
+ } else {
+ int version = AddCompatibilityJarAction.getInstalledRevision();
+ sCachedName = SUPPORT_LIBRARY_NAME;
+ sCachedVersion = version;
+ return version;
+ }
+ }
+
+ private void updateVersionLabels() {
+ int version = getInstalledSupportLibVersion();
+ if (version == -1) {
+ mInstalledVersion.setText("Not installed");
+ } else {
+ mInstalledVersion.setText(Integer.toString(version));
+ }
+
+ if (mTemplate != null) {
+ for (Pair<String, Integer> dependency : mTemplate.getDependencies()) {
+ String name = dependency.getFirst();
+ if (name.equals(SUPPORT_LIBRARY_NAME)) {
+ int required = dependency.getSecond();
+ mRequiredVersion.setText(Integer.toString(required));
+ break;
+ }
+ }
+ }
+ }
+
+ private void validatePage() {
+ if (mTemplate == null) {
+ return;
+ }
+
+ IStatus status = null;
+
+ List<Pair<String, Integer>> dependencies = mTemplate.getDependencies();
+ if (dependencies.size() > 1 || dependencies.size() == 1
+ && !dependencies.get(0).getFirst().equals(SUPPORT_LIBRARY_NAME)) {
+ status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID,
+ "Unsupported template dependency: Upgrade your Android Eclipse plugin");
+ }
+
+ setPageComplete(status == null || status.getSeverity() != IStatus.ERROR);
+ if (status != null) {
+ setMessage(status.getMessage(),
+ status.getSeverity() == IStatus.ERROR
+ ? IMessageProvider.ERROR : IMessageProvider.WARNING);
+ } else {
+ setErrorMessage(null);
+ setMessage(null);
+ }
+ }
+
+ // ---- Implements SelectionListener ----
+
+ @Override
+ public void widgetSelected(SelectionEvent e) {
+ Object source = e.getSource();
+ if (source == mCheckButton) {
+ sCachedName = null;
+ if (isInstalled()) {
+ showNextPage();
+ } else {
+ updateVersionLabels();
+ }
+ } else if (source == mInstallButton) {
+ sCachedName = null;
+ for (Pair<String, Integer> dependency : mTemplate.getDependencies()) {
+ String name = dependency.getFirst();
+ if (SUPPORT_LIBRARY_NAME.equals(name)) {
+ int version = dependency.getSecond();
+ File installed = AddCompatibilityJarAction.installSupport(version);
+ if (installed != null) {
+ showNextPage();
+ } else {
+ updateVersionLabels();
+ }
+ }
+ }
+ } else if (source == mLink) {
+ try {
+ IWorkbench workbench = PlatformUI.getWorkbench();
+ IWebBrowser browser = workbench.getBrowserSupport().getExternalBrowser();
+ browser.openURL(new URL(URL));
+ } catch (Exception ex) {
+ String message = String.format("Could not open browser. Vist\n%1$s\ninstead.",
+ URL);
+ MessageDialog.openError(getShell(), "Browser Error", message);
+ }
+ }
+ }
+
+ @Override
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewActivityWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewActivityWizard.java
index a2e3518..52d7cec 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewActivityWizard.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewActivityWizard.java
@@ -54,10 +54,10 @@ public class NewActivityWizard extends Wizard implements INewWizard {
private IWorkbench mWorkbench;
private UpdateToolsPage mUpdatePage;
- private NewProjectPage mMainPage;
private NewTemplatePage mTemplatePage;
private ActivityPage mActivityPage;
private NewProjectWizardState mValues;
+ protected InstallDependencyPage mDependencyPage;
private NewTemplateWizardState mActivityValues;
/** Creates a new {@link NewActivityWizard} */
@@ -99,7 +99,7 @@ public class NewActivityWizard extends Wizard implements INewWizard {
@Override
public IWizardPage getStartingPage() {
if (mUpdatePage != null && mUpdatePage.isPageComplete()) {
- return mMainPage;
+ return mActivityPage;
}
return super.getStartingPage();
}
@@ -118,6 +118,20 @@ public class NewActivityWizard extends Wizard implements INewWizard {
addPage(mTemplatePage);
}
return mTemplatePage;
+ } else if (page == mTemplatePage) {
+ TemplateMetadata template = mActivityValues.getTemplateHandler().getTemplate();
+ if (template != null) {
+ if (InstallDependencyPage.isInstalled(template.getDependencies())) {
+ return null;
+ } else {
+ if (mDependencyPage == null) {
+ mDependencyPage = new InstallDependencyPage();
+ addPage(mDependencyPage);
+ }
+ mDependencyPage.setTemplate(template);
+ return mDependencyPage;
+ }
+ }
}
return super.getNextPage(page);
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java
index 1de4b2c..2d67086 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectWizard.java
@@ -78,6 +78,7 @@ public class NewProjectWizard extends Wizard implements INewWizard {
private AppSkeletonPage mAppSkeletonPage;
private NewTemplatePage mTemplatePage;
private ActivityPage mActivityPage;
+ protected InstallDependencyPage mDependencyPage;
private ConfigureAssetSetPage mIconPage;
private NewProjectWizardState mValues;
@@ -154,7 +155,21 @@ public class NewProjectWizard extends Wizard implements INewWizard {
return mTemplatePage;
}
- if (page == mTemplatePage || !mValues.createActivity && page == mActivityPage) {
+ if (page == mTemplatePage ) {
+ TemplateMetadata template = mValues.activityValues.getTemplateHandler().getTemplate();
+ if (template != null
+ && !InstallDependencyPage.isInstalled(template.getDependencies())) {
+ if (mDependencyPage == null) {
+ mDependencyPage = new InstallDependencyPage();
+ addPage(mDependencyPage);
+ }
+ mDependencyPage.setTemplate(template);
+ return mDependencyPage;
+ }
+ }
+
+ if (page == mTemplatePage || !mValues.createActivity && page == mActivityPage
+ || page == mDependencyPage) {
if (mValues.createIcon) {
if (mIconPage == null) {
// Bundle asset studio wizard to create the launcher icon
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java
index 1e443bc..ea9774e 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplatePage.java
@@ -461,7 +461,7 @@ public class NewTemplatePage extends WizardPage
@Override
public boolean isPageComplete() {
// Force user to reach this page before hitting Finish
- return mShown;
+ return mShown && super.isPageComplete();
}
@Override
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizard.java
index 28f5ca6..666e2f6 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizard.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewTemplateWizard.java
@@ -59,6 +59,7 @@ public class NewTemplateWizard extends Wizard implements INewWizard {
protected IWorkbench mWorkbench;
protected NewTemplatePage mMainPage;
protected UpdateToolsPage mUpdatePage;
+ protected InstallDependencyPage mDependencyPage;
protected NewTemplateWizardState mValues;
private final String mTemplateName;
@@ -115,6 +116,22 @@ public class NewTemplateWizard extends Wizard implements INewWizard {
@Override
public IWizardPage getNextPage(IWizardPage page) {
+ if (page == mMainPage) {
+ TemplateMetadata template = mValues.getTemplateHandler().getTemplate();
+ if (template != null) {
+ if (InstallDependencyPage.isInstalled(template.getDependencies())) {
+ return null;
+ } else {
+ if (mDependencyPage == null) {
+ mDependencyPage = new InstallDependencyPage();
+ addPage(mDependencyPage);
+ }
+ mDependencyPage.setTemplate(template);
+ return mDependencyPage;
+ }
+ }
+ }
+
return super.getNextPage(page);
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
index 1532228..16b38e3 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateHandler.java
@@ -17,7 +17,9 @@ package com.android.ide.eclipse.adt.internal.wizards.templates;
import static com.android.ide.eclipse.adt.AdtConstants.DOT_FTL;
import static com.android.ide.eclipse.adt.AdtConstants.DOT_XML;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.InstallDependencyPage.SUPPORT_LIBRARY_NAME;
import static com.android.sdklib.SdkConstants.FD_EXTRAS;
+import static com.android.sdklib.SdkConstants.FD_NATIVE_LIBS;
import static com.android.sdklib.SdkConstants.FD_TEMPLATES;
import static com.android.sdklib.SdkConstants.FD_TOOLS;
@@ -25,6 +27,7 @@ import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AdtUtils;
+import com.android.ide.eclipse.adt.internal.actions.AddCompatibilityJarAction;
import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatPreferences;
import com.android.ide.eclipse.adt.internal.editors.formatting.XmlFormatStyle;
import com.android.ide.eclipse.adt.internal.editors.formatting.XmlPrettyPrinter;
@@ -35,6 +38,7 @@ import com.android.manifmerger.MergerLog;
import com.android.resources.ResourceFolderType;
import com.android.sdklib.SdkConstants;
import com.google.common.base.Charsets;
+import com.google.common.collect.Lists;
import com.google.common.io.Files;
import freemarker.cache.TemplateLoader;
@@ -75,8 +79,6 @@ import java.util.Map;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
-import lombok.ast.libs.org.parboiled.google.collect.Lists;
-
/**
* Handler which manages instantiating FreeMarker templates, copying resources
* and merging into existing files
@@ -435,9 +437,25 @@ class TemplateHandler {
if (path != null) {
execute(freemarker, path, paramMap, outputPath);
}
+ } else if (TAG_DEPENDENCY.equals(name)) {
+ String dependencyName = attributes.getValue(ATTR_NAME);
+ if (dependencyName.equals(SUPPORT_LIBRARY_NAME)) {
+ // We assume the revision requirement has been satisfied
+ // by the wizard
+ File path = AddCompatibilityJarAction.getCompatJarFile();
+ if (path != null) {
+ File to = new File(outputPath, FD_NATIVE_LIBS
+ + File.separator + path.getName());
+ try {
+ copy(path, to);
+ } catch (IOException ioe) {
+ AdtPlugin.log(ioe, null);
+ }
+ }
+ }
} else if (!name.equals("template") && !name.equals("category")
&& !name.equals("option") && !name.equals(TAG_THUMBS) &&
- !name.equals(TAG_THUMB)) {
+ !name.equals(TAG_THUMB) && !name.equals(TAG_DEPENDENCY)) {
System.err.println("WARNING: Unknown template directive " + name);
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java
index db0f8ce..f7037f1 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java
@@ -24,6 +24,7 @@ import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHan
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.util.Pair;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
@@ -33,15 +34,19 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import lombok.ast.libs.org.parboiled.google.collect.Lists;
+
/** An ADT template along with metadata */
class TemplateMetadata {
private final Document mDocument;
private final List<Parameter> mParameters;
private final Map<String, Parameter> mParameterMap;
+ private List<Pair<String, Integer>> mDependencies;
TemplateMetadata(@NonNull Document document) {
mDocument = document;
@@ -59,7 +64,7 @@ class TemplateMetadata {
}
}
- public boolean isSupported() {
+ boolean isSupported() {
String versionString = mDocument.getDocumentElement().getAttribute(ATTR_FORMAT);
if (versionString != null && !versionString.isEmpty()) {
try {
@@ -153,6 +158,34 @@ class TemplateMetadata {
return null;
}
+ /**
+ * Returns the dependencies (as a list of pairs of names and revisions)
+ * required by this template
+ */
+ List<Pair<String, Integer>> getDependencies() {
+ if (mDependencies == null) {
+ NodeList elements = mDocument.getElementsByTagName(TemplateHandler.TAG_DEPENDENCY);
+ if (elements.getLength() == 0) {
+ return Collections.emptyList();
+ }
+
+ List<Pair<String, Integer>> dependencies = Lists.newArrayList();
+ for (int i = 0, n = elements.getLength(); i < n; i++) {
+ Element element = (Element) elements.item(i);
+ String name = element.getAttribute(TemplateHandler.ATTR_NAME);
+ int revision = -1;
+ String revisionString = element.getAttribute(TemplateHandler.ATTR_REVISION);
+ if (!revisionString.isEmpty()) {
+ revision = Integer.parseInt(revisionString);
+ }
+ dependencies.add(Pair.of(name, revision));
+ }
+ mDependencies = dependencies;
+ }
+
+ return mDependencies;
+ }
+
/** Returns the list of available parameters */
@NonNull
List<Parameter> getParameters() {
diff --git a/templates/activities/BlankActivity/recipe.xml.ftl b/templates/activities/BlankActivity/recipe.xml.ftl
index 97b9ba7..a6d0ce9 100644
--- a/templates/activities/BlankActivity/recipe.xml.ftl
+++ b/templates/activities/BlankActivity/recipe.xml.ftl
@@ -13,11 +13,6 @@
<merge from="res/values-large/dimens.xml" />
<merge from="res/values/strings.xml.ftl" />
- <!-- Always include the support library because we use NavUtils, ViewPager, etc. -->
- <!-- TODO: automatically overwrite only if the version is newer, otherwise silently fail -->
- <copy from="${android.templatesRes}/android-support-v4.jar.bin"
- to="libs/android-support-v4.jar" />
-
<!-- Decide what kind of layout to add (viewpager or not) -->
<#if navType?contains("pager")>
<instantiate from="res/layout/activity_pager.xml.ftl"
diff --git a/templates/activities/BlankActivity/template.xml b/templates/activities/BlankActivity/template.xml
index 997051e..bce675d 100644
--- a/templates/activities/BlankActivity/template.xml
+++ b/templates/activities/BlankActivity/template.xml
@@ -4,6 +4,7 @@
revision="1"
name="New Blank Activity"
description="Creates a new blank activity, with optional inner navigation.">
+ <dependency name="android-support-v4" revision="8" />
<category value="Activities" />
diff --git a/templates/activities/MasterDetailFlow/recipe.xml.ftl b/templates/activities/MasterDetailFlow/recipe.xml.ftl
index a07635e..2c1f057 100644
--- a/templates/activities/MasterDetailFlow/recipe.xml.ftl
+++ b/templates/activities/MasterDetailFlow/recipe.xml.ftl
@@ -2,9 +2,6 @@
<recipe>
<merge from="AndroidManifest.xml.ftl" />
- <copy from="${android.templatesRes}/android-support-v4.jar.bin"
- to="libs/android-support-v4.jar" />
-
<merge from="res/values-large/refs.xml.ftl" />
<merge from="res/values-sw600dp/refs.xml.ftl" />
<merge from="res/values/strings.xml.ftl" />
diff --git a/templates/activities/MasterDetailFlow/template.xml b/templates/activities/MasterDetailFlow/template.xml
index 4f759cf..05ddb68 100644
--- a/templates/activities/MasterDetailFlow/template.xml
+++ b/templates/activities/MasterDetailFlow/template.xml
@@ -4,6 +4,7 @@
revision="1"
name="New Master/Detail Flow"
description="Creates a new master/detail flow, which is two columns on tablets, and one column on smaller screens. This creates a master fragment, detail fragment, and two activities.">
+ <dependency name="android-support-v4" revision="8" />
<thumbs>
<thumb>template_master_detail.png</thumb>
diff --git a/templates/projects/NewAndroidApplication/template.xml b/templates/projects/NewAndroidApplication/template.xml
index f0ee375..c8464c5 100644
--- a/templates/projects/NewAndroidApplication/template.xml
+++ b/templates/projects/NewAndroidApplication/template.xml
@@ -4,6 +4,7 @@
revision="1"
name="New Android Application"
description="Creates a new Android application with an activity.">
+ <dependency name="android-support-v4" revision="8" />
<thumbs>
<thumb>template_new_project.png</thumb>
diff --git a/templates/resources/android-support-v4.jar.bin b/templates/resources/android-support-v4.jar.bin
deleted file mode 100644
index d006198..0000000
--- a/templates/resources/android-support-v4.jar.bin
+++ /dev/null
Binary files differ