Bug 429420 - Manifest Extensions editor should indicate deprecated extension elements

Add support for indicating warnings and deprecation notes within
the manifest extensions page.

Change-Id: I5a82e24ade2df3097968af7e563ca6686950acef
Signed-off-by: Brian de Alwis <bsd@mt.ca>
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ischema/ISchemaElement.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ischema/ISchemaElement.java
index c5a91af..dfc2032 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ischema/ISchemaElement.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ischema/ISchemaElement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2000, 2012 IBM Corporation and others.
+ *  Copyright (c) 2000, 2014 IBM Corporation and others.
  *  All rights reserved. This program and the accompanying materials
  *  are made available under the terms of the Eclipse Public License v1.0
  *  which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  * 
  *  Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Brian de Alwis (MTI) - bug 429420
  *******************************************************************************/
 package org.eclipse.pde.internal.core.ischema;
 
@@ -44,4 +45,9 @@
 	 * so that SchemaComplexType does not need to implement needlessly.
 	 */
 	public String[] getAttributeNames();
+
+	/**
+	 * Return true if this element has deprecated attributes
+	 */
+	public boolean hasDeprecatedAttributes();
 }
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/schema/SchemaElement.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/schema/SchemaElement.java
index 52e753b..443a9b8 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/schema/SchemaElement.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/schema/SchemaElement.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2000, 2008 IBM Corporation and others.
+ *  Copyright (c) 2000, 2014 IBM Corporation and others.
  *  All rights reserved. This program and the accompanying materials
  *  are made available under the terms of the Eclipse Public License v1.0
  *  which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
  *  Contributors:
  *     IBM Corporation - initial API and implementation
  *     David Carver - STAR - bug 213255
+ *     Brian de Alwis (MTI) - bug 429420
  *******************************************************************************/
 package org.eclipse.pde.internal.core.schema;
 
@@ -297,6 +298,18 @@
 		return fDeprecated;
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.pde.internal.core.ischema.ISchemaElement#hasDeprecatedAttributes()
+	 */
+	public boolean hasDeprecatedAttributes() {
+		for (ISchemaAttribute att : getAttributes()) {
+			if (att.isDeprecated()) {
+				return true;
+			}
+		}
+		return false;
+	}
+
 	public String getExtendedAttributes() {
 		return null;
 	}
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/schema/SchemaElementReference.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/schema/SchemaElementReference.java
index e45c466..7c2d611 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/schema/SchemaElementReference.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/schema/SchemaElementReference.java
@@ -283,6 +283,15 @@
 		return element.isDeprecated();
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.pde.internal.core.ischema.ISchemaElement#hasDeprecatedAttributes()
+	 */
+	public boolean hasDeprecatedAttributes() {
+		if (element == null)
+			return false;
+		return element.hasDeprecatedAttributes();
+	}
+
 	public int compareTo(Object arg0) {
 		if (element == null) {
 			return -1;
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDELabelProvider.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDELabelProvider.java
index 065a45b..7bff5e4 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDELabelProvider.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDELabelProvider.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2013 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Benjamin Cabe <benjamin.cabe@anyware-tech.com> - bug 218618
+ *     Brian de Alwis (MTI) - bug 429420
  *******************************************************************************/
 package org.eclipse.pde.internal.ui;
 
@@ -33,6 +34,7 @@
 import org.eclipse.pde.internal.core.ischema.*;
 import org.eclipse.pde.internal.core.isite.*;
 import org.eclipse.pde.internal.core.plugin.ImportObject;
+import org.eclipse.pde.internal.core.schema.SchemaRegistry;
 import org.eclipse.pde.internal.core.text.bundle.*;
 import org.eclipse.pde.internal.core.util.VersionUtil;
 import org.eclipse.pde.internal.ui.elements.NamedElement;
@@ -362,6 +364,9 @@
 		if (obj instanceof ImportObject) {
 			return getObjectImage((ImportObject) obj);
 		}
+		if (obj instanceof IPluginElement) {
+			return getObjectImage((IPluginElement) obj);
+		}
 		if (obj instanceof IPluginImport) {
 			return getObjectImage((IPluginImport) obj);
 		}
@@ -566,6 +571,44 @@
 		return get(getRequiredPluginImageDescriptor(iimport), flags);
 	}
 
+	protected ImageDescriptor getRequiredPluginImageDescriptor(IPluginElement iobj) {
+		return PDEPluginImages.DESC_GENERIC_XML_OBJ;
+	}
+
+	private Image getObjectImage(IPluginElement obj) {
+		int flags = 0;
+		IPluginObject parent = obj.getParent();
+		while (parent != null && !(parent instanceof IPluginExtension)) {
+			parent = parent.getParent();
+		}
+		if (parent != null) {
+			String point = ((IPluginExtension) parent).getPoint();
+			SchemaRegistry registry = PDECore.getDefault().getSchemaRegistry();
+			ISchema schema = registry.getSchema(point);
+			if (schema != null) {
+				ISchemaElement schemaElement = schema.findElement(obj.getName());
+				// Only label an element if either the element is deprecated or it actually specifies a deprecated attribute;
+				// We don't want to mislabel non-deprecated elements with no deprecated attributes.  
+				if (schemaElement != null && (schemaElement.isDeprecated() || hasDeprecatedAttributes(obj, schemaElement)))
+					flags |= F_WARNING;
+			}
+		}
+		return get(getRequiredPluginImageDescriptor(obj), flags);
+	}
+
+	/** Return true if the {@code obj} has an attribute that is deprecated */
+	private boolean hasDeprecatedAttributes(IPluginElement obj, ISchemaElement schemaElement) {
+		for (ISchemaAttribute schAtt : schemaElement.getAttributes()) {
+			if (schAtt.isDeprecated()) {
+				IPluginAttribute pAtt = obj.getAttribute(schAtt.getName());
+				if (pAtt != null) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
 	protected ImageDescriptor getRequiredPluginImageDescriptor(IPluginImport iobj) {
 		return PDEPluginImages.DESC_REQ_PLUGIN_OBJ;
 	}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java
index 50a645e..cd42866 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java
@@ -1226,6 +1226,7 @@
 	public static String ExtensionDetails_noPoint_title;
 	public static String ExtensionDetails_extensionPointLinks;
 	public static String ExtensionElementDetails_setDesc;
+	public static String ExtensionElementDetails_setDescDepr;
 	public static String ExtensionEditorSelectionPage_title;
 	public static String ExtensionEditorSelectionPage_message;
 	public static String ExtensionEditorSelectionPage_desc;
@@ -3042,4 +3043,7 @@
 	public static String OSGiConsoleFactory_title;
 
 	public static String NewElement_deprecated;
+	public static String ElementIsDeprecated;
+
+	public static String ExtensionAttributeRow_AttrDepr;
 }
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionElementBodyTextDetails.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionElementBodyTextDetails.java
index d89e470..ec3241c 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionElementBodyTextDetails.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionElementBodyTextDetails.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2007, 2011 IBM Corporation and others.
+ *  Copyright (c) 2007, 2014 IBM Corporation and others.
  *  All rights reserved. This program and the accompanying materials
  *  are made available under the terms of the Eclipse Public License v1.0
  *  which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  * 
  *  Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Brian de Alwis (MTI) - bug 429420
  *******************************************************************************/
 
 package org.eclipse.pde.internal.ui.editor.plugin;
@@ -202,7 +203,12 @@
 		fSectionElementDetails = fToolkit.createSection(parent, section_style);
 		fSectionElementDetails.clientVerticalSpacing = FormLayoutFactory.SECTION_HEADER_VERTICAL_SPACING;
 		fSectionElementDetails.setText(PDEUIMessages.ExtensionElementDetails_title);
-		fSectionElementDetails.setDescription(PDEUIMessages.ExtensionElementBodyTextDetails_sectionDescElementGeneral);
+		String description = PDEUIMessages.ExtensionElementBodyTextDetails_sectionDescElementGeneral;
+		if (fSchemaElement != null && fSchemaElement.isDeprecated()) {
+			description += "\n\n"; //$NON-NLS-1$
+			description += NLS.bind(PDEUIMessages.ElementIsDeprecated, fSchemaElement.getName());
+		}
+		fSectionElementDetails.setDescription(description);
 		fSectionElementDetails.setLayout(FormLayoutFactory.createClearGridLayout(false, 1));
 		int layout_style = GridData.FILL_HORIZONTAL;
 		GridData data = new GridData(layout_style);
@@ -248,11 +254,17 @@
 	private void updateUISectionElementDetails() {
 		// Set the general or specifc section description depending if whether
 		// the plugin element data is defined
+		String description;
 		if (fPluginElement == null) {
-			fSectionElementDetails.setDescription(PDEUIMessages.ExtensionElementBodyTextDetails_sectionDescElementGeneral);
+			description = PDEUIMessages.ExtensionElementBodyTextDetails_sectionDescElementGeneral;
 		} else {
-			fSectionElementDetails.setDescription(NLS.bind(PDEUIMessages.ExtensionElementBodyTextDetails_sectionDescElementSpecific, fPluginElement.getName()));
+			description = NLS.bind(PDEUIMessages.ExtensionElementBodyTextDetails_sectionDescElementSpecific, fPluginElement.getName());
 		}
+		if (fSchemaElement != null && fSchemaElement.isDeprecated()) {
+			description += "\n\n"; //$NON-NLS-1$
+			description += NLS.bind(PDEUIMessages.ElementIsDeprecated, fSchemaElement.getName());
+		}
+		fSectionElementDetails.setDescription(description);
 		// Re-layout the section to properly wrap the new section description
 		fSectionElementDetails.layout();
 	}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionElementDetails.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionElementDetails.java
index 2eb1ca8..df6bf7a 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionElementDetails.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionElementDetails.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2003, 2012 IBM Corporation and others.
+ * Copyright (c) 2003, 2014 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,11 +8,10 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *     Remy Chi Jian Suen <remy.suen@gmail.com> - Provide more structure, safety, and convenience for ID-based references between extension points (id hell)
+ *     Brian de Alwis (MTI) - bug 429420
  *******************************************************************************/
 package org.eclipse.pde.internal.ui.editor.plugin;
 
-import org.eclipse.pde.internal.ui.editor.plugin.rows.ExtensionAttributeRow;
-
 import java.util.ArrayList;
 import org.eclipse.jface.viewers.ISelection;
 import org.eclipse.jface.viewers.IStructuredSelection;
@@ -99,14 +98,20 @@
 				}
 			}
 			glayout.numColumns = span;
-			// Add required attributes first
+			// Add required but non-deprecated attributes first
 			for (int i = 0; i < atts.length; i++) {
-				if (atts[i].getUse() == ISchemaAttribute.REQUIRED)
+				if (atts[i].getUse() == ISchemaAttribute.REQUIRED && !atts[i].isDeprecated())
 					rows.add(createAttributeRow(atts[i], client, toolkit, span));
 			}
-			// Add the rest
+			// Add the non-required non-deprecated attributes
 			for (int i = 0; i < atts.length; i++) {
-				if (atts[i].getUse() != ISchemaAttribute.REQUIRED)
+				if (atts[i].getUse() != ISchemaAttribute.REQUIRED && !atts[i].isDeprecated())
+					rows.add(createAttributeRow(atts[i], client, toolkit, span));
+			}
+			createSpacer(toolkit, client, span);
+			// Add finally the deprecated attributes
+			for (int i = 0; i < atts.length; i++) {
+				if (atts[i].isDeprecated())
 					rows.add(createAttributeRow(atts[i], client, toolkit, span));
 			}
 			createSpacer(toolkit, client, span);
@@ -250,12 +255,22 @@
 
 	private void updateDescription() {
 		if (input != null) {
+			String iname = input.getName();
+			String label = null;
 			if (0 == input.getAttributeCount()) {
-				section.setDescription(PDEUIMessages.ExtensionElementDetails_descNoAttributes);
+				label = PDEUIMessages.ExtensionElementDetails_descNoAttributes;
 			} else {
-				String iname = input.getName();
-				section.setDescription(NLS.bind(PDEUIMessages.ExtensionElementDetails_setDesc, iname));
+				label = NLS.bind(PDEUIMessages.ExtensionElementDetails_setDesc, iname);
 			}
+			if (schemaElement.hasDeprecatedAttributes()) {
+				label += " "; //$NON-NLS-1$
+				label += NLS.bind(PDEUIMessages.ExtensionElementDetails_setDescDepr, iname);
+			}
+			if (schemaElement.isDeprecated()) {
+				label += "\n\n"; //$NON-NLS-1$
+				label += NLS.bind(PDEUIMessages.ElementIsDeprecated, iname);
+			}
+			section.setDescription(label);
 		} else {
 			// no extensions = no description
 			section.setDescription(""); //$NON-NLS-1$
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionsSection.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionsSection.java
index 33ebc99..bc4c9d6 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionsSection.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/ExtensionsSection.java
@@ -932,6 +932,9 @@
 			Image customImage = getCustomImage(element);
 			if (customImage != null)
 				elementImage = customImage;
+			customImage = PDEPlugin.getDefault().getLabelProvider().getImage(obj);
+			if (customImage != null)
+				elementImage = customImage;
 		}
 		return elementImage;
 	}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/rows/ExtensionAttributeRow.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/rows/ExtensionAttributeRow.java
index c63458e..b21c444 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/rows/ExtensionAttributeRow.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/editor/plugin/rows/ExtensionAttributeRow.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- *  Copyright (c) 2003, 2012 IBM Corporation and others.
+ *  Copyright (c) 2003, 2014 IBM Corporation and others.
  *  All rights reserved. This program and the accompanying materials
  *  are made available under the terms of the Eclipse Public License v1.0
  *  which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  * 
  *  Contributors:
  *     IBM Corporation - initial API and implementation
+ *     Brian de Alwis (MTI) - bug 429420
  *******************************************************************************/
 
 package org.eclipse.pde.internal.ui.editor.plugin.rows;
@@ -16,6 +17,7 @@
 import org.eclipse.pde.core.plugin.IPluginAttribute;
 import org.eclipse.pde.core.plugin.IPluginElement;
 import org.eclipse.pde.internal.core.ischema.ISchemaAttribute;
+import org.eclipse.pde.internal.ui.PDEUIMessages;
 import org.eclipse.pde.internal.ui.editor.IContextPart;
 import org.eclipse.pde.internal.ui.editor.text.IControlHoverContentProvider;
 import org.eclipse.pde.internal.ui.editor.text.PDETextHover;
@@ -63,9 +65,20 @@
 		return ISchemaAttribute.OPTIONAL;
 	}
 
-	protected String getDescription() {
+	protected boolean isDeprecated() {
 		if (att instanceof ISchemaAttribute)
-			return ((ISchemaAttribute) att).getDescription();
+			return ((ISchemaAttribute) att).isDeprecated();
+		return false;
+	}
+
+	protected String getDescription() {
+		if (att instanceof ISchemaAttribute) {
+			ISchemaAttribute attribute = (ISchemaAttribute) att;
+			if (isDeprecated()) {
+				return "<b>" + PDEUIMessages.ExtensionAttributeRow_AttrDepr + "</b><br>" + attribute.getDescription(); //$NON-NLS-1$//$NON-NLS-2$
+			}
+			return attribute.getDescription();
+		}
 		return ""; //$NON-NLS-1$
 	}
 
@@ -81,6 +94,8 @@
 
 	protected String getPropertyLabel() {
 		String label = getName();
+		if (isDeprecated())
+			label += " (!)"; //$NON-NLS-1$
 		if (getUse() == ISchemaAttribute.REQUIRED)
 			label += "*:"; //$NON-NLS-1$
 		else
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties
index b2f3dac..25a7525 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties
@@ -917,6 +917,7 @@
 <p><img href="search"/> <a href="search">Find declaring extension point</a></p>\
 </form>
 ExtensionElementDetails_setDesc=Set the properties of "{0}". Required fields are denoted by "*".
+ExtensionElementDetails_setDescDepr=Deprecated fields are denoted by "(!)".
 ExtensionEditorSelectionPage_title=Extension Editors
 ExtensionEditorSelectionPage_message=Ex&tension Editors:
 ExtensionEditorSelectionPage_desc=Choose one of the provided wizards to edit the selected extension
@@ -2413,4 +2414,5 @@
 OSGiConsoleFactory_title=WARNING: This console is connected to the current running instance of Eclipse!
 
 NewElement_deprecated={0} (deprecated)
-
+ElementIsDeprecated="{0}" is deprecated.
+ExtensionAttributeRow_AttrDepr=This attribute is deprecated.