aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java468
1 files changed, 468 insertions, 0 deletions
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
new file mode 100644
index 000000000..4ce7d74c2
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/templates/TemplateMetadata.java
@@ -0,0 +1,468 @@
+/*
+ * 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 static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_API;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_MIN_BUILD_API;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.NewProjectWizard.ATTR_REVISION;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_BACKGROUND;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_CLIPART_NAME;
+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_FOREGROUND;
+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.ATTR_PADDING;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_SHAPE;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_SOURCE_TYPE;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_TEXT;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_TRIM;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_TYPE;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.ATTR_VALUE;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.CURRENT_FORMAT;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TAG_DEPENDENCY;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TAG_ICONS;
+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;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TAG_FORMFACTOR;
+import static com.android.ide.eclipse.adt.internal.wizards.templates.TemplateHandler.TAG_CATEGORY;
+
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.assetstudiolib.GraphicGenerator;
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.internal.assetstudio.AssetType;
+import com.android.ide.eclipse.adt.internal.assetstudio.CreateAssetSetWizardState;
+import com.android.ide.eclipse.adt.internal.assetstudio.CreateAssetSetWizardState.SourceType;
+import com.android.ide.eclipse.adt.internal.editors.IconFactory;
+import com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageUtils;
+import com.android.utils.Pair;
+import com.google.common.collect.Lists;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.RGB;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+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.Locale;
+import java.util.Map;
+
+/** 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;
+ private Integer mMinApi;
+ private Integer mMinBuildApi;
+ private Integer mRevision;
+ private boolean mNoIcons;
+ private CreateAssetSetWizardState mIconState;
+ private String mFormFactor;
+ private String mCategory;
+
+ TemplateMetadata(@NonNull Document document) {
+ mDocument = document;
+
+ NodeList parameters = mDocument.getElementsByTagName(TAG_PARAMETER);
+ mParameters = new ArrayList<Parameter>(parameters.getLength());
+ mParameterMap = new HashMap<String, Parameter>(parameters.getLength());
+ for (int index = 0, max = parameters.getLength(); index < max; index++) {
+ Element element = (Element) parameters.item(index);
+ Parameter parameter = new Parameter(this, element);
+ mParameters.add(parameter);
+ if (parameter.id != null) {
+ mParameterMap.put(parameter.id, parameter);
+ }
+ }
+ }
+
+ boolean isSupported() {
+ String versionString = mDocument.getDocumentElement().getAttribute(ATTR_FORMAT);
+ if (versionString != null && !versionString.isEmpty()) {
+ try {
+ int version = Integer.parseInt(versionString);
+ return version <= 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);
+ if (name != null && !name.isEmpty()) {
+ return name;
+ }
+
+ return null;
+ }
+
+ @Nullable
+ String getDescription() {
+ String description = mDocument.getDocumentElement().getAttribute(ATTR_DESCRIPTION);
+ if (description != null && !description.isEmpty()) {
+ return description;
+ }
+
+ return null;
+ }
+
+ int getMinSdk() {
+ if (mMinApi == null) {
+ mMinApi = 1;
+ String api = mDocument.getDocumentElement().getAttribute(ATTR_MIN_API);
+ if (api != null && !api.isEmpty()) {
+ try {
+ mMinApi = Integer.parseInt(api);
+ } catch (NumberFormatException nufe) {
+ // Templates aren't allowed to contain codenames, should always be an integer
+ AdtPlugin.log(nufe, null);
+ mMinApi = 1;
+ }
+ }
+ }
+
+ return mMinApi.intValue();
+ }
+
+ int getMinBuildApi() {
+ if (mMinBuildApi == null) {
+ mMinBuildApi = 1;
+ String api = mDocument.getDocumentElement().getAttribute(ATTR_MIN_BUILD_API);
+ if (api != null && !api.isEmpty()) {
+ try {
+ mMinBuildApi = Integer.parseInt(api);
+ } catch (NumberFormatException nufe) {
+ // Templates aren't allowed to contain codenames, should always be an integer
+ AdtPlugin.log(nufe, null);
+ mMinBuildApi = 1;
+ }
+ }
+ }
+
+ return mMinBuildApi.intValue();
+ }
+
+ public int getRevision() {
+ if (mRevision == null) {
+ mRevision = 1;
+ String revision = mDocument.getDocumentElement().getAttribute(ATTR_REVISION);
+ if (revision != null && !revision.isEmpty()) {
+ try {
+ mRevision = Integer.parseInt(revision);
+ } catch (NumberFormatException nufe) {
+ AdtPlugin.log(nufe, null);
+ mRevision = 1;
+ }
+ }
+ }
+
+ return mRevision.intValue();
+ }
+
+ public String getFormFactor() {
+ if (mFormFactor == null) {
+ mFormFactor = "Mobile";
+
+ NodeList formfactorDeclarations = mDocument.getElementsByTagName(TAG_FORMFACTOR);
+ if (formfactorDeclarations.getLength() > 0) {
+ Element element = (Element) formfactorDeclarations.item(0);
+ String formFactor = element.getAttribute(ATTR_VALUE);
+ if (formFactor != null && !formFactor.isEmpty()) {
+ mFormFactor = formFactor;
+ }
+ }
+ }
+ return mFormFactor;
+ }
+
+ public String getCategory() {
+ if (mCategory == null) {
+ mCategory = "";
+ NodeList categories = mDocument.getElementsByTagName(TAG_CATEGORY);
+ if (categories.getLength() > 0) {
+ Element element = (Element) categories.item(0);
+ String category = element.getAttribute(ATTR_VALUE);
+ if (category != null && !category.isEmpty()) {
+ mCategory = category;
+ }
+ }
+ }
+ return mCategory;
+ }
+
+ /**
+ * Returns a suitable icon wizard state instance if this wizard requests
+ * icons to be created, and null otherwise
+ *
+ * @return icon wizard state or null
+ */
+ @Nullable
+ public CreateAssetSetWizardState getIconState(IProject project) {
+ if (mIconState == null && !mNoIcons) {
+ NodeList icons = mDocument.getElementsByTagName(TAG_ICONS);
+ if (icons.getLength() < 1) {
+ mNoIcons = true;
+ return null;
+ }
+ Element icon = (Element) icons.item(0);
+
+ mIconState = new CreateAssetSetWizardState();
+ mIconState.project = project;
+
+ String typeString = getAttributeOrNull(icon, ATTR_TYPE);
+ if (typeString != null) {
+ typeString = typeString.toUpperCase(Locale.US);
+ boolean found = false;
+ for (AssetType type : AssetType.values()) {
+ if (typeString.equals(type.name())) {
+ mIconState.type = type;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ AdtPlugin.log(null, "Unknown asset type %1$s", typeString);
+ }
+ }
+
+ mIconState.outputName = getAttributeOrNull(icon, ATTR_NAME);
+ if (mIconState.outputName != null) {
+ // Register parameter such that if it is referencing other values, it gets
+ // updated when other values are edited
+ Parameter outputParameter = new Parameter(this,
+ Parameter.Type.STRING, "_iconname", mIconState.outputName); //$NON-NLS-1$
+ getParameters().add(outputParameter);
+ }
+
+ RGB background = getRgb(icon, ATTR_BACKGROUND);
+ if (background != null) {
+ mIconState.background = background;
+ }
+ RGB foreground = getRgb(icon, ATTR_FOREGROUND);
+ if (foreground != null) {
+ mIconState.foreground = foreground;
+ }
+ String shapeString = getAttributeOrNull(icon, ATTR_SHAPE);
+ if (shapeString != null) {
+ shapeString = shapeString.toUpperCase(Locale.US);
+ boolean found = false;
+ for (GraphicGenerator.Shape shape : GraphicGenerator.Shape.values()) {
+ if (shapeString.equals(shape.name())) {
+ mIconState.shape = shape;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ AdtPlugin.log(null, "Unknown shape %1$s", shapeString);
+ }
+ }
+ String trimString = getAttributeOrNull(icon, ATTR_TRIM);
+ if (trimString != null) {
+ mIconState.trim = Boolean.valueOf(trimString);
+ }
+ String paddingString = getAttributeOrNull(icon, ATTR_PADDING);
+ if (paddingString != null) {
+ mIconState.padding = Integer.parseInt(paddingString);
+ }
+ String sourceTypeString = getAttributeOrNull(icon, ATTR_SOURCE_TYPE);
+ if (sourceTypeString != null) {
+ sourceTypeString = sourceTypeString.toUpperCase(Locale.US);
+ boolean found = false;
+ for (SourceType type : SourceType.values()) {
+ if (sourceTypeString.equals(type.name())) {
+ mIconState.sourceType = type;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ AdtPlugin.log(null, "Unknown source type %1$s", sourceTypeString);
+ }
+ }
+ mIconState.clipartName = getAttributeOrNull(icon, ATTR_CLIPART_NAME);
+
+ String textString = getAttributeOrNull(icon, ATTR_TEXT);
+ if (textString != null) {
+ mIconState.text = textString;
+ }
+ }
+
+ return mIconState;
+ }
+
+ void updateIconName(List<Parameter> parameters, StringEvaluator evaluator) {
+ if (mIconState != null) {
+ NodeList icons = mDocument.getElementsByTagName(TAG_ICONS);
+ if (icons.getLength() < 1) {
+ return;
+ }
+ Element icon = (Element) icons.item(0);
+ String name = getAttributeOrNull(icon, ATTR_NAME);
+ if (name != null) {
+ mIconState.outputName = evaluator.evaluate(name, parameters);
+ }
+ }
+ }
+
+ private static RGB getRgb(@NonNull Element element, @NonNull String name) {
+ String colorString = getAttributeOrNull(element, name);
+ if (colorString != null) {
+ int rgb = ImageUtils.getColor(colorString.trim());
+ return ImageUtils.intToRgb(rgb);
+ }
+
+ return null;
+ }
+
+ @Nullable
+ private static String getAttributeOrNull(@NonNull Element element, @NonNull String name) {
+ String value = element.getAttribute(name);
+ if (value != null && value.isEmpty()) {
+ return null;
+ }
+ return value;
+ }
+
+ @Nullable
+ String getThumbnailPath() {
+ // Apply selector logic. Pick the thumb first thumb that satisfies the largest number
+ // of conditions.
+ NodeList thumbs = mDocument.getElementsByTagName(TAG_THUMB);
+ if (thumbs.getLength() == 0) {
+ return null;
+ }
+
+
+ int bestMatchCount = 0;
+ Element bestMatch = null;
+
+ for (int i = 0, n = thumbs.getLength(); i < n; i++) {
+ Element thumb = (Element) thumbs.item(i);
+
+ NamedNodeMap attributes = thumb.getAttributes();
+ if (bestMatch == null && attributes.getLength() == 0) {
+ bestMatch = thumb;
+ } else if (attributes.getLength() <= bestMatchCount) {
+ // Already have a match with this number of attributes, no point checking
+ continue;
+ } else {
+ boolean match = true;
+ for (int j = 0, max = attributes.getLength(); j < max; j++) {
+ Attr attribute = (Attr) attributes.item(j);
+ Parameter parameter = mParameterMap.get(attribute.getName());
+ if (parameter == null) {
+ AdtPlugin.log(null, "Unexpected parameter in template thumbnail: %1$s",
+ attribute.getName());
+ continue;
+ }
+ String thumbNailValue = attribute.getValue();
+ String editedValue = parameter.value != null ? parameter.value.toString() : "";
+ if (!thumbNailValue.equals(editedValue)) {
+ match = false;
+ break;
+ }
+ }
+ if (match) {
+ bestMatch = thumb;
+ bestMatchCount = attributes.getLength();
+ }
+ }
+ }
+
+ if (bestMatch != null) {
+ NodeList children = bestMatch.getChildNodes();
+ for (int i = 0, n = children.getLength(); i < n; i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.TEXT_NODE) {
+ return child.getNodeValue().trim();
+ }
+ }
+ }
+
+ 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(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(ATTR_NAME);
+ int revision = -1;
+ String revisionString = element.getAttribute(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() {
+ return mParameters;
+ }
+
+ /**
+ * Returns the parameter of the given id, or null if not found
+ *
+ * @param id the id of the target parameter
+ * @return the corresponding parameter, or null if not found
+ */
+ @Nullable
+ public Parameter getParameter(@NonNull String id) {
+ for (Parameter parameter : mParameters) {
+ if (id.equals(parameter.id)) {
+ return parameter;
+ }
+ }
+
+ return null;
+ }
+
+ /** Returns a default icon for templates */
+ static Image getDefaultTemplateIcon() {
+ return IconFactory.getInstance().getIcon("default_template"); //$NON-NLS-1$
+ }
+}