Fix FELIX-2624 Support multiple whiteboards using annotations
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1032253 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Whiteboards.java b/ipojo/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Whiteboards.java
new file mode 100644
index 0000000..d00f1b5
--- /dev/null
+++ b/ipojo/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Whiteboards.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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 org.apache.felix.ipojo.whiteboard;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Whiteboard pattern Handler annotation.
+ * Allows configuring several whiteboard patterns.
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.TYPE)
+public @interface Whiteboards {
+
+ /**
+ * Whiteboards list.
+ */
+ Wbp[] whiteboards() default {};
+}
diff --git a/ipojo/handler/whiteboard/metadata.xml b/ipojo/handler/whiteboard/metadata.xml
index d9c1c53..88eec46 100644
--- a/ipojo/handler/whiteboard/metadata.xml
+++ b/ipojo/handler/whiteboard/metadata.xml
@@ -6,9 +6,9 @@
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
@@ -21,4 +21,10 @@
classname="org.apache.felix.ipojo.handler.wbp.WhiteBoardPatternHandler"
name="wbp" namespace="org.apache.felix.ipojo.whiteboard">
</handler>
+
+ <!-- Alternative handler for component using the @Whiteboards annotation -->
+ <handler
+ classname="org.apache.felix.ipojo.handler.wbp.WhiteBoardPatternHandler"
+ name="whiteboards" namespace="org.apache.felix.ipojo.whiteboard">
+ </handler>
</ipojo>
\ No newline at end of file
diff --git a/ipojo/handler/whiteboard/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardPatternHandler.java b/ipojo/handler/whiteboard/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardPatternHandler.java
index 778eae7..70a880e 100644
--- a/ipojo/handler/whiteboard/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardPatternHandler.java
+++ b/ipojo/handler/whiteboard/src/main/java/org/apache/felix/ipojo/handler/wbp/WhiteBoardPatternHandler.java
@@ -53,7 +53,27 @@
* @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
*/
public void configure(Element elem, Dictionary dict) throws ConfigurationException {
+
+ // There is two way to configure the handler :
+ // - the wbp elements
+ // - the whiteboards elements
Element[] elems = elem.getElements("wbp", NAMESPACE);
+
+ if (elems == null || elems.length == 0) {
+ // Alternative way
+ Element[] whiteboards = elem.getElements("whiteboards", NAMESPACE);
+ if (whiteboards == null) {
+ throw new ConfigurationException("Cannot configure the whiteboard pattern handler - no suitable configuration found");
+ } else {
+ elems = whiteboards[0].getElements("wbp", NAMESPACE);
+ }
+ }
+
+ // Last check.
+ if (elems == null) {
+ throw new ConfigurationException("Cannot configure the whiteboard pattern handler - no suitable configuration found");
+ }
+
for (int i = 0; i < elems.length; i++) {
String filter = elems[i].getAttribute("filter");
String onArrival = elems[i].getAttribute("onArrival");
diff --git a/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/annotations/WhiteBoard.java b/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/annotations/WhiteBoard.java
index b2e38d0..418364f 100644
--- a/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/annotations/WhiteBoard.java
+++ b/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/annotations/WhiteBoard.java
@@ -5,17 +5,18 @@
import org.apache.felix.ipojo.metadata.Element;
public class WhiteBoard extends OSGiTestCase {
-
+
String typeWI = "org.apache.felix.ipojo.test.scenarios.component.whiteboard.WhiteBoardWIModification";
String typeWO = "org.apache.felix.ipojo.test.scenarios.component.whiteboard.WhiteBoardWOModification";
+ String typeWhiteboards = "org.apache.felix.ipojo.test.scenarios.component.whiteboard.WhiteBoards";
String namespace = "org.apache.felix.ipojo.whiteboard";
-
+
private IPOJOHelper helper;
-
+
public void setUp() {
helper = new IPOJOHelper(this);
}
-
+
public void testMetadataWithOnModification() {
Element meta = helper.getMetadata(typeWI);
assertNotNull("Check meta", meta);
@@ -26,14 +27,14 @@
String onDep = ext[0].getAttribute("onDeparture");
String onMod = ext[0].getAttribute("onModification");
-
+
assertEquals("Check filter", "(foo=true)", filter);
assertEquals("Check onArrival", "onArrival", onArr);
assertEquals("Check onDeparture", "onDeparture", onDep);
assertEquals("Check onModification", "onModification", onMod);
}
-
+
public void testMetadataWithoutOnModification() {
Element meta = helper.getMetadata(typeWO);
assertNotNull("Check meta", meta);
@@ -44,7 +45,7 @@
String onDep = ext[0].getAttribute("onDeparture");
String onMod = ext[0].getAttribute("onModification");
-
+
assertEquals("Check filter", "(foo=true)", filter);
assertEquals("Check onArrival", "onArrival", onArr);
assertEquals("Check onDeparture", "onDeparture", onDep);
@@ -52,4 +53,36 @@
}
+ public void testWhiteboards() {
+ Element meta = helper.getMetadata(typeWhiteboards);
+ assertNotNull("Check meta", meta);
+ Element[] ext = meta.getElements("whiteboards", namespace);
+ assertEquals("Check size", 1, ext.length);
+
+ // Two sub-element
+ Element[] wbps = ext[0].getElements("wbp", namespace);
+ assertEquals("Check size", 2, wbps.length);
+
+ String filter = wbps[0].getAttribute("filter");
+ String onArr = wbps[0].getAttribute("onArrival");
+ String onDep = wbps[0].getAttribute("onDeparture");
+ String onMod = wbps[0].getAttribute("onModification");
+
+ assertEquals("Check filter", "(foo=true)", filter);
+ assertEquals("Check onArrival", "onArrival", onArr);
+ assertEquals("Check onDeparture", "onDeparture", onDep);
+ assertNull("Check onModification", onMod);
+
+ filter = wbps[1].getAttribute("filter");
+ onArr = wbps[1].getAttribute("onArrival");
+ onDep = wbps[1].getAttribute("onDeparture");
+ onMod = wbps[1].getAttribute("onModification");
+
+ assertEquals("Check filter", "(foo=true)", filter);
+ assertEquals("Check onArrival", "onArrival", onArr);
+ assertEquals("Check onDeparture", "onDeparture", onDep);
+ assertEquals("Check onModification", "onModification", onMod);
+ }
+
+
}
diff --git a/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/component/whiteboard/WhiteBoards.java b/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/component/whiteboard/WhiteBoards.java
new file mode 100644
index 0000000..540837f
--- /dev/null
+++ b/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/component/whiteboard/WhiteBoards.java
@@ -0,0 +1,27 @@
+package org.apache.felix.ipojo.test.scenarios.component.whiteboard;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.whiteboard.Whiteboards;
+import org.apache.felix.ipojo.whiteboard.Wbp;
+import org.osgi.framework.ServiceReference;
+
+@Component
+@Whiteboards(whiteboards={
+ @Wbp(filter="(foo=true)", onArrival="onArrival", onDeparture="onDeparture"),
+ @Wbp(filter="(foo=true)", onArrival="onArrival", onDeparture="onDeparture", onModification="onModification")
+ })
+public class WhiteBoards {
+
+ public void onArrival(ServiceReference ref) {
+ // nothing
+ }
+
+ public void onDeparture(ServiceReference ref) {
+ // nothing
+ }
+
+ public void onModification(ServiceReference ref) {
+ // nothing
+ }
+
+}
diff --git a/ipojo/tests/handler/whiteboard/pom.xml b/ipojo/tests/handler/whiteboard/pom.xml
index 1c56f54..88c7f35 100644
--- a/ipojo/tests/handler/whiteboard/pom.xml
+++ b/ipojo/tests/handler/whiteboard/pom.xml
@@ -86,8 +86,7 @@
<![CDATA[
<ipojo
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/SNAPSHOT/core.xsd
- org.apache.felix.ipojo.whiteboard http://felix.apache.org/ipojo/schemas/SNAPSHOT/whiteboard-pattern.xsd"
+ xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/SNAPSHOT/core.xsd"
xmlns="org.apache.felix.ipojo"
xmlns:wbp="org.apache.felix.ipojo.whiteboard">
<component classname="org.apache.felix.ipojo.test.FooProvider" name="fooprovider">
@@ -111,6 +110,16 @@
<provides/>
</component>
+ <component classname="org.apache.felix.ipojo.test.FooWhiteBoardPattern" name="under-providers-2">
+ <wbp:whiteboards>
+ <wbp:wbp
+ filter="(objectclass=org.apache.felix.ipojo.test.FooService)"
+ onArrival="onArrival" onDeparture="onDeparture" onModification="onModification"
+ />
+ </wbp:whiteboards>
+ <provides/>
+ </component>
+
<component classname="org.apache.felix.ipojo.test.FooWhiteBoardPattern" name="under-providers-lifecycle">
<wbp:wbp
filter="(objectclass=org.apache.felix.ipojo.test.FooService)"
diff --git a/ipojo/tests/handler/whiteboard/src/main/java/org/apache/felix/ipojo/test/WbpTests.java b/ipojo/tests/handler/whiteboard/src/main/java/org/apache/felix/ipojo/test/WbpTests.java
index e791e40..0206900 100644
--- a/ipojo/tests/handler/whiteboard/src/main/java/org/apache/felix/ipojo/test/WbpTests.java
+++ b/ipojo/tests/handler/whiteboard/src/main/java/org/apache/felix/ipojo/test/WbpTests.java
@@ -16,13 +16,14 @@
public class WbpTests extends OSGiTestCase {
Factory provFactory;
- Factory factory, factory2, factory3;
+ Factory factory, factory2, factory3, factory4;
public void setUp() {
provFactory = Utils.getFactoryByName(context, "fooprovider");
factory = Utils.getFactoryByName(context, "under-providers");
factory2 = Utils.getFactoryByName(context, "under-properties");
factory3 = Utils.getFactoryByName(context, "under-providers-lifecycle");
+ factory4 = Utils.getFactoryByName(context, "under-providers-2");
}
public void tearDown() {
@@ -219,4 +220,62 @@
ci.dispose();
}
+
+ public void testServiceProvidersWhiteWhiteboards() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+ ComponentInstance ci = factory4.createComponentInstance(new Properties());
+
+ ServiceReference ref = Utils.getServiceReferenceByName(context, Observable.class.getName(), ci.getInstanceName());
+ assertNotNull("Check Observable availability", ref);
+ Observable obs = (Observable) context.getService(ref);
+
+ Map map = obs.getObservations();
+ assertEquals("Check empty list" , ((List) map.get("list")).size(), 0);
+
+ Properties p1 = new Properties();
+ p1.put("foo", "foo");
+ ComponentInstance prov1 = provFactory.createComponentInstance(p1);
+
+ map = obs.getObservations();
+ assertEquals("Check list #1" , ((List) map.get("list")).size(), 1);
+
+ Properties p2 = new Properties();
+ p2.put("foo", "foo");
+ ComponentInstance prov2 = provFactory.createComponentInstance(p2);
+
+ map = obs.getObservations();
+ assertEquals("Check list #2" , ((List) map.get("list")).size(), 2);
+
+ prov1.stop();
+
+ map = obs.getObservations();
+ assertEquals("(1) Check list #1" , ((List) map.get("list")).size(), 1);
+
+ prov2.stop();
+
+ map = obs.getObservations();
+ assertEquals("(2) Check list #0" , ((List) map.get("list")).size(), 0);
+
+ prov2.start();
+
+ map = obs.getObservations();
+ assertEquals("(3) Check list #1" , ((List) map.get("list")).size(), 1);
+
+ prov1.start();
+
+ map = obs.getObservations();
+ assertEquals("(4) Check list #2" , ((List) map.get("list")).size(), 2);
+
+ prov1.dispose();
+
+ map = obs.getObservations();
+ assertEquals("(5) Check list #1" , ((List) map.get("list")).size(), 1);
+
+ prov2.dispose();
+
+ map = obs.getObservations();
+ assertEquals("(6) Check list #0" , ((List) map.get("list")).size(), 0);
+
+ context.ungetService(ref);
+ ci.dispose();
+ }
}