Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 379112 | Differences between
and this patch

Collapse All | Expand All

(-)a/org.eclipse.gemini.web.core/src/main/java/org/eclipse/gemini/web/internal/url/WebBundleScanner.java (-14 / +82 lines)
Lines 19-33 package org.eclipse.gemini.web.internal.url; Link Here
19
import java.io.File;
19
import java.io.File;
20
import java.io.FileInputStream;
20
import java.io.FileInputStream;
21
import java.io.IOException;
21
import java.io.IOException;
22
import java.io.InputStream;
22
import java.net.URI;
23
import java.net.URI;
23
import java.net.URISyntaxException;
24
import java.net.URISyntaxException;
24
import java.net.URL;
25
import java.net.URL;
26
import java.net.URLDecoder;
27
import java.util.Collection;
28
import java.util.Enumeration;
25
import java.util.HashSet;
29
import java.util.HashSet;
26
import java.util.Set;
30
import java.util.Set;
27
import java.util.jar.Attributes;
31
import java.util.jar.Attributes;
28
import java.util.jar.JarEntry;
32
import java.util.jar.JarEntry;
33
import java.util.jar.JarFile;
29
import java.util.jar.JarInputStream;
34
import java.util.jar.JarInputStream;
30
import java.util.jar.Manifest;
35
import java.util.jar.Manifest;
36
import java.util.zip.ZipEntry;
31
37
32
import org.slf4j.Logger;
38
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
39
import org.slf4j.LoggerFactory;
Lines 59-64 final class WebBundleScanner { Link Here
59
    private final Object monitor = new Object();
65
    private final Object monitor = new Object();
60
66
61
    private final URL source;
67
    private final URL source;
68
    private final String localSourcePath;
69
    private final Collection<ZipEntry> sourceZipEntries = new HashSet<ZipEntry>();
62
70
63
    private final WebBundleScannerCallback callBack;
71
    private final WebBundleScannerCallback callBack;
64
72
Lines 81-86 final class WebBundleScanner { Link Here
81
        this.source = source;
89
        this.source = source;
82
        this.callBack = callBack;
90
        this.callBack = callBack;
83
        this.findClassesInNestedJars = findClassesInNestedJars;
91
        this.findClassesInNestedJars = findClassesInNestedJars;
92
        this.localSourcePath = getLocalSourcePath(source);
84
    }
93
    }
85
94
86
    /**
95
    /**
Lines 92-97 final class WebBundleScanner { Link Here
92
    void scanWar() throws IOException {
101
    void scanWar() throws IOException {
93
        synchronized (this.monitor) {
102
        synchronized (this.monitor) {
94
            this.scannedJars.clear();
103
            this.scannedJars.clear();
104
            this.sourceZipEntries.clear();
95
            if (isDirectory()) {
105
            if (isDirectory()) {
96
                scanWarDirectory();
106
                scanWarDirectory();
97
            } else {
107
            } else {
Lines 208-221 final class WebBundleScanner { Link Here
208
                }
218
                }
209
            }
219
            }
210
        }
220
        }
211
221
        
212
        JarEntry entry;
222
        if (this.findClassesInNestedJars) {
213
        while ((entry = jis.getNextJarEntry()) != null) {
223
	        JarEntry entry;
214
            String entryName = entry.getName();
224
	        while ((entry = jis.getNextJarEntry()) != null) {
215
            if (entryName.endsWith(CLASS_SUFFIX)) {
225
	            String entryName = entry.getName();
216
                notifyClassFound(entryName);
226
	            if (entryName.endsWith(CLASS_SUFFIX)) {
217
            }
227
	                notifyClassFound(entryName);
218
        }
228
	            }
229
	        }
230
    	}
219
    }
231
    }
220
232
221
    private static Path getNormalisedDirectoryPath(String jarEntryName) {
233
    private static Path getNormalisedDirectoryPath(String jarEntryName) {
Lines 246-253 final class WebBundleScanner { Link Here
246
            throw new IllegalStateException("Unexpected URISyntaxException.", e);
258
            throw new IllegalStateException("Unexpected URISyntaxException.", e);
247
        }
259
        }
248
    }
260
    }
261
    
262
    private void scanNestedJarInWarFile(final String jarPath) throws IOException {
263
    	if (this.localSourcePath == null) {
264
    		scanNestedJarInWarFileWithStream(jarPath);			
265
			return;
266
		}
267
    	
268
    	scanNestedJarInWarFileWithZipFile(jarPath, this.localSourcePath);
269
    }
270
    
271
    private String getLocalSourcePath(final URL url) { 
272
    	if (!FILE_SCHEME.equals(url.getProtocol())) {
273
    		return null;
274
    	}    	
275
    	return URLDecoder.decode(url.getPath());
276
    }
249
277
250
    private void scanNestedJarInWarFile(String jarPath) throws IOException {
278
    private void scanNestedJarInWarFileWithStream(String jarPath) throws IOException {
251
        JarInputStream jis = new JarInputStream(this.source.openStream());
279
        JarInputStream jis = new JarInputStream(this.source.openStream());
252
        try {
280
        try {
253
            JarEntry entry;
281
            JarEntry entry;
Lines 263-275 final class WebBundleScanner { Link Here
263
        } finally {
291
        } finally {
264
            IOUtils.closeQuietly(jis);
292
            IOUtils.closeQuietly(jis);
265
        }
293
        }
266
294
    }
295
    
296
    private void scanNestedJarInWarFileWithZipFile(String jarPath, String localSourcePath) throws IOException {        
297
        JarFile jarFile = null;        
298
        try {
299
        	InputStream foundInputStream = null;
300
	        String foundZipEntryName = null;        	
301
	    	if (sourceZipEntries.isEmpty()) {//then search and cache all entries
302
	    		jarFile = new JarFile(localSourcePath);
303
	    		Enumeration<JarEntry> jarFileEntries = jarFile.entries(); 
304
	    		while (jarFileEntries.hasMoreElements()) {
305
	    			final ZipEntry zipEntry = jarFileEntries.nextElement();
306
	    			// 1. cache
307
	    			sourceZipEntries.add(zipEntry);
308
	    			// 2. search if it is not found still
309
	    			if ((foundZipEntryName == null) && jarPath.endsWith(zipEntry.getName())) {
310
	    				foundZipEntryName = zipEntry.getName();
311
	    				foundInputStream = jarFile.getInputStream(zipEntry);
312
	    			}    			
313
	    		}
314
	    	} else {//search entry in cache
315
	    		for (ZipEntry zipEntry: sourceZipEntries) {
316
	    			if (jarPath.endsWith(zipEntry.getName())) {    				
317
	    				jarFile = new JarFile(localSourcePath);
318
	    				foundZipEntryName = zipEntry.getName();
319
	    				foundInputStream = jarFile.getInputStream(zipEntry);    				
320
	    				break;
321
	    			}
322
	    			
323
	    		}
324
	    	}
325
	    	
326
	    	if ((foundZipEntryName != null) && driveCallBackIfNewJarFound(foundZipEntryName)) {
327
	            JarInputStream nestedJis = new JarInputStream(foundInputStream);
328
	            doScanNestedJar(foundZipEntryName, nestedJis);
329
	        }
330
        } finally {//quiet close
331
        	if (jarFile != null) {
332
	        	try {		    		
333
	        		jarFile.close();		    		
334
	        	} catch (IOException _) {}
335
        	}
336
    	}    
267
    }
337
    }
268
338
269
    private void notifyClassFound(String entryName) {
339
	private void notifyClassFound(String entryName) {
270
        if (this.findClassesInNestedJars) {
340
        this.callBack.classFound(entryName);        
271
            this.callBack.classFound(entryName);
272
        }
273
    }
341
    }
274
342
275
    private boolean isDirectory() {
343
    private boolean isDirectory() {
(-)a/org.eclipse.gemini.web.core/src/test/java/org/eclipse/gemini/web/internal/url/WebBundleScannerTests.java (-24 / +35 lines)
Lines 21-26 import static org.easymock.EasyMock.verify; Link Here
21
21
22
import java.io.File;
22
import java.io.File;
23
import java.io.IOException;
23
import java.io.IOException;
24
import java.net.URL;
24
25
25
import org.easymock.EasyMock;
26
import org.easymock.EasyMock;
26
import org.junit.Test;
27
import org.junit.Test;
Lines 33-51 import org.eclipse.virgo.util.io.PathReference; Link Here
33
public class WebBundleScannerTests {
34
public class WebBundleScannerTests {
34
35
35
	private static final File WAR_FILE = new File("target/resources/simple-war.war");
36
	private static final File WAR_FILE = new File("target/resources/simple-war.war");
37
	private static final File WAR_CLASSPATHDEPS = new File("../org.eclipse.gemini.web.test/src/test/resources/classpathdeps.war");
38
	
39
	@Test
40
    public void testScanClasspathDeps() throws IOException {
41
        final WebBundleScannerCallback callback = EasyMock.createMock(WebBundleScannerCallback.class);
42
        
43
        setExpectationsClasspathDeps(callback);
44
        
45
        scan(WAR_CLASSPATHDEPS.toURI().toURL(), callback);
46
    }
36
47
37
    @Test
48
    @Test
38
    public void testScanLib() throws IOException {
49
    public void testScanLib() throws IOException {
39
        WebBundleScannerCallback callback = EasyMock.createMock(WebBundleScannerCallback.class);
50
        WebBundleScannerCallback callback = EasyMock.createMock(WebBundleScannerCallback.class);
40
        
51
        
41
        setExpectations(callback);
52
        setExpectations(callback);
42
                
43
        replay(callback);
44
        
45
        WebBundleScanner scanner = new WebBundleScanner(WAR_FILE.toURI().toURL(), callback);
46
        scanner.scanWar();
47
        
53
        
48
        verify(callback);        
54
        scan(WAR_FILE.toURI().toURL(), callback);
55
    }
56
    
57
    private void setExpectationsClasspathDeps(WebBundleScannerCallback callback) {
58
        callback.jarFound("WEB-INF/lib/jar1.jar");
59
        callback.jarFound("j2/jar2.jar");        
60
        callback.jarFound("j3/jar3.jar");
61
        callback.jarFound("j4/jar4.jar");
49
    }
62
    }
50
    
63
    
51
    private void setExpectations(WebBundleScannerCallback callback) {
64
    private void setExpectations(WebBundleScannerCallback callback) {
Lines 89-100 public class WebBundleScannerTests { Link Here
89
        
102
        
90
        setExpectationsIncludingNestedJars(callback);
103
        setExpectationsIncludingNestedJars(callback);
91
        
104
        
92
        replay(callback);
105
        scan(WAR_FILE.toURL(), callback, true);
93
        
94
        WebBundleScanner scanner = new WebBundleScanner(WAR_FILE.toURL(), callback, true);
95
        scanner.scanWar();
96
        
97
        verify(callback);        
98
    }
106
    }
99
    
107
    
100
    @Test
108
    @Test
Lines 105-116 public class WebBundleScannerTests { Link Here
105
            
113
            
106
            setExpectations(callback);
114
            setExpectations(callback);
107
            
115
            
108
            replay(callback);
116
            scan(pr.toURI().toURL(), callback);
109
            
110
            WebBundleScanner scanner = new WebBundleScanner(pr.toURI().toURL(), callback);            
111
            scanner.scanWar();
112
            
113
            verify(callback);
114
        } finally {
117
        } finally {
115
            pr.delete(true);
118
            pr.delete(true);
116
        }
119
        }
Lines 124-140 public class WebBundleScannerTests { Link Here
124
            
127
            
125
            setExpectationsIncludingNestedJars(callback);
128
            setExpectationsIncludingNestedJars(callback);
126
            
129
            
127
            replay(callback);
130
            scan(pr.toURI().toURL(), callback, true);
128
            
129
            WebBundleScanner scanner = new WebBundleScanner(pr.toURI().toURL(), callback, true);            
130
            scanner.scanWar();
131
            
132
            verify(callback);
133
        } finally {
131
        } finally {
134
            pr.delete(true);
132
            pr.delete(true);
135
        }
133
        }
136
    }
134
    }
137
    
135
    
136
    private void scan(final URL url, final WebBundleScannerCallback callback) throws IOException {
137
    	this.scan(url, callback, false);
138
    }
139
140
	private void scan(final URL url, final WebBundleScannerCallback callback, final boolean findClassesInNestedJars) throws IOException {
141
		replay(callback);
142
		
143
		final WebBundleScanner scanner = new WebBundleScanner(url, callback, findClassesInNestedJars);            
144
		scanner.scanWar();
145
		
146
		verify(callback);
147
	}
148
    
138
    private PathReference unpackToDir() throws IOException {
149
    private PathReference unpackToDir() throws IOException {
139
        String tmpDir = System.getProperty("java.io.tmpdir");
150
        String tmpDir = System.getProperty("java.io.tmpdir");
140
        PathReference dest = new PathReference(new File(tmpDir, "unpack-" + System.currentTimeMillis()));
151
        PathReference dest = new PathReference(new File(tmpDir, "unpack-" + System.currentTimeMillis()));

Return to bug 379112