KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jline > ClassNameCompletor


1 /**
2  * jline - Java console input library
3  * Copyright (c) 2002-2006, Marc Prud'hommeaux <mwp1@cornell.edu>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or
7  * without modification, are permitted provided that the following
8  * conditions are met:
9  *
10  * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer
15  * in the documentation and/or other materials provided with
16  * the distribution.
17  *
18  * Neither the name of JLine nor the names of its contributors
19  * may be used to endorse or promote products derived from this
20  * software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
24  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
25  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
26  * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34  * OF THE POSSIBILITY OF SUCH DAMAGE.
35  */

36 package jline;
37
38 import java.io.*;
39 import java.net.*;
40 import java.util.*;
41 import java.util.jar.JarFile JavaDoc;
42 import java.util.jar.JarEntry JavaDoc;
43
44
45 /**
46  * A Completor implementation that completes java class names. By default,
47  * it scans the java class path to locate all the classes.
48  *
49  * @author <a HREF="mailto:mwp1@cornell.edu">Marc Prud'hommeaux</a>
50  */

51 public class ClassNameCompletor
52     extends SimpleCompletor
53 {
54     /**
55      * Complete candidates using all the classes available in the
56      * java <em>CLASSPATH</em>.
57      */

58     public ClassNameCompletor ()
59         throws IOException
60     {
61         this (null);
62     }
63
64
65     public ClassNameCompletor (final SimpleCompletorFilter filter)
66         throws IOException
67     {
68         super (getClassNames (), filter);
69         setDelimiter (".");
70     }
71
72
73     public static String JavaDoc[] getClassNames ()
74         throws IOException
75     {
76         Set urls = new HashSet ();
77         for (ClassLoader JavaDoc loader = ClassNameCompletor.class.getClassLoader ();
78             loader != null; loader = loader.getParent ())
79         {
80             if (!(loader instanceof URLClassLoader))
81                 continue;
82
83             urls.addAll (Arrays.asList (((URLClassLoader)loader).getURLs ()));
84         }
85
86         // Now add the URL that holds java.lang.String. This is because
87
// some JVMs do not report the core classes jar in the list of
88
// class loaders.
89
Class JavaDoc[] systemClasses = new Class JavaDoc[] {
90             String JavaDoc.class,
91             javax.swing.JFrame JavaDoc.class
92             };
93         for (int i = 0; i < systemClasses.length; i++)
94         {
95             URL classURL = systemClasses[i].getResource ("/"
96                 + systemClasses[i].getName ().replace ('.', '/') + ".class");
97             if (classURL != null)
98             {
99                 URLConnection uc = (URLConnection)classURL.openConnection ();
100                 if (uc instanceof JarURLConnection)
101                     urls.add (((JarURLConnection)uc).getJarFileURL ());
102             }
103         }
104
105
106         Set classes = new HashSet ();
107         for (Iterator i = urls.iterator (); i.hasNext (); )
108         {
109             URL url = (URL)i.next ();
110             File JavaDoc file = new File JavaDoc (url.getFile ());
111             if (file.isDirectory ())
112             {
113                 Set files = getClassFiles (file.getAbsolutePath (),
114                     new HashSet (), file, new int[] { 200 });
115                 classes.addAll (files);
116                 continue;
117             }
118
119             if (file == null || !file.isFile ()) // TODO: handle directories
120
continue;
121
122             JarFile JavaDoc jf = new JarFile JavaDoc (file);
123             for (Enumeration entries = jf.entries ();
124                 entries.hasMoreElements () ;)
125             {
126                 JarEntry JavaDoc entry = (JarEntry JavaDoc)entries.nextElement ();
127                 if (entry == null)
128                     continue;
129
130                 String JavaDoc name = entry.getName ();
131                 if (!name.endsWith (".class")) // only use class files
132
continue;
133
134                 classes.add (name);
135             }
136         }
137
138         // now filter classes by changing "/" to "." and trimming the
139
// trailing ".class"
140
Set classNames = new TreeSet ();
141         for (Iterator i = classes.iterator (); i.hasNext (); )
142         {
143             String JavaDoc name = (String JavaDoc)i.next ();
144             classNames.add (name.replace ('/', '.').substring (0,
145                 name.length () - 6));
146         }
147
148         return (String JavaDoc[])classNames.toArray (new String JavaDoc[classNames.size ()]);
149     }
150
151
152     private static Set getClassFiles (String JavaDoc root, Set holder, File JavaDoc directory,
153         int[] maxDirectories)
154     {
155         // we have passed the maximum number of directories to scan
156
if (maxDirectories[0]-- < 0)
157             return holder;
158
159         File JavaDoc[] files = directory.listFiles ();
160         for (int i = 0; files != null && i < files.length; i++)
161         {
162             String JavaDoc name = files[i].getAbsolutePath ();
163             if (!(name.startsWith (root)))
164                 continue;
165             else if (files[i].isDirectory ())
166                 getClassFiles (root, holder, files[i], maxDirectories);
167             else if (files[i].getName ().endsWith (".class"))
168                 holder.add (files[i].getAbsolutePath ().substring (
169                     root.length () + 1));
170         }
171
172         return holder;
173     }
174 }
175
176
Popular Tags