Initial Commit
[packages] / xemacs-packages / jde / java / src / jde / util / ProjectClasses.java
1 /*
2  * Copyright (C) 2001, 2003, 2004 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  * Created: Tue Aug 14 19:24:02 2001
19  */
20
21 package jde.util;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.StringTokenizer;
29
30 /**
31  * A class that represents a set of classpath entries for a project.
32  * All projects include the entries found in boot.class.path and in
33  * the various extension directories.  Classpath entries are shared
34  * across projects and so are not loaded/copied more than once.
35  *
36  * @author Eric D. Friedman
37  * @version $Id: ProjectClasses.java,v 1.8 2004/11/25 05:23:20 jslopez Exp $
38  */
39
40 class ProjectClasses {
41   
42   private String classPath;
43   
44   // the boot classpath is loaded at startup.
45   private static ArrayList bootClassPathEntries = new ArrayList();
46   
47   static {
48     try {
49       loadBootClassPathEntries();
50     } catch (IOException e) {
51       e.printStackTrace(System.err);
52     } // end of try-catch
53   }
54
55   // take a shallow clone of the boot classpath as the starting
56   // point for the project classpath.
57   private List classPathEntries = (List)bootClassPathEntries.clone();
58
59   /**
60    * Creates a new <code>ProjectClasses</code> instance.
61    *
62    * @param classPath the project classpath
63    * @exception IOException if an error occurs
64    */
65   ProjectClasses(String classPath) throws IOException {
66     this.classPath = classPath;
67
68     String classPathEntry;
69     File classPathFile;
70     StringTokenizer st = new StringTokenizer(classPath,
71                                              File.pathSeparator);
72
73     while (st.hasMoreTokens()) {
74       classPathEntry = st.nextToken();
75       classPathFile = new File(classPathEntry);
76       if (classPathFile.exists()) {
77         ClassPathEntry cpe = ClassPathEntry.instanceForEntry(classPathFile);
78         if (cpe != null) {
79           classPathEntries.add(cpe);     
80         } // end of if (cpe != null)          
81       }
82     }
83   }
84
85
86
87   /**
88    * Reload classes in a single classpath entry, which may be a class,
89    * jar, or zip file.
90    *
91    * @param classPathEntry Classpath entry to be reloaded.
92    * @exception IOException if an error occurs
93    */
94   void reloadClasses(String classPathEntry) throws IOException {
95     File classPathFile = new File(classPathEntry);
96     if (classPathFile.exists()) {
97       ClassPathEntry cpe = ClassPathEntry.instanceForEntry(classPathFile);
98       if (cpe != null) {
99         cpe.reload();
100       }
101     }
102   }
103
104
105   /**
106    * Reload all classes in classpath.
107    *
108    * @exception IOException if an error occurs
109    */
110   void reloadClasses() throws IOException {
111     ClassPathEntry cpe;
112
113     for (Iterator i = classPathEntries.iterator(); i.hasNext();) {
114       cpe = (ClassPathEntry)i.next();
115       cpe.reload();
116     }
117   }
118
119     
120   /**
121    * Get the classpath represented by this project.
122    *
123    * @return a <code>String</code> value
124    */
125   public String getClassPath() {
126     return classPath;
127   }
128     
129   /**
130    * Get fully qualified classnames in this classpath that
131    * matching the specified unqualified name.
132    *
133    * @param unqualifiedName Unqualified name for which matching
134    * qualified names are to be found.
135    * @return list of qualified names.
136    * @exception IOException if an error occurs
137    */
138   List getClassNames(String unqualifiedName) throws IOException {
139     List rv = new ArrayList();
140     for (Iterator i = classPathEntries.iterator(); i.hasNext();) {
141
142       ClassPathEntry cpe = (ClassPathEntry) i.next();
143       List classNames = cpe.getClassNames(unqualifiedName);
144       for (Iterator iter = classNames.iterator(); iter.hasNext();) {
145           String className = (String) iter.next();
146           if (!rv.contains(className)) {
147               rv.add(className);
148           }
149       }
150     }
151     return rv;
152   }
153
154   public String toString() {
155     return classPathEntries.toString();
156   }
157
158   public static void main (String[] args) throws Exception {
159     System.out.println(new ProjectClasses(System.getProperty("java.class.path")).getClassNames(args[0]));
160   }
161     
162   /**
163    * loads the boot classpath entries.
164    *
165    * @exception IOException if an error occurs
166    */
167   static void loadBootClassPathEntries() throws IOException {
168     StringTokenizer st;
169     File file;
170     File[] extFiles;
171         
172     String bootClassPath = System.getProperty("sun.boot.class.path");
173     String extDirs = System.getProperty("java.ext.dirs");
174
175     st = new StringTokenizer(bootClassPath,File.pathSeparator);
176     while (st.hasMoreTokens()) {
177       file = new File(st.nextToken());
178       addToBootClassPath(file);
179     }
180         
181     if (extDirs != null) {
182       st = new StringTokenizer(extDirs,File.pathSeparator);
183                          
184       // Iterate through extension directories
185       while (st.hasMoreTokens()) {
186         extFiles = new File(st.nextToken()).listFiles();
187                                  
188         if (extFiles != null) {
189           // Iterate through files added them to classPath
190           for (int i = 0; i < extFiles.length; i++) {
191             addToBootClassPath(extFiles[i]);
192           }
193         }
194       }
195     }
196   }
197
198   static void addToBootClassPath(File file) throws IOException {
199     if (file.exists()) {
200       ClassPathEntry entry = ClassPathEntry.instanceForEntry(file);
201       if (null != entry) {
202         bootClassPathEntries.add(new ImmutableClassPathEntry(entry));
203       }
204     } // end of if (file.exists())
205   }
206   
207 }// ProjectClasses
208
209 /*
210  * $Log: ProjectClasses.java,v $
211  * Revision 1.8  2004/11/25 05:23:20  jslopez
212  * Fixes getClassNames to avoid adding duplicate entries.
213  *
214  * Revision 1.7  2004/10/20 06:14:53  paulk
215  * Update to support reloading classes from a single classpath entry. Thanks to Martin Schwamberger.
216  *
217  * Revision 1.6  2003/06/18 10:12:53  paulk
218  * Fixed null pointer exception caused by insertion of null entries
219  * into classPathEntries for files that are not class files or zip or jar files.
220  * Thanks to Boyan Slavoff for reporting this problem.
221  *
222  * Revision 1.5  2002/02/21 12:24:32  jslopez
223  * Adds method getClassPath.
224  *
225  * Revision 1.4  2001/10/17 04:03:37  paulk
226  * Cosmetic changes to fit JDE coding style.
227  *
228  *
229  */
230
231 // End of ProjectClasses.java