From 7f10682cf646bcb3e761fbb6bcb2f645bd748c03 Mon Sep 17 00:00:00 2001 From: Tor Norbye Date: Thu, 14 Jun 2012 08:17:48 -0700 Subject: Add format handling to the template wizards This changeset adds a format attribute to the templates. When the ADT plugin reads a template file, and the format version is a higher number than one it knows about, it rejects the templates and informs the user to upgrade the plugin. This allows us to change the format of the templates incompatibly in the future without worrying about users with older versions of the plugin running into problems (because they upgraded the tools but not ADT). It also adds a revision number to each template which is used for the opposite purpose: we can tell if a template is a slightly older revision and then do some conditional handling. Change-Id: If6c49012a1beca44c3a05b3e880ffde70294a57e --- .../internal/wizards/templates/ActivityPage.java | 10 ++-- .../internal/wizards/templates/NewProjectPage.java | 53 +++++++++++++--------- .../wizards/templates/NewTemplatePage.java | 2 +- .../wizards/templates/TemplateHandler.java | 35 +++++++++++++- .../wizards/templates/TemplateMetadata.java | 16 +++++++ templates/activities/BlankActivity/template.xml | 2 + templates/activities/MasterDetailFlow/template.xml | 4 +- templates/other/CustomView/template.xml | 4 +- .../projects/NewAndroidApplication/template.xml | 2 + 9 files changed, 97 insertions(+), 31 deletions(-) diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ActivityPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ActivityPage.java index d9f650c..1cd0739 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ActivityPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/ActivityPage.java @@ -210,11 +210,11 @@ class ActivityPage extends WizardPage implements SelectionListener { private void validatePage() { IStatus status = null; - if (status == null || status.getSeverity() != IStatus.ERROR) { - if (mList.getSelectionCount() < 1) { - status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, - "Select an activity type"); - } + if (mList.getSelectionCount() < 1) { + status = new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, + "Select an activity type"); + } else { + status = mValues.activityValues.getTemplateHandler().validateTemplate(); } setPageComplete(status == null || status.getSeverity() != IStatus.ERROR); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectPage.java index b6993c7..3ba3939 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/NewProjectPage.java @@ -538,33 +538,42 @@ public class NewProjectPage extends WizardPage // Validation private void validatePage() { - IStatus appStatus = validateAppName(); - - IStatus status = appStatus; + IStatus status = mValues.template.validateTemplate(); + if (status != null && !status.isOK()) { + updateDecorator(mApplicationDec, null, true); + updateDecorator(mPackageDec, null, true); + updateDecorator(mProjectDec, null, true); + } else { + IStatus appStatus = validateAppName(); + if (appStatus != null && (status == null + || appStatus.getSeverity() > status.getSeverity())) { + status = appStatus; + } - IStatus projectStatus = validateProjectName(); - if (projectStatus != null && (status == null - || projectStatus.getSeverity() > status.getSeverity())) { - status = projectStatus; - } + IStatus projectStatus = validateProjectName(); + if (projectStatus != null && (status == null + || projectStatus.getSeverity() > status.getSeverity())) { + status = projectStatus; + } - IStatus packageStatus = validatePackageName(); - if (packageStatus != null && (status == null - || packageStatus.getSeverity() > status.getSeverity())) { - status = packageStatus; - } + IStatus packageStatus = validatePackageName(); + if (packageStatus != null && (status == null + || packageStatus.getSeverity() > status.getSeverity())) { + status = packageStatus; + } - if (status == null || status.getSeverity() != IStatus.ERROR) { - if (mValues.target == null) { - status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID, - "Select an Android build target version"); + if (status == null || status.getSeverity() != IStatus.ERROR) { + if (mValues.target == null) { + status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID, + "Select an Android build target version"); + } } - } - if (status == null || status.getSeverity() != IStatus.ERROR) { - if (mValues.minSdk == null || mValues.minSdk.isEmpty()) { - status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID, - "Select a minimum SDK version"); + if (status == null || status.getSeverity() != IStatus.ERROR) { + if (mValues.minSdk == null || mValues.minSdk.isEmpty()) { + status = new Status(IStatus.WARNING, AdtPlugin.PLUGIN_ID, + "Select a minimum SDK version"); + } } } 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 eece39b..1e443bc 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 @@ -492,7 +492,7 @@ public class NewTemplatePage extends WizardPage // ---- Validation ---- private void validatePage() { - IStatus status = null; + IStatus status = mValues.getTemplateHandler().validateTemplate(); // -- validate project if (mChooseProject && mValues.project == null) { 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 ee6115f..1532228 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 @@ -43,9 +43,13 @@ import freemarker.template.DefaultObjectWrapper; import freemarker.template.Template; import freemarker.template.TemplateException; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; +import org.osgi.framework.Constants; +import org.osgi.framework.Version; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -78,6 +82,9 @@ import lombok.ast.libs.org.parboiled.google.collect.Lists; * and merging into existing files */ class TemplateHandler { + /** Highest supported format; templates with a higher number will be skipped */ + static final int CURRENT_FORMAT = 1; + /** * Special marker indicating that this path refers to the special shared * resource directory rather than being somewhere inside the root/ directory @@ -113,6 +120,9 @@ class TemplateHandler { static final String TAG_OPEN = "open"; //$NON-NLS-1$ static final String TAG_THUMB = "thumb"; //$NON-NLS-1$ static final String TAG_THUMBS = "thumbs"; //$NON-NLS-1$ + static final String TAG_DEPENDENCY = "dependency"; //$NON-NLS-1$ + static final String ATTR_FORMAT = "format"; //$NON-NLS-1$ + static final String ATTR_REVISION = "revision"; //$NON-NLS-1$ static final String ATTR_VALUE = "value"; //$NON-NLS-1$ static final String ATTR_DEFAULT = "default"; //$NON-NLS-1$ static final String ATTR_SUGGEST = "suggest"; //$NON-NLS-1$ @@ -936,7 +946,8 @@ class TemplateHandler { } } - /** Returns all the templates with the given prefix + /** + * Returns all the templates with the given prefix * * @param folder the folder prefix * @return the available templates @@ -967,4 +978,26 @@ class TemplateHandler { return templates; } + + /** + * Validates this template to make sure it's supported + * + * @return a status object with the error, or null if there is no problem + */ + @SuppressWarnings("cast") // In Eclipse 3.6.2 cast below is needed + @Nullable + public IStatus validateTemplate() { + TemplateMetadata template = getTemplate(); + if (template != null && !template.isSupported()) { + String versionString = (String) AdtPlugin.getDefault().getBundle().getHeaders().get( + Constants.BUNDLE_VERSION); + Version version = new Version(versionString); + return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, + String.format("This template requires a more recent version of the " + + "Android Eclipse plugin. Please update from version %1$d.%2$d.%3$d.", + version.getMajor(), version.getMinor(), version.getMicro())); + } + + return null; + } } 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 eac818a..db0f8ce 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 @@ -16,6 +16,7 @@ package com.android.ide.eclipse.adt.internal.wizards.templates; import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_DESCRIPTION; +import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_FORMAT; import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_NAME; import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TAG_PARAMETER; import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TAG_THUMB; @@ -58,6 +59,21 @@ class TemplateMetadata { } } + public boolean isSupported() { + String versionString = mDocument.getDocumentElement().getAttribute(ATTR_FORMAT); + if (versionString != null && !versionString.isEmpty()) { + try { + int version = Integer.parseInt(versionString); + return version <= TemplateHandler.CURRENT_FORMAT; + } catch (NumberFormatException nufe) { + return false; + } + } + + // Older templates without version specified: supported + return true; + } + @Nullable String getTitle() { String name = mDocument.getDocumentElement().getAttribute(ATTR_NAME); diff --git a/templates/activities/BlankActivity/template.xml b/templates/activities/BlankActivity/template.xml index f7fa903..997051e 100644 --- a/templates/activities/BlankActivity/template.xml +++ b/templates/activities/BlankActivity/template.xml @@ -1,5 +1,7 @@ diff --git a/templates/other/CustomView/template.xml b/templates/other/CustomView/template.xml index 9511566..9bd6d98 100644 --- a/templates/other/CustomView/template.xml +++ b/templates/other/CustomView/template.xml @@ -1,5 +1,7 @@ \ No newline at end of file + diff --git a/templates/projects/NewAndroidApplication/template.xml b/templates/projects/NewAndroidApplication/template.xml index 84ba6c7..f0ee375 100644 --- a/templates/projects/NewAndroidApplication/template.xml +++ b/templates/projects/NewAndroidApplication/template.xml @@ -1,5 +1,7 @@