bug 397284: Cache the URL and the URLConnection when constructing BundleEntryAttributes.
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDirContext.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDirContext.java
index c0f7468..c7f5724 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDirContext.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleDirContext.java
@@ -18,6 +18,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -107,10 +108,11 @@
 
     private Object entryToResult(BundleEntry entry) {
         Object result;
-        if (entry.isDirectory()) {
+        URL url = entry.getURL();
+        if (BundleEntry.isDirectory(url)) {
             result = new BundleDirContext(entry);
         } else {
-            result = new URLResource(entry.getURL());
+            result = new URLResource(url);
         }
         return result;
     }
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntry.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntry.java
index 81ac5aa..cdea752 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntry.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntry.java
@@ -19,6 +19,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.net.URL;
+import java.net.URLConnection;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashSet;
@@ -220,9 +221,8 @@
         return this.path;
     }
 
-    public boolean isDirectory() {
-        URL entryFromBundle = getEntryFromBundle(this.path);
-        return entryFromBundle.getFile().endsWith(PATH_SEPARATOR);
+    public static boolean isDirectory(URL url) {
+        return url.getFile().endsWith(PATH_SEPARATOR);
     }
 
     @Override
@@ -238,13 +238,10 @@
      * 
      * @return the bundle entry size
      */
-    public long getContentLength() {
+    public long getContentLength(URLConnection urlConnection) {
         long size = this.bundleFileResolver.resolveBundleEntrySize(this.bundle, this.path);
-        if (size == -1) {
-            try {
-                size = getURL().openConnection().getContentLength();
-            } catch (IOException e) {
-            }
+        if (size == -1 && urlConnection != null) {
+            size = urlConnection.getContentLength();
         }
         return size;
     }
diff --git a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryAttributes.java b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryAttributes.java
index e430c44..4df41e7 100644
--- a/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryAttributes.java
+++ b/org.eclipse.gemini.web.tomcat/src/main/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryAttributes.java
@@ -51,11 +51,17 @@
     BundleEntryAttributes(BundleEntry bundleEntry, String[] attrIds) {
         this.bundleEntry = bundleEntry;
         this.attrIds = attrIds;
-        setCollection(this.bundleEntry.isDirectory());
         getName();
-        getLastModified();
-        getCreation();
-        getContentLength();
+        URL url = this.bundleEntry.getURL();
+        if (url != null) {
+            setCollection(BundleEntry.isDirectory(url));
+        }
+        URLConnection urlConnection = getBundleEntryURLConnection(url);
+        if (urlConnection != null) {
+            long lastModified = getLastModified(urlConnection);
+            getCreation(urlConnection, lastModified);
+            getContentLength(urlConnection);
+        }
     }
 
     /**
@@ -63,22 +69,30 @@
      */
     @Override
     public long getCreation() {
+        return getCreation(null, TIME_NOT_SET);
+    }
+
+    private long getCreation(URLConnection urlConnection, long lastModified) {
         long creation = TIME_NOT_SET;
 
         if (attrPresent(CREATION_DATE) || attrPresent(ALTERNATE_CREATION_DATE)) {
             creation = super.getCreation();
 
             if (creation == TIME_NOT_SET) {
-                try {
-                    URLConnection urlConnection = getBundleEntryURLConnection();
-                    if (urlConnection != null) {
-                        creation = determineDate(urlConnection);
+                if (urlConnection == null) {
+                    urlConnection = getBundleEntryURLConnection(this.bundleEntry.getURL());
+                }
 
-                        if (creation == CREATION_DATE_UNKNOWN) {
-                            creation = determineLastModified(urlConnection);
+                if (urlConnection != null) {
+                    creation = determineDate(urlConnection);
+
+                    if (creation == CREATION_DATE_UNKNOWN) {
+                        if (lastModified == TIME_NOT_SET) {
+                            lastModified = determineLastModified(urlConnection);
                         }
+
+                        creation = lastModified;
                     }
-                } catch (IOException e) {
                 }
 
                 if (creation != TIME_NOT_SET) {
@@ -113,18 +127,22 @@
      */
     @Override
     public long getLastModified() {
+        return getLastModified(null);
+    }
+
+    private long getLastModified(URLConnection urlConnection) {
         long lastModified = TIME_NOT_SET;
 
         if (attrPresent(LAST_MODIFIED) || attrPresent(ALTERNATE_LAST_MODIFIED)) {
             lastModified = super.getLastModified();
 
             if (lastModified == TIME_NOT_SET) {
-                try {
-                    URLConnection urlConnection = getBundleEntryURLConnection();
-                    if (urlConnection != null) {
-                        lastModified = determineLastModified(urlConnection);
-                    }
-                } catch (IOException e) {
+                if (urlConnection == null) {
+                    urlConnection = getBundleEntryURLConnection(this.bundleEntry.getURL());
+                }
+
+                if (urlConnection != null) {
+                    lastModified = determineLastModified(urlConnection);
                 }
 
                 if (lastModified != TIME_NOT_SET) {
@@ -158,13 +176,21 @@
 
     @Override
     public long getContentLength() {
+        return getContentLength(null);
+    }
+
+    private long getContentLength(URLConnection urlConnection) {
         long contentLength = CONTENT_LENGTH_NOT_SET;
 
         if (attrPresent(CONTENT_LENGTH) || attrPresent(ALTERNATE_CONTENT_LENGTH)) {
             contentLength = super.getContentLength();
 
             if (contentLength == CONTENT_LENGTH_NOT_SET) {
-                contentLength = determineContentLength();
+                if (urlConnection == null) {
+                    urlConnection = getBundleEntryURLConnection(this.bundleEntry.getURL());
+                }
+
+                contentLength = determineContentLength(urlConnection);
 
                 if (contentLength != CONTENT_LENGTH_NOT_SET) {
                     setContentLength(contentLength);
@@ -175,15 +201,18 @@
         return contentLength;
     }
 
-    private long determineContentLength() {
-        return this.bundleEntry.getContentLength();
+    private long determineContentLength(URLConnection urlConnection) {
+        return this.bundleEntry.getContentLength(urlConnection);
     }
 
-    private URLConnection getBundleEntryURLConnection() throws IOException {
-        URL url = this.bundleEntry.getURL();
-        if (url != null) {
-            return url.openConnection();
-        } else {
+    private URLConnection getBundleEntryURLConnection(URL url) {
+        try {
+            if (url != null) {
+                return url.openConnection();
+            } else {
+                return null;
+            }
+        } catch (IOException e) {
             return null;
         }
     }
diff --git a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryTests.java b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryTests.java
index 02fa0bb..89696f3 100644
--- a/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryTests.java
+++ b/org.eclipse.gemini.web.tomcat/src/test/java/org/eclipse/gemini/web/tomcat/internal/loading/BundleEntryTests.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2012 VMware Inc.
+ * Copyright (c) 2009, 2013 VMware Inc.
  *
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
@@ -155,12 +155,12 @@
         assertNotNull(entry.getEntry(""));
         assertNotNull(entry.getEntry("/"));
 
-        assertTrue(entry.getEntry("sub/").isDirectory());
-        assertTrue(entry.getEntry("sub/another.sub/").isDirectory());
-        assertTrue(entry.getEntry(".").isDirectory());
-        assertTrue(entry.getEntry("sub/.").isDirectory());
-        assertTrue(entry.getEntry("").isDirectory());
-        assertTrue(entry.getEntry("/").isDirectory());
+        assertTrue(BundleEntry.isDirectory(entry.getEntry("sub/").getURL()));
+        assertTrue(BundleEntry.isDirectory(entry.getEntry("sub/another.sub/").getURL()));
+        assertTrue(BundleEntry.isDirectory(entry.getEntry(".").getURL()));
+        assertTrue(BundleEntry.isDirectory(entry.getEntry("sub/.").getURL()));
+        assertTrue(BundleEntry.isDirectory(entry.getEntry("").getURL()));
+        assertTrue(BundleEntry.isDirectory(entry.getEntry("/").getURL()));
     }
 
     @Test