Fix issue Felix-795. 
Improve metadata and manipulator performances by avoiding useless object construction, code and invocations

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@708489 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/ant/src/main/java/org/apache/felix/ipojo/task/IPojoTask.java b/ipojo/ant/src/main/java/org/apache/felix/ipojo/task/IPojoTask.java
index d88bfde..57335c8 100644
--- a/ipojo/ant/src/main/java/org/apache/felix/ipojo/task/IPojoTask.java
+++ b/ipojo/ant/src/main/java/org/apache/felix/ipojo/task/IPojoTask.java
@@ -22,6 +22,7 @@
 
 import org.apache.felix.ipojo.manipulator.Pojoization;
 import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
 import org.apache.tools.ant.Task;
 
 /**
@@ -130,14 +131,19 @@
         }
         pojo.pojoization(m_input, m_output, m_metadata);
         for (int i = 0; i < pojo.getWarnings().size(); i++) {
-            log((String) pojo.getWarnings().get(i));
+            log((String) pojo.getWarnings().get(i), Project.MSG_WARN);
         }
         if (pojo.getErrors().size() > 0) { throw new BuildException((String) pojo.getErrors().get(0)); }
         
         String out;
         if (m_output.getName().equals("_out.jar")) {
-            m_input.delete();
-            m_output.renameTo(m_input);
+            if (m_input.delete()) {
+                if (! m_output.renameTo(m_input)) {
+                    log("Cannot rename the output jar to " + m_input.getAbsolutePath(), Project.MSG_WARN);
+                }   
+            } else {
+                log("Cannot delete the input file : " + m_input.getAbsolutePath(), Project.MSG_WARN);
+            }
             out = m_input.getAbsolutePath();
         } else {
             out = m_output.getAbsolutePath();
diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
index 71b3837..eababe1 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ClassChecker.java
@@ -578,7 +578,7 @@
      * recreate this attribute on another annotation.

      * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

      */

-    public final class SimpleAttribute {

+    public static final class SimpleAttribute {

         /**

          * The name of the attribute.

          */

@@ -615,7 +615,7 @@
      * recreate this attribute on another annotation.

      * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>

      */

-    public final class EnumAttribute {

+    public static final class EnumAttribute {

         /**

          * The name of the attribute.

          */

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java
index 7d81c2b..9e110c4 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/ManipulationProperty.java
@@ -59,7 +59,7 @@
     /**

      * Helper array for byte code manipulation of primitive type.

      */

-    protected static final String[][] PRIMITIVE_BOXING_INFORMATION = new String[][] { 

+    static final String[][] PRIMITIVE_BOXING_INFORMATION = new String[][] { 

         {"V", "ILLEGAL", "ILLEGAL"}, 

         {"Z", "java/lang/Boolean", "booleanValue"},

         {"C", "java/lang/Character", "charValue"}, 

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java
index 45bdec5..44a2761 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodCreator.java
@@ -466,21 +466,21 @@
      * @return  method ID

      */

     private String generateMethodId(String name, String desc) {

-        String id = name;

+        StringBuffer id = new StringBuffer(name);

         Type[] args = Type.getArgumentTypes(desc);

         for (int i = 0; i < args.length; i++) {

             String arg = args[i].getClassName();

             if (arg.endsWith("[]")) {

                 arg = arg.substring(0, arg.length() - 2);

-                id += "$" + arg.replace('.', '_') + "__";

+                id.append("$" + arg.replace('.', '_') + "__");

             } else {

-                id += "$" + arg.replace('.', '_');

+                id.append("$" + arg.replace('.', '_'));

             }

         }

-        if (!m_methods.contains(id)) {

-            m_methods.add(id);

+        if (!m_methods.contains(id.toString())) {

+            m_methods.add(id.toString());

         }

-        return id;

+        return id.toString();

     }

 

     /**

@@ -521,11 +521,6 @@
             itfs = interfaces;

         }

 

-        String str = "";

-        for (int i = 0; i < itfs.length; i++) {

-            str += itfs[i] + " ";

-        }

-

         cv.visit(version, access, name, signature, superName, itfs);

     }

 

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
index 6e975f9..2de5744 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/MethodDescriptor.java
@@ -111,13 +111,13 @@
 

         // Add arguments

         if (m_arguments.length > 0) {

-            String args = "{";

-            args += m_arguments[0];

+            StringBuffer args = new StringBuffer("{");

+            args.append(m_arguments[0]);

             for (int i = 1; i < m_arguments.length; i++) {

-                args += "," + m_arguments[i];

+                args.append("," + m_arguments[i]);

             }

-            args += "}";

-            method.addAttribute(new Attribute("arguments", args));

+            args.append("}");

+            method.addAttribute(new Attribute("arguments", args.toString()));

         }

 

         return method;

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/FieldCollector.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/FieldCollector.java
index ba0b6a9..afbd4ec 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/FieldCollector.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/FieldCollector.java
@@ -122,11 +122,6 @@
         private String m_optional;

         

         /**

-         * Is the dependency aggregate ?

-         */

-        private String m_aggregate;

-        

-        /**

          * Dependency specification.

          */

         private String m_specification;

@@ -237,9 +232,6 @@
             if (m_specification != null) {

                 req.addAttribute(new Attribute("interface", m_specification));

             }

-            if (m_aggregate != null) {

-                req.addAttribute(new Attribute("aggregate", m_aggregate));

-            }

             if (m_filter != null) {

                 req.addAttribute(new Attribute("filter", m_filter));

             }

@@ -278,9 +270,9 @@
     }

     

     /**

-     * Parse a @property annotation.

+     * Parses a Property annotation.

      */

-    private final class PropertyAnnotationParser extends EmptyVisitor implements AnnotationVisitor {

+    private static final class PropertyAnnotationParser extends EmptyVisitor implements AnnotationVisitor {

         

         /**

          * Parent element element.

diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java
index c489012..cb059fc 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulation/annotations/MethodCollector.java
@@ -385,7 +385,7 @@
         }
     }
 
-    private final class PropertyAnnotationParser extends EmptyVisitor implements AnnotationVisitor {
+    private static final class PropertyAnnotationParser extends EmptyVisitor implements AnnotationVisitor {
 
         /**
          * Parent element.
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 ee180b4..5b08d54 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
@@ -121,12 +121,12 @@
     }
 
     /**
-     * Manipulate a normal bundle.
-     * It will create an iPOJO bundle based on the given metadata file.
-     * The original and final bundle must be different.
-     * @param in : original bundle.
-     * @param out : final bundle.
-     * @param metadataFile : iPOJO metadata file (XML). 
+     * Manipulates an input bundle.
+     * This method creates an iPOJO bundle based on the given metadata file.
+     * The original and final bundles must be different.
+     * @param in the original bundle.
+     * @param out the final bundle.
+     * @param metadataFile the iPOJO metadata file (XML). 
      */
     public void pojoization(File in, File out, File metadataFile) {
         // Get the metadata.xml location if not null
@@ -136,9 +136,12 @@
                 path = "/" + path;
             }
             m_metadata = parseXMLMetadata(path);
-            if (m_metadata == null) {
+            if (m_metadata == null) { // An error occurs during the parsing.
                 return;
             }
+            // m_metadata can be either an empty array or an Element
+            // array with component type description. It also can be null
+            // if no metadata file is given.
         }
         
         JarFile inputJar;
@@ -182,7 +185,8 @@
                 }
             }
             if (!toskip) {
-                if (m_metadata != null || m_metadata.length != 0) {
+                // 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();
@@ -365,7 +369,9 @@
         try {
             mf = initial.getManifest(); // Get the initial manifest
         } catch (IOException e) {
-            e.printStackTrace();
+            // Could not happen, the input bundle is a bundle so must have a manifest.
+            error("Cannot get the manifest from the input bundle : " + e.getMessage());
+            return null;
         }
         Attributes att = mf.getMainAttributes();
         setImports(att); // Set the imports (add ipojo and handler namespaces
@@ -543,12 +549,12 @@
      * @param att : the manifest attribute list to modify.
      */
     private void setPOJOMetadata(Attributes att) {
-        String meta = "";
+        StringBuffer meta = new StringBuffer();
         for (int i = 0; i < m_metadata.length; i++) {
-            meta += buildManifestMetadata(m_metadata[i], "");
+            meta.append(buildManifestMetadata(m_metadata[i], new StringBuffer()));
         }
-        if (!meta.equals("")) { 
-            att.putValue("iPOJO-Components", meta);
+        if (meta.length() != 0) { 
+            att.putValue("iPOJO-Components", meta.toString());
         }
     }
 
@@ -604,21 +610,24 @@
     public String printClauses(Map exports, String allowedDirectives) {
         StringBuffer sb = new StringBuffer();
         String del = "";
-        for (Iterator i = exports.keySet().iterator(); i.hasNext();) {
-            String name = (String) i.next();
-            Map map = (Map) exports.get(name);
+        
+        for (Iterator i = exports.entrySet().iterator(); i.hasNext();) {
+            Map.Entry entry = (Map.Entry) i.next();
+            String name = (String) entry.getKey();
+            Map map = (Map) entry.getValue();
             sb.append(del);
             sb.append(name);
 
-            for (Iterator j = map.keySet().iterator(); j.hasNext();) {
-                String key = (String) j.next();
+            for (Iterator j = map.entrySet().iterator(); j.hasNext();) {
+                Map.Entry entry2 = (Map.Entry) j.next();
+                String key = (String) entry2.getKey();
 
                 // Skip directives we do not recognize
                 if (key.endsWith(":") && allowedDirectives.indexOf(key) < 0) {
                     continue;
                 }
 
-                String value = (String) map.get(key);
+                String value = (String) entry2.getValue();
                 sb.append(";");
                 sb.append(key);
                 sb.append("=");
@@ -730,21 +739,21 @@
      * @param actual : actual manipulation metadata.
      * @return : given manipulation metadata + manipulation metadata of the given element.
      */
-    private String buildManifestMetadata(Element element, String actual) {
-        String result = "";
+    private StringBuffer buildManifestMetadata(Element element, StringBuffer actual) {
+        StringBuffer result = new StringBuffer();
         if (element.getNameSpace() == null) {
-            result = actual + element.getName() + " { ";
+            result.append(actual + element.getName() + " { ");
         } else {
-            result = actual + element.getNameSpace() + ":" + element.getName() + " { ";
+            result.append(actual + element.getNameSpace() + ":" + element.getName() + " { ");
         }
 
         Attribute[] atts = element.getAttributes();
         for (int i = 0; i < atts.length; i++) {
             Attribute current = (Attribute) atts[i];
             if (current.getNameSpace() == null) {
-                result = result + "$" + current.getName() + "=\"" + current.getValue() + "\" ";
+                result.append("$" + current.getName() + "=\"" + current.getValue() + "\" ");
             } else {
-                result = result + "$" + current.getNameSpace() + ":" + current.getName() + "=\"" + current.getValue() + "\" ";
+                result.append("$" + current.getNameSpace() + ":" + current.getName() + "=\"" + current.getValue() + "\" ");
             }
         }
 
@@ -753,7 +762,8 @@
             result = buildManifestMetadata(elems[i], result);
         }
 
-        return result + "}";
+        result.append("}");
+        return result;
     }
 
     public List getWarnings() {
diff --git a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/QuotedTokenizer.java b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/QuotedTokenizer.java
index 31cd68d..862604c 100644
--- a/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/QuotedTokenizer.java
+++ b/ipojo/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/QuotedTokenizer.java
@@ -45,12 +45,7 @@
      * Does the tokenizer returns token.

      */

     boolean m_returnTokens;

-

-    /**

-     * Does the tokenizer should ignore white space.

-     */

-    boolean m_ignoreWhiteSpace = true;

-

+    

     /**

      * Peek.

      */

diff --git a/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java b/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
index 8a357f3..2b310f2 100644
--- a/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
+++ b/ipojo/metadata/src/main/java/org/apache/felix/ipojo/metadata/Element.java
@@ -295,46 +295,48 @@
      * @return the XML snippet representing this element.
      */
     private String toXMLString(int indent) {
-        String xml = "";
+        StringBuffer xml = new StringBuffer();
 
-        String tabs = "";
+        StringBuffer tabs = new StringBuffer();
         for (int j = 0; j < indent; j++) {
-            tabs += "\t";
+            tabs.append("\t");
         }
 
+        xml.append(tabs);
         if (m_nameSpace == null) {
-            xml = tabs + "<" + m_name;
+            xml.append("<" + m_name);
         } else {
-            xml = tabs + "<" + m_nameSpace + ":" + m_name;
+            xml.append("<" + m_nameSpace + ":" + m_name);
         }
-
+        
         Set keys = m_attributes.keySet();
         Iterator it = keys.iterator();
         while (it.hasNext()) {
             Attribute current = (Attribute) m_attributes.get(it.next());
             if (current.getNameSpace() == null) {
-                xml += " " + current.getName() + "=\"" + current.getValue() + "\"";
+                xml.append(" " + current.getName() + "=\"" + current.getValue() + "\"");
             } else {
-                xml += " " + current.getNameSpace() + ":" + current.getName() + "=\"" + current.getValue() + "\"";
+                xml.append(" " + current.getNameSpace() + ":" + current.getName() + "=\"" + current.getValue() + "\"");
             }
         }
 
+
         if (m_elements.size() == 0) {
-            xml += "/>";
-            return xml;
+            xml.append("/>");
+            return xml.toString();
         } else {
-            xml += ">";
+            xml.append(">");
             keys = m_elements.keySet();
             it = keys.iterator();
             while (it.hasNext()) {
                 Element[] e = (Element[]) m_elements.get(it.next());
                 for (int i = 0; i < e.length; i++) {
-                    xml += "\n";
-                    xml += e[i].toXMLString(indent + 1);
+                    xml.append("\n");
+                    xml.append(e[i].toXMLString(indent + 1));
                 }
             }
-            xml += "\n" + tabs + "</" + m_name + ">";
-            return xml;
+            xml.append("\n" + tabs + "</" + m_name + ">");
+            return xml.toString();
         }
     }
 
@@ -353,17 +355,18 @@
      * @return the String form of this element.
      */
     private String toString(int indent) {
-        String xml = "";
+        StringBuffer xml = new StringBuffer();
 
-        String tabs = "";
+        StringBuffer tabs = new StringBuffer();
         for (int j = 0; j < indent; j++) {
-            tabs += "\t";
+            tabs.append("\t");
         }
 
+        xml.append(tabs);
         if (m_nameSpace == null) {
-            xml = tabs + m_name;
+            xml.append(m_name);
         } else {
-            xml = tabs + m_nameSpace + ":" + m_name;
+            xml.append(m_nameSpace + ":" + m_name);
         }
 
         Set keys = m_attributes.keySet();
@@ -371,25 +374,25 @@
         while (it.hasNext()) {
             Attribute current = (Attribute) m_attributes.get(it.next());
             if (current.getNameSpace() == null) {
-                xml += " " + current.getName() + "=\"" + current.getValue() + "\"";
+                xml.append(" " + current.getName() + "=\"" + current.getValue() + "\"");
             } else {
-                xml += " " + current.getNameSpace() + ":" + current.getName() + "=\"" + current.getValue() + "\"";
+                xml.append(" " + current.getNameSpace() + ":" + current.getName() + "=\"" + current.getValue() + "\"");
             }
         }
 
         if (m_elements.size() == 0) {
-            return xml;
+            return xml.toString();
         } else {
             keys = m_elements.keySet();
             it = keys.iterator();
             while (it.hasNext()) {
                 Element[] e = (Element[]) m_elements.get(it.next());
                 for (int i = 0; i < e.length; i++) {
-                    xml += "\n";
-                    xml += e[i].toString(indent + 1);
+                    xml.append("\n");
+                    xml.append(e[i].toString(indent + 1));
                 }
             }
-            return xml;
+            return xml.toString();
         }
     }
 
diff --git a/ipojo/plugin/src/main/java/org/apache/felix/ipojo/plugin/ManipulatorMojo.java b/ipojo/plugin/src/main/java/org/apache/felix/ipojo/plugin/ManipulatorMojo.java
index ccb2998..62f5633 100644
--- a/ipojo/plugin/src/main/java/org/apache/felix/ipojo/plugin/ManipulatorMojo.java
+++ b/ipojo/plugin/src/main/java/org/apache/felix/ipojo/plugin/ManipulatorMojo.java
@@ -168,8 +168,13 @@
             m_helper.attachArtifact(m_project, "jar", m_classifier, out);
         } else {
             // Usual behavior
-            in.delete();
-            out.renameTo(in);
+            if (in.delete()) {
+                if (! out.renameTo(in)) {
+                    getLog().warn("Cannot rename the manipulated jar file");
+                }
+            } else {
+                getLog().warn("Cannot delete the input jar file");
+            }
         }
         getLog().info("Bundle manipulation - SUCCESS");
     }