bug 253753: show namespaces and details about the element in the
properties view
Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/NamespaceTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/NamespaceTest.java
index 558deaa..ed546d5 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/NamespaceTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/NamespaceTest.java
@@ -314,4 +314,33 @@
assertEquals(inputContent, outputContent);
}
+
+ @Test
+ public void allVisibleNamespacePrefixes() throws Exception {
+ final Element parent = new Element("parent");
+ final Element element = new Element("element");
+ final Element child = new Element("child");
+ parent.addChild(element);
+ parent.declareDefaultNamespace("http://namespace/uri/parent/default");
+ parent.declareNamespace("ns1", "http://namespace/uri/1");
+ parent.declareNamespace("ns2", "http://namespace/uri/2");
+ element.addChild(child);
+ element.declareNamespace("ns3", "http://namespace/uri/3");
+ element.declareNamespace("ns1", "http://namespace/uri/1a");
+ child.declareDefaultNamespace("http://namespace/uri/child/default");
+
+ assertEquals(2, parent.getNamespacePrefixes().size());
+ assertTrue(parent.getNamespacePrefixes().contains("ns1"));
+ assertTrue(parent.getNamespacePrefixes().contains("ns2"));
+
+ assertEquals(3, element.getNamespacePrefixes().size());
+ assertTrue(element.getNamespacePrefixes().contains("ns1"));
+ assertTrue(element.getNamespacePrefixes().contains("ns2"));
+ assertTrue(element.getNamespacePrefixes().contains("ns3"));
+
+ assertEquals(3, child.getNamespacePrefixes().size());
+ assertTrue(child.getNamespacePrefixes().contains("ns1"));
+ assertTrue(child.getNamespacePrefixes().contains("ns2"));
+ assertTrue(child.getNamespacePrefixes().contains("ns3"));
+ }
}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Element.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Element.java
index 5640308..eb95d37 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Element.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Element.java
@@ -15,6 +15,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -266,49 +267,6 @@
return sb.toString();
}
- // ========================================================= PRIVATE
-
- private class AttributeChangeEdit implements IUndoableEdit {
-
- private QualifiedName name;
- private String oldValue;
- private String newValue;
-
- public AttributeChangeEdit(QualifiedName name, String oldValue, String newValue) {
- this.name = name;
- this.oldValue = oldValue;
- this.newValue = newValue;
- }
-
- public boolean combine(IUndoableEdit edit) {
- return false;
- }
-
- public void undo() throws CannotUndoException {
- Document doc = (Document) getDocument();
- try {
- doc.setUndoEnabled(false);
- setAttribute(name, oldValue);
- } catch (DocumentValidationException ex) {
- throw new CannotUndoException();
- } finally {
- doc.setUndoEnabled(true);
- }
- }
-
- public void redo() throws CannotRedoException {
- Document doc = (Document) getDocument();
- try {
- doc.setUndoEnabled(false);
- setAttribute(name, newValue);
- } catch (DocumentValidationException ex) {
- throw new CannotUndoException();
- } finally {
- doc.setUndoEnabled(true);
- }
- }
- }
-
public void setParent(Element parent) {
this.parent = parent;
}
@@ -353,6 +311,14 @@
return result;
}
+ public Collection<String> getNamespacePrefixes() {
+ final HashSet<String> result = new HashSet<String>();
+ result.addAll(getDeclaredNamespacePrefixes());
+ if (parent != null)
+ result.addAll(parent.getNamespacePrefixes());
+ return result;
+ }
+
public void declareNamespace(final String namespacePrefix, final String namespaceURI) {
if (namespaceURI == null || "".equals(namespaceURI.trim()))
return;
@@ -376,16 +342,6 @@
return "Element";
}
- /**
- * Sets the content of the node
- *
- * @param content
- * Content object holding the node's content
- * @param startOffset
- * offset at which the node's content starts
- * @param endOffset
- * offset at which the node's content ends
- */
public void setContent(Content content, int startOffset, int endOffset) {
super.setContent(content, startOffset, endOffset);
}
@@ -401,4 +357,46 @@
return getDocument().getBaseURI();
return null;
}
+
+ private class AttributeChangeEdit implements IUndoableEdit {
+
+ private QualifiedName name;
+ private String oldValue;
+ private String newValue;
+
+ public AttributeChangeEdit(QualifiedName name, String oldValue, String newValue) {
+ this.name = name;
+ this.oldValue = oldValue;
+ this.newValue = newValue;
+ }
+
+ public boolean combine(IUndoableEdit edit) {
+ return false;
+ }
+
+ public void undo() throws CannotUndoException {
+ Document doc = (Document) getDocument();
+ try {
+ doc.setUndoEnabled(false);
+ setAttribute(name, oldValue);
+ } catch (DocumentValidationException ex) {
+ throw new CannotUndoException();
+ } finally {
+ doc.setUndoEnabled(true);
+ }
+ }
+
+ public void redo() throws CannotRedoException {
+ Document doc = (Document) getDocument();
+ try {
+ doc.setUndoEnabled(false);
+ setAttribute(name, newValue);
+ } catch (DocumentValidationException ex) {
+ throw new CannotUndoException();
+ } finally {
+ doc.setUndoEnabled(true);
+ }
+ }
+ }
+
}
diff --git a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/property/ElementPropertySource.java b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/property/ElementPropertySource.java
index 78ceb93..174ec37 100644
--- a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/property/ElementPropertySource.java
+++ b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/property/ElementPropertySource.java
@@ -1,98 +1,145 @@
/*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2011 John Krasnay 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * John Krasnay - initial API and implementation
+ * John Krasnay - initial API and implementation
+ * Florian Thienel - namespace support (bug 253753)
*******************************************************************************/
package org.eclipse.vex.ui.internal.property;
+import java.util.ArrayList;
import java.util.List;
import org.eclipse.ui.views.properties.ComboBoxPropertyDescriptor;
import org.eclipse.ui.views.properties.IPropertyDescriptor;
+import org.eclipse.ui.views.properties.IPropertySheetEntry;
import org.eclipse.ui.views.properties.IPropertySource2;
import org.eclipse.ui.views.properties.PropertyDescriptor;
import org.eclipse.ui.views.properties.TextPropertyDescriptor;
import org.eclipse.vex.core.internal.dom.Attribute;
import org.eclipse.vex.core.internal.dom.DocumentValidationException;
import org.eclipse.vex.core.internal.dom.Element;
+import org.eclipse.vex.core.internal.dom.Namespace;
import org.eclipse.vex.core.internal.dom.Validator;
import org.eclipse.vex.core.internal.validator.AttributeDefinition;
import org.eclipse.vex.ui.internal.editor.Messages;
-/**
- * Property source that treats element attributes as properties.
- */
public class ElementPropertySource implements IPropertySource2 {
- /**
- * Class constructor.
- *
- * @param element
- * Selected element.
- * @param validator
- * Validator used to get attribute definitions for the element.
- * @param multi
- * True if multiple elements are selected. In this case the "id"
- * attribute will not be editable.
- */
- public ElementPropertySource(final Element element, final Validator validator, final boolean multi) {
+ private static final String ATTR_ID = "id"; //$NON-NLS-1$
+
+ private static final String ELEMENT_NAME_PROPERTY = "elementName"; //$NON-NLS-1$
+ private static final String ELEMENT_NAMESPACE_URI_PROPERTY = "elementNsUri"; //$NON-NLS-1$
+ private static final String ELEMENT_NAMESPACE_PREFIX_PROPERTY = "elementNsPrefix"; //$NON-NLS-1$
+
+ private static final String ELEMENT_CATEGORY = "Element";
+ private static final String ATTRIBUTES_CATEGORY = "Attributes";
+ private static final String NAMESPACES_CATEGORY = "Namespaces";
+
+ private final Element element;
+ private final Validator validator;
+ private final boolean multipleElementsSelected;
+
+ public ElementPropertySource(final Element element, final Validator validator, final boolean multipleElementsSelected) {
this.element = element;
this.validator = validator;
- this.multi = multi;
+ this.multipleElementsSelected = multipleElementsSelected;
}
public Object getEditableValue() {
- // TODO Auto-generated method stub
return null;
}
public IPropertyDescriptor[] getPropertyDescriptors() {
- // note that elements from DocumentFragments don't have access
- // to their original document, so we get it from the VexWidget
- final List<AttributeDefinition> attrDefs = validator.getAttributeDefinitions(element);
- final IPropertyDescriptor[] pds = new IPropertyDescriptor[attrDefs.size()];
- for (int i = 0; i < attrDefs.size(); i++) {
- final AttributeDefinition def = attrDefs.get(i);
- if (multi && def.getName().equals(ATTR_ID))
- pds[i] = new PropertyDescriptor(def, def.getName());
- else if (def.isFixed())
- pds[i] = new PropertyDescriptor(def, def.getName());
- else if (def.getType() == AttributeDefinition.Type.ENUMERATION)
- pds[i] = new ComboBoxPropertyDescriptor(def, def.getName(), getEnumValues(def));
- else
- pds[i] = new TextPropertyDescriptor(def, def.getName());
+ final List<IPropertyDescriptor> result = new ArrayList<IPropertyDescriptor>();
+
+ result.add(createExpertPropertyDescriptor(ELEMENT_NAME_PROPERTY, "Element Name", ELEMENT_CATEGORY));
+
+ if (element.getQualifiedName().getQualifier() != null) {
+ result.add(createExpertPropertyDescriptor(ELEMENT_NAMESPACE_URI_PROPERTY, "Namespace URI", ELEMENT_CATEGORY));
+ result.add(createExpertPropertyDescriptor(ELEMENT_NAMESPACE_PREFIX_PROPERTY, "Namespace Prefix", ELEMENT_CATEGORY));
}
- return pds;
+
+ /*
+ * Note that elements from DocumentFragments don't have access to
+ * their original document, so we get it from the VexWidget.
+ */
+ final List<AttributeDefinition> attributeDefinitions = validator.getAttributeDefinitions(element);
+ for (final AttributeDefinition attributeDefinition : attributeDefinitions) {
+ final PropertyDescriptor propertyDescriptor;
+ if (multipleElementsSelected && attributeDefinition.getName().equals(ATTR_ID))
+ propertyDescriptor = new PropertyDescriptor(attributeDefinition, attributeDefinition.getName());
+ else if (attributeDefinition.isFixed())
+ propertyDescriptor = new PropertyDescriptor(attributeDefinition, attributeDefinition.getName());
+ else if (attributeDefinition.getType() == AttributeDefinition.Type.ENUMERATION)
+ propertyDescriptor = new ComboBoxPropertyDescriptor(attributeDefinition, attributeDefinition.getName(), getEnumValues(attributeDefinition));
+ else
+ propertyDescriptor = new TextPropertyDescriptor(attributeDefinition, attributeDefinition.getName());
+ propertyDescriptor.setCategory(ATTRIBUTES_CATEGORY);
+ result.add(propertyDescriptor);
+ }
+
+ for (final String namespacePrefix : element.getNamespacePrefixes()) {
+ final String namespaceUri = element.getNamespaceURI(namespacePrefix);
+ final NamespaceUri namespaceDeclaration = new NamespaceUri(namespaceUri);
+ result.add(createExpertPropertyDescriptor(namespaceDeclaration, Namespace.XMLNS_NAMESPACE_PREFIX + ":" + namespacePrefix, NAMESPACES_CATEGORY));
+ }
+
+ final String defaultNamespaceUri = element.getDefaultNamespaceURI();
+ if (defaultNamespaceUri != null) {
+ final NamespaceUri namespaceDeclaration = new NamespaceUri(defaultNamespaceUri);
+ result.add(createExpertPropertyDescriptor(namespaceDeclaration, Namespace.XMLNS_NAMESPACE_PREFIX, NAMESPACES_CATEGORY));
+ }
+
+ return result.toArray(new IPropertyDescriptor[result.size()]);
+ }
+
+ private IPropertyDescriptor createExpertPropertyDescriptor(final Object id, final String displayName, final String category) {
+ final PropertyDescriptor propertyDescriptor = new PropertyDescriptor(id, displayName);
+ propertyDescriptor.setCategory(category);
+ propertyDescriptor.setFilterFlags(new String[] { IPropertySheetEntry.FILTER_ID_EXPERT });
+ return propertyDescriptor;
}
public Object getPropertyValue(final Object id) {
- if (!(id instanceof AttributeDefinition))
- return "";
- final AttributeDefinition attributeDefinition = (AttributeDefinition) id;
- if (multi && id.equals(ATTR_ID))
- return Messages.getString("ElementPropertySource.multiple"); //$NON-NLS-1$
+ if (id == ELEMENT_NAME_PROPERTY)
+ return element.getLocalName();
+ if (id == ELEMENT_NAMESPACE_URI_PROPERTY)
+ return element.getQualifiedName().getQualifier();
+ if (id == ELEMENT_NAMESPACE_PREFIX_PROPERTY)
+ return element.getNamespacePrefix(element.getQualifiedName().getQualifier());
+
+ if (id instanceof AttributeDefinition) {
+ final AttributeDefinition attributeDefinition = (AttributeDefinition) id;
+ if (multipleElementsSelected && id.equals(ATTR_ID))
+ return Messages.getString("ElementPropertySource.multiple"); //$NON-NLS-1$
- final Attribute attribute = element.getAttribute(attributeDefinition.getName());
- final String value;
- if (attribute != null)
- value = attribute.getValue();
- else
- value = nullToEmpty(attributeDefinition.getDefaultValue());
+ final Attribute attribute = element.getAttribute(attributeDefinition.getName());
+ final String value;
+ if (attribute != null)
+ value = attribute.getValue();
+ else
+ value = nullToEmpty(attributeDefinition.getDefaultValue());
- if (attributeDefinition.getType() == AttributeDefinition.Type.ENUMERATION) {
- final String[] values = getEnumValues(attributeDefinition);
- for (int i = 0; i < values.length; i++)
- if (values[i].equals(value))
- return Integer.valueOf(i);
- return Integer.valueOf(0);
- // TODO: If the actual value is not in the list, we should probably add it.
+ if (attributeDefinition.getType() == AttributeDefinition.Type.ENUMERATION) {
+ final String[] values = getEnumValues(attributeDefinition);
+ for (int i = 0; i < values.length; i++)
+ if (values[i].equals(value))
+ return Integer.valueOf(i);
+ return Integer.valueOf(0);
+ // TODO: If the actual value is not in the list, we should probably add it.
+ }
+ return value;
}
- return value;
+
+ if (id instanceof NamespaceUri)
+ return ((NamespaceUri) id).uri;
+
+ return "";
}
private static String nullToEmpty(final String string) {
@@ -102,24 +149,39 @@
}
public boolean isPropertySet(final Object id) {
- // TODO Auto-generated method stub
+ if (id == ELEMENT_NAME_PROPERTY)
+ return true;
+ if (id == ELEMENT_NAMESPACE_URI_PROPERTY)
+ return true;
+ if (id == ELEMENT_NAMESPACE_PREFIX_PROPERTY)
+ return true;
+
+ if (id instanceof AttributeDefinition) {
+ final AttributeDefinition attributeDefinition = (AttributeDefinition) id;
+ final Attribute attribute = element.getAttribute(attributeDefinition.getName());
+ if (attribute == null)
+ return false;
+ return true;
+ }
+
+ if (id instanceof NamespaceUri)
+ return true;
+
return false;
}
public void resetPropertyValue(final Object id) {
- // TODO Auto-generated method stub
-
+ if (!(id instanceof AttributeDefinition))
+ return;
+ final AttributeDefinition attributeDefinition = (AttributeDefinition) id;
+ element.removeAttribute(attributeDefinition.getName());
}
public void setPropertyValue(final Object id, final Object value) {
if (!(id instanceof AttributeDefinition))
return;
- /*
- * Note that elements from DocumentFragments don't have access to
- * their original document, so we get it from the VexWidget.
- */
final AttributeDefinition attributeDefinition = (AttributeDefinition) id;
-
+
try {
if (attributeDefinition.getType() == AttributeDefinition.Type.ENUMERATION) {
final int i = ((Integer) value).intValue();
@@ -139,22 +201,9 @@
}
}
- public boolean isPropertyResettable(final Object id) {
- // TODO Auto-generated method stub
- return true;
- }
-
- // ======================================== PRIVATE
-
- private static final String ATTR_ID = "id"; //$NON-NLS-1$
-
- private final Element element;
- private final Validator validator;
- private final boolean multi;
-
- private String[] getEnumValues(final AttributeDefinition def) {
- String[] values = def.getValues();
- if (def.isRequired())
+ private static String[] getEnumValues(final AttributeDefinition attributeDefinition) {
+ String[] values = attributeDefinition.getValues();
+ if (attributeDefinition.isRequired())
return values;
else {
if (values == null) {
@@ -168,4 +217,18 @@
}
}
+ public boolean isPropertyResettable(final Object id) {
+ if (!(id instanceof AttributeDefinition))
+ return false;
+ return true;
+ }
+
+ private static class NamespaceUri {
+ public final String uri;
+
+ public NamespaceUri(final String uri) {
+ this.uri = uri;
+ }
+ }
+
}
\ No newline at end of file