Add the processing of the Instantiate annotation (FELIX-1940)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@892615 13f79535-47bb-0310-9956-ffa450edef68
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 4de1e58..0355084 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
@@ -63,8 +63,8 @@
/**
* True if the visited class is a component type declaration (i.e. contains the @component annotation).
*/
- private boolean m_containsAnnotation = false;
-
+ private boolean m_containsComponentAnnotation = false;
+
/**
* Map of [element ids, element].
* This map is used to easily get an already created element.
@@ -73,25 +73,34 @@
/**
* Map of [element, referto].
- * This map is used to recreate the element hierarchie.
+ * This map is used to recreate the element hierarchy.
* Stored element are added under referred element.
*/
private Map m_elements = new HashMap();
+
+ /**
+ * Instance declaration.
+ */
+ private Element m_instance;
/**
* XML document parser.
*/
private DocumentBuilder m_builder;
- public Element getElem() {
+
+ public Element getComponentTypeDeclaration() {
return m_elem;
}
-
- public boolean isAnnotated() {
- return m_containsAnnotation;
+
+ public Element getInstanceDeclaration() {
+ return m_instance;
}
-
-
+
+ public boolean isComponentType() {
+ return m_containsComponentAnnotation;
+ }
+
/**
* Start visiting a class.
* Initialize the getter/setter generator, add the _cm field, add the pojo interface.
@@ -123,7 +132,7 @@
if (desc.equals("Lorg/apache/felix/ipojo/annotations/Component;")) {
// It is a component
m_elem = new Element("component", "");
- m_containsAnnotation = true;
+ m_containsComponentAnnotation = true;
m_elem.addAttribute(new Attribute("className", m_className.replace('/', '.')));
return new ComponentVisitor();
}
@@ -132,7 +141,7 @@
if (desc.equals("Lorg/apache/felix/ipojo/annotations/Handler;")) {
// It is a handler, change the root element
m_elem = new Element("handler", "");
- m_containsAnnotation = true;
+ m_containsComponentAnnotation = true;
m_elem.addAttribute(new Attribute("classname", m_className.replace('/', '.')));
return new HandlerVisitor();
}
@@ -146,6 +155,11 @@
if (desc.equals("Lorg/apache/felix/ipojo/annotations/HandlerDeclaration;")) {
return new HandlerDeclarationVisitor();
}
+
+ // @Instantiate
+ if (desc.equals("Lorg/apache/felix/ipojo/annotations/Instantiate;")) {
+ return new InstantiateVisitor();
+ }
if (CustomAnnotationVisitor.isCustomAnnotation(desc)) {
Element elem = CustomAnnotationVisitor.buildElement(desc);
@@ -156,7 +170,6 @@
}
-
/**
* Visit a field.
* Call the field collector visitor.
@@ -327,7 +340,45 @@
}
}
+
+ /**
+ * Parse the @Instantitate annotation.
+ */
+ private class InstantiateVisitor extends EmptyVisitor implements AnnotationVisitor {
+ /**
+ * Instance name.
+ */
+ private String m_name;
+
+ /**
+ * Visit an annotation attribute.
+ * @param arg0 the attribute name
+ * @param arg1 the attribute value
+ * @see org.objectweb.asm.commons.EmptyVisitor#visit(java.lang.String, java.lang.Object)
+ */
+ public void visit(String arg0, Object arg1) {
+ if (arg0.equals("name")) {
+ m_name = arg1.toString();
+ return;
+ }
+ }
+
+ /**
+ * End of the visit. Creates the instance element.
+ * @see org.objectweb.asm.commons.EmptyVisitor#visitEnd()
+ */
+ public void visitEnd() {
+ m_instance = new Element("instance", "");
+ if (m_className != null) { // Should not be null.
+ m_instance.addAttribute(new Attribute("component", m_className));
+ }
+ if (m_name != null) {
+ m_instance.addAttribute(new Attribute("name", m_name));
+ }
+ }
+ }
+
/**
* Parse the @component annotation.
*/
@@ -577,8 +628,7 @@
// Add converted element as a root's child
root.addElement(converted);
}
-
-
}
+
}
diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
index a8dd373..6084bb4 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
@@ -28,6 +28,7 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
@@ -76,7 +77,7 @@
/**
* Metadata (in internal format).
*/
- private Element[] m_metadata = new Element[0];
+ private List/*Element*/ m_metadata = new ArrayList/*Element*/();
/**
* Errors which occur during the manipulation.
@@ -291,35 +292,37 @@
ClassReader cr = new ClassReader(inC);
MetadataCollector xml = new MetadataCollector();
cr.accept(xml, 0);
- if (xml.isAnnotated()) {
+ if (xml.isComponentType()) {
boolean toskip = false;
- for (int i = 0; !toskip && i < m_metadata.length; i++) {
- if (! m_metadata[i].getName().equals("instance") // Only if its a component type definition,
+ for (int i = 0; !toskip && i < m_metadata.size(); i++) {
+ Element meta = (Element) m_metadata.get(i);
+ if (! meta.getName().equals("instance") // Only if its a component type definition,
// so skip instance declaration
- && m_metadata[i].containsAttribute("name")
- && m_metadata[i].getAttribute("name").equalsIgnoreCase(xml.getElem().getAttribute("name"))) {
+ && meta.containsAttribute("name")
+ && meta.getAttribute("name").equalsIgnoreCase(xml.getComponentTypeDeclaration().getAttribute("name"))) {
toskip = true;
- warn("The component type " + xml.getElem().getAttribute("name") + " is overriden by the metadata file");
+ warn("The component type " + xml.getComponentTypeDeclaration().getAttribute("name") + " is overriden by the metadata file");
}
}
if (!toskip) {
// if no metadata or empty one, create a new array.
- if (m_metadata != null && m_metadata.length > 0) {
- Element[] newElementsList = new Element[m_metadata.length + 1];
- System.arraycopy(m_metadata, 0, newElementsList, 0, m_metadata.length);
- newElementsList[m_metadata.length] = xml.getElem();
- m_metadata = newElementsList;
- } else {
- m_metadata = new Element[] { xml.getElem() };
- }
- String name = m_metadata[m_metadata.length - 1].getAttribute("classname");
+ Element elem = xml.getComponentTypeDeclaration();
+ m_metadata.add(elem);
+
+ String name = elem.getAttribute("classname");
name = name.replace('.', '/');
name += ".class";
// Creates the ComponentInfo and store bytecode
- ComponentInfo info = new ComponentInfo(name, m_metadata[m_metadata.length - 1]);
+ ComponentInfo info = new ComponentInfo(name, elem);
info.m_bytecode = inC;
m_components.add(info);
+
+ // Instantiate ?
+ if (xml.getInstanceDeclaration() != null) {
+ warn("Declaring an empty instance of " + elem.getAttribute("classname"));
+ m_metadata.add(xml.getInstanceDeclaration());
+ }
}
}
}
@@ -760,12 +763,13 @@
*/
private void computeDeclaredComponents() {
List componentClazzes = new ArrayList();
- for (int i = 0; i < m_metadata.length; i++) {
- String name = m_metadata[i].getAttribute("classname");
+ for (int i = 0; i < m_metadata.size(); i++) {
+ Element meta = (Element) m_metadata.get(i);
+ String name = meta.getAttribute("classname");
if (name != null) { // Only handler and component have a classname attribute
name = name.replace('.', '/');
name += ".class";
- componentClazzes.add(new ComponentInfo(name, m_metadata[i]));
+ componentClazzes.add(new ComponentInfo(name, meta));
}
}
m_components = componentClazzes;
@@ -911,8 +915,9 @@
*/
private void setPOJOMetadata(Attributes att) {
StringBuffer meta = new StringBuffer();
- for (int i = 0; i < m_metadata.length; i++) {
- meta.append(buildManifestMetadata(m_metadata[i], new StringBuffer()));
+ for (int i = 0; i < m_metadata.size(); i++) {
+ Element metadata = (Element) m_metadata.get(i);
+ meta.append(buildManifestMetadata(metadata, new StringBuffer()));
}
if (meta.length() != 0) {
att.putValue("iPOJO-Components", meta.toString());
@@ -1013,10 +1018,10 @@
private void parseXMLMetadata(File metadataFile) {
try {
InputStream stream = null;
- URL url = metadataFile.toURL();
+ URL url = metadataFile.toURI().toURL();
if (url == null) {
warn("Cannot find the metadata file : " + metadataFile.getAbsolutePath());
- m_metadata = new Element[0];
+ m_metadata = new ArrayList/*Element*/();
} else {
stream = url.openStream();
parseXMLMetadata(stream); // m_metadata is set by the method.
@@ -1074,7 +1079,7 @@
warn("Neither component types, nor instances in the metadata");
}
- m_metadata = meta;
+ m_metadata.addAll(Arrays.asList(meta));
}
/**
@@ -1083,8 +1088,8 @@
*/
private List getReferredPackages() {
List referred = new ArrayList();
- for (int i = 0; i < m_metadata.length; i++) {
- Element[] elems = m_metadata[i].getElements();
+ for (int i = 0; i < m_metadata.size(); i++) {
+ Element[] elems = ((Element) m_metadata.get(i)).getElements();
for (int j = 0; j < elems.length; j++) {
String att = elems[j].getAttribute("specification");
if (att != null) {