FELIX-4095 Add CDI-like @Stereotype
* All iPOJO annotations can nom be used on other annotations (ANNOTATION_TYPE)
* New @Stereotype meta annotation
* Stereotype related bindings are placed before generics bindings (that means that they have priority)
* Added integration tests
* Notice that this feature works at the moment with bnd-ipojo-plugin (except if the @Stereotype is in the manipulated bundle), other front-ends (maven, ant, cli, ...) will be updated soon
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1489041 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Bind.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Bind.java
index 05a7a61..e0e383e 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Bind.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Bind.java
@@ -26,7 +26,7 @@
* This annotation declares a bind method.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface Bind {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Component.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Component.java
index 28fbb2d..36501e3 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Component.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Component.java
@@ -26,7 +26,7 @@
* This annotation is mandatory to declares an iPOJO component.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.TYPE)
+@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface Component {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Controller.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Controller.java
index e4bfaeb..4f3dc92 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Controller.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Controller.java
@@ -25,7 +25,7 @@
* This annotation declares a lifecycle controller.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.FIELD)
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface Controller {
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Handler.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Handler.java
index 7b8e4a4..b921267 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Handler.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Handler.java
@@ -26,7 +26,7 @@
* This annotation is mandatory to declares an iPOJO handler.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.TYPE)
+@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface Handler {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerDeclaration.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerDeclaration.java
index c4eaeaf..608b6bf 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerDeclaration.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerDeclaration.java
@@ -25,7 +25,7 @@
* This annotation is used to configure a handler.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.TYPE)
+@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface HandlerDeclaration {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Instantiate.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Instantiate.java
index dba9d43..90b0b7b 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Instantiate.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Instantiate.java
@@ -26,7 +26,7 @@
* current component type.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.TYPE)
+@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface Instantiate {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Invalidate.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Invalidate.java
index 72a7c6c..01b0c66 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Invalidate.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Invalidate.java
@@ -25,7 +25,7 @@
* This annotation declares an invalidate callback.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface Invalidate {
}
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Modified.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Modified.java
index ea18919..b5bb099 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Modified.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Modified.java
@@ -26,7 +26,7 @@
* This annotation declares a modify method.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface Modified {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostRegistration.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostRegistration.java
index 2e6bac8..e4a65c6 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostRegistration.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostRegistration.java
@@ -26,7 +26,7 @@
* This annotation declares a post-service-registration method.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface PostRegistration {
}
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostUnregistration.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostUnregistration.java
index 428dff5..ce9208e 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostUnregistration.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostUnregistration.java
@@ -26,7 +26,7 @@
* This annotation declares a post-service-unregistration method.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface PostUnregistration {
}
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Property.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Property.java
index a5ba338..9af34cb 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Property.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Property.java
@@ -26,7 +26,7 @@
* It can target both fields and methods.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
public @interface Property {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Provides.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Provides.java
index c58c3ef..1db18f5 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Provides.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Provides.java
@@ -25,7 +25,7 @@
* This annotation declares that the component instances will provide a service.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.TYPE)
+@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface Provides {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Requires.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Requires.java
index 4ea2408..864a5a7 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Requires.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Requires.java
@@ -27,7 +27,7 @@
* This annotation declares a service requirement.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target({ ElementType.FIELD, ElementType.PARAMETER })
+@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Inherited
public @interface Requires {
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceController.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceController.java
index bd0dd5f..61e539e 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceController.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceController.java
@@ -25,7 +25,7 @@
* This annotation declares a service controller.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.FIELD)
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface ServiceController {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceProperty.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceProperty.java
index ceba75f..5eed009 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceProperty.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceProperty.java
@@ -26,7 +26,7 @@
* It can target both fields and methods.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.FIELD)
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface ServiceProperty {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Stereotype.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Stereotype.java
new file mode 100644
index 0000000..e4cb647
--- /dev/null
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Stereotype.java
@@ -0,0 +1,33 @@
+/*
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Mark the annotated annotation type to be a marker annotation dedicated to an iPOJO handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.ANNOTATION_TYPE)
+@Retention(RetentionPolicy.CLASS)
+public @interface Stereotype {
+}
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Unbind.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Unbind.java
index f34129f..56dfb6c 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Unbind.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Unbind.java
@@ -26,7 +26,7 @@
* This annotation declares an unbind method.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface Unbind {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Updated.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Updated.java
index 285d236..8abff5e 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Updated.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Updated.java
@@ -26,7 +26,7 @@
* Updated callback are called after a reconfiguration.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface Updated {
}
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Validate.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Validate.java
index 50e239f..aaaa321 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Validate.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/annotations/Validate.java
@@ -25,7 +25,7 @@
* This annotation declares a validate callback.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface Validate {
}
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/extender/Extender.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/extender/Extender.java
index 6c1af00..587710a 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/extender/Extender.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/extender/Extender.java
@@ -28,7 +28,7 @@
* it refers to an external handler.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.TYPE)
+@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface Extender {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handler/temporal/Temporal.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handler/temporal/Temporal.java
index c123cda..52496a5 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handler/temporal/Temporal.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handler/temporal/Temporal.java
@@ -29,7 +29,7 @@
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.FIELD)
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface Temporal {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Publishes.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Publishes.java
index 5102df4..eea2f80 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Publishes.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Publishes.java
@@ -28,7 +28,7 @@
* it refers to an external handler.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.FIELD)
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface Publishes {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Subscriber.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Subscriber.java
index 70cb7a8..2418944 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Subscriber.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Subscriber.java
@@ -28,7 +28,7 @@
* it refers to an external handler.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface Subscriber {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXBean.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXBean.java
index ca31185..b07abfb 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXBean.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXBean.java
@@ -28,7 +28,7 @@
* it refers to an external handler.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.TYPE)
+@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface JMXBean {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXMethod.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXMethod.java
index 27ca89a..3f957fe 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXMethod.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXMethod.java
@@ -30,7 +30,7 @@
* it refers to an external handler.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface JMXMethod {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXProperty.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXProperty.java
index 1b31c7c..069878d 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXProperty.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXProperty.java
@@ -30,7 +30,7 @@
* it refers to an external handler.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.FIELD)
+@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface JMXProperty {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transaction.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transaction.java
index c70762c..9860323 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transaction.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transaction.java
@@ -28,7 +28,7 @@
* it refers to an external handler.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.TYPE)
+@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface Transaction {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transactional.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transactional.java
index ba41f5e..f89133d 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transactional.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transactional.java
@@ -28,7 +28,7 @@
* it refers to an external handler.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.METHOD)
+@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
public @interface Transactional {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Wbp.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Wbp.java
index 570ade1..4c66f5e 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Wbp.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Wbp.java
@@ -28,7 +28,7 @@
* it refers to an external handler.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.TYPE)
+@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface Wbp {
/**
diff --git a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Whiteboards.java b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Whiteboards.java
index d00f1b5..995bd1c 100644
--- a/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Whiteboards.java
+++ b/ipojo/manipulator/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Whiteboards.java
@@ -28,7 +28,7 @@
* it refers to an external handler.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-@Target(ElementType.TYPE)
+@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface Whiteboards {
/**
diff --git a/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/ImmediateComponent.java b/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/ImmediateComponent.java
new file mode 100644
index 0000000..23ad270
--- /dev/null
+++ b/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/ImmediateComponent.java
@@ -0,0 +1,40 @@
+/*
+ * 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.runtime.core.components;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Instantiate;
+import org.apache.felix.ipojo.annotations.Provides;
+import org.apache.felix.ipojo.annotations.Stereotype;
+
+/**
+ * User: guillaume
+ * Date: 03/06/13
+ * Time: 11:55
+ */
+@Component
+@Instantiate
+@Provides
+@Stereotype
+@Target(ElementType.TYPE)
+public @interface ImmediateComponent {}
diff --git a/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/MultiBind.java b/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/MultiBind.java
new file mode 100644
index 0000000..c28d716
--- /dev/null
+++ b/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/MultiBind.java
@@ -0,0 +1,39 @@
+/*
+ * 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.runtime.core.components;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+import org.apache.felix.ipojo.annotations.Bind;
+import org.apache.felix.ipojo.annotations.Stereotype;
+
+/**
+ * User: guillaume
+ * Date: 03/06/13
+ * Time: 16:09
+ */
+@Bind(
+ aggregate = true,
+ optional = false
+)
+@Stereotype
+@Target(ElementType.METHOD)
+public @interface MultiBind {}
diff --git a/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/StereotypedBazComponent.java b/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/StereotypedBazComponent.java
new file mode 100644
index 0000000..83fd0cd
--- /dev/null
+++ b/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/StereotypedBazComponent.java
@@ -0,0 +1,35 @@
+/*
+ * 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.runtime.core.components;
+
+import org.apache.felix.ipojo.runtime.core.services.BazService;
+
+/**
+ * User: guillaume
+ * Date: 03/06/13
+ * Time: 12:22
+ */
+@ImmediateComponent
+public class StereotypedBazComponent implements BazService {
+ @Override
+ public String hello(final String name) {
+ return "Hello " + name;
+ }
+}
diff --git a/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/StereotypedMultiBind.java b/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/StereotypedMultiBind.java
new file mode 100644
index 0000000..650d63b
--- /dev/null
+++ b/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/components/StereotypedMultiBind.java
@@ -0,0 +1,37 @@
+/*
+ * 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.runtime.core.components;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.architecture.Architecture;
+
+/**
+ * User: guillaume
+ * Date: 03/06/13
+ * Time: 12:22
+ */
+@Component
+public class StereotypedMultiBind {
+
+ @MultiBind
+ public void bindArchitecture(Architecture service) {
+
+ }
+}
diff --git a/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/services/BazService.java b/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/services/BazService.java
new file mode 100644
index 0000000..f2d7c6e
--- /dev/null
+++ b/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/main/java/org/apache/felix/ipojo/runtime/core/services/BazService.java
@@ -0,0 +1,29 @@
+/*
+ * 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.runtime.core.services;
+
+/**
+ * User: guillaume
+ * Date: 03/06/13
+ * Time: 12:23
+ */
+public interface BazService {
+ String hello(String name);
+}
diff --git a/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestStereotypeAnnotation.java b/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestStereotypeAnnotation.java
new file mode 100644
index 0000000..c956eda
--- /dev/null
+++ b/ipojo/manipulator/manipulator-it/src/it/ipojo-manipulator-manipulation-test/src/test/java/org/apache/felix/ipojo/runtime/core/TestStereotypeAnnotation.java
@@ -0,0 +1,86 @@
+/*
+ * 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.runtime.core;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.runtime.core.services.BazService;
+import org.junit.Test;
+import org.ow2.chameleon.testing.helpers.BaseTest;
+
+import junit.framework.Assert;
+
+public class TestStereotypeAnnotation extends BaseTest {
+
+ public static final String BAZ_FACTORY_NAME = "org.apache.felix.ipojo.runtime.core.components.StereotypedBazComponent";
+
+ public static final String MB_FACTORY_NAME = "org.apache.felix.ipojo.runtime.core.components.StereotypedMultiBind";
+
+ @Test
+ public void testTypeStereotype() {
+
+ // verify component's factory is here
+ // verify BazService has been published
+ // --> verify instance has been created
+
+ Factory factory = ipojoHelper.getFactory(BAZ_FACTORY_NAME);
+ Assert.assertNotNull(factory);
+ assertEquals(Factory.VALID, factory.getState());
+
+
+ List<BazService> services = osgiHelper.getServiceObjects(BazService.class);
+ assertEquals(1, services.size());
+
+ BazService baz = services.get(0);
+ assertEquals("Hello Guillaume", baz.hello("Guillaume"));
+ ipojoHelper.dispose();
+ }
+
+ @Test
+ public void testMethodStereotype() {
+
+ // verify component's factory is here
+ // verify that the requires handler has been activated
+ // verify that a created instance works
+
+ Factory factory = ipojoHelper.getFactory(MB_FACTORY_NAME);
+ Assert.assertNotNull(factory);
+ assertEquals(Factory.VALID, factory.getState());
+
+ assertTrue(factory.getRequiredHandlers().contains("org.apache.felix.ipojo:requires"));
+
+ ComponentInstance instance = ipojoHelper.createComponentInstance(MB_FACTORY_NAME, "stereotype-multibind-instance");
+ assertTrue(ipojoHelper.isInstanceValid(instance));
+
+ ipojoHelper.dispose();
+ }
+
+ @Override
+ protected List<String> getExtraExports() {
+ return Arrays.asList("org.apache.felix.ipojo.runtime.core.components");
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/AnnotationMetadataProvider.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/AnnotationMetadataProvider.java
index ac89bdc..67de673 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/AnnotationMetadataProvider.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/AnnotationMetadataProvider.java
@@ -48,7 +48,7 @@
public AnnotationMetadataProvider(final ResourceStore store,
final Reporter reporter) {
- this(store, newBindingRegistry(reporter), reporter);
+ this(store, newBindingRegistry(reporter, store), reporter);
}
public AnnotationMetadataProvider(final ResourceStore store,
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/ClassMetadataCollector.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/ClassMetadataCollector.java
index 5f8df18..79a738f 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/ClassMetadataCollector.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/ClassMetadataCollector.java
@@ -26,6 +26,7 @@
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.EmptyVisitor;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
@@ -103,13 +104,13 @@
* at runtime. We retain runtime visible annotations on component
* as they are and left them out in meta-data calculation.
*/
- if(visible) {
+ if (visible) {
return null;
}
// Return the visitor to be executed (may be null)
return registry.selection(workbench)
- .type(node)
+ .type(this, node)
.annotatedWith(desc)
.get();
@@ -151,30 +152,38 @@
*/
@Override
public void visitEnd() {
- if (workbench.getRoot() == null) {
- // No 'top-level' element has been contributed
+ // Only process real class (no annotations, no interfaces)
+ if (!(is(Opcodes.ACC_ANNOTATION) || is(Opcodes.ACC_INTERFACE) || is(Opcodes.ACC_ABSTRACT))) {
+ if (workbench.getRoot() == null) {
+ // No 'top-level' element has been contributed
- if (!workbench.getElements().isEmpty()) {
- // There are other annotation's contribution on this type (additional handler declaration/configuration)
- // That means that there is a missing 'component type' annotation
+ if (!workbench.getElements().isEmpty()) {
+ // There are other annotation's contribution on this type (additional handler declaration/configuration)
+ // That means that there is a missing 'component type' annotation
- reporter.warn("Class %s has not been marked as a component type (no @Component, @Handler, " +
- "...). It will be ignored by the iPOJO manipulator.",
- workbench.getType().getClassName());
+ reporter.warn("Class %s has not been marked as a component type (no @Component, @Handler, " +
+ "...). It will be ignored by the iPOJO manipulator.",
+ workbench.getType().getClassName());
+ return;
+ } // else: no root and no elements
return;
- } // else: no root and no elements
- return;
- }
+ }
- componentMetadata = workbench.build();
- instanceMetadata = workbench.getInstance();
+ componentMetadata = workbench.build();
+ instanceMetadata = workbench.getInstance();
- // If we have an instance declared and the component metadata has a name, we update the component's attribute
- // of the instance (https://issues.apache.org/jira/browse/FELIX-4052).
- if (componentMetadata != null && componentMetadata.containsAttribute("name") && instanceMetadata != null) {
- // Update the component attribute
- instanceMetadata.addAttribute(new Attribute("component", componentMetadata.getAttribute("name")));
+ // If we have an instance declared and the component metadata has a name, we update the component's attribute
+ // of the instance (https://issues.apache.org/jira/browse/FELIX-4052).
+ if (componentMetadata != null && componentMetadata.containsAttribute("name") && instanceMetadata != null) {
+ // Update the component attribute
+ instanceMetadata.addAttribute(new Attribute("component", componentMetadata.getAttribute("name")));
+ }
+
}
}
+ private boolean is(int flags) {
+ return (node.access & flags) == flags;
+ }
+
}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/FieldMetadataCollector.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/FieldMetadataCollector.java
index 2efe009..09b08ed 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/FieldMetadataCollector.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/FieldMetadataCollector.java
@@ -62,7 +62,7 @@
// Return the visitor to be executed (may be null)
return registry.selection(workbench)
- .field(node)
+ .field(this, node)
.annotatedWith(desc)
.get();
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/MethodMetadataCollector.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/MethodMetadataCollector.java
index 874ecd4..9ca9db9 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/MethodMetadataCollector.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/MethodMetadataCollector.java
@@ -70,7 +70,7 @@
// Return the visitor to be executed (may be null)
return registry.selection(workbench)
- .method(node)
+ .method(this, node)
.annotatedWith(desc)
.get();
@@ -89,7 +89,7 @@
// Return the visitor to be executed (may be null)
return registry.selection(workbench)
- .parameter(node, index)
+ .parameter(this, node, index)
.annotatedWith(desc)
.get();
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/AnnotationRegistry.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/AnnotationRegistry.java
new file mode 100644
index 0000000..5de31f5
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/AnnotationRegistry.java
@@ -0,0 +1,75 @@
+/*
+ * 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.manipulator.metadata.annotation.registry;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
+import org.objectweb.asm.Type;
+
+/**
+ * User: guillaume
+ * Date: 30/05/13
+ * Time: 20:35
+ */
+public class AnnotationRegistry {
+
+ /**
+ * Contains the annotations definitions for the given Stereotype annotation.
+ */
+ private Map<Type, List<RootAnnotationRecorder>> stereotypes = new HashMap<Type, List<RootAnnotationRecorder>>();
+
+ /**
+ * Other annotations.
+ */
+ private List<Type> unbound = new ArrayList<Type>();
+
+ public void addStereotype(Type type, List<RootAnnotationRecorder> recorders) {
+ stereotypes.put(type, recorders);
+ }
+
+ public void addUnbound(Type type) {
+ unbound.add(type);
+ }
+
+ public List<RootAnnotationRecorder> getRecorders(Type type) {
+ List<RootAnnotationRecorder> recorders = stereotypes.get(type);
+ if (recorders == null) {
+ return Collections.emptyList();
+ }
+ return recorders;
+ }
+
+ public boolean isStereotype(Type type) {
+ return stereotypes.get(type) != null;
+ }
+
+ public boolean isUnbound(Type type) {
+ return unbound.contains(type);
+ }
+
+ public boolean isUnknown(Type type) {
+ return !isStereotype(type) && !isUnbound(type);
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/Selection.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/Selection.java
index 1d26d80..5fb435e 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/Selection.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/Selection.java
@@ -23,6 +23,9 @@
import org.apache.felix.ipojo.manipulator.metadata.annotation.ComponentWorkbench;
import org.apache.felix.ipojo.manipulator.spi.BindingContext;
import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldNode;
@@ -48,6 +51,7 @@
private int index = -1;
private String annotation;
private ElementType elementType = null;
+ private Object visitor;
public Selection(BindingRegistry registry, ComponentWorkbench workbench, Reporter reporter) {
this.registry = registry;
@@ -55,25 +59,29 @@
this.reporter = reporter;
}
- public Selection field(FieldNode node) {
+ public Selection field(FieldVisitor visitor, FieldNode node) {
+ this.visitor = visitor;
this.node = node;
this.elementType = ElementType.FIELD;
return this;
}
- public Selection method(MethodNode node) {
+ public Selection method(MethodVisitor visitor, MethodNode node) {
+ this.visitor = visitor;
this.node = node;
this.elementType = ElementType.METHOD;
return this;
}
- public Selection type(ClassNode node) {
+ public Selection type(ClassVisitor visitor, ClassNode node) {
+ this.visitor = visitor;
this.node = node;
this.elementType = ElementType.TYPE;
return this;
}
- public Selection parameter(MethodNode node, int index) {
+ public Selection parameter(MethodVisitor visitor, MethodNode node, int index) {
+ this.visitor = visitor;
this.index = index;
this.node = node;
this.elementType = ElementType.PARAMETER;
@@ -97,7 +105,7 @@
List<AnnotationVisitor> visitors = new ArrayList<AnnotationVisitor>();
- BindingContext context = new BindingContext(workbench, reporter, Type.getType(annotation), node, elementType, index);
+ BindingContext context = new BindingContext(workbench, reporter, Type.getType(annotation), node, elementType, index, visitor);
List<Binding> predicates = registry.getBindings(annotation);
if (predicates != null && !predicates.isEmpty()) {
@@ -116,7 +124,9 @@
for (Binding binding : bindings) {
if (binding.getPredicate().matches(context)) {
AnnotationVisitor visitor = binding.getFactory().newAnnotationVisitor(context);
- visitors.add(visitor);
+ if (visitor != null) {
+ visitors.add(visitor);
+ }
}
}
}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeParser.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeParser.java
new file mode 100644
index 0000000..672edee
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeParser.java
@@ -0,0 +1,53 @@
+/*
+ * 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.manipulator.metadata.annotation.stereotype;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
+import org.objectweb.asm.ClassReader;
+
+/**
+ * User: guillaume
+ * Date: 30/05/13
+ * Time: 12:42
+ */
+public class StereotypeParser {
+ private boolean stereotype = false;
+ private List<RootAnnotationRecorder> replays = new ArrayList<RootAnnotationRecorder>();
+
+ public void read(byte[] resource) {
+ ClassReader reader = new ClassReader(resource);
+ reader.accept(new StereotypeVisitor(this), ClassReader.SKIP_CODE);
+ }
+
+ public boolean isStereotype() {
+ return stereotype;
+ }
+
+ public void setStereotype(final boolean stereotype) {
+ this.stereotype = stereotype;
+ }
+
+ public List<RootAnnotationRecorder> getRecorders() {
+ return replays;
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeVisitor.java
new file mode 100644
index 0000000..6216831
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeVisitor.java
@@ -0,0 +1,67 @@
+/*
+ * 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.manipulator.metadata.annotation.stereotype;
+
+import org.apache.felix.ipojo.annotations.Stereotype;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.EmptyVisitor;
+
+/**
+* User: guillaume
+* Date: 30/05/13
+* Time: 17:09
+*/
+public class StereotypeVisitor extends EmptyVisitor {
+
+ public static final Type MARKER_TYPE = Type.getType(Stereotype.class);
+
+ private StereotypeParser m_definition;
+
+ public StereotypeVisitor(final StereotypeParser definition) {
+ m_definition = definition;
+ }
+
+ @Override
+ public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
+ Type annotationType = Type.getType(desc);
+ if (MARKER_TYPE.equals(annotationType)) {
+ m_definition.setStereotype(true);
+ return null;
+ }
+ RootAnnotationRecorder visitor = new RootAnnotationRecorder(desc, visible);
+ m_definition.getRecorders().add(visitor);
+ return visitor;
+ }
+
+ @Override
+ public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
+ return null;
+ }
+
+ @Override
+ public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) {
+ return null;
+ }
+
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/AnnotationRecorder.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/AnnotationRecorder.java
new file mode 100644
index 0000000..b0afaa4
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/AnnotationRecorder.java
@@ -0,0 +1,65 @@
+/*
+ * 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.manipulator.metadata.annotation.stereotype.replay;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+* User: guillaume
+* Date: 30/05/13
+* Time: 17:22
+*/
+public class AnnotationRecorder implements AnnotationVisitor, Replay {
+
+ private List<Replay> record = new ArrayList<Replay>();
+
+ public void visit(final String name, final Object value) {
+ record.add(new Visit(name, value));
+ }
+
+ public void visitEnum(final String name, final String desc, final String value) {
+ record.add(new VisitEnum(name, desc, value));
+ }
+
+ public AnnotationVisitor visitAnnotation(final String name, final String desc) {
+ AnnotationRecorder sub = new AnnotationRecorder();
+ record.add(new VisitAnnotation(name, desc, sub));
+ return sub;
+ }
+
+ public AnnotationVisitor visitArray(final String name) {
+ AnnotationRecorder sub = new AnnotationRecorder();
+ record.add(new VisitArray(name, sub));
+ return sub;
+ }
+
+ public void visitEnd() {
+ record.add(new VisitEnd());
+ }
+
+ public void accept(final AnnotationVisitor visitor) {
+ for (Replay replay : record) {
+ replay.accept(visitor);
+ }
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
new file mode 100644
index 0000000..1748cfc
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Replay.java
@@ -0,0 +1,31 @@
+/*
+ * 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.manipulator.metadata.annotation.stereotype.replay;
+
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+* User: guillaume
+* Date: 30/05/13
+* Time: 17:23
+*/
+public interface Replay {
+ void accept(AnnotationVisitor visitor);
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/RootAnnotationRecorder.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/RootAnnotationRecorder.java
new file mode 100644
index 0000000..70548bd
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/RootAnnotationRecorder.java
@@ -0,0 +1,68 @@
+/*
+ * 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.manipulator.metadata.annotation.stereotype.replay;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * User: guillaume
+ * Date: 30/05/13
+ * Time: 19:20
+ */
+public class RootAnnotationRecorder extends AnnotationRecorder {
+ private final String m_desc;
+ private final boolean m_visible;
+
+ public RootAnnotationRecorder(final String desc, final boolean visible) {
+ m_desc = desc;
+ m_visible = visible;
+ }
+
+ public void accept(final FieldVisitor visitor) {
+ AnnotationVisitor av = visitor.visitAnnotation(m_desc, m_visible);
+ if (av != null) {
+ accept(av);
+ }
+ }
+
+ public void accept(final ClassVisitor visitor) {
+ AnnotationVisitor av = visitor.visitAnnotation(m_desc, m_visible);
+ if (av != null) {
+ accept(av);
+ }
+ }
+
+ public void accept(final MethodVisitor visitor) {
+ AnnotationVisitor av = visitor.visitAnnotation(m_desc, m_visible);
+ if (av != null) {
+ accept(av);
+ }
+ }
+
+ public void accept(final MethodVisitor visitor, int index) {
+ AnnotationVisitor av = visitor.visitParameterAnnotation(index, m_desc, m_visible);
+ if (av != null) {
+ accept(av);
+ }
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Visit.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Visit.java
new file mode 100644
index 0000000..e0d46c2
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/Visit.java
@@ -0,0 +1,41 @@
+/*
+ * 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.manipulator.metadata.annotation.stereotype.replay;
+
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+* User: guillaume
+* Date: 30/05/13
+* Time: 17:23
+*/
+public class Visit implements Replay {
+ private final String m_name;
+ private final Object m_value;
+
+ public Visit(final String name, final Object value) {
+ m_name = name;
+ m_value = value;
+ }
+
+ public void accept(AnnotationVisitor visitor) {
+ visitor.visit(m_name, m_value);
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitAnnotation.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitAnnotation.java
new file mode 100644
index 0000000..ee61d7d
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitAnnotation.java
@@ -0,0 +1,46 @@
+/*
+ * 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.manipulator.metadata.annotation.stereotype.replay;
+
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+* User: guillaume
+* Date: 30/05/13
+* Time: 17:24
+*/
+public class VisitAnnotation implements Replay {
+ private final String m_name;
+ private final String m_desc;
+ private final AnnotationRecorder m_sub;
+
+ public VisitAnnotation(final String name, final String desc, final AnnotationRecorder sub) {
+ m_name = name;
+ m_desc = desc;
+ m_sub = sub;
+ }
+
+ public void accept(final AnnotationVisitor visitor) {
+ AnnotationVisitor child = visitor.visitAnnotation(m_name, m_desc);
+ if (child != null) {
+ m_sub.accept(child);
+ }
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitArray.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitArray.java
new file mode 100644
index 0000000..124d75a
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitArray.java
@@ -0,0 +1,44 @@
+/*
+ * 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.manipulator.metadata.annotation.stereotype.replay;
+
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+* User: guillaume
+* Date: 30/05/13
+* Time: 17:24
+*/
+public class VisitArray implements Replay {
+ private final String m_name;
+ private final AnnotationRecorder m_sub;
+
+ public VisitArray(final String name, final AnnotationRecorder sub) {
+ m_name = name;
+ m_sub = sub;
+ }
+
+ public void accept(final AnnotationVisitor visitor) {
+ AnnotationVisitor child = visitor.visitArray(m_name);
+ if (child != null) {
+ m_sub.accept(child);
+ }
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitEnd.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitEnd.java
new file mode 100644
index 0000000..51ddb58
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitEnd.java
@@ -0,0 +1,34 @@
+/*
+ * 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.manipulator.metadata.annotation.stereotype.replay;
+
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+* User: guillaume
+* Date: 30/05/13
+* Time: 17:24
+*/
+public class VisitEnd implements Replay {
+
+ public void accept(final AnnotationVisitor visitor) {
+ visitor.visitEnd();
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitEnum.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitEnum.java
new file mode 100644
index 0000000..12708d6
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/VisitEnum.java
@@ -0,0 +1,42 @@
+/*
+ * 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.manipulator.metadata.annotation.stereotype.replay;
+
+import org.objectweb.asm.AnnotationVisitor;
+
+/**
+* User: guillaume
+* Date: 30/05/13
+* Time: 17:23
+*/
+public class VisitEnum implements Replay {
+ private final String m_name;
+ private final String m_desc;
+ private final String m_value;
+
+ public VisitEnum(final String name, final String desc, final String value) {m_name = name;
+ m_desc = desc;
+ m_value = value;
+ }
+
+ public void accept(final AnnotationVisitor visitor) {
+ visitor.visitEnum(m_name, m_desc, m_value);
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/FieldStereotypeVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/FieldStereotypeVisitor.java
new file mode 100644
index 0000000..913677e
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/FieldStereotypeVisitor.java
@@ -0,0 +1,51 @@
+/*
+ * 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.manipulator.metadata.annotation.visitor.stereotype;
+
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.commons.EmptyVisitor;
+
+/**
+ * User: guillaume
+ * Date: 30/05/13
+ * Time: 18:55
+ */
+public class FieldStereotypeVisitor extends EmptyVisitor {
+
+ private final FieldVisitor delegate;
+ private final List<RootAnnotationRecorder> m_recorder;
+
+ public FieldStereotypeVisitor(final FieldVisitor delegate, List<RootAnnotationRecorder> recorder) {
+ this.delegate = delegate;
+ m_recorder = recorder;
+ }
+
+ @Override
+ public void visitEnd() {
+ // Replay stereotype annotations
+ for (RootAnnotationRecorder recorder : m_recorder) {
+ recorder.accept(delegate);
+ }
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/MethodStereotypeVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/MethodStereotypeVisitor.java
new file mode 100644
index 0000000..06dc9af
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/MethodStereotypeVisitor.java
@@ -0,0 +1,51 @@
+/*
+ * 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.manipulator.metadata.annotation.visitor.stereotype;
+
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.commons.EmptyVisitor;
+
+/**
+ * User: guillaume
+ * Date: 30/05/13
+ * Time: 18:55
+ */
+public class MethodStereotypeVisitor extends EmptyVisitor {
+
+ private final MethodVisitor delegate;
+ private final List<RootAnnotationRecorder> m_recorder;
+
+ public MethodStereotypeVisitor(final MethodVisitor delegate, List<RootAnnotationRecorder> recorder) {
+ this.delegate = delegate;
+ m_recorder = recorder;
+ }
+
+ @Override
+ public void visitEnd() {
+ // Replay stereotype annotations
+ for (RootAnnotationRecorder recorder : m_recorder) {
+ recorder.accept(delegate);
+ }
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/ParameterStereotypeVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/ParameterStereotypeVisitor.java
new file mode 100644
index 0000000..c764399
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/ParameterStereotypeVisitor.java
@@ -0,0 +1,53 @@
+/*
+ * 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.manipulator.metadata.annotation.visitor.stereotype;
+
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.commons.EmptyVisitor;
+
+/**
+ * User: guillaume
+ * Date: 30/05/13
+ * Time: 18:55
+ */
+public class ParameterStereotypeVisitor extends EmptyVisitor {
+
+ private final MethodVisitor delegate;
+ private final int index;
+ private final List<RootAnnotationRecorder> m_recorder;
+
+ public ParameterStereotypeVisitor(final MethodVisitor delegate, final int index, List<RootAnnotationRecorder> recorder) {
+ this.delegate = delegate;
+ this.index = index;
+ m_recorder = recorder;
+ }
+
+ @Override
+ public void visitEnd() {
+ // Replay stereotype annotations
+ for (RootAnnotationRecorder recorder : m_recorder) {
+ recorder.accept(delegate, index);
+ }
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/TypeStereotypeVisitor.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/TypeStereotypeVisitor.java
new file mode 100644
index 0000000..255219f
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/stereotype/TypeStereotypeVisitor.java
@@ -0,0 +1,50 @@
+/*
+ * 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.manipulator.metadata.annotation.visitor.stereotype;
+
+import java.util.List;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.commons.EmptyVisitor;
+
+/**
+ * User: guillaume
+ * Date: 30/05/13
+ * Time: 18:55
+ */
+public class TypeStereotypeVisitor extends EmptyVisitor {
+
+ private final ClassVisitor delegate;
+ private final List<RootAnnotationRecorder> m_recorder;
+
+ public TypeStereotypeVisitor(final ClassVisitor delegate, List<RootAnnotationRecorder> recorder) {
+ this.delegate = delegate;
+ m_recorder = recorder;
+ }
+
+ @Override
+ public void visitEnd() {
+ // Replay stereotype annotations
+ for (RootAnnotationRecorder recorder : m_recorder) {
+ recorder.accept(delegate);
+ }
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/util/Bindings.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/util/Bindings.java
index 877794a..d675351 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/util/Bindings.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/metadata/annotation/visitor/util/Bindings.java
@@ -20,8 +20,15 @@
package org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.util;
import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.ResourceStore;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.AnnotationRegistry;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.StereotypeParser;
import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.Binding;
import org.apache.felix.ipojo.manipulator.metadata.annotation.registry.BindingRegistry;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype.FieldStereotypeVisitor;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype.MethodStereotypeVisitor;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype.ParameterStereotypeVisitor;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.stereotype.TypeStereotypeVisitor;
import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.FieldGenericVisitor;
import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.MethodGenericVisitor;
import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.ParameterGenericVisitor;
@@ -30,20 +37,25 @@
import org.apache.felix.ipojo.manipulator.spi.BindingContext;
import org.apache.felix.ipojo.manipulator.spi.Module;
import org.apache.felix.ipojo.manipulator.spi.Predicate;
+import org.apache.felix.ipojo.manipulator.util.Strings;
import org.apache.felix.ipojo.metadata.Element;
import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Type;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
+import java.io.IOException;
import java.lang.annotation.ElementType;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import java.util.ServiceLoader;
-import java.util.regex.Pattern;
import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.and;
import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.on;
+import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.or;
import static org.apache.felix.ipojo.manipulator.spi.helper.Predicates.pattern;
/**
@@ -51,16 +63,6 @@
*/
public class Bindings {
- private static List<Binding> DEFAULT_BINDINGS;
- static {
- DEFAULT_BINDINGS = new ArrayList<Binding>();
- DEFAULT_BINDINGS.add(newGenericTypeBinding());
- DEFAULT_BINDINGS.add(newGenericFieldBinding());
- DEFAULT_BINDINGS.add(newGenericMethodBinding());
- DEFAULT_BINDINGS.add(newGenericParameterBinding());
- DEFAULT_BINDINGS = Collections.unmodifiableList(DEFAULT_BINDINGS);
- }
-
private static Binding newGenericTypeBinding() {
Binding binding = new Binding();
// ElementType is TYPE
@@ -138,8 +140,9 @@
}
- public static BindingRegistry newBindingRegistry(Reporter reporter) {
+ public static BindingRegistry newBindingRegistry(Reporter reporter, ResourceStore store) {
+ AnnotationRegistry ar = new AnnotationRegistry();
BindingRegistry registry = new BindingRegistry(reporter);
ServiceLoader<Module> loader = ServiceLoader.load(Module.class, classloader());
@@ -150,13 +153,129 @@
}
// Do not forget the default Bindings
- registry.getDefaultBindings().addAll(DEFAULT_BINDINGS);
+ registry.getDefaultBindings().addAll(newDefaultBindings(store, ar));
return registry;
}
- public static List<Binding> getDefaultBindings() {
- return DEFAULT_BINDINGS;
+ public static List<Binding> newDefaultBindings(final ResourceStore store, final AnnotationRegistry ar) {
+ List<Binding> bindings = new ArrayList<Binding>();
+
+ // Register Stereotype binding support first
+ // That allows iPOJO to provide its own stereotyped annotations
+ bindings.add(newStereotypeTypeBinding(store, ar));
+ bindings.add(newStereotypeFieldBinding(store, ar));
+ bindings.add(newStereotypeMethodBinding(store, ar));
+ bindings.add(newStereotypeParameterBinding(store, ar));
+
+ // Then register the generic bindings
+ bindings.add(newGenericTypeBinding());
+ bindings.add(newGenericFieldBinding());
+ bindings.add(newGenericMethodBinding());
+ bindings.add(newGenericParameterBinding());
+ return bindings;
+
+ }
+
+ private static Binding newStereotypeParameterBinding(final ResourceStore store, final AnnotationRegistry registry) {
+ Binding binding = new Binding();
+ binding.setPredicate(
+ and(
+ on(ElementType.PARAMETER),
+ stereotype(store, registry)
+ ));
+ binding.setFactory(new AnnotationVisitorFactory() {
+ public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
+ return new ParameterStereotypeVisitor((MethodVisitor) context.getVisitor(),
+ context.getParameterIndex(),
+ registry.getRecorders(context.getAnnotationType()));
+ }
+ });
+ return binding;
+ }
+
+ private static Binding newStereotypeMethodBinding(final ResourceStore store, final AnnotationRegistry registry) {
+ Binding binding = new Binding();
+ binding.setPredicate(
+ and(
+ on(ElementType.METHOD),
+ stereotype(store, registry)
+ ));
+ binding.setFactory(new AnnotationVisitorFactory() {
+ public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
+ return new MethodStereotypeVisitor((MethodVisitor) context.getVisitor(),
+ registry.getRecorders(context.getAnnotationType()));
+ }
+ });
+ return binding;
+ }
+
+ private static Binding newStereotypeFieldBinding(final ResourceStore store, final AnnotationRegistry registry) {
+ Binding binding = new Binding();
+ binding.setPredicate(
+ and(
+ on(ElementType.FIELD),
+ stereotype(store, registry)
+ ));
+ binding.setFactory(new AnnotationVisitorFactory() {
+ public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
+ return new FieldStereotypeVisitor((FieldVisitor) context.getVisitor(),
+ registry.getRecorders(context.getAnnotationType()));
+ }
+ });
+ return binding;
+ }
+
+ private static Binding newStereotypeTypeBinding(final ResourceStore store, final AnnotationRegistry registry) {
+ Binding binding = new Binding();
+ binding.setPredicate(
+ and(
+ on(ElementType.TYPE),
+ stereotype(store, registry)
+ ));
+ binding.setFactory(new AnnotationVisitorFactory() {
+ public AnnotationVisitor newAnnotationVisitor(BindingContext context) {
+ return new TypeStereotypeVisitor((ClassVisitor) context.getVisitor(),
+ registry.getRecorders(context.getAnnotationType()));
+ }
+ });
+ return binding;
+ }
+
+ private static Predicate stereotype(final ResourceStore store, final AnnotationRegistry registry) {
+ return new Predicate() {
+ public boolean matches(final BindingContext context) {
+
+ Type type = context.getAnnotationType();
+ if (registry.isUnknown(type)) {
+ // The given annotation type was never parsed before
+ try {
+
+ // Try to read the annotation's byte code
+ byte[] bytes = store.read(Strings.asResourcePath(context.getAnnotationType().getClassName()));
+ if (bytes != null) {
+ StereotypeParser parser = new StereotypeParser();
+ parser.read(bytes);
+ if (parser.isStereotype()) {
+ registry.addStereotype(type, parser.getRecorders());
+ return true;
+ } else {
+ registry.addUnbound(type);
+ return false;
+ }
+ }
+ registry.addUnbound(type);
+ return false;
+ } catch (IOException e) {
+ // Cannot load the byte code, assume it's not a stereotype
+ // TODO print a warning ?
+ registry.addUnbound(type);
+ return false;
+ }
+ }
+ return registry.isStereotype(type);
+ }
+ };
}
private static ClassLoader classloader() {
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/spi/BindingContext.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/spi/BindingContext.java
index 14129bf..72bdc25 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/spi/BindingContext.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/spi/BindingContext.java
@@ -40,19 +40,22 @@
private int parameterIndex;
private Reporter reporter;
private Type annotationType;
+ private Object visitor;
public BindingContext(final ComponentWorkbench workbench,
final Reporter reporter,
final Type annotationType,
final MemberNode node,
final ElementType elementType,
- final int parameterIndex) {
+ final int parameterIndex,
+ final Object visitor) {
this.workbench = workbench;
this.reporter = reporter;
this.annotationType = annotationType;
this.node = node;
this.elementType = elementType;
this.parameterIndex = parameterIndex;
+ this.visitor = visitor;
}
public ComponentWorkbench getWorkbench() {
@@ -78,4 +81,8 @@
public Type getAnnotationType() {
return annotationType;
}
+
+ public Object getVisitor() {
+ return visitor;
+ }
}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/AnnotationRegistryTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/AnnotationRegistryTestCase.java
new file mode 100644
index 0000000..1607589
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/AnnotationRegistryTestCase.java
@@ -0,0 +1,59 @@
+/*
+ * 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.manipulator.metadata.annotation.registry;
+
+import java.util.Collections;
+
+import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
+import org.objectweb.asm.Type;
+
+import junit.framework.TestCase;
+
+/**
+ * User: guillaume
+ * Date: 31/05/13
+ * Time: 00:18
+ */
+public class AnnotationRegistryTestCase extends TestCase {
+ public void testEmptyRegistry() throws Exception {
+ AnnotationRegistry registry = new AnnotationRegistry();
+ assertTrue(registry.isUnknown(Type.BOOLEAN_TYPE));
+ assertFalse(registry.isStereotype(Type.BOOLEAN_TYPE));
+ assertFalse(registry.isUnbound(Type.BOOLEAN_TYPE));
+ }
+
+ public void testRegistry1() throws Exception {
+ AnnotationRegistry registry = new AnnotationRegistry();
+ registry.addStereotype(Type.BOOLEAN_TYPE, Collections.<RootAnnotationRecorder>emptyList());
+
+ assertFalse(registry.isUnknown(Type.BOOLEAN_TYPE));
+ assertTrue(registry.isStereotype(Type.BOOLEAN_TYPE));
+ assertFalse(registry.isUnbound(Type.BOOLEAN_TYPE));
+ }
+
+ public void testRegistry2() throws Exception {
+ AnnotationRegistry registry = new AnnotationRegistry();
+ registry.addUnbound(Type.BOOLEAN_TYPE);
+
+ assertFalse(registry.isUnknown(Type.BOOLEAN_TYPE));
+ assertFalse(registry.isStereotype(Type.BOOLEAN_TYPE));
+ assertTrue(registry.isUnbound(Type.BOOLEAN_TYPE));
+ }
+}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/SelectionTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/SelectionTestCase.java
index 5055ed0..7067d63 100644
--- a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/SelectionTestCase.java
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/registry/SelectionTestCase.java
@@ -21,6 +21,7 @@
import junit.framework.TestCase;
import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.ResourceStore;
import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.FieldGenericVisitor;
import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.MethodGenericVisitor;
import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.generic.ParameterGenericVisitor;
@@ -64,6 +65,8 @@
private AnnotationVisitorFactory factory;
@Mock
private AnnotationVisitor visitor;
+ @Mock
+ private ResourceStore store;
@Override
public void setUp() throws Exception {
@@ -149,7 +152,7 @@
assertMethodSelection(OnMethodOnly.class, nullValue());
assertParameterSelection(OnParameterOnly.class, nullValue());
- registry.getDefaultBindings().addAll(Bindings.getDefaultBindings());
+ registry.getDefaultBindings().addAll(Bindings.newDefaultBindings(store, new AnnotationRegistry()));
// Verifications
assertClassSelection(OnTypeOnly.class, instanceOf(TypeGenericVisitor.class));
@@ -161,7 +164,7 @@
private void assertClassSelection(Class<? extends Annotation> type, Matcher matcher) {
Selection selection = new Selection(registry, null, reporter);
- selection.type(classNode());
+ selection.type(null, classNode());
selection.annotatedWith(descriptor(type));
assertTrue(matcher.matches(selection.get()));
@@ -169,7 +172,7 @@
private void assertFieldSelection(Class<? extends Annotation> type, Matcher matcher) {
Selection selection = new Selection(registry, null, reporter);
- selection.field(fieldNode());
+ selection.field(null, fieldNode());
selection.annotatedWith(descriptor(type));
assertTrue(matcher.matches(selection.get()));
@@ -177,7 +180,7 @@
private void assertMethodSelection(Class<? extends Annotation> type, Matcher matcher) {
Selection selection = new Selection(registry, null, reporter);
- selection.method(methodNode());
+ selection.method(null, methodNode());
selection.annotatedWith(descriptor(type));
assertTrue(matcher.matches(selection.get()));
@@ -185,7 +188,7 @@
private void assertParameterSelection(Class<? extends Annotation> type, Matcher matcher) {
Selection selection = new Selection(registry, null, reporter);
- selection.parameter(methodNode(), 0);
+ selection.parameter(null, methodNode(), 0);
selection.annotatedWith(descriptor(type));
assertTrue(matcher.matches(selection.get()));
@@ -204,7 +207,7 @@
public void testSelectionWithEmptyRegistry() throws Exception {
Selection selection = new Selection(registry, null, reporter);
- selection.field(fieldNode())
+ selection.field(null, fieldNode())
.annotatedWith(descriptor(OnTypeOnly.class));
assertNull(selection.get());
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeParserTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeParserTestCase.java
new file mode 100644
index 0000000..10fc0ef
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/StereotypeParserTestCase.java
@@ -0,0 +1,115 @@
+/*
+ * 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.manipulator.metadata.annotation.stereotype;
+
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.when;
+
+import java.net.URL;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Instantiate;
+import org.apache.felix.ipojo.annotations.Stereotype;
+import org.apache.felix.ipojo.manipulator.metadata.annotation.stereotype.replay.RootAnnotationRecorder;
+import org.apache.felix.ipojo.manipulator.util.Streams;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.Type;
+
+import junit.framework.TestCase;
+
+/**
+ * User: guillaume
+ * Date: 30/05/13
+ * Time: 23:51
+ */
+public class StereotypeParserTestCase extends TestCase {
+ public static final String COMPONENT_DESC = Type.getType(Component.class).getDescriptor();
+ public static final String INSTANTIATE_DESC = Type.getType(Instantiate.class).getDescriptor();
+ @Mock
+ private AnnotationVisitor av;
+
+ @Mock
+ private ClassVisitor cv;
+
+ @Override
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ public void testStereotypeParsing() throws Exception {
+ StereotypeParser parser = new StereotypeParser();
+ parser.read(resource(IsStereotype.class));
+ assertTrue(parser.isStereotype());
+ }
+
+ public void testStereotypeParsingWithAnnotations() throws Exception {
+
+ when(cv.visitAnnotation(COMPONENT_DESC, false))
+ .thenReturn(av);
+ when(cv.visitAnnotation(INSTANTIATE_DESC, false))
+ .thenReturn(av);
+
+ StereotypeParser parser = new StereotypeParser();
+ parser.read(resource(ComponentInstanceStereotype.class));
+ assertTrue(parser.isStereotype());
+ assertEquals(2, parser.getRecorders().size());
+
+ RootAnnotationRecorder rec1 = parser.getRecorders().get(0);
+ rec1.accept(cv);
+ RootAnnotationRecorder rec2 = parser.getRecorders().get(1);
+ rec2.accept(cv);
+
+ InOrder order = inOrder(cv, av);
+ order.verify(cv).visitAnnotation(COMPONENT_DESC, false);
+ order.verify(av).visit("immediate", Boolean.TRUE);
+ order.verify(av).visitEnd();
+ order.verify(cv).visitAnnotation(INSTANTIATE_DESC, false);
+ order.verify(av).visitEnd();
+ }
+
+ public void testNoStereotypeParsing() throws Exception {
+ StereotypeParser parser = new StereotypeParser();
+ parser.read(resource(NoStereotype.class));
+ assertFalse(parser.isStereotype());
+ }
+
+ private byte[] resource(final Class<?> aClass) throws Exception {
+ String name = aClass.getDeclaringClass().getSimpleName() +
+ "$" + aClass.getSimpleName()
+ + ".class";
+ URL url = aClass.getResource(name);
+ return Streams.readBytes(url.openStream());
+ }
+
+ @Stereotype
+ public static @interface IsStereotype {}
+
+ public static @interface NoStereotype {}
+
+ @Component(immediate = true)
+ @Instantiate
+ @Stereotype
+ public static @interface ComponentInstanceStereotype {}
+
+}
diff --git a/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/AnnotationRecorderTestCase.java b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/AnnotationRecorderTestCase.java
new file mode 100644
index 0000000..71e5058
--- /dev/null
+++ b/ipojo/manipulator/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/annotation/stereotype/replay/AnnotationRecorderTestCase.java
@@ -0,0 +1,92 @@
+/*
+ * 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.manipulator.metadata.annotation.stereotype.replay;
+
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.objectweb.asm.AnnotationVisitor;
+
+import junit.framework.TestCase;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * User: guillaume
+ * Date: 30/05/13
+ * Time: 22:04
+ */
+public class AnnotationRecorderTestCase extends TestCase {
+
+ @Mock
+ private AnnotationVisitor visitor;
+
+ @Override
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ public void testVisitRecord() throws Exception {
+ AnnotationRecorder recorder = new AnnotationRecorder();
+ recorder.visit("attribute", "a value");
+ recorder.accept(visitor);
+ verify(visitor).visit("attribute", "a value");
+ }
+
+ public void testVisitEndRecord() throws Exception {
+ AnnotationRecorder recorder = new AnnotationRecorder();
+ recorder.visitEnd();
+ recorder.accept(visitor);
+ verify(visitor).visitEnd();
+ }
+
+ public void testVisitEnumRecord() throws Exception {
+ AnnotationRecorder recorder = new AnnotationRecorder();
+ recorder.visitEnum("name", "type-desc", "A");
+ recorder.accept(visitor);
+ verify(visitor).visitEnum("name", "type-desc", "A");
+ }
+
+ public void testVisitAnnotationRecord() throws Exception {
+
+ when(visitor.visitAnnotation("name", "type-desc")).thenReturn(visitor);
+
+ AnnotationRecorder recorder = new AnnotationRecorder();
+ AnnotationVisitor sub = recorder.visitAnnotation("name", "type-desc");
+ sub.visit("name2", "value2");
+ recorder.accept(visitor);
+
+ verify(visitor).visitAnnotation("name", "type-desc");
+ verify(visitor).visit("name2", "value2");
+ }
+
+ public void testVisitArrayRecord() throws Exception {
+
+ when(visitor.visitArray("name")).thenReturn(visitor);
+
+ AnnotationRecorder recorder = new AnnotationRecorder();
+ AnnotationVisitor sub = recorder.visitArray("name");
+ sub.visit("name2", "value2");
+ recorder.accept(visitor);
+
+ verify(visitor).visitArray("name");
+ verify(visitor).visit("name2", "value2");
+ }
+}