[java-metadata-aggregator] 01/03: MDA-109 add stage to trim whitespace from elements

Ian Young ian at iay.org.uk
Tue Dec 1 09:14:58 EST 2015


This is an automated email from the git hooks/post-receive script.

iay pushed a commit to branch master
in repository java-metadata-aggregator.

commit 3bbadc17f3e086b32e0c8675351a760f1c5e3f3c
Author: Ian Young <ian at iay.org.uk>
AuthorDate: Tue Dec 1 15:13:32 2015 +0100

    MDA-109 add stage to trim whitespace from elements
    
    Import DOM traversal framework from ukf-mda project.
---
 .../metadata/dom/AbstractDOMTraversalStage.java    | 179 +++++++++++++++++++++
 .../metadata/dom/AbstractElementVisitingStage.java |  91 +++++++++++
 .../net/shibboleth/metadata/dom/AttrVisitor.java   |  40 +++++
 .../shibboleth/metadata/dom/ElementVisitor.java    |  39 +++++
 .../net/shibboleth/metadata/dom/NodeVisitor.java   |  40 +++++
 5 files changed, 389 insertions(+)

diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMTraversalStage.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMTraversalStage.java
new file mode 100644
index 0000000..c29951a
--- /dev/null
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMTraversalStage.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development, 
+ * Inc. (UCAID) under one or more contributor license agreements.  See the 
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache 
+ * License, Version 2.0 (the "License"); you may not use this file except in 
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.metadata.dom;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.ThreadSafe;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+
+import net.shibboleth.metadata.ErrorStatus;
+import net.shibboleth.metadata.Item;
+import net.shibboleth.metadata.ItemMetadata;
+import net.shibboleth.metadata.dom.saml.SAMLMetadataSupport;
+import net.shibboleth.metadata.pipeline.BaseStage;
+import net.shibboleth.metadata.pipeline.StageProcessingException;
+import net.shibboleth.utilities.java.support.collection.ClassToInstanceMultiMap;
+import net.shibboleth.utilities.java.support.xml.ElementSupport;
+
+/**
+ * A DOM traversal class using the template method pattern.
+ */
+ at ThreadSafe
+public abstract class AbstractDOMTraversalStage extends BaseStage<Element> {
+    
+    /** Context for a particular traversal. */
+    protected class TraversalContext {
+        
+        /** The {@link Item} this traversal is being performed on. */
+        private final Item<Element> item;
+        
+        /** Map of data for this traversal. */
+        private final ClassToInstanceMultiMap<Object> stash = new ClassToInstanceMultiMap<>();
+        
+        /**
+         * Constructor.
+         * 
+         * @param contextItem the {@link Item} this traversal is being performed on.
+         */
+        public TraversalContext(@Nonnull Item<Element> contextItem) {
+            item = contextItem;
+        }
+        
+        /**
+         * Get the {@link Item} this traversal is being performed on.
+         * 
+         * @return the context {@link Item}
+         */
+        public Item<Element> getItem() {
+            return item;
+        }
+        
+        /**
+         * Get the stashed information for this traversal.
+         * 
+         * @return the stashed information
+         */
+        public ClassToInstanceMultiMap<Object> getStash() {
+            return stash;
+        }
+        
+    }
+
+    /**
+     * Indicates whether the visitor should be applied to a particular {@link Element}.
+     * 
+     * @param element {@link Element} to which we may wish to apply the visitor
+     * 
+     * @return <code>true</code> if the visitor should be applied to this {@link Element}.
+     */
+    protected abstract boolean applicable(@Nonnull final Element element);
+
+    /**
+     * Visit a particular {@link Element}.
+     * 
+     * @param element the {@link Element} to visit
+     * @param context the traversal context
+     * @throws StageProcessingException if errors occur during processing
+     */
+    protected abstract void visit(@Nonnull final Element element, @Nonnull final TraversalContext context)
+        throws StageProcessingException;
+    
+    /**
+     * Depth-first traversal of the DOM tree rooted in an element, applying the
+     * visitor when appropriate.  The traversal snapshots the child elements at
+     * each level, so that the visitor could in principle reorder or delete them
+     * during processing.
+     * 
+     * @param element {@link Element} to start from
+     * @param context context for the traversal
+     * @throws StageProcessingException if errors occur during processing
+     */
+    private void traverse(@Nonnull final Element element, @Nonnull final TraversalContext context) 
+        throws StageProcessingException {
+        final List<Element> children = ElementSupport.getChildElements(element);
+        for (Element child : children) {
+            traverse(child, context);
+        }
+        if (applicable(element)) {
+            visit(element, context);
+        }
+    }
+    
+    @Override
+    protected void doExecute(Collection<Item<Element>> itemCollection) throws StageProcessingException {
+        for (Item<Element> item : itemCollection) {
+            final Element docElement = item.unwrap();
+            final TraversalContext context = new TraversalContext(item);
+            traverse(docElement, context);
+        }
+    }
+
+    /**
+     * Returns the {@link Element} representing the EntityDescriptor which is the
+     * closest-containing ancestor of the given element.
+     * 
+     * @param element {@link Element} to locate the ancestor Entity of.
+     * @return ancestor EntityDescriptor {@link Element}, or null.
+     */
+    protected Element ancestorEntity(@Nonnull final Element element) {
+        assert element != null;
+        for (Element e = element; e != null; e = (Element) e.getParentNode()) {
+            if (SAMLMetadataSupport.isEntityDescriptor(e)) {
+                return e;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Add an {@link ErrorStatus} to the given item, in respect of the given {@link Element}.
+     * If the item is an EntitiesDescriptor, interpose an identifier for the individual
+     * EntityDescriptor.
+     * 
+     * @param item      {@link Item} to add the error to
+     * @param element   {@link Element} the error reflects
+     * @param error     error text
+     */
+    protected void addError(@Nonnull final Item<Element> item, @Nonnull final Element element,
+            @Nonnull final String error) {
+        assert item != null;
+        assert element != null;
+        assert error != null;
+        final ClassToInstanceMultiMap<ItemMetadata> metadata = item.getItemMetadata();
+        String prefix = "";
+        if (SAMLMetadataSupport.isEntitiesDescriptor(element)) {
+            final Element entity = ancestorEntity(element);
+            final Attr id = entity.getAttributeNode("ID");
+            if (id != null) {
+                prefix = id.getTextContent() + ": ";
+            } else {
+                Attr entityID = entity.getAttributeNode("entityID");
+                if (entityID != null) {
+                    prefix = entityID.getTextContent() + ": ";
+                }
+            }
+        }
+        metadata.put(new ErrorStatus(getId(), prefix + error));
+    }
+
+}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractElementVisitingStage.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractElementVisitingStage.java
new file mode 100644
index 0000000..983e082
--- /dev/null
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractElementVisitingStage.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development, 
+ * Inc. (UCAID) under one or more contributor license agreements.  See the 
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache 
+ * License, Version 2.0 (the "License"); you may not use this file except in 
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.metadata.dom;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.annotation.Nonnull;
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+/**
+ * Abstract parent class for stages which visit {@link Element}s named by a
+ * collection of {@link QName}s.
+ */
+public abstract class AbstractElementVisitingStage extends AbstractDOMTraversalStage {
+
+    /** Collection of element names for those elements we will be visiting. */
+    @Nonnull private Set<QName> elementNames = Collections.emptySet();
+
+    @Override
+    protected void doDestroy() {
+        elementNames = null;
+
+        super.doDestroy();
+    }
+
+    /**
+     * Gets the collection of element names to visit.
+     * 
+     * @return collection of element names to visit.
+     */
+    @Nonnull public Collection<QName> getElementNames() {
+        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+        return elementNames;
+    }
+
+    /**
+     * Sets the collection of element names to visit.
+     * 
+     * @param names collection of element names to visit.
+     */
+    public void setElementNames(@Nonnull final Collection<QName> names) {
+        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        Constraint.isNotNull(names, "elementNames may not be null");
+        elementNames = new HashSet<>(names);
+    }
+    
+    /**
+     * Sets a single element name to be visited.
+     * 
+     * Shorthand for {@link #setElementNames} with a singleton set.
+     * 
+     * @param name {@link QName} for the element to be visited.
+     */
+    public void setElementName(@Nonnull final QName name) {
+        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        Constraint.isNotNull(name, "elementName may not be null");
+        elementNames = Collections.singleton(name);
+    }
+    
+    @Override
+    protected boolean applicable(@Nonnull final Element e) {
+        final QName q = new QName(e.getNamespaceURI(), e.getLocalName());
+        return elementNames.contains(q);
+    }
+
+}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AttrVisitor.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AttrVisitor.java
new file mode 100644
index 0000000..be1032b
--- /dev/null
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AttrVisitor.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development, 
+ * Inc. (UCAID) under one or more contributor license agreements.  See the 
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache 
+ * License, Version 2.0 (the "License"); you may not use this file except in 
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.metadata.dom;
+
+import net.shibboleth.metadata.Item;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+
+/**
+ * Provides a variation of the Visitor pattern for performing operations on
+ * DOM attributes which are part of {@link Element} items.
+ */
+public interface AttrVisitor {
+
+    /**
+     * Called on each {@link Attr} visited as part of the processing
+     * of an {@link Element} item.
+     * 
+     * @param visited the {@link Attr} being visited.
+     * @param item the {@link Item} which is the context for the visit.
+     */
+    public void visitAttr(Attr visited, Item<Element> item);
+    
+}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementVisitor.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementVisitor.java
new file mode 100644
index 0000000..89283ed
--- /dev/null
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementVisitor.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development, 
+ * Inc. (UCAID) under one or more contributor license agreements.  See the 
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache 
+ * License, Version 2.0 (the "License"); you may not use this file except in 
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.metadata.dom;
+
+import net.shibboleth.metadata.Item;
+
+import org.w3c.dom.Element;
+
+/**
+ * Provides a variation of the Visitor pattern for performing operations on
+ * DOM elements which are part of {@link Element} items.
+ */
+public interface ElementVisitor {
+
+    /**
+     * Called on each {@link Element} visited as part of the processing
+     * of an {@link Element} item.
+     * 
+     * @param visited the {@link Element} being visited.
+     * @param item the {@link Item} which is the context for the visit.
+     */
+    public void visitElement(Element visited, Item<Element> item);
+    
+}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/NodeVisitor.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/NodeVisitor.java
new file mode 100644
index 0000000..9e43c4e
--- /dev/null
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/NodeVisitor.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development, 
+ * Inc. (UCAID) under one or more contributor license agreements.  See the 
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache 
+ * License, Version 2.0 (the "License"); you may not use this file except in 
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.metadata.dom;
+
+import net.shibboleth.metadata.Item;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Provides a variation of the Visitor pattern for performing operations on
+ * DOM nodes which are part of {@link Element} items.
+ */
+public interface NodeVisitor {
+
+    /**
+     * Called on each {@link Node} visited as part of the processing
+     * of an {@link Element} item.
+     * 
+     * @param visited the {@link Node} being visited.
+     * @param item the {@link Item} which is the context for the visit.
+     */
+    public void visitNode(Node visited, Item<Element> item);
+    
+}

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list