Initial Commit
[packages] / xemacs-packages / jde / java / src / jde / util / ClassPathEntry.java
1 /* 
2  * Copyright (C) 2001 Eric D. Friedman (eric@hfriedman.rdsl.lmi.net)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 package jde.util;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26
27
28 /**
29  * An abstraction of ClassPath entries, which can concretely include
30  * directories, zipfiles, and jarfiles, some of which are immutable
31  * inasmuch as they are part of the JDK and are shared across projects
32  * by virtue of being part of the boot classpath.
33  *
34  * <p>ClassPathEntries are Singleton/Flyweight implementations: they
35  * can appear in multiple projects, but there is only ever one
36  * instance.</p>
37  *
38  * Created: Tue Aug 14 19:28:04 2001
39  *
40  * @author Eric D. Friedman
41  * @version $Id: ClassPathEntry.java,v 1.4 2002/09/06 12:57:55 jslopez Exp $
42  */
43
44 abstract class ClassPathEntry {
45     /** a map of unqualified class names to qualified names */
46     protected MultiValueMap nameToClassMap = new MultiValueMap();
47     /** a flag indicating whether this instance has been loaded or not */
48     protected boolean loaded = false;
49     private static Map entryMap = new HashMap();
50     
51     ClassPathEntry () {
52     }
53
54     /**
55      * Returns the singleton/flyweight instance for
56      * <code>resource</code>.  The specific instance type returned is
57      * based on the extension of the file or on it being a directory.
58      *
59      * @param resource a <code>File</code> value
60      * @return a <code>ClassPathEntry</code> value
61      * @exception IOException if an error occurs
62      * @exception IllegalArgumentException if resource is not a
63      * zip/jar or a directory.
64      */
65     static ClassPathEntry instanceForEntry(File resource)
66         throws IOException {
67         ClassPathEntry entry = null;
68         
69         if (entryMap.containsKey(resource)) {
70             entry = (ClassPathEntry)entryMap.get(resource);
71         } else {
72             if (resource.getName().toLowerCase().endsWith(".jar")) {
73                 entry = new ClassPathZip(resource);
74             } else if (resource.getName().toLowerCase().endsWith(".zip")) {
75                 entry = new ClassPathZip(resource);
76             } else if (resource.isDirectory()) {
77                 entry = new ClassPathDir(resource);
78             } else {
79                 entry = null;   // shouldn't be in classpath
80             } // end of else
81
82             if (null != entry) {
83                 entryMap.put(resource,entry);
84             }
85         }
86         return entry;
87     }
88
89     /**
90      * defines class loading behavior.
91      *
92      * @exception IOException if an error occurs
93      */
94     abstract void load() throws IOException;
95
96     /**
97      * clears the class list in the entry.
98      *
99      */
100     void clear() {
101         nameToClassMap.clear();
102         setLoaded(false);
103     }
104
105     /**
106      * clears and reloads the class list in the entry.
107      *
108      * @exception IOException if an error occurs
109      */
110     void reload() throws IOException {
111         clear();
112         load();
113     }
114
115     /**
116      * adds an unqualified => qualified mapping.
117      *
118      * @param qualifiedName a <code>String</code> value
119      */
120     protected void addClass(String qualifiedName) {
121         String unqualified;
122
123         int lastDot = qualifiedName.lastIndexOf('.');
124         int innerClass = qualifiedName.indexOf('$');
125         if (innerClass < 0) {
126             unqualified = qualifiedName.substring(lastDot + 1);
127         } else {
128             unqualified = qualifiedName.substring(innerClass + 1);
129         }
130         nameToClassMap.put(unqualified, qualifiedName);
131     }
132     
133     /**
134      * Returns the list of qualified names that map to the specified
135      * unqualified name.  Lazily loads the classes.
136      *
137      * @param unqualifiedName a <code>String</code> value
138      * @return a <code>List</code> value
139      * @exception IOException if an error occurs
140      */
141     List getClassNames(String unqualifiedName)
142         throws IOException {
143         if (! isLoaded()) {
144             load();
145         } // end of if (! isLoaded())
146         
147         return nameToClassMap.getAsList(unqualifiedName);
148     }
149
150     
151     /**
152      * Get the value of loaded.
153      * @return value of loaded.
154      */
155     public boolean isLoaded() {
156         return loaded;
157     }
158
159     /**
160      * Set the value of loaded.
161      *
162      * @param loaded a <code>boolean</code> value
163      */
164     public void setLoaded(boolean loaded) {
165         this.loaded = loaded;
166     }
167 }// ClassPathEntry
168
169 /*
170  * $Log: ClassPathEntry.java,v $
171  * Revision 1.4  2002/09/06 12:57:55  jslopez
172  * Fixes addClass method to handle inner classes in a friendlier manner.
173  * The key for an inner class such as jde.util.A$B was A$B.
174  * Now the key for such a class is only B.
175  *
176  * Revision 1.3  2001/10/17 04:09:33  paulk
177  * Cosmetic changes to fit JDE coding style.
178  *
179  *
180  */
181
182 // End of ClassPathEntry.java