#317 A null Element attribute is counted as an attribute

closed-fixed
nobody
5
2010-02-06
2009-07-01
No

When setting an Element attribute to null, somehow the attribute is still counted as an attribute, it is returned from the attribute map (with value null) and it causes two otherwise equal elements to be considered not equal.

Here's a test case:

public void testElementEquals() throws Exception {
assertFalse(new Element("Test").equals(new Object()));
assertFalse(new Element("Test").equals("" ));
assertFalse(new Element("Test").equals(null ));

assertEquals(new Element("Test"), new Element("Test"));

Element elem1 = new Element("Test");
elem1.setAttribute("a", "0");
elem1.setAttribute("b", "1");
elem1.setAttribute("c", "2");

Element elem2 = new Element("Test");
elem2.setAttribute("c", "2");
elem2.setAttribute("b", "1");
elem2.setAttribute("a", "0");

assertTrue(elem1.equals(elem1));
assertTrue(elem1.equals(elem2));
assertTrue(elem2.equals(elem1));
assertTrue(elem2.equals(elem2));

elem1.addChild(new Element("Test2"));
assertFalse(elem1.equals(elem2));
assertFalse(elem2.equals(elem1));
elem2.addChild(new Element("Test2"));
assertTrue(elem1.equals(elem2));
assertTrue(elem2.equals(elem1));

elem1.addText("Bla");
assertFalse(elem1.equals(elem2));
assertFalse(elem2.equals(elem1));
elem2.addText("Bla");
assertTrue(elem1.equals(elem2));
assertTrue(elem2.equals(elem1));

elem1.addChild(new Element("Test3"));
assertFalse(elem1.equals(elem2));
assertFalse(elem2.equals(elem1));
elem2.addChild(new Element("Test3"));
assertTrue(elem1.equals(elem2));
assertTrue(elem2.equals(elem1));

elem2.setAttribute("a899", null);
assertTrue(elem1.equals(elem2));
assertTrue(elem2.equals(elem1));
}

The last two lines fail. I propose adding this test case to ElementTests.java.

The real issue is probably in the ChainedMap.

Discussion

  • Anthony Goubard

    Anthony Goubard - 2010-02-06

    What behaviour do you think it should have?
    - Ignore (if (value==null) return;)
    - Fail with an IAE
    - Add an empty string
    - Remove the attribute

     
  • Ernst de Haan

    Ernst de Haan - 2010-02-06

    What I would expect that if an attribute value is set to null, then the attribute is treated as being unset from that point on.

     
  • Ernst de Haan

    Ernst de Haan - 2010-02-06

    See: http://github.com/znerd/xins/blob/master/src/java/org/xins/common/xml/Element.java

    I think the issue is fixed there in the setAttribute(String,String,String,String) method, as follows:

    public void setAttribute(String namespacePrefix, String namespaceURI, String localName, String value)
    throws IllegalArgumentException {

    // Construct a QualifiedName object; this will check the preconditions
    QualifiedName qn = new QualifiedName(namespacePrefix, namespaceURI, localName);

    // If there are no attributes and the attribute should become null, then
    // nothing needs to be done
    if (_attributes == null && value == null) {
    return;

    // Check if there are any attributes yet, since the collection is lazily
    // initialized
    } else if (_attributes == null) {
    _attributes = new LinkedHashMap<QualifiedName,String>();
    }

    // Reset or set the attribute
    if (value == null) {
    _attributes.remove(qn);
    } else {
    _attributes.put(qn, value);
    }
    }

     
  • Anthony Goubard

    Anthony Goubard - 2010-02-06
    • status: open --> closed-fixed
     
  • Anthony Goubard

    Anthony Goubard - 2010-02-06

    Fixed, will be in 2.3-alpah3.

     

Log in to post a comment.