Initial Commit
[packages] / xemacs-packages / jde / java / src / jde / util / JdeUtilities.java
1 /*
2  *    JdeUtilities.java
3  *    $Revision: 1.13.2.1 $
4  *
5  *    Copyright (C) 1999-2004, 2006 Len Trigg (trigg@cs.waikato.ac.nz)
6  *    Copyright (C) 1999-2002 Paul Kinnucan (paulk@mathworks.com)
7  *
8  *    This program is free software; you can redistribute it and/or modify
9  *    it under the terms of the GNU General Public License as published by
10  *    the Free Software Foundation; either version 2 of the License, or
11  *    (at your option) any later version.
12  *
13  *    This program is distributed in the hope that it will be useful,
14  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *    GNU General Public License for more details.
17  *
18  *    You should have received a copy of the GNU General Public License
19  *    along with this program; if not, write to the Free Software
20  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 package jde.util;
24
25 import java.io.*;
26 import java.util.*;
27
28 /**
29  * This class provides various utility methods.
30  *
31  * @author Len Trigg (trigg@cs.waikato.ac.nz) 
32  * @author Paul Kinnucan (paulk@mathworks.com)
33  * @author Matt Conway (Matt_Conway@i2.com )
34  * @author Eric D. Friedman (eric@hfriedman.rdsl.lmi.net)
35  * @version $Revision: 1.13.2.1 $
36  */
37 public class JdeUtilities {
38
39   /** A cache of the items that are important across projects,
40    * indexed by the project name */
41   private static Map projectCache = new HashMap();
42
43   /** The current project so that callers need not pass in the
44       project name every time.  This is convenient, but not
45       threadsafe.  If we need thread saftey, we can go change all
46       the emacs lisp callers to always pass in the project name */
47   private static String currentProjectName = "default";
48     
49   // Have a default one just in case
50   static {
51     try {
52       ProjectClasses defaultProject =
53         new ProjectClasses(System.getProperty("java.class.path"));
54       projectCache.put(currentProjectName,defaultProject);
55     } catch (IOException e) {
56       e.printStackTrace(System.err);
57     } // end of try-catch
58   }
59
60   /*************************************************************************
61    * Constants
62    *************************************************************************/
63   public static final String NIL = "nil";
64   public static final String T = "t";
65   public static final String LIST = "list";
66   public static final String START_PAREN = "(";
67   public static final String END_PAREN = ")";
68   public static final String DOUBLE_QUOTE = "\"";
69   public static final String SPACE = " ";
70   public static final String START_LIST;
71   static {
72     StringBuffer sb = new StringBuffer (10);
73     sb.append(START_PAREN);
74     sb.append(LIST);
75     sb.append(SPACE);
76     START_LIST = sb.toString();
77   }
78     
79   /**
80    * Jde should call this everytime the project changes, or if the
81    * classpath needs to be updated.
82    *
83    * @param projectName a <code>String</code> value
84    * @param projectClassPath a <code>String</code> value
85    */
86   public static void setProjectValues(String projectName,
87                                       String projectClassPath) {
88     try {
89       currentProjectName = projectName;
90       ProjectClasses pc = new ProjectClasses(projectClassPath);
91       projectCache.put(projectName, pc);
92     } catch (IOException e) {
93       e.printStackTrace(System.err);
94     } // end of try-catch
95   }
96
97   /* Convenience to get current project's name */
98   public static String getCurrentProjectName() {
99     return currentProjectName;
100   }
101     
102   public static ProjectClasses getCurrentProjectClass() {
103     return (ProjectClasses) projectCache.get(currentProjectName);
104   }
105
106   /**
107    * Determine whether a class exists on the JDEE classpath.
108    *
109    * @param fqn Fully qualified name of the class to be found.
110    */
111   public static void classExists(String fqn) {
112     DynamicClassLoader dcl = new DynamicClassLoader();
113     while (fqn != null) {
114       try {
115         dcl.loadClass( fqn );
116         System.out.println( "\"" + fqn + "\"");
117         return;
118       } catch (ClassNotFoundException e) {
119       } catch (NoClassDefFoundError e) {
120       } catch (Exception e) {
121         System.out.println("(error \"Trying to load " + fqn +
122                            " caused a Java exception: " + e + "\")");
123         return;
124       } catch (UnsatisfiedLinkError e) {
125         // This occurs with classes that have native methods whose native
126         // implementations cannot be found.
127         System.out.println("(error \"Trying to load " + fqn +
128                            " caused a Java UnsatisfiedLinkError: " + e + "\")");
129         return;
130       } catch (LinkageError e) {
131         System.out.println("(error \"Trying to load " + fqn +
132                            " caused a Java LinkageError: " + e + "\")");
133         return;
134       }
135       // Test whether fqn is an inner class.
136       int index = fqn.lastIndexOf('.');
137       if (index != -1) {
138         fqn = fqn.substring (0, index) + '$' + fqn.substring (index + 1);
139       } else {
140         fqn = null;
141       }
142     }
143     System.out.println(NIL);              
144   }//met
145
146
147   /**
148    * Reload classes contained by a class, jar, or zip file or
149    * the current project's classpath.
150    *
151    * @param classPathEntry path to be reloaded. If null, this method
152    * reloads the current project's classpath.
153    */
154   public static void updateClassList(String classPathEntry) {
155     ProjectClasses pc =
156       (ProjectClasses) projectCache.get(getCurrentProjectName());
157
158     try {
159       if (classPathEntry!=null) {
160         pc.reloadClasses(classPathEntry);
161       } else {
162         pc.reloadClasses();
163       } // end of if (classPathEntry!=null)
164     } catch (IOException e) {
165       e.printStackTrace(System.err);
166     } // end of try-catch
167   }
168
169   /**
170    * Reload the current project's classpath.
171    */
172   public static void updateClassList() {
173     updateClassList(null);
174   }
175  
176   /**
177    * Looks up an unqualified class name in the class path to find possible
178    * fully qualified matches.  Given `List,' this will find
179    * `java.util.List' and `java.awt.List'
180    *
181    * @param className a value of type 'String'
182    */
183   public static void getQualifiedName(String className) {
184     ProjectClasses pc = null;
185     StringBuffer result = null;
186
187     try {
188       pc = (ProjectClasses)projectCache.get(currentProjectName);
189       result = new StringBuffer(START_PAREN);
190       result.append(LIST);
191
192       for (Iterator i = pc.getClassNames(className).iterator();
193            i.hasNext();) {
194         result.append(SPACE);
195         result.append(DOUBLE_QUOTE);
196         result.append(i.next().toString());
197         result.append(DOUBLE_QUOTE);
198       }
199       result.append(END_PAREN);
200       System.out.println(result.toString());
201       System.out.flush();
202     } catch (IOException e) {
203       e.printStackTrace(System.err);
204     } // end of try-catch
205   }
206
207   public static void getJavaVersion() {
208     StringBuffer sb = new StringBuffer(30);
209     sb.append(DOUBLE_QUOTE);
210     sb.append(System.getProperty("java.version"));
211     sb.append(DOUBLE_QUOTE);
212     System.out.println(sb);
213     System.out.flush();
214   }
215
216   public static void exit() {
217     System.exit(7);
218   }
219 } // JdeUtilities
220
221 /*
222  * $Log: JdeUtilities.java,v $
223  * Revision 1.13.2.1  2006/03/01 05:02:57  paulk
224  * Fix classExists() to handle inner classes. Thanks to Suraj Acharya [sacharya@gmail.com].
225  *
226  * Revision 1.13  2004/11/16 05:47:14  paulk
227  * restore updateClassList() method. Thanks to Martin Schwamberger.
228  *
229  * Revision 1.12  2004/10/20 06:14:53  paulk
230  * Update to support reloading classes from a single classpath entry. Thanks to Martin Schwamberger.
231  *
232  * Revision 1.11  2003/07/25 04:39:46  paulk
233  * More precisely catch exceptions and errors in classExists() method.
234  *
235  * Revision 1.10  2002/02/21 12:25:40  jslopez
236  * Adds method getCurrentClassPath.
237  * Update method classExists to use the DynamicClassLoader.
238  *
239  * Revision 1.9  2001/11/05 02:03:17  jslopez
240  * Adds an exit method.
241  *
242  * Revision 1.8  2001/09/13 02:35:40  eric
243  * (comment copied from branch)
244  * java 2-only implementation of JdeUtilities functions.  This uses a lazy
245  * map based lookup scheme instead of a linear search of class lists to find
246  * fully qualified class names.  It also implements a flyweight/singleton
247  * approach to sharing classpath entries that appear in multiple projects.
248  * Finally, classpath entries that are part of the `system' classes are
249  * wrapped in an immutable decorator which balks are reloading them.
250  * This eliminates the overhead of rescanning classes which cannot change
251  * over the lifetime of a single bsh process.
252  *
253  * Revision 1.6.2.2  2001/09/13 02:32:06  eric
254  * merge HEAD => branch, in anticipation of merging branch => HEAD
255  *
256  */
257
258 // End of JdeUtilities.java