bug 253753: handle the element's namespace

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/css/PseudoElement.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/css/PseudoElement.java
index 595b4a6..0c73081 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/css/PseudoElement.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/css/PseudoElement.java
@@ -42,13 +42,13 @@
 		}
 		PseudoElement other = (PseudoElement) o;
 		return this.getParent() == other.getParent()
-				&& this.getName().equals(other.getName());
+				&& this.getQualifiedName().equals(other.getQualifiedName());
 	}
 
 	/**
 	 * @see java.lang.Object#hashCode()
 	 */
 	public int hashCode() {
-		return this.getParent().hashCode() + this.getName().hashCode();
+		return this.getParent().hashCode() + this.getQualifiedName().hashCode();
 	}
 }
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/css/Rule.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/css/Rule.java
index 67b213a..30cc2fb 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/css/Rule.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/css/Rule.java
@@ -120,7 +120,6 @@
 			return false;
 		}
 
-		String elementName = element.getName();
 		int selectorType = selector.getSelectorType();
 
 		switch (selectorType) {
@@ -141,7 +140,7 @@
 				if (element instanceof PseudoElement) {
 					AttributeCondition ac = (AttributeCondition) cs
 							.getCondition();
-					return ac.getValue().equals(element.getName())
+					return ac.getValue().equals(element.getLocalName())
 							&& matches(cs.getSimpleSelector(), element
 									.getParent());
 				} else {
@@ -153,6 +152,7 @@
 			}
 
 		case Selector.SAC_ELEMENT_NODE_SELECTOR:
+			String elementName = element.getLocalName();
 			String selectorName = ((ElementSelector) selector).getLocalName();
 			if (selectorName == null) {
 				// We land here if we have a wildcard selector (*) or
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/dom/Element.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/dom/Element.java
index d8e4da0..9d9cac7 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/dom/Element.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/dom/Element.java
@@ -20,6 +20,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.eclipse.core.runtime.QualifiedName;
 import org.eclipse.wst.xml.vex.core.internal.undo.CannotRedoException;
 import org.eclipse.wst.xml.vex.core.internal.undo.CannotUndoException;
 import org.eclipse.wst.xml.vex.core.internal.undo.IUndoableEdit;
@@ -32,21 +33,19 @@
 
 	private static final String XML_BASE_ATTRIBUTE = "xml:base";
 	
-	private String name;
+	private final QualifiedName name;
+	
 	private Element parent = null;
 	private List<Node> childNodes = new ArrayList<Node>();
 	private Map<String, Attribute> attributes = new HashMap<String, Attribute>();
 	private Map<String, String> namespaceDeclarations = new HashMap<String, String>();
 
-	// private String namespaceURI = null;
-	// private String namespacePrefix = null;
-
-	/**
-	 * @param name
-	 *            element name
-	 */
-	public Element(String name) {
-		this.name = name;
+	public Element(final String localName) {
+		this(new QualifiedName(null, localName));
+	}
+	
+	public Element(final QualifiedName qualifiedName) {
+		this.name = qualifiedName;
 	}
 
 	public void addChild(Element child) {
@@ -154,7 +153,26 @@
 	}
 
 	public String getName() {
-		return this.name;
+		return getLocalName();
+	}
+	
+	public String getLocalName() {
+		return name.getLocalName();
+	}
+	
+	public QualifiedName getQualifiedName() {
+		return name;
+	}
+	
+	public String getPrefix() {
+		return getNamespacePrefix(name.getQualifier());
+	}
+	
+	public String getPrefixedName() {
+		String prefix = getPrefix();
+		if (prefix == null)
+			return getLocalName();
+		return prefix + ":" + getLocalName();
 	}
 
 	public Element getParent() {
@@ -190,7 +208,7 @@
 
 		StringBuffer sb = new StringBuffer();
 		sb.append("<");
-		sb.append(this.getName());
+		sb.append(this.getPrefixedName().toString());
 		List<String> attrs = this.getAttributeNames();
 
 		for (int i = 0; i < attrs.size(); i++) {
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/dom/RootElement.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/dom/RootElement.java
index 2b13fdf..458dc32 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/dom/RootElement.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/dom/RootElement.java
@@ -10,6 +10,8 @@
  *******************************************************************************/
 package org.eclipse.wst.xml.vex.core.internal.dom;
 
+import org.eclipse.core.runtime.QualifiedName;
+
 /**
  * The root element of a document. Keeps track of the document to which it is
  * associated. Any element can find the document to which it is associated by
@@ -21,14 +23,12 @@
 
 	private Document document;
 
-	/**
-	 * Class constructor
-	 * 
-	 * @param name
-	 *            Name of the element.
-	 */
-	public RootElement(String name) {
-		super(name);
+	public RootElement(final String localName) {
+		super(localName);
+	}
+	
+	public RootElement(final QualifiedName qualifiedName) {
+		super(qualifiedName);
 	}
 	
 	public Document getDocument() {
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/layout/BlockElementBox.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/layout/BlockElementBox.java
index ed31030..464645c 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/layout/BlockElementBox.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/layout/BlockElementBox.java
@@ -110,7 +110,7 @@
 	}
 
 	public String toString() {
-		return "BlockElementBox: <" + this.getElement().getName() + ">" + "[x="
+		return "BlockElementBox: <" + this.getElement().getPrefixedName() + ">" + "[x="
 				+ this.getX() + ",y=" + this.getY() + ",width="
 				+ this.getWidth() + ",height=" + this.getHeight() + "]";
 	}
diff --git a/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/layout/InlineElementBox.java b/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/layout/InlineElementBox.java
index 39a486d..15755d0 100644
--- a/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/layout/InlineElementBox.java
+++ b/sourceediting/plugins/org.eclipse.wst.xml.vex.core/src/org/eclipse/wst/xml/vex/core/internal/layout/InlineElementBox.java
@@ -229,7 +229,7 @@
 		StringBuffer sb = new StringBuffer();
 		if (this.getStartOffset() == this.getElement().getStartOffset() + 1) {
 			sb.append("<");
-			sb.append(this.getElement().getName());
+			sb.append(this.getElement().getPrefixedName());
 			sb.append(">");
 		}
 		Box[] children = this.getChildren();
@@ -238,7 +238,7 @@
 		}
 		if (this.getEndOffset() == this.getElement().getEndOffset()) {
 			sb.append("</");
-			sb.append(this.getElement().getName());
+			sb.append(this.getElement().getPrefixedName());
 			sb.append(">");
 		}
 		return sb.toString();
diff --git a/sourceediting/tests/org.eclipse.wst.xml.vex.core.tests/src/org/eclipse/wst/xml/vex/core/internal/css/RuleTest.java b/sourceediting/tests/org.eclipse.wst.xml.vex.core.tests/src/org/eclipse/wst/xml/vex/core/internal/css/RuleTest.java
index b5e4712..09f5349 100644
--- a/sourceediting/tests/org.eclipse.wst.xml.vex.core.tests/src/org/eclipse/wst/xml/vex/core/internal/css/RuleTest.java
+++ b/sourceediting/tests/org.eclipse.wst.xml.vex.core.tests/src/org/eclipse/wst/xml/vex/core/internal/css/RuleTest.java
@@ -13,32 +13,30 @@
 import java.net.URL;
 import java.util.List;
 
-import org.eclipse.wst.xml.vex.core.internal.css.Rule;
-import org.eclipse.wst.xml.vex.core.internal.css.StyleSheet;
-import org.eclipse.wst.xml.vex.core.internal.css.StyleSheetReader;
+import junit.framework.TestCase;
+
+import org.eclipse.core.runtime.QualifiedName;
 import org.eclipse.wst.xml.vex.core.internal.dom.Document;
 import org.eclipse.wst.xml.vex.core.internal.dom.Element;
 import org.eclipse.wst.xml.vex.core.internal.dom.RootElement;
 
-import junit.framework.TestCase;
-
 /**
  * Test rule matching.
  */
 public class RuleTest extends TestCase {
 
 	public void testRuleMatching() throws Exception {
-		URL url = RuleTest.class.getResource("testRules.css");
-		StyleSheetReader reader = new StyleSheetReader();
-		StyleSheet ss = reader.read(url);
-		List<Rule> rules = ss.getRules();
+		final URL url = RuleTest.class.getResource("testRules.css");
+		final StyleSheetReader reader = new StyleSheetReader();
+		final StyleSheet ss = reader.read(url);
+		final List<Rule> rules = ss.getRules();
 
-		RootElement a = new RootElement("a");
-		Element b = new Element("b");
-		Element c = new Element("c");
-		Element d = new Element("d");
-		Element e = new Element("e");
-		Element f = new Element("f");
+		final RootElement a = new RootElement("a");
+		final Element b = new Element("b");
+		final Element c = new Element("c");
+		final Element d = new Element("d");
+		final Element e = new Element("e");
+		final Element f = new Element("f");
 
 		b.setAttribute("color", "blue");
 		c.setAttribute("color", "blue red");
@@ -46,7 +44,7 @@
 		e.setAttribute("color", "red blue");
 		f.setAttribute("color", "bluered");
 
-		Document doc = new Document(a);
+		final Document doc = new Document(a);
 		doc.insertElement(1, b);
 		doc.insertElement(2, c);
 		doc.insertElement(3, d);
@@ -267,6 +265,141 @@
 		assertFalse(rule.matches(b));
 		assertTrue(rule.matches(c));
 		assertFalse(rule.matches(d));
+	}
+
+	public void testWithNamespace() throws Exception {
+		final URL url = RuleTest.class.getResource("testRules.css");
+		final StyleSheetReader reader = new StyleSheetReader();
+		final StyleSheet ss = reader.read(url);
+		final List<Rule> rules = ss.getRules();
+
+		final RootElement a = new RootElement("a");
+		final Element ns = new Element(new QualifiedName("http://namespace/uri", "b"));
+
+		ns.setAttribute("color", "blue");
+
+		final Document doc = new Document(a);
+		doc.insertElement(1, ns);
+
+		// /* 0 */ c { }
+		Rule rule = rules.get(0);
+		assertFalse(rule.matches(a));
+		assertFalse(rule.matches(ns));
+
+		// /* 1 */ b c { }
+		rule = rules.get(1);
+		assertFalse(rule.matches(a));
+		assertFalse(rule.matches(ns));
+
+		// /* 2 */ b d { }
+		rule = rules.get(2);
+		assertFalse(rule.matches(a));
+		assertFalse(rule.matches(ns));
+
+		// /* 3 */ other b c { }
+		rule = rules.get(3);
+		assertFalse(rule.matches(a));
+		assertFalse(rule.matches(ns));
+
+		// /* 4 */ other b d { }
+		rule = rules.get(4);
+		assertFalse(rule.matches(a));
+		assertFalse(rule.matches(ns));
+
+		// /* 5 */ a c e { }
+		rule = rules.get(5);
+		assertFalse(rule.matches(a));
+		assertFalse(rule.matches(ns));
+
+		// /* 6 */ c a e { }
+		rule = rules.get(6);
+		assertFalse(rule.matches(a));
+		assertFalse(rule.matches(ns));
+
+		// /* 7 */ * { }
+		rule = rules.get(7);
+		assertTrue(rule.matches(a));
+		assertTrue(rule.matches(ns));
+
+		// /* 8 */ *[color]
+		rule = rules.get(8);
+		assertFalse(rule.matches(a));
+		assertTrue(rule.matches(ns));
+
+		// /* 9 */ a[color]
+		rule = rules.get(9);
+		assertFalse(rule.matches(a));
+		assertFalse(rule.matches(ns));
+
+		// /* 10 */ b[color]
+		rule = rules.get(10);
+		assertFalse(rule.matches(a));
+		assertTrue(rule.matches(ns));
+
+		// /* 11 */ c[color]
+		rule = rules.get(11);
+		assertFalse(rule.matches(a));
+		assertFalse(rule.matches(ns));
+
+		// /* 12 */ d[color]
+		rule = rules.get(12);
+		assertFalse(rule.matches(a));
+		assertFalse(rule.matches(ns));
+
+		// /* 13 */ *[color=blue]
+		rule = rules.get(13);
+		assertFalse(rule.matches(a));
+		assertTrue(rule.matches(ns));
+
+		// /* 14 */ a[color=blue]
+		rule = rules.get(14);
+		assertFalse(rule.matches(a));
+		assertFalse(rule.matches(ns));
+
+		// /* 15 */ b[color=blue]
+		rule = rules.get(15);
+		assertFalse(rule.matches(a));
+		assertTrue(rule.matches(ns));
+
+		// /* 16 */ b[color='blue']
+		rule = rules.get(16);
+		assertFalse(rule.matches(a));
+		assertTrue(rule.matches(ns));
+
+		// /* 17 */ b[color="blue"]
+		rule = rules.get(17);
+		assertFalse(rule.matches(a));
+		assertTrue(rule.matches(ns));
+
+		// /* 18 */ c[color=blue]
+		rule = rules.get(18);
+		assertFalse(rule.matches(a));
+		assertFalse(rule.matches(ns));
+
+		// /* 19 */ a * { }
+		rule = rules.get(19);
+		assertFalse(rule.matches(a));
+		assertTrue(rule.matches(ns));
+
+		// /* 20 */ a > * { }
+		rule = rules.get(20);
+		assertFalse(rule.matches(a));
+		assertTrue(rule.matches(ns));
+
+		// /* 21 */ a *[color] { }
+		rule = rules.get(21);
+		assertFalse(rule.matches(a));
+		assertTrue(rule.matches(ns));
+
+		// /* 22 */ a > *[color] { }
+		rule = rules.get(22);
+		assertFalse(rule.matches(a));
+		assertTrue(rule.matches(ns));
+
+		// /* 23 */ *[color~=blue] { }
+		rule = rules.get(23);
+		assertFalse(rule.matches(a));
+		assertTrue(rule.matches(ns));
 
 	}
 }
diff --git a/sourceediting/tests/org.eclipse.wst.xml.vex.core.tests/src/org/eclipse/wst/xml/vex/core/internal/dom/NamespaceTest.java b/sourceediting/tests/org.eclipse.wst.xml.vex.core.tests/src/org/eclipse/wst/xml/vex/core/internal/dom/NamespaceTest.java
index ea22e22..9452a3d 100644
--- a/sourceediting/tests/org.eclipse.wst.xml.vex.core.tests/src/org/eclipse/wst/xml/vex/core/internal/dom/NamespaceTest.java
+++ b/sourceediting/tests/org.eclipse.wst.xml.vex.core.tests/src/org/eclipse/wst/xml/vex/core/internal/dom/NamespaceTest.java
@@ -113,4 +113,48 @@
 		element.declareDefaultNamespace("http://namespace/uri");

 		assertEquals("http://namespace/uri", element.getDefaultNamespaceURI());

 	}

+	

+	@Test

+	public void elementLocalName() throws Exception {

+		final Element elementWithoutNamespace = new Element("localName");

+		assertEquals("localName", elementWithoutNamespace.getLocalName());

+		final Element elementWithNamespace = new Element(new QualifiedName("http://namespace/uri", "localName"));

+		assertEquals("localName", elementWithNamespace.getLocalName());

+	}

+	

+	@Test

+	public void elementQualifiedName() throws Exception {

+		final Element elementWithoutNamespace = new Element("localName");

+		assertEquals("localName", elementWithoutNamespace.getQualifiedName().toString());

+		final Element elementWithNamespace = new Element(new QualifiedName("http://namespace/uri", "localName"));

+		assertEquals("http://namespace/uri:localName", elementWithNamespace.getQualifiedName().toString());

+	}

+	

+	@Test

+	public void elementPrefix() throws Exception {

+		final Element elementWithoutNamespace = new Element("element");

+		assertNull(elementWithoutNamespace.getPrefix());

+

+		final Element elementWithNamespace = new Element(new QualifiedName("http://namespace/uri", "element"));

+		elementWithNamespace.declareNamespace("nsPrefix", "http://namespace/uri");

+		assertEquals("nsPrefix", elementWithNamespace.getPrefix());

+		

+		final Element elementWithDefaultNamespace = new Element(new QualifiedName("http://namespace/uri", "element"));

+		elementWithDefaultNamespace.declareDefaultNamespace("http://namespace/uri");

+		assertNull(elementWithDefaultNamespace.getPrefix());

+	}

+	

+	@Test

+	public void elementPrefixedName() throws Exception {

+		final Element elementWithoutNamespace = new Element("element");

+		assertEquals("element", elementWithoutNamespace.getPrefixedName());

+

+		final Element elementWithNamespace = new Element(new QualifiedName("http://namespace/uri", "element"));

+		elementWithNamespace.declareNamespace("nsPrefix", "http://namespace/uri");

+		assertEquals("nsPrefix:element", elementWithNamespace.getPrefixedName());

+		

+		final Element elementWithDefaultNamespace = new Element(new QualifiedName("http://namespace/uri", "element"));

+		elementWithDefaultNamespace.declareDefaultNamespace("http://namespace/uri");

+		assertEquals("element", elementWithDefaultNamespace.getPrefixedName());

+	}

 }