first scanner /parser copied from the jdt java version
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / batch / ClasspathJar.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v0.5 
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v05.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  ******************************************************************************/
11 package net.sourceforge.phpdt.internal.compiler.batch;
12
13 import java.io.File;
14 import java.io.IOException;
15 import java.util.Enumeration;
16 import java.util.Hashtable;
17 import java.util.zip.ZipEntry;
18 import java.util.zip.ZipFile;
19
20 import net.sourceforge.phpdt.internal.compiler.classfmt.ClassFileReader;
21 import net.sourceforge.phpdt.internal.compiler.env.NameEnvironmentAnswer;
22
23 public class ClasspathJar implements FileSystem.Classpath {
24         
25 ZipFile zipFile;
26 Hashtable packageCache;
27 boolean closeZipFileAtEnd;
28
29 public ClasspathJar(File file) throws IOException {
30         this(new ZipFile(file), true);
31 }
32 public ClasspathJar(ZipFile zipFile, boolean closeZipFileAtEnd) throws IOException {
33         this.zipFile = zipFile;
34         this.packageCache = null;
35         this.closeZipFileAtEnd = closeZipFileAtEnd;
36 }       
37 public NameEnvironmentAnswer findClass(char[] typeName, String qualifiedPackageName, String qualifiedBinaryFileName) {
38         if (!isPackage(qualifiedPackageName)) return null; // most common case
39
40         try {
41                 ClassFileReader reader = ClassFileReader.read(zipFile, qualifiedBinaryFileName);
42                 if (reader != null) return new NameEnvironmentAnswer(reader);
43         } catch (Exception e) {} // treat as if class file is missing
44         return null;
45 }
46 public boolean isPackage(String qualifiedPackageName) {
47         if (packageCache != null)
48                 return packageCache.containsKey(qualifiedPackageName);
49
50         this.packageCache = new Hashtable(41);
51         packageCache.put("", ""); //$NON-NLS-1$ //$NON-NLS-2$
52
53         nextEntry : for (Enumeration e = zipFile.entries(); e.hasMoreElements(); ) {
54                 String fileName = ((ZipEntry) e.nextElement()).getName();
55
56                 // add the package name & all of its parent packages
57                 int last = fileName.lastIndexOf('/');
58                 while (last > 0) {
59                         // extract the package name
60                         String packageName = fileName.substring(0, last);
61                         if (packageCache.containsKey(packageName))
62                                 continue nextEntry;
63                         packageCache.put(packageName, packageName);
64                         last = packageName.lastIndexOf('/');
65                 }
66         }
67         return packageCache.containsKey(qualifiedPackageName);
68 }
69 public void reset() {
70         if (zipFile != null && closeZipFileAtEnd) {
71                 try { zipFile.close(); } catch(IOException e) {}
72         }
73         this.packageCache = null;
74 }
75 public String toString() {
76         return "Classpath for jar file " + zipFile; //$NON-NLS-1$
77 }
78 }