Fix FELIX-4668
When a required stereotype class (or any class) is not in the bundle, tries to load it from the classpath.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1643082 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
index b9b0ce6..445caf2 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/Pojoization.java
@@ -154,6 +154,7 @@
         try {
             JarFile origin = new JarFile(in);
             JarFileResourceStore jfrs = new JarFileResourceStore(origin, out);
+            jfrs.setClassLoader(loader);
             if (in.getName().endsWith(".war")) {
                 // this is a war file, use the right mapper
                 jfrs.setResourceMapper(new WABResourceMapper());
@@ -222,6 +223,7 @@
         try {
             JarFile origin = new JarFile(in);
             JarFileResourceStore jfrs = new JarFileResourceStore(origin, out);
+            jfrs.setClassLoader(loader);
             if (in.getName().endsWith(".war")) {
                 // this is a war file, use the right mapper
                 jfrs.setResourceMapper(new WABResourceMapper());
@@ -336,7 +338,8 @@
 
     public void pojoization(final ResourceStore store,
                             final MetadataProvider metadata,
-                            final ManipulationVisitor visitor, ClassLoader loader) {
+                            final ManipulationVisitor visitor,
+                            final ClassLoader loader) {
 
         ManipulationEngine engine = new ManipulationEngine(loader);
         engine.setResourceStore(store);
diff --git a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStore.java b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStore.java
index 0f0e660..44d185a 100644
--- a/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStore.java
+++ b/ipojo/manipulator/manipulator/src/main/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStore.java
@@ -26,10 +26,8 @@
 import org.apache.felix.ipojo.manipulator.util.Streams;
 import org.apache.felix.ipojo.metadata.Element;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
+import java.net.URL;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -78,9 +76,12 @@
      */
     private Manifest m_manifest;
 
+    private ClassLoader classLoader;
+
     /**
      * Construct a {@link JarFileResourceStore} wrapping the given original bundle,
      * and configured to output in the given target file.
+     *
      * @param source original Bundle
      * @param target File where the updated Bundle will be outputted
      * @throws IOException if there is an error retrieving the Manifest from the original JarFile
@@ -111,14 +112,42 @@
         this.m_manifest = manifest;
     }
 
+    public void setClassLoader(ClassLoader classLoader) {
+        this.classLoader = classLoader;
+    }
+
     public byte[] read(String path) throws IOException {
         ZipEntry entry = m_source.getEntry(getInternalPath(path));
         if (entry == null) {
-            throw new IOException("Jar Entry is not found for class " + path + ".");
+            // Not in the Jar file, trying from classpath
+            return tryToLoadFromClassloader(path);
         }
         return Streams.readBytes(m_source.getInputStream(entry));
     }
 
+    private byte[] tryToLoadFromClassloader(String path) throws IOException {
+        if (classLoader != null) {
+            byte[] bytes = toByteArray(classLoader.getResource(path));
+            if (bytes != null) {
+                return bytes;
+            }
+        }
+        throw new IOException("Class not found " + path + ".");
+    }
+
+    public static byte[] toByteArray(URL url) throws IOException {
+        if (url == null) {
+            return null;
+        }
+        InputStream input = url.openStream();
+        try {
+            return Streams.readBytes(input);
+        } finally {
+            Streams.close(input);
+        }
+
+    }
+
     private String getInternalPath(String path) {
         return m_mapper.internalize(path);
     }