diff --git a/core/pom.xml b/core/pom.xml
index d5b9697..1cafd94 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -37,6 +37,13 @@
test
+
+ cglib
+ cglib
+ 2.2.2
+ test
+
+
diff --git a/core/src/main/java/org/springframework/plugin/core/MutablePluginRegistry.java b/core/src/main/java/org/springframework/plugin/core/MutablePluginRegistry.java
deleted file mode 100644
index d4798fe..0000000
--- a/core/src/main/java/org/springframework/plugin/core/MutablePluginRegistry.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2008-2012 the original author or authors.
- *
- * Licensed 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 org.springframework.plugin.core;
-
-/**
- * Extension of {@link PluginRegistry} with additional methods to modify the registry.
- *
- * @author Oliver Gierke
- */
-public interface MutablePluginRegistry, S> extends PluginRegistry {
-
- /**
- * Adds a given plugin to the registry.
- *
- * @param plugin must not be {@literal null}.
- */
- MutablePluginRegistry addPlugin(T plugin);
-
- /**
- * Removes a given plugin from the registry.
- *
- * @param plugin must not be {@literal null}.
- */
- boolean removePlugin(T plugin);
-}
diff --git a/core/src/main/java/org/springframework/plugin/core/OrderAwarePluginRegistry.java b/core/src/main/java/org/springframework/plugin/core/OrderAwarePluginRegistry.java
index addcca5..718c6db 100644
--- a/core/src/main/java/org/springframework/plugin/core/OrderAwarePluginRegistry.java
+++ b/core/src/main/java/org/springframework/plugin/core/OrderAwarePluginRegistry.java
@@ -58,7 +58,7 @@ public class OrderAwarePluginRegistry, S> extends SimplePlug
protected OrderAwarePluginRegistry(List extends T> plugins, Comparator super T> comparator) {
super(plugins);
- setComparator(comparator);
+ this.comparator = (Comparator super T>) (comparator == null ? DEFAULT_COMPARATOR : comparator);
}
/**
@@ -122,34 +122,16 @@ public class OrderAwarePluginRegistry, S> extends SimplePlug
return new OrderAwarePluginRegistry(plugins, comparator);
}
- /**
- * Sets the comparator to use. Resorts the contained {@link Plugin}s if any available.
- *
- * @param comparator the comparator to set
- */
- private void setComparator(Comparator super T> comparator) {
-
- this.comparator = DEFAULT_COMPARATOR;
-
- if (comparator != null) {
- this.comparator = comparator;
- }
-
- if (plugins != null) {
- Collections.sort(plugins, comparator);
- }
- }
-
- /*
+ /*
* (non-Javadoc)
- * @see org.springframework.plugin.core.SimplePluginRegistry#addPlugin(org.springframework.plugin.core.Plugin)
+ * @see org.springframework.plugin.core.PluginRegistrySupport#initialize(java.util.List)
*/
@Override
- public OrderAwarePluginRegistry addPlugin(T plugin) {
+ protected List initialize(List plugins) {
- super.addPlugin(plugin);
- Collections.sort(plugins, comparator);
- return this;
+ List result = super.initialize(plugins);
+ Collections.sort(result, comparator);
+ return result;
}
/**
@@ -160,7 +142,7 @@ public class OrderAwarePluginRegistry, S> extends SimplePlug
@SuppressWarnings({ "unchecked", "rawtypes" })
public OrderAwarePluginRegistry reverse() {
- ArrayList copy = new ArrayList(plugins);
+ ArrayList copy = new ArrayList(getPlugins());
return create(copy, new InvertibleComparator(comparator, false));
}
}
diff --git a/core/src/main/java/org/springframework/plugin/core/PluginRegistrySupport.java b/core/src/main/java/org/springframework/plugin/core/PluginRegistrySupport.java
new file mode 100644
index 0000000..0643348
--- /dev/null
+++ b/core/src/main/java/org/springframework/plugin/core/PluginRegistrySupport.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2012 the original author or authors.
+ *
+ * Licensed 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 org.springframework.plugin.core;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.springframework.util.Assert;
+
+/**
+ * Base class for {@link PluginRegistry} implementations. Implements an initialization mechanism triggered on forst
+ * invocation of {@link #getPlugins()}.
+ *
+ * @author Oliver Gierke
+ */
+public abstract class PluginRegistrySupport, S> implements PluginRegistry, Iterable {
+
+ private List plugins;
+ private boolean initialized;
+
+ /**
+ * Creates a new {@link PluginRegistrySupport} instance using the given plugins.
+ *
+ * @param plugins must not be {@literal null}.
+ */
+ @SuppressWarnings("unchecked")
+ public PluginRegistrySupport(List extends T> plugins) {
+
+ Assert.notNull(plugins);
+
+ this.plugins = plugins == null ? new ArrayList() : (List) plugins;
+ this.initialized = false;
+ }
+
+ /**
+ * Returns all registered plugins. Only use this method if you really need to access all plugins. For distinguished
+ * access to certain plugins favour accessor methods like {link #getPluginFor} over this one. This method should only
+ * be used for testing purposes to check registry configuration.
+ *
+ * @return all plugins of the registry
+ */
+ public List getPlugins() {
+
+ if (!initialized) {
+ this.plugins = initialize(this.plugins);
+ this.initialized = true;
+ }
+
+ return plugins;
+ }
+
+ /**
+ * Callback to initialize the plugin {@link List}. Will create a defensive copy of the {@link List} to potentially
+ * unwrap a {@link List} proxy. Will filter {@literal null} values from the source list as well.
+ *
+ * @param plugins must not be {@literal null}.
+ * @return
+ */
+ protected synchronized List initialize(List plugins) {
+
+ Assert.notNull(plugins);
+ List result = new ArrayList();
+
+ for (T plugin : this.plugins) {
+ if (plugin != null) {
+ result.add(plugin);
+ }
+ }
+
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see java.lang.Iterable#iterator()
+ */
+ @Override
+ public Iterator iterator() {
+ return getPlugins().iterator();
+ }
+}
diff --git a/core/src/main/java/org/springframework/plugin/core/SimplePluginRegistry.java b/core/src/main/java/org/springframework/plugin/core/SimplePluginRegistry.java
index 2007176..47771f0 100644
--- a/core/src/main/java/org/springframework/plugin/core/SimplePluginRegistry.java
+++ b/core/src/main/java/org/springframework/plugin/core/SimplePluginRegistry.java
@@ -17,7 +17,6 @@ package org.springframework.plugin.core;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Iterator;
import java.util.List;
/**
@@ -28,18 +27,15 @@ import java.util.List;
* @param the delimiter type
* @author Oliver Gierke
*/
-public class SimplePluginRegistry, S> implements MutablePluginRegistry {
-
- protected final List plugins;
+public class SimplePluginRegistry, S> extends PluginRegistrySupport {
/**
* Creates a new {@code SimplePluginRegistry}. Will create an empty registry if {@literal null} is provided.
*
* @param plugins must not be {@literal null}.
*/
- @SuppressWarnings("unchecked")
protected SimplePluginRegistry(List extends T> plugins) {
- this.plugins = plugins == null ? new ArrayList() : (List) plugins;
+ super(plugins);
}
/**
@@ -50,7 +46,7 @@ public class SimplePluginRegistry, S> implements MutablePlug
* @return
*/
public static > SimplePluginRegistry create() {
- return new SimplePluginRegistry(null);
+ return create(Collections. emptyList());
}
/**
@@ -64,26 +60,12 @@ public class SimplePluginRegistry, S> implements MutablePlug
return new SimplePluginRegistry(plugins);
}
- /*
- * (non-Javadoc)
- * @see org.springframework.plugin.core.MutablePluginRegistry#addPlugin(org.springframework.plugin.core.Plugin)
+ /* (non-Javadoc)
+ * @see org.springframework.plugin.core.PluginRegistrySupport#getPlugins()
*/
- public SimplePluginRegistry addPlugin(T plugin) {
-
- if (plugin != null) {
- this.plugins.add(plugin);
- }
-
- return this;
- }
-
- /*
- * (non-Javadoc)
- * @see org.springframework.plugin.core.MutablePluginRegistry#removePlugin(org.springframework.plugin.core.Plugin)
- */
- public boolean removePlugin(T plugin) {
-
- return this.plugins.remove(plugin);
+ @Override
+ public List getPlugins() {
+ return Collections.unmodifiableList(super.getPlugins());
}
/*
@@ -109,7 +91,7 @@ public class SimplePluginRegistry, S> implements MutablePlug
List result = new ArrayList();
- for (T plugin : plugins) {
+ for (T plugin : super.getPlugins()) {
if (plugin != null && plugin.supports(delimiter)) {
result.add(plugin);
}
@@ -176,18 +158,7 @@ public class SimplePluginRegistry, S> implements MutablePlug
*/
public int countPlugins() {
- return plugins.size();
- }
-
- /**
- * Returns all registered plugins. Only use this method if you really need to access all plugins. For distinguished
- * access to certain plugins favour accessor methods like {link #getPluginFor} over this one. This method should only
- * be used for testing purposes to check registry configuration.
- *
- * @return all plugins of the registry
- */
- public List getPlugins() {
- return Collections.unmodifiableList(plugins);
+ return super.getPlugins().size();
}
/*
@@ -195,22 +166,14 @@ public class SimplePluginRegistry, S> implements MutablePlug
* @see org.springframework.plugin.core.PluginRegistry#contains(org.springframework.plugin.core.Plugin)
*/
public boolean contains(T plugin) {
- return this.plugins.contains(plugin);
+ return super.getPlugins().contains(plugin);
}
/*
* (non-Javadoc)
* @see org.springframework.plugin.core.PluginRegistry#hasPluginFor(java.lang.Object)
*/
- public boolean hasPluginFor(S delimter) {
- return null != getPluginFor(delimter);
- }
-
- /*
- * (non-Javadoc)
- * @see java.lang.Iterable#iterator()
- */
- public Iterator iterator() {
- return plugins.iterator();
+ public boolean hasPluginFor(S delimiter) {
+ return null != getPluginFor(delimiter);
}
}
diff --git a/core/src/main/java/org/springframework/plugin/core/support/AbstractTypeAwareSupport.java b/core/src/main/java/org/springframework/plugin/core/support/AbstractTypeAwareSupport.java
index 48cdfb1..f483966 100644
--- a/core/src/main/java/org/springframework/plugin/core/support/AbstractTypeAwareSupport.java
+++ b/core/src/main/java/org/springframework/plugin/core/support/AbstractTypeAwareSupport.java
@@ -102,7 +102,7 @@ public abstract class AbstractTypeAwareSupport implements ApplicationContextA
*
* @author Oliver Gierke
*/
- private static class BeansOfTypeTargetSource implements TargetSource {
+ static class BeansOfTypeTargetSource implements TargetSource {
private final ListableBeanFactory context;
private final Class> type;
diff --git a/core/src/test/java/org/springframework/plugin/core/AbstractMutablePluginRegistryUnitTest.java b/core/src/test/java/org/springframework/plugin/core/AbstractMutablePluginRegistryUnitTest.java
deleted file mode 100644
index 7462603..0000000
--- a/core/src/test/java/org/springframework/plugin/core/AbstractMutablePluginRegistryUnitTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2008-2012 the original author or authors.
- *
- * Licensed 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 org.springframework.plugin.core;
-
-import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.*;
-
-import org.junit.Test;
-import org.springframework.plugin.core.MutablePluginRegistry;
-
-/**
- * Unit test for implementations of {@link MutablePluginRegistry}.
- *
- * @author Oliver Gierke
- */
-public abstract class AbstractMutablePluginRegistryUnitTest {
-
- private SamplePlugin plugin = new SamplePluginImplementation();
-
- @Test
- public void allowsAddingPluginsAfterCreation() throws Exception {
-
- MutablePluginRegistry registry = getRegistry();
- registry.addPlugin(plugin);
-
- assertTrue(registry.contains(plugin));
- assertThat(registry.getPlugins().size(), is(1));
- }
-
- /**
- * Return the {@link MutablePluginRegistry} to test.
- *
- * @return
- */
- protected abstract MutablePluginRegistry getRegistry();
-}
diff --git a/core/src/test/java/org/springframework/plugin/core/OrderAwarePluginRegistryUnitTest.java b/core/src/test/java/org/springframework/plugin/core/OrderAwarePluginRegistryUnitTest.java
index 66a3126..6135006 100644
--- a/core/src/test/java/org/springframework/plugin/core/OrderAwarePluginRegistryUnitTest.java
+++ b/core/src/test/java/org/springframework/plugin/core/OrderAwarePluginRegistryUnitTest.java
@@ -23,7 +23,6 @@ import java.util.Arrays;
import java.util.List;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.core.Ordered;
@@ -49,12 +48,6 @@ public class OrderAwarePluginRegistryUnitTest extends SimplePluginRegistryUnitTe
secondPlugin = new SecondImplementation();
}
- @Override
- protected OrderAwarePluginRegistry getRegistry() {
-
- return OrderAwarePluginRegistry.create();
- }
-
@Test
public void honorsOrderOnAddPlugins() throws Exception {
@@ -63,16 +56,6 @@ public class OrderAwarePluginRegistryUnitTest extends SimplePluginRegistryUnitTe
assertOrder(registry, secondPlugin, firstPlugin);
}
- @Test
- @Ignore
- public void assertsOrderOnAddingPlugins() throws Exception {
-
- MutablePluginRegistry registry = OrderAwarePluginRegistry.create(Arrays.asList(firstPlugin));
- registry.addPlugin(secondPlugin);
-
- assertOrder(registry, secondPlugin, firstPlugin);
- }
-
private void assertOrder(PluginRegistry registry, TestPlugin... plugins) {
List result = registry.getPluginsFor(null);
diff --git a/core/src/test/java/org/springframework/plugin/core/SimplePluginRegistryUnitTest.java b/core/src/test/java/org/springframework/plugin/core/SimplePluginRegistryUnitTest.java
index 2b4a102..fce09d9 100644
--- a/core/src/test/java/org/springframework/plugin/core/SimplePluginRegistryUnitTest.java
+++ b/core/src/test/java/org/springframework/plugin/core/SimplePluginRegistryUnitTest.java
@@ -19,21 +19,19 @@ package org.springframework.plugin.core;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
-import org.springframework.plugin.core.MutablePluginRegistry;
-import org.springframework.plugin.core.Plugin;
-import org.springframework.plugin.core.SimplePluginRegistry;
/**
* Unit test for {@link SimplePluginRegistry}.
*
* @author Oliver Gierke
*/
-public class SimplePluginRegistryUnitTest extends AbstractMutablePluginRegistryUnitTest {
+public class SimplePluginRegistryUnitTest {
SamplePlugin plugin;
@@ -49,16 +47,6 @@ public class SimplePluginRegistryUnitTest extends AbstractMutablePluginRegistryU
registry = SimplePluginRegistry.create();
}
- /*
- * (non-Javadoc)
- * @see org.springframework.plugin.core.AbstractMutablePluginRegistryUnitTest#getRegistry()
- */
- @Override
- protected MutablePluginRegistry getRegistry() {
-
- return SimplePluginRegistry.create();
- }
-
/**
* Asserts that the registry contains the plugin it was initialized with.
*
@@ -67,7 +55,7 @@ public class SimplePluginRegistryUnitTest extends AbstractMutablePluginRegistryU
@Test
public void assertRegistryInitialized() throws Exception {
- registry.addPlugin(plugin);
+ registry = SimplePluginRegistry.create(Arrays.asList(plugin));
assertThat(registry.countPlugins(), is(1));
assertTrue(registry.contains(plugin));
@@ -79,7 +67,7 @@ public class SimplePluginRegistryUnitTest extends AbstractMutablePluginRegistryU
@Test
public void assertFindsEmailNotificationProvider() {
- registry.addPlugin(plugin);
+ registry = SimplePluginRegistry.create(Arrays.asList(plugin));
String delimiter = "FOO";
@@ -135,7 +123,10 @@ public class SimplePluginRegistryUnitTest extends AbstractMutablePluginRegistryU
@Test
public void handlesAddingNullPluginsCorrecty() throws Exception {
- registry.addPlugin(null);
+ List plugins = new ArrayList();
+ plugins.add(null);
+
+ registry = SimplePluginRegistry.create(plugins);
assertThat(registry.countPlugins(), is(0));
}
diff --git a/core/src/test/java/org/springframework/plugin/core/support/OrderAwarePluginRegistryIntegrationTest.java b/core/src/test/java/org/springframework/plugin/core/support/OrderAwarePluginRegistryIntegrationTest.java
new file mode 100644
index 0000000..2c36ba8
--- /dev/null
+++ b/core/src/test/java/org/springframework/plugin/core/support/OrderAwarePluginRegistryIntegrationTest.java
@@ -0,0 +1,68 @@
+package org.springframework.plugin.core.support;
+
+import java.util.List;
+
+import org.springframework.aop.framework.ProxyFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.plugin.core.OrderAwarePluginRegistry;
+import org.springframework.plugin.core.Plugin;
+import org.springframework.plugin.core.support.AbstractTypeAwareSupport.BeansOfTypeTargetSource;
+
+//@RunWith(SpringJUnit4ClassRunner.class)
+public class OrderAwarePluginRegistryIntegrationTest {
+
+ @Autowired
+ ApplicationContext context;
+
+ // @Test
+ public void considersJdkProxiedOrderedImplementation() {
+ BeansOfTypeTargetSource targetSource = new AbstractTypeAwareSupport.BeansOfTypeTargetSource(context,
+ TestPlugin.class, false);
+
+ ProxyFactory factory = new ProxyFactory(List.class, targetSource);
+ List beans = (List) factory.getProxy();
+ OrderAwarePluginRegistry registry = OrderAwarePluginRegistry.create(beans);
+
+ List plugins = registry.getPlugins();
+ }
+
+ private static interface TestPlugin extends Plugin {
+
+ }
+
+ @Order(5)
+ private static class FirstImplementation implements TestPlugin {
+
+ @Override
+ public boolean supports(String delimiter) {
+
+ return true;
+ }
+ }
+
+ @Order(1)
+ private static class SecondImplementation implements TestPlugin {
+
+ @Override
+ public boolean supports(String delimiter) {
+
+ return true;
+ }
+ }
+
+ private static class ThirdImplementation implements TestPlugin, Ordered {
+
+ @Override
+ public int getOrder() {
+ return 3;
+ }
+
+ @Override
+ public boolean supports(String delimiter) {
+ return true;
+ }
+ }
+}
diff --git a/pom.xml b/pom.xml
index 61240f1..37eefb8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -44,7 +44,7 @@
- 3.0.7.RELEASE
+ 3.1.2.RELEASE