[java-opensaml COMMIT] /trunk/opensaml-util/src/main/java/org/opensaml/util/xml/traversal/IdAttributeIndexer.java
noreply at shibboleth.net
noreply at shibboleth.net
Mon Oct 17 14:12:19 BST 2011
Author: lajoie
Date: Mon Oct 17 14:12:18 2011
New Revision: 2916
URL: http://svn.shibboleth.net/view/java-opensaml?rev=2916&view=rev
Log:
Implement the actual logic for this
Modified:
trunk/opensaml-util/src/main/java/org/opensaml/util/xml/traversal/IdAttributeIndexer.java
Modified: trunk/opensaml-util/src/main/java/org/opensaml/util/xml/traversal/IdAttributeIndexer.java
URL: http://svn.shibboleth.net/view/java-opensaml/trunk/opensaml-util/src/main/java/org/opensaml/util/xml/traversal/IdAttributeIndexer.java?rev=2916&r1=2915&r2=2916&view=diff
==============================================================================
--- trunk/opensaml-util/src/main/java/org/opensaml/util/xml/traversal/IdAttributeIndexer.java (original)
+++ trunk/opensaml-util/src/main/java/org/opensaml/util/xml/traversal/IdAttributeIndexer.java Mon Oct 17 14:12:18 2011
@@ -17,33 +17,79 @@
package org.opensaml.util.xml.traversal;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import javax.xml.namespace.QName;
+
+import org.opensaml.util.constraint.documented.NoNullElements;
+import org.opensaml.util.constraint.documented.NotNull;
+import org.opensaml.util.constraint.documented.Unmodifiable;
+import org.opensaml.util.xml.QNameSupport;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
-import org.w3c.dom.UserDataHandler;
/**
* This {@link NodeVisitor} performs two tasks. One it creates an index, stored as use data on the {@link Document}
* node, that maps an ID to the element that carries that ID. Second, it ensure thats all IDs in the document are
- * unique. This visitor only works if the first node in the traversal is either a {@link Document} or an {@link Element}
- * that is the document element.
+ * unique.
*
* In addition to attributes which are known to be ID attributes (i.e., {@link Attr#isId()} returns true) this visitor
* can treat other attributes as ID attributes. This is helpful if the content model of the document is known ahead of
* time and schema validation is not used (and thus ID attributes are not marked as such).
*
- * This visitor installs a {@link UserDataHandler} on all {@link Element} and {@link Attr} nodes and uses this to keep
- * the ID index up to date across DOM mutations.
- *
- * If, at any point, the uniqueness constraint on IDs is violated, a {@link DuplicateIdException} will be thrown.
+ * This visitor only works if the first node in the traversal is either a {@link Document} or an {@link Element} that is
+ * the document element. If more than one element has the same ID a {@link DuplicateIdException} is thrown.
*/
public class IdAttributeIndexer implements NodeVisitor {
/** The name under which the ID index will be stored as {@link Document} user data. */
private static final String USER_DATA_NAME = IdAttributeIndexer.class.getPackage().getName() + ".IdIndex";
+
+ /** Name of attributes that should be considered ID attribute, regardless of whether {@link Attr#isId()} is true. */
+ private Set<QName> idAttributes;
+
+ /** Constructor. */
+ public IdAttributeIndexer() {
+ idAttributes = Collections.emptySet();
+ }
+
+ /**
+ * Gets attributes considered ID attributes.
+ *
+ * @return attributes considered ID attributes
+ */
+ public @NotNull @NoNullElements @Unmodifiable Set<QName> getIdAttributes() {
+ return idAttributes;
+ }
+
+ /**
+ * Sets the attributes considered ID attributes.
+ *
+ * @param attributes attributes considered ID attributes
+ */
+ public void setIdAttributes(final Set<QName> attributes) {
+ if (attributes == null || attributes.isEmpty()) {
+ idAttributes = Collections.emptySet();
+ }
+
+ HashSet<QName> newIdAttributes = new HashSet<QName>();
+ for (QName attribute : attributes) {
+ if (attribute != null) {
+ newIdAttributes.add(attribute);
+ }
+ }
+
+ if (newIdAttributes.isEmpty()) {
+ idAttributes = Collections.emptySet();
+ } else {
+ idAttributes = Collections.unmodifiableSet(attributes);
+ }
+ }
/** {@inheritDoc} */
public boolean supportsNodeType(Short nodeType) {
@@ -70,10 +116,25 @@
/** {@inheritDoc} */
public void visit(Node node) throws TraversalException {
- Attr attribute = (Attr) node;
+ final Attr attribute = (Attr) node;
+ final QName attributeName = QNameSupport.getNodeQName(attribute);
- // TODO Auto-generated method stub
+ if (idAttributes.contains(attributeName)) {
+ final HashMap<String, Element> idIndex =
+ (HashMap<String, Element>) node.getOwnerDocument().getUserData(USER_DATA_NAME);
+ final Element element = attribute.getOwnerElement();
+ final String id = attribute.getValue();
+ if (idIndex.containsKey(id)) {
+ final Element previousElement = idIndex.get(id);
[... 31 lines stripped ...]
More information about the commits
mailing list