Improve FELIX-1159 by providing annotation support.
It's now possible to declare component type version with annotations:
@Component(version="1.0.0" ...)
public class Foo {
...
}
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@777817 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Component.java b/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Component.java
index 5c4210f..d590fe5 100644
--- a/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Component.java
+++ b/ipojo/annotations/src/main/java/org/apache/felix/ipojo/annotations/Component.java
@@ -1,4 +1,4 @@
-/*
+/*
* 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
@@ -28,48 +28,53 @@
*/
@Target(ElementType.TYPE)
public @interface Component {
-
+
/**
* Set if the component type is public.
* Default: true
*/
boolean public_factory() default true;
-
+
/**
* Set the component type name.
* Default : implementation class name.
*/
String name() default "";
-
+
/**
* Enable / Disable the architecture exposition.
* Default : false
*/
boolean architecture() default false;
-
+
/**
* Set if the component is immediate.
* Default : false
*/
boolean immediate() default false;
-
+
/**
* Set if the component must propagate received configuration to provided services.
* default: false
*/
boolean propagation() default false;
-
+
/**
* Set the Managed Service PID.
* default no PID (i.e. the managed service will not be exposed).
*/
String managedservice() default "";
-
+
/**
* Set the factory-method, if the pojo has to be created
* from a static method. The specified method must be a static
* method and return a pojo object.
- * By default, iPOJO uses the 'regular' constructor.
+ * By default, iPOJO uses the 'regular' constructor.
*/
String factory_method() default "";
+
+ /**
+ * Set the version of the component type.
+ */
+ String version() default "";
}
diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java
index e28120e..2b3d09c 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MetadataCollector.java
@@ -1,4 +1,4 @@
-/*
+/*
* 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
@@ -43,45 +43,45 @@
* Class name.
*/
private String m_className;
-
+
/**
* Root element of computed metadata.
*/
private Element m_elem = new Element("component", "");
-
+
/**
* True if the visited class is a component type declaration (i.e. contains the @component annotation).
*/
private boolean m_containsAnnotation = false;
-
+
/**
* Map of [element ids, element].
- * This map is used to easily get an already created element.
+ * This map is used to easily get an already created element.
*/
private Map m_ids = new HashMap();
-
+
/**
* Map of [element, referto].
* This map is used to recreate the element hierarchie.
- * Stored element are added under referred element.
+ * Stored element are added under referred element.
*/
private Map m_elements = new HashMap();
-
+
public Element getElem() {
return m_elem;
}
-
+
public boolean isAnnotated() {
return m_containsAnnotation;
}
-
+
/**
* Start visiting a class.
* Initialize the getter/setter generator, add the _cm field, add the pojo interface.
* @param version : class version
* @param access : class access
- * @param name : class name
+ * @param name : class name
* @param signature : class signature
* @param superName : class super class
* @param interfaces : implemented interfaces
@@ -93,7 +93,7 @@
m_className = name;
}
-
+
/**
* Visit class annotations.
* This method detects @component and @provides annotations.
@@ -110,20 +110,20 @@
m_elem.addAttribute(new Attribute("className", m_className.replace('/', '.')));
return new ComponentVisitor();
}
-
+
// @Provides
if (desc.equals("Lorg/apache/felix/ipojo/annotations/Provides;")) {
return new ProvidesVisitor();
}
-
+
if (CustomAnnotationVisitor.isCustomAnnotation(desc)) {
Element elem = CustomAnnotationVisitor.buildElement(desc);
return new CustomAnnotationVisitor(elem, this, true, true);
}
-
+
return null;
}
-
+
/**
@@ -155,7 +155,7 @@
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new MethodCollector(name, this);
}
-
+
/**
* End of the visit : compute final elements.
* @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
@@ -213,7 +213,7 @@
m_prov.addAttribute(new Attribute("strategy", arg1.toString()));
}
}
-
+
/**
* Visit specifications array.
* @param arg0 : attribute name
@@ -227,7 +227,7 @@
return null;
}
}
-
+
/**
* End of the visit.
* Append to the parent element the computed "provides" element.
@@ -237,13 +237,13 @@
getIds().put("provides", m_prov);
getElements().put(m_prov, null);
}
-
+
private class InterfaceArrayVisitor extends EmptyVisitor {
/**
* List of parsed interface.
*/
private String m_itfs;
-
+
/**
* Visit one element of the array.
* @param arg0 : null
@@ -257,7 +257,7 @@
m_itfs += "," + ((Type) arg1).getClassName();
}
}
-
+
/**
* End of the array visit.
* Add the attribute to 'provides' element.
@@ -266,31 +266,31 @@
public void visitEnd() {
m_prov.addAttribute(new Attribute("specifications", m_itfs + "}"));
}
-
+
}
-
+
}
-
+
/**
* Parse the @component annotation.
*/
private class ComponentVisitor extends EmptyVisitor implements AnnotationVisitor {
-
+
/**
* Factory attribute.
*/
private String m_factory;
/**
- * Is the component an immediate component?
+ * Is the component an immediate component?
*/
private String m_immediate;
-
+
/**
- * Component name (cannot be null).
+ * Component name (cannot be null).
*/
private String m_name;
-
+
/**
* Does the component exposes its architecture?
*/
@@ -300,17 +300,22 @@
* Does the component propagate configuration to provided services?
*/
private String m_propagation;
-
+
/**
* Managed Service PID.
*/
private String m_managedservice;
-
+
/**
* Factory-Method.
*/
private String m_method;
-
+
+ /**
+ * Version.
+ */
+ private String m_version;
+
/**
* Element properties.
*/
@@ -351,6 +356,10 @@
m_method = arg1.toString();
return;
}
+ if (arg0.equals("version")) {
+ m_version = arg1.toString();
+ return;
+ }
}
/**
@@ -358,7 +367,7 @@
* Append to the "component" element computed attribute.
* @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
*/
- public void visitEnd() {
+ public void visitEnd() {
if (m_name == null) {
m_name = m_className.replace('/', '.');
}
@@ -366,7 +375,7 @@
if (m_factory != null && m_factory.equalsIgnoreCase("false")) {
m_elem.addAttribute(new Attribute("public", "false"));
} else {
- m_elem.addAttribute(new Attribute("public", "true"));
+ m_elem.addAttribute(new Attribute("public", "true"));
}
if (m_architecture != null) {
m_elem.addAttribute(new Attribute("architecture", m_architecture));
@@ -377,6 +386,9 @@
if (m_method != null) {
m_elem.addAttribute(new Attribute("factory-method", m_method));
}
+ if (m_version != null) {
+ m_elem.addAttribute(new Attribute("version", m_version));
+ }
if (m_propagation != null) {
if (m_props == null) {
m_props = new Element("properties", "");
@@ -393,6 +405,6 @@
}
m_props.addAttribute(new Attribute("pid", m_managedservice));
}
- }
+ }
}
}
diff --git a/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/annotations/Factory.java b/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/annotations/Factory.java
index 22bca51..5da28e6 100644
--- a/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/annotations/Factory.java
+++ b/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/annotations/Factory.java
@@ -5,13 +5,13 @@
import org.apache.felix.ipojo.metadata.Element;
public class Factory extends OSGiTestCase {
-
+
private IPOJOHelper helper;
-
+
public void setUp() {
helper = new IPOJOHelper(this);
}
-
+
public void testArch() {
Element meta = helper.getMetadata("org.apache.felix.ipojo.test.scenarios.component.Factory");
String fact = meta.getAttribute("public");
@@ -21,7 +21,7 @@
assertNotNull("Name exists ", name);
assertEquals("Name value", "factory", name);
}
-
+
public void testNoArch() {
Element meta = helper.getMetadata("org.apache.felix.ipojo.test.scenarios.component.NoFactory");
String fact = meta.getAttribute("public");
@@ -31,15 +31,28 @@
assertNotNull("Name exists ", name);
assertEquals("Name value", "nofactory", name);
}
-
+
public void testFactoryMethod() {
Element meta = helper.getMetadata("org.apache.felix.ipojo.test.scenarios.component.FactoryMethod");
String method = meta.getAttribute("factory-method");
assertNotNull("Method exists ", method);
assertEquals("Method value", "create", method);
}
-
-
+
+ public void testVersion() {
+ Element meta = helper.getMetadata("org.apache.felix.ipojo.test.scenarios.component.ComponentTypeVersion");
+ String version = meta.getAttribute("version");
+ assertNotNull("Version exist", version);
+ assertEquals("Version value", "1.0.0", version);
+ }
+
+ public void testNoVersion() {
+ Element meta = helper.getMetadata("org.apache.felix.ipojo.test.scenarios.component.FactoryMethod");
+ String version = meta.getAttribute("version");
+ assertNull("No Version", version);
+ }
+
+
}
diff --git a/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ComponentTypeVersion.java b/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ComponentTypeVersion.java
new file mode 100644
index 0000000..a1b08ed
--- /dev/null
+++ b/ipojo/tests/core/annotations/src/main/java/org/apache/felix/ipojo/test/scenarios/component/ComponentTypeVersion.java
@@ -0,0 +1,9 @@
+package org.apache.felix.ipojo.test.scenarios.component;
+
+import org.apache.felix.ipojo.annotations.Component;
+
+
+@Component(version="1.0.0")
+public class ComponentTypeVersion {
+
+}