[FELIX-4810] Cache WeakZipFile#getEntries()

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1663368 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/util/WeakZipFileFactory.java b/framework/src/main/java/org/apache/felix/framework/util/WeakZipFileFactory.java
index aa2e157..8bc3ff6 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/WeakZipFileFactory.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/WeakZipFileFactory.java
@@ -21,6 +21,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.ref.SoftReference;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
@@ -172,6 +173,7 @@
         private ZipFile m_zipFile;
         private int m_status = OPEN;
         private long m_timestamp;
+        private volatile SoftReference<List<ZipEntry>> m_entries;
 
         /**
          * Constructor is private since instances need to be centrally
@@ -229,17 +231,36 @@
 
             try
             {
-                // We need to suck in all of the entries since the zip
-                // file may get weakly closed during iteration. Technically,
-                // this may not be 100% correct either since if the zip file
-                // gets weakly closed and reopened, then the zip entries
-                // will be from a different zip file. It is not clear if this
-                // will cause any issues.
-                Enumeration<? extends ZipEntry> e = m_zipFile.entries();
-                List<ZipEntry> entries = new ArrayList<ZipEntry>();
-                while (e.hasMoreElements())
+                List<ZipEntry> entries = null;
+                if (m_entries != null)
                 {
-                    entries.add(e.nextElement());
+                    entries = m_entries.get();
+                }
+                if (entries == null)
+                {
+                    synchronized (this)
+                    {
+                        if (m_entries != null)
+                        {
+                            entries = m_entries.get();
+                        }
+                        if (entries == null)
+                        {
+                            // We need to suck in all of the entries since the zip
+                            // file may get weakly closed during iteration. Technically,
+                            // this may not be 100% correct either since if the zip file
+                            // gets weakly closed and reopened, then the zip entries
+                            // will be from a different zip file. It is not clear if this
+                            // will cause any issues.
+                            Enumeration<? extends ZipEntry> e = m_zipFile.entries();
+                            entries = new ArrayList<ZipEntry>();
+                            while (e.hasMoreElements())
+                            {
+                                entries.add(e.nextElement());
+                            }
+                            m_entries = new SoftReference<List<ZipEntry>>(entries);
+                        }
+                    }
                 }
                 return Collections.enumeration(entries);
             }