[java-metadata-aggregator] 03/03: MDA-234 - Add an item ordering stage, refactor interfaces

Ian Young ian at iay.org.uk
Sat Mar 14 12:58:50 EDT 2020


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=2ef2600bf6ccf7ee83e53234bea59f98209d2b5c

commit 2ef2600bf6ccf7ee83e53234bea59f98209d2b5c
Author: Ian Young <ian at iay.org.uk>
AuthorDate: Sat Mar 14 16:58:40 2020 +0000

    MDA-234 - Add an item ordering stage, refactor interfaces
    
    https://issues.shibboleth.net/jira/browse/MDA-234
---
 .../dom/saml/EntitiesDescriptorAssemblerStage.java | 63 ++++-------------
 .../metadata/pipeline/ItemOrderingStage.java       | 80 ++++++++++++++++++++++
 .../metadata/pipeline/ItemOrderingStrategy.java    | 50 ++++++++++++++
 .../pipeline/impl/NoOpItemOrderingStrategy.java    | 43 ++++++++++++
 .../metadata/pipeline/impl/package-info.java       | 21 ++++++
 .../resources/net/shibboleth/metadata/beans.xml    |  3 +
 .../saml/EntitiesDescriptorAssemblerStageTest.java |  8 +--
 .../metadata/pipeline/ItemOrderingStageTest.java   | 68 ++++++++++++++++++
 8 files changed, 284 insertions(+), 52 deletions(-)

diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/saml/EntitiesDescriptorAssemblerStage.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/saml/EntitiesDescriptorAssemblerStage.java
index 19b3dd4..dc65f54 100644
--- a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/saml/EntitiesDescriptorAssemblerStage.java
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/dom/saml/EntitiesDescriptorAssemblerStage.java
@@ -17,7 +17,6 @@
 
 package net.shibboleth.metadata.dom.saml;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
@@ -26,12 +25,19 @@ import javax.annotation.Nullable;
 import javax.annotation.concurrent.ThreadSafe;
 import javax.xml.namespace.QName;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
 import net.shibboleth.metadata.Item;
 import net.shibboleth.metadata.dom.DOMElementItem;
 import net.shibboleth.metadata.pipeline.AbstractStage;
+import net.shibboleth.metadata.pipeline.ItemOrderingStrategy;
 import net.shibboleth.metadata.pipeline.StageProcessingException;
+import net.shibboleth.metadata.pipeline.impl.NoOpItemOrderingStrategy;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
-import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 import net.shibboleth.utilities.java.support.component.ComponentSupport;
 import net.shibboleth.utilities.java.support.logic.Constraint;
 import net.shibboleth.utilities.java.support.primitive.StringSupport;
@@ -39,12 +45,6 @@ import net.shibboleth.utilities.java.support.xml.AttributeSupport;
 import net.shibboleth.utilities.java.support.xml.ElementSupport;
 import net.shibboleth.utilities.java.support.xml.NamespaceSupport;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.DOMImplementation;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
 /**
  * A {@link net.shibboleth.metadata.pipeline.Stage} capable of assembling a collection of EntityDescriptor elements in
  * to a single EntitiesDescriptor element.
@@ -65,7 +65,8 @@ public class EntitiesDescriptorAssemblerStage extends AbstractStage<Element> {
     private boolean noChildrenAProcessingError;
 
     /** Strategy used to order a collection of Items. The default strategy performs no ordering. */
-    private ItemOrderingStrategy orderingStrategy = new NoOpItemOrderingStrategy();
+    @Nonnull
+    private ItemOrderingStrategy<Element> orderingStrategy = new NoOpItemOrderingStrategy<>();
 
     /** Name to use for the EntitiesDescriptor. */
     private String descriptorName;
@@ -98,7 +99,7 @@ public class EntitiesDescriptorAssemblerStage extends AbstractStage<Element> {
      * 
      * @return strategy used to order a collection of Items
      */
-    @Nonnull public ItemOrderingStrategy getItemOrderingStrategy() {
+    @Nonnull public ItemOrderingStrategy<Element> getItemOrderingStrategy() {
         return orderingStrategy;
     }
 
@@ -107,7 +108,7 @@ public class EntitiesDescriptorAssemblerStage extends AbstractStage<Element> {
      * 
      * @param strategy strategy used to order a collection of Items
      */
-    public synchronized void setItemOrderingStrategy(@Nonnull final ItemOrderingStrategy strategy) {
+    public synchronized void setItemOrderingStrategy(@Nonnull final ItemOrderingStrategy<Element> strategy) {
         ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
         ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
 
@@ -192,46 +193,12 @@ public class EntitiesDescriptorAssemblerStage extends AbstractStage<Element> {
         }
     }
 
-    /** {@inheritDoc} */
-    @Override protected void doDestroy() {
+    @Override
+    protected void doDestroy() {
         orderingStrategy = null;
         descriptorName = null;
 
         super.doDestroy();
     }
 
-    /** {@inheritDoc} */
-    @Override protected void doInitialize() throws ComponentInitializationException {
-        super.doInitialize();
-
-        if (orderingStrategy == null) {
-            orderingStrategy = new NoOpItemOrderingStrategy();
-        }
-    }
-
-    /** A strategy that defines how to order a {@link net.shibboleth.metadata.Item} collection. */
-    public static interface ItemOrderingStrategy {
-
-        /**
-         * Orders a given Item collection.
-         * 
-         * @param items collection of {@link Item}s, never null
-         * 
-         * @return sorted collection of {@link Item}s, never null
-         * 
-         * @throws StageProcessingException if the items in the collection cannot be ordered, for example
-         *      because they do not meet required pre-conditions
-         */
-        public List<Item<Element>> order(@Nonnull @NonnullElements final Collection<Item<Element>> items)
-            throws StageProcessingException;
-    }
-
-    /** An ordering strategy that simply returns the collection in whatever order it was already in. */
-    private class NoOpItemOrderingStrategy implements ItemOrderingStrategy {
-
-        /** {@inheritDoc} */
-        @Override public List<Item<Element>> order(@Nonnull @NonnullElements final Collection<Item<Element>> items) {
-            return new ArrayList<>(items);
-        }
-    }
-}
\ No newline at end of file
+}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/pipeline/ItemOrderingStage.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/pipeline/ItemOrderingStage.java
new file mode 100644
index 0000000..c0c9b72
--- /dev/null
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/pipeline/ItemOrderingStage.java
@@ -0,0 +1,80 @@
+/*
+ * 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.pipeline;
+
+import java.util.Collection;
+
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.ThreadSafe;
+
+import net.shibboleth.metadata.Item;
+import net.shibboleth.metadata.pipeline.impl.NoOpItemOrderingStrategy;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+/**
+ * A {@link net.shibboleth.metadata.pipeline.Stage} capable of ordering a collection of {@link Item}s
+ * according to a supplied strategy.
+ * 
+ * @param <T> type of the items to be ordered
+ */
+ at ThreadSafe
+public class ItemOrderingStage<T> extends AbstractStage<T> {
+
+    /** Strategy used to order a collection of Items. The default strategy performs no ordering. */
+    @Nonnull
+    private ItemOrderingStrategy<T> orderingStrategy = new NoOpItemOrderingStrategy<>();
+
+    /**
+     * Gets the strategy used to order a collection of Items.
+     * 
+     * @return strategy used to order a collection of Items
+     */
+    @Nonnull public ItemOrderingStrategy<T> getItemOrderingStrategy() {
+        return orderingStrategy;
+    }
+
+    /**
+     * Sets the strategy used to order a collection of Items.
+     * 
+     * @param strategy strategy used to order a collection of Items
+     */
+    public synchronized void setItemOrderingStrategy(@Nonnull final ItemOrderingStrategy<T> strategy) {
+        ComponentSupport.ifDestroyedThrowDestroyedComponentException(this);
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+        orderingStrategy = Constraint.isNotNull(strategy, "Item ordering strategy can not be null");
+    }
+
+    @Override
+    protected void doExecute(@Nonnull @NonnullElements final Collection<Item<T>> itemCollection)
+            throws StageProcessingException {
+        final var orderedItems = orderingStrategy.order(itemCollection);
+        itemCollection.clear();
+        itemCollection.addAll(orderedItems);
+    }
+
+    @Override
+    protected void doDestroy() {
+        orderingStrategy = null;
+
+        super.doDestroy();
+    }
+
+}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/pipeline/ItemOrderingStrategy.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/pipeline/ItemOrderingStrategy.java
new file mode 100644
index 0000000..c7aa6a5
--- /dev/null
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/pipeline/ItemOrderingStrategy.java
@@ -0,0 +1,50 @@
+/*
+ * 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.pipeline;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.metadata.Item;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
+
+/**
+ * A strategy that defines how to order a {@link net.shibboleth.metadata.Item} collection.
+ *
+ * @param <T> type of item to be handled
+ */
+public interface ItemOrderingStrategy<T> {
+
+    /**
+     * Orders a given Item collection.
+     * 
+     * @param items collection of {@link Item}s, never null
+     * 
+     * @return sorted {@link List} of {@link Item}s, never null
+     * 
+     * @throws StageProcessingException if the items in the collection cannot be ordered, for example
+     *      because they do not meet required pre-conditions
+     */
+    @Nonnull @NonnullElements @Unmodifiable
+    List<Item<T>> order(@Nonnull @NonnullElements @Unmodifiable final Collection<Item<T>> items)
+        throws StageProcessingException;
+
+}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/pipeline/impl/NoOpItemOrderingStrategy.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/pipeline/impl/NoOpItemOrderingStrategy.java
new file mode 100644
index 0000000..cd74f68
--- /dev/null
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/pipeline/impl/NoOpItemOrderingStrategy.java
@@ -0,0 +1,43 @@
+/*
+ * 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.pipeline.impl;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+
+import net.shibboleth.metadata.Item;
+import net.shibboleth.metadata.pipeline.ItemOrderingStrategy;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
+
+/**
+ * An ordering strategy that simply returns the collection in whatever order it was already in.
+ *
+ * @param <T> type of item to be handled
+ */
+public class NoOpItemOrderingStrategy<T> implements ItemOrderingStrategy<T> {
+
+    @Override
+    @Nonnull @NonnullElements @Unmodifiable
+    public List<Item<T>> order(@Nonnull @NonnullElements @Unmodifiable final Collection<Item<T>> items) {
+        return List.copyOf(items);
+    }
+
+}
diff --git a/aggregator-pipeline/src/main/java/net/shibboleth/metadata/pipeline/impl/package-info.java b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/pipeline/impl/package-info.java
new file mode 100644
index 0000000..e4e543c
--- /dev/null
+++ b/aggregator-pipeline/src/main/java/net/shibboleth/metadata/pipeline/impl/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Non-API classes for the pipeline package.
+ */
+package net.shibboleth.metadata.pipeline.impl;
diff --git a/aggregator-pipeline/src/main/resources/net/shibboleth/metadata/beans.xml b/aggregator-pipeline/src/main/resources/net/shibboleth/metadata/beans.xml
index 766df94..0fd6d15 100644
--- a/aggregator-pipeline/src/main/resources/net/shibboleth/metadata/beans.xml
+++ b/aggregator-pipeline/src/main/resources/net/shibboleth/metadata/beans.xml
@@ -216,6 +216,9 @@
     <bean id="mda.ItemMetadataTerminationStage" abstract="true" parent="mda.stage_parent"
         class="net.shibboleth.metadata.pipeline.ItemMetadataTerminationStage"/>
 
+    <bean id="mda.ItemOrderingStage" abstract="true" parent="mda.stage_parent"
+        class="net.shibboleth.metadata.pipeline.ItemOrderingStage"/>
+    
     <bean id="mda.MDQueryMD5ItemIdTransformer" abstract="true"
         class="net.shibboleth.metadata.pipeline.MDQueryMD5ItemIdTransformer"/>
 
diff --git a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/saml/EntitiesDescriptorAssemblerStageTest.java b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/saml/EntitiesDescriptorAssemblerStageTest.java
index b70b1c8..38e7189 100644
--- a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/saml/EntitiesDescriptorAssemblerStageTest.java
+++ b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/dom/saml/EntitiesDescriptorAssemblerStageTest.java
@@ -25,7 +25,7 @@ import java.util.List;
 import net.shibboleth.metadata.Item;
 import net.shibboleth.metadata.dom.BaseDOMTest;
 import net.shibboleth.metadata.dom.DOMElementItem;
-import net.shibboleth.metadata.dom.saml.EntitiesDescriptorAssemblerStage.ItemOrderingStrategy;
+import net.shibboleth.metadata.pipeline.ItemOrderingStrategy;
 
 import org.testng.Assert;
 import org.testng.annotations.Test;
@@ -85,10 +85,10 @@ public class EntitiesDescriptorAssemblerStageTest extends BaseDOMTest {
     public void testAssemblingWithOrdering() throws Exception {
         
         /** Ordering strategy class which simply reverses the order of items. */
-        class ReverseOrder implements ItemOrderingStrategy {
+        class ReverseOrder implements ItemOrderingStrategy<Element> {
 
-            /** {@inheritDoc} */
-        	@Override public List<Item<Element>> order(Collection<Item<Element>> items) {
+        	@Override
+        	public List<Item<Element>> order(Collection<Item<Element>> items) {
                 final List<Item<Element>> result = new ArrayList<>(items);
                 Collections.reverse(result);
                 return result;
diff --git a/aggregator-pipeline/src/test/java/net/shibboleth/metadata/pipeline/ItemOrderingStageTest.java b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/pipeline/ItemOrderingStageTest.java
new file mode 100644
index 0000000..ac11d41
--- /dev/null
+++ b/aggregator-pipeline/src/test/java/net/shibboleth/metadata/pipeline/ItemOrderingStageTest.java
@@ -0,0 +1,68 @@
+
+package net.shibboleth.metadata.pipeline;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import net.shibboleth.metadata.Item;
+import net.shibboleth.metadata.MockItem;
+
+public class ItemOrderingStageTest {
+
+    private class ReversalOrderingStrategy<T> implements ItemOrderingStrategy<T> {
+
+        @Override
+        public List<Item<T>> order(Collection<Item<T>> items) throws StageProcessingException {
+            final var collection = new ArrayList<Item<T>>();
+            collection.addAll(items);
+            Collections.reverse(collection);
+            return List.copyOf(collection);
+        }
+        
+    }
+
+    @Test
+    public void testIdentity() throws Exception {
+        final var stage = new ItemOrderingStage<String>();
+        stage.setId("test");
+        stage.initialize();
+
+        final List<Item<String>> items = new ArrayList<>();
+        items.add(new MockItem("one"));
+        items.add(new MockItem("two"));
+        items.add(new MockItem("three"));
+        
+        stage.execute(items);
+        
+        Assert.assertEquals(items.size(), 3);
+        Assert.assertEquals(items.get(0).unwrap(), "one");
+        Assert.assertEquals(items.get(1).unwrap(), "two");
+        Assert.assertEquals(items.get(2).unwrap(), "three");
+    }
+
+    @Test
+    public void testReverse() throws Exception {
+        final var stage = new ItemOrderingStage<String>();
+        stage.setId("test");
+        stage.setItemOrderingStrategy(new ReversalOrderingStrategy<String>());
+        stage.initialize();
+
+        final List<Item<String>> items = new ArrayList<>();
+        items.add(new MockItem("one"));
+        items.add(new MockItem("two"));
+        items.add(new MockItem("three"));
+        
+        stage.execute(items);
+        
+        Assert.assertEquals(items.size(), 3);
+        Assert.assertEquals(items.get(2).unwrap(), "one");
+        Assert.assertEquals(items.get(1).unwrap(), "two");
+        Assert.assertEquals(items.get(0).unwrap(), "three");
+    }
+
+}

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


More information about the commits mailing list