[java-metadata-aggregator] branch master updated: MDA-188 - refactor DOM traversal with more generic context mechanism
Ian Young
ian at iay.org.uk
Tue Aug 8 11:40:37 EDT 2017
This is an automated email from the git hooks/post-receive script.
iay pushed a commit to branch master
in repository java-metadata-aggregator.
View the commit online:
http://git.shibboleth.net/view/?p=java-metadata-aggregator.git;a=commit;h=2660ba0c241a6fac3c443ca19573573906a93b53
The following commit(s) were added to refs/heads/master by this push:
new 2660ba0 MDA-188 - refactor DOM traversal with more generic context mechanism
2660ba0 is described below
commit 2660ba0c241a6fac3c443ca19573573906a93b53
Author: Ian Young <ian at iay.org.uk>
AuthorDate: Tue Aug 8 16:40:25 2017 +0100
MDA-188 - refactor DOM traversal with more generic context mechanism
---
.../metadata/dom/AbstractDOMTraversalStage.java | 79 ++++++++--------------
.../metadata/dom/AbstractDOMValidationStage.java | 18 ++---
.../metadata/dom/AbstractElementVisitingStage.java | 8 ++-
.../shibboleth/metadata/dom/CRDetectionStage.java | 50 ++++++++++++--
...TrimmingStage.java => DOMTraversalContext.java} | 30 +++++---
.../dom/ElementWhitespaceTrimmingStage.java | 2 +-
.../metadata/dom/ElementsStrippingStage.java | 60 ++++++++++++----
...ngStage.java => SimpleDOMTraversalContext.java} | 28 ++++++--
.../metadata/dom/ds/X509ValidationStage.java | 67 ++++++++++++++++--
.../dom/AbstractDOMValidationStageTest.java | 11 ++-
10 files changed, 247 insertions(+), 106 deletions(-)
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
index e4cd818..b4e24c2 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMTraversalStage.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMTraversalStage.java
@@ -36,47 +36,30 @@ import net.shibboleth.utilities.java.support.xml.ElementSupport;
/**
* An abstract DOM traversal class using the template method pattern.
+ *
+ * A context object, extending {@link DOMTraversalContext}, is created by the
+ * implementing subclass and passed to the {@link #visit} method when
+ * each applicable {@link Element} is visited. In very simple cases, the
+ * {@link SimpleDOMTraversalContext} may suffice, but more complicated
+ * behaviour can be built up by extending or re-implementing that class.
+ *
+ * At the end of the traversal, the context's {@link DOMTraversalContext#end()}
+ * method is called to perform any post-processing required.
+ *
+ * @param <C> the context to carry through the traversal
*/
@ThreadSafe
-public abstract class AbstractDOMTraversalStage extends AbstractIteratingStage<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<>(true);
-
- /**
- * Constructor.
- *
- * @param contextItem the {@link Item} this traversal is being performed on.
- */
- public TraversalContext(@Nonnull final 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;
- }
-
- }
+public abstract class AbstractDOMTraversalStage<C extends DOMTraversalContext>
+ extends AbstractIteratingStage<Element> {
+
+ /**
+ * Build the context for a particular traversal.
+ *
+ * @param item the {@link Item} we are traversing
+ *
+ * @return an appropriate context
+ */
+ protected abstract C buildContext(@Nonnull final Item<Element> item);
/**
* Indicates whether the visitor should be applied to a particular {@link Element}.
@@ -94,9 +77,9 @@ public abstract class AbstractDOMTraversalStage extends AbstractIteratingStage<E
* @param context the traversal context
* @throws StageProcessingException if errors occur during processing
*/
- protected abstract void visit(@Nonnull final Element element, @Nonnull final TraversalContext context)
+ protected abstract void visit(@Nonnull final Element element, @Nonnull final C 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
@@ -107,7 +90,7 @@ public abstract class AbstractDOMTraversalStage extends AbstractIteratingStage<E
* @param context context for the traversal
* @throws StageProcessingException if errors occur during processing
*/
- private void traverse(@Nonnull final Element element, @Nonnull final TraversalContext context)
+ private void traverse(@Nonnull final Element element, @Nonnull final C context)
throws StageProcessingException {
final List<Element> children = ElementSupport.getChildElements(element);
for (final Element child : children) {
@@ -121,9 +104,9 @@ public abstract class AbstractDOMTraversalStage extends AbstractIteratingStage<E
@Override
protected void doExecute(final Item<Element> item) throws StageProcessingException {
final Element docElement = item.unwrap();
- final TraversalContext context = new TraversalContext(item);
+ final C context = buildContext(item);
traverse(docElement, context);
- endTraversal(context);
+ context.end();
}
/**
@@ -174,12 +157,4 @@ public abstract class AbstractDOMTraversalStage extends AbstractIteratingStage<E
metadata.put(new ErrorStatus(getId(), prefix + error));
}
- /**
- * This method is called once the traversal has finished. It may be overridden by subclasses.
- *
- * @param context the context for which the traversal has finished
- */
- protected void endTraversal(@Nonnull final TraversalContext context) {
- }
-
}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMValidationStage.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMValidationStage.java
index 985a8ae..2bad57f 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMValidationStage.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractDOMValidationStage.java
@@ -22,21 +22,23 @@ import java.util.List;
import javax.annotation.Nonnull;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
import net.shibboleth.metadata.pipeline.StageProcessingException;
import net.shibboleth.metadata.validate.Validator;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
/**
* An abstract stage to apply a collection of validators to each object from each item.
- *
+ *
* @param <V> type of the object to be validated
- */
-public abstract class AbstractDOMValidationStage<V> extends AbstractDOMTraversalStage {
+ * @param <C> the context to carry through the traversal
+ */
+public abstract class AbstractDOMValidationStage<V, C extends DOMTraversalContext>
+ extends AbstractDOMTraversalStage<C> {
/** The list of validators to apply. */
@Nonnull
@@ -71,7 +73,7 @@ public abstract class AbstractDOMValidationStage<V> extends AbstractDOMTraversal
* @param context context for the validation
* @throws StageProcessingException if errors occur during processing
*/
- protected void applyValidators(@Nonnull final V obj, @Nonnull final TraversalContext context)
+ protected void applyValidators(@Nonnull final V obj, @Nonnull final C context)
throws StageProcessingException {
for (final Validator<V> validator: validators) {
final Validator.Action action = validator.validate(obj, context.getItem(), getId());
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
index 8532dc8..b390270 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractElementVisitingStage.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/AbstractElementVisitingStage.java
@@ -27,6 +27,7 @@ import javax.xml.namespace.QName;
import org.w3c.dom.Element;
+import net.shibboleth.metadata.Item;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
@@ -34,7 +35,7 @@ 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 {
+public abstract class AbstractElementVisitingStage extends AbstractDOMTraversalStage<DOMTraversalContext> {
/** Collection of element names for those elements we will be visiting. */
@Nonnull private Set<QName> elementNames = Collections.emptySet();
@@ -88,4 +89,9 @@ public abstract class AbstractElementVisitingStage extends AbstractDOMTraversalS
return elementNames.contains(q);
}
+ @Override
+ protected DOMTraversalContext buildContext(@Nonnull final Item<Element> item) {
+ return new SimpleDOMTraversalContext(item);
+ }
+
}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/CRDetectionStage.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/CRDetectionStage.java
index 112834b..795bfd0 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/CRDetectionStage.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/CRDetectionStage.java
@@ -17,6 +17,8 @@
package net.shibboleth.metadata.dom;
+import javax.annotation.Nonnull;
+
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
@@ -34,7 +36,40 @@ import net.shibboleth.metadata.pipeline.StageProcessingException;
*
* @see <a href="https://issues.shibboleth.net/jira/browse/SSPCPP-684">SSPCPP-684</a>
*/
-public class CRDetectionStage extends AbstractDOMTraversalStage {
+public class CRDetectionStage extends AbstractDOMTraversalStage<CRDetectionStage.Context> {
+
+ /** Context class for this kind of traversal. */
+ protected static class Context extends SimpleDOMTraversalContext {
+
+ /** <code>true</code> once an error has been detected. */
+ private boolean error;
+
+ /**
+ * Constructor.
+ *
+ * @param contextItem the {@link Item} this traversal is being performed on.
+ */
+ public Context(@Nonnull final Item<Element> contextItem) {
+ super(contextItem);
+ }
+
+ /**
+ * Returns <code>true</code> if an error has been detected.
+ *
+ * @return <code>true</code> if an error has been detected
+ */
+ public boolean hasError() {
+ return error;
+ }
+
+ /**
+ * Record that an error has been detected.
+ */
+ public void setError() {
+ error = true;
+ }
+
+ }
/** Character value we are looking for. */
private static final char CR = '\r';
@@ -46,9 +81,9 @@ public class CRDetectionStage extends AbstractDOMTraversalStage {
}
@Override
- protected void visit(final Element element, final TraversalContext context) throws StageProcessingException {
+ protected void visit(final Element element, final Context context) throws StageProcessingException {
// Only permit one error; short-circuit any further examinations
- if (!context.getStash().isEmpty()) {
+ if (context.hasError()) {
return;
}
@@ -63,7 +98,7 @@ public class CRDetectionStage extends AbstractDOMTraversalStage {
*/
if (node.getNodeType() == Node.TEXT_NODE && node.getNodeValue().indexOf(CR) >= 0) {
addError(item, element, "element text content contains a carriage return character");
- context.getStash().put(Boolean.TRUE);
+ context.setError();
return;
}
}
@@ -74,10 +109,15 @@ public class CRDetectionStage extends AbstractDOMTraversalStage {
final Node attribute = attributes.item(index);
if (attribute.getNodeValue().indexOf(CR) >= 0) {
addError(item, element, "attribute value contains a carriage return character");
- context.getStash().put(Boolean.TRUE);
+ context.setError();
return;
}
}
}
+ @Override
+ protected Context buildContext(@Nonnull final Item<Element> item) {
+ return new Context(item);
+ }
+
}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementWhitespaceTrimmingStage.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/DOMTraversalContext.java
similarity index 58%
copy from aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementWhitespaceTrimmingStage.java
copy to aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/DOMTraversalContext.java
index 0cbd511..66c4e0c 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementWhitespaceTrimmingStage.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/DOMTraversalContext.java
@@ -21,18 +21,28 @@ import javax.annotation.Nonnull;
import org.w3c.dom.Element;
+import net.shibboleth.metadata.Item;
+
/**
- * Stage to trim leading and trailing whitespace from the text content of named elements
- * within a {@link net.shibboleth.metadata.dom.DOMElementItem}.
+ * The context for a particular DOM traversal.
+ *
+ * Implementations may add additional fields and methods to the definition
+ * of a {@link DOMTraversalContext}, and may define {@link #end()} to perform
+ * operations at the end of the traversal.
*/
-public class ElementWhitespaceTrimmingStage extends AbstractElementVisitingStage {
-
- /** Visitor to apply to each visited element. */
- @Nonnull private final ElementVisitor visitor = new WhitespaceTrimmingVisitor();
+public interface DOMTraversalContext {
- @Override
- protected void visit(@Nonnull final Element e, @Nonnull final TraversalContext context) {
- visitor.visitElement(e, context.getItem());
- }
+ /**
+ * Get the {@link Item} this traversal is being performed on.
+ *
+ * @return the context {@link Item}
+ */
+ @Nonnull Item<Element> getItem();
+ /**
+ * Perform any clean-up or final operations for the traversal.
+ *
+ * Called at the end of the traversal, may be overridden by subclasses.
+ */
+ void end();
}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementWhitespaceTrimmingStage.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementWhitespaceTrimmingStage.java
index 0cbd511..f849f17 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementWhitespaceTrimmingStage.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementWhitespaceTrimmingStage.java
@@ -31,7 +31,7 @@ public class ElementWhitespaceTrimmingStage extends AbstractElementVisitingStage
@Nonnull private final ElementVisitor visitor = new WhitespaceTrimmingVisitor();
@Override
- protected void visit(@Nonnull final Element e, @Nonnull final TraversalContext context) {
+ protected void visit(@Nonnull final Element e, @Nonnull final DOMTraversalContext context) {
visitor.visitElement(e, context.getItem());
}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementsStrippingStage.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementsStrippingStage.java
index 9706f87..22a8d7a 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementsStrippingStage.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementsStrippingStage.java
@@ -17,8 +17,10 @@
package net.shibboleth.metadata.dom;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import javax.annotation.Nonnull;
@@ -27,6 +29,7 @@ import javax.annotation.concurrent.ThreadSafe;
import org.w3c.dom.Element;
+import net.shibboleth.metadata.Item;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
@@ -51,7 +54,42 @@ import net.shibboleth.utilities.java.support.primitive.StringSupport;
* do <i>not</i> appear in the collection of names.
*/
@ThreadSafe
-public class ElementsStrippingStage extends AbstractDOMTraversalStage {
+public class ElementsStrippingStage extends AbstractDOMTraversalStage<ElementsStrippingStage.Context> {
+
+ /** Context class for this kind of traversal. */
+ protected static class Context extends SimpleDOMTraversalContext {
+
+ /**
+ * List of {@link Element}s to be removed from the document at the
+ * end of the traversal.
+ */
+ private List<Element> elements = new ArrayList<>();
+
+ /**
+ * Constructor.
+ *
+ * @param contextItem the {@link Item} we are traversing
+ */
+ public Context(@Nonnull final Item<Element> contextItem) {
+ super(contextItem);
+ }
+
+ /**
+ * Add the given {@link Element} to the list for later removal.
+ *
+ * @param element the {@link Element} to be removed
+ */
+ protected void add(@Nonnull final Element element) {
+ elements.add(element);
+ }
+
+ @Override
+ public void end() {
+ for (final Element element : elements) {
+ element.getParentNode().removeChild(element);
+ }
+ }
+ }
/** Namespace of the elements to strip. */
private String elementNamespace;
@@ -106,7 +144,7 @@ public class ElementsStrippingStage extends AbstractDOMTraversalStage {
}
/**
- * Set whether the {@link #names} are to be used as a whitelist.
+ * Set whether the {@link #elementNames} are to be used as a whitelist.
*
* The default behaviour is for the names to be used as a blacklist.
*
@@ -117,7 +155,7 @@ public class ElementsStrippingStage extends AbstractDOMTraversalStage {
}
/**
- * Indicates whether the {@link #names} are being used as a whitelist.
+ * Indicates whether the {@link #elementNames} are being used as a whitelist.
*
* @return <code>true</code> if the names are being used as a whitelist
*/
@@ -138,15 +176,8 @@ public class ElementsStrippingStage extends AbstractDOMTraversalStage {
@Override
protected void visit(@Nonnull final Element element,
- @Nonnull final TraversalContext context) {
- context.getStash().put(element);
- }
-
- @Override
- protected void endTraversal(@Nonnull final TraversalContext context) {
- for (final Element element : context.getStash().get(Element.class)) {
- element.getParentNode().removeChild(element);
- }
+ @Nonnull final Context context) {
+ context.add(element);
}
@Override
@@ -165,4 +196,9 @@ public class ElementsStrippingStage extends AbstractDOMTraversalStage {
}
}
+ @Override
+ protected Context buildContext(@Nonnull final Item<Element> item) {
+ return new Context(item);
+ }
+
}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementWhitespaceTrimmingStage.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/SimpleDOMTraversalContext.java
similarity index 60%
copy from aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementWhitespaceTrimmingStage.java
copy to aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/SimpleDOMTraversalContext.java
index 0cbd511..24b1f6a 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ElementWhitespaceTrimmingStage.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/SimpleDOMTraversalContext.java
@@ -21,18 +21,32 @@ import javax.annotation.Nonnull;
import org.w3c.dom.Element;
+import net.shibboleth.metadata.Item;
+
/**
- * Stage to trim leading and trailing whitespace from the text content of named elements
- * within a {@link net.shibboleth.metadata.dom.DOMElementItem}.
+ * A simple implementation of the {@link DOMTraversalContext} interface.
*/
-public class ElementWhitespaceTrimmingStage extends AbstractElementVisitingStage {
+public class SimpleDOMTraversalContext implements DOMTraversalContext {
+
+ /** The {@link Item} this traversal is being performed on. */
+ private final Item<Element> item;
+
+ /**
+ * Constructor.
+ *
+ * @param contextItem the {@link Item} this traversal is being performed on.
+ */
+ public SimpleDOMTraversalContext(@Nonnull final Item<Element> contextItem) {
+ item = contextItem;
+ }
- /** Visitor to apply to each visited element. */
- @Nonnull private final ElementVisitor visitor = new WhitespaceTrimmingVisitor();
+ @Override
+ public Item<Element> getItem() {
+ return item;
+ }
@Override
- protected void visit(@Nonnull final Element e, @Nonnull final TraversalContext context) {
- visitor.visitElement(e, context.getItem());
+ public void end() {
}
}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ds/X509ValidationStage.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ds/X509ValidationStage.java
index db853a8..117ded2 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ds/X509ValidationStage.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/ds/X509ValidationStage.java
@@ -21,27 +21,80 @@ import java.io.ByteArrayInputStream;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.Map;
import javax.annotation.Nonnull;
+import org.w3c.dom.Element;
+
import net.shibboleth.metadata.ErrorStatus;
+import net.shibboleth.metadata.Item;
import net.shibboleth.metadata.dom.AbstractDOMValidationStage;
+import net.shibboleth.metadata.dom.SimpleDOMTraversalContext;
import net.shibboleth.metadata.pipeline.StageProcessingException;
import net.shibboleth.utilities.java.support.codec.Base64Support;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
-import org.w3c.dom.Element;
-
/**
* Stage to apply a collection of validators to each X.509 certificate in items.
*
* Each X.509 certificate is processed only once per item, so that duplicate status messages are suppressed.
*/
-public class X509ValidationStage extends AbstractDOMValidationStage<X509Certificate> {
+public class X509ValidationStage extends AbstractDOMValidationStage<X509Certificate, X509ValidationStage.Context> {
+
+ /** Context class for this kind of traversal. */
+ protected static class Context extends SimpleDOMTraversalContext {
+
+ /**
+ * Collection of certificates we have already seen.
+ *
+ * This is used to ensure that we only issue one error for each different certificate;
+ * duplicates are ignored.
+ *
+ * This is achieved by using a {@link Map} from certificates to themselves and
+ * detecting presence using {@link Map#containsKey}.
+ */
+ private Map<X509Certificate, X509Certificate> certMap = new HashMap<>();
+
+ /**
+ * Constructor.
+ *
+ * @param contextItem the {@link Item} this traversal is being performed on.
+ */
+ public Context(@Nonnull final Item<Element> contextItem) {
+ super(contextItem);
+ }
+
+ /**
+ * Returns whether we have seen this certificate before.
+ *
+ * @param cert {@link X509Certificate} to check for.
+ * @return <code>true</code> if we have seen this certificate before.
+ */
+ protected boolean haveSeen(@Nonnull final X509Certificate cert) {
+ return certMap.containsKey(cert);
+ }
+
+ /**
+ * Add a certificate to the list of certificates we have seen and processed already.
+ *
+ * @param cert {@link X509Certificate} to add to the list of already seen certificates.
+ */
+ protected void add(@Nonnull final X509Certificate cert) {
+ certMap.put(cert, cert);
+ }
+
+ }
/** Certificate factory to use to convert to X.509 certificates. */
private CertificateFactory factory;
-
+
+ @Override
+ protected Context buildContext(@Nonnull final Item<Element> item) {
+ return new Context(item);
+ }
+
@Override
protected boolean applicable(@Nonnull final Element e) {
return XMLDSIGSupport.XML_DSIG_NS.equals(e.getNamespaceURI()) &&
@@ -49,7 +102,7 @@ public class X509ValidationStage extends AbstractDOMValidationStage<X509Certific
}
@Override
- protected void visit(@Nonnull final Element element, @Nonnull final TraversalContext context)
+ protected void visit(@Nonnull final Element element, @Nonnull final Context context)
throws StageProcessingException {
final String text = element.getTextContent();
final byte[] data = Base64Support.decode(text);
@@ -57,8 +110,8 @@ public class X509ValidationStage extends AbstractDOMValidationStage<X509Certific
final X509Certificate cert =
(X509Certificate) factory.generateCertificate(new ByteArrayInputStream(data));
// only process each certificate once per item
- if (!context.getStash().containsValue(cert)) {
- context.getStash().put(cert);
+ if (!context.haveSeen(cert)) {
+ context.add(cert);
applyValidators(cert, context);
}
} catch (final CertificateException e) {
diff --git a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/AbstractDOMValidationStageTest.java b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/AbstractDOMValidationStageTest.java
index 3d0cd8e..708b8e4 100644
--- a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/AbstractDOMValidationStageTest.java
+++ b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/AbstractDOMValidationStageTest.java
@@ -37,7 +37,7 @@ public class AbstractDOMValidationStageTest extends BaseDOMTest {
super(AbstractDOMValidationStage.class);
}
- private static class StringValidationStage extends AbstractDOMValidationStage<String> {
+ private static class StringValidationStage extends AbstractDOMValidationStage<String, DOMTraversalContext> {
@Override
protected boolean applicable(Element element) {
@@ -45,10 +45,15 @@ public class AbstractDOMValidationStageTest extends BaseDOMTest {
}
@Override
- protected void visit(Element element, TraversalContext context) throws StageProcessingException {
+ protected void visit(Element element, DOMTraversalContext context) throws StageProcessingException {
applyValidators(element.getTextContent(), context);
}
-
+
+ @Override
+ protected DOMTraversalContext buildContext(Item<Element> item) {
+ return new SimpleDOMTraversalContext(item);
+ }
+
}
private static class FirstStringValidator extends BaseValidator implements Validator<String> {
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list