KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > antlr > works > IDE


1 /*
2
3 [The "BSD licence"]
4 Copyright (c) 2005 Jean Bovet
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16 3. The name of the author may not be used to endorse or promote products
17 derived from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 */

31
32 package org.antlr.works;
33
34 import org.antlr.xjlib.appkit.app.XJApplication;
35 import org.antlr.xjlib.appkit.app.XJApplicationDelegate;
36 import org.antlr.xjlib.appkit.document.XJDataPlainText;
37 import org.antlr.xjlib.appkit.document.XJDataXML;
38 import org.antlr.xjlib.appkit.document.XJDocument;
39 import org.antlr.xjlib.appkit.frame.XJPanel;
40 import org.antlr.xjlib.appkit.menu.XJMainMenuBar;
41 import org.antlr.xjlib.appkit.menu.XJMenu;
42 import org.antlr.xjlib.appkit.menu.XJMenuItem;
43 import org.antlr.xjlib.appkit.menu.XJMenuItemDelegate;
44 import org.antlr.xjlib.appkit.swing.XJLookAndFeel;
45 import org.antlr.xjlib.appkit.utils.BrowserLauncher;
46 import org.antlr.xjlib.appkit.utils.XJAlert;
47 import org.antlr.xjlib.appkit.utils.XJLocalizable;
48 import org.antlr.xjlib.foundation.XJSystem;
49 import org.antlr.Tool;
50 import org.antlr.tool.ErrorManager;
51 import org.antlr.works.components.grammar.CContainerGrammar;
52 import org.antlr.works.components.grammar.CDocumentGrammar;
53 import org.antlr.works.components.project.CContainerProject;
54 import org.antlr.works.components.project.CDocumentProject;
55 import org.antlr.works.dialog.DialogAbout;
56 import org.antlr.works.dialog.DialogPersonalInfo;
57 import org.antlr.works.editor.EditorMenu;
58 import org.antlr.works.prefs.AWPrefs;
59 import org.antlr.works.prefs.AWPrefsDialog;
60 import org.antlr.works.stats.Statistics;
61 import org.antlr.works.stats.StatisticsAW;
62 import org.antlr.works.utils.Console;
63 import org.antlr.works.utils.ErrorListener;
64 import org.antlr.works.utils.HelpManager;
65 import org.antlr.works.utils.Localizable;
66
67 import javax.swing.*;
68 import java.awt.*;
69 import java.io.ByteArrayOutputStream JavaDoc;
70 import java.io.IOException JavaDoc;
71 import java.io.OutputStream JavaDoc;
72 import java.io.PrintStream JavaDoc;
73 import java.net.URL JavaDoc;
74 import java.util.ArrayList JavaDoc;
75 import java.util.List JavaDoc;
76 import java.util.ResourceBundle JavaDoc;
77
78 public class IDE extends XJApplicationDelegate implements XJMenuItemDelegate {
79
80     public static final String JavaDoc PROPERTIES_PATH = "org/antlr/works/properties/";
81
82     public static SplashScreen sc;
83
84     public static void main(String JavaDoc[] args) {
85         // Needs to specify the Mac OS X property here (starting from Tiger)
86
// before any other line of code (the usual XJApplication won't work
87
// because we are instanciating a SplashScreen before it)
88
XJSystem.setSystemProperties();
89         XJApplication.setPropertiesPath(PROPERTIES_PATH);
90
91         if(args.length >= 1 && args[0].equals("-stats")) {
92             XJApplication.run(new Statistics(), args, "Statistics");
93         } else {
94             sc = new SplashScreen();
95
96             try {
97                 SwingUtilities.invokeAndWait(new Runnable JavaDoc() {
98                     public void run() {
99                         sc.setVisible(true);
100                     }
101                 });
102             } catch (Exception JavaDoc e) {
103                 e.printStackTrace();
104             }
105
106             XJApplication.run(new IDE(), args);
107         }
108     }
109
110     public void appDidLaunch(String JavaDoc[] args, List JavaDoc<String JavaDoc> documentsToOpenAtStartup) {
111         AWPrefs.setLookAndFeel(XJLookAndFeel.applyLookAndFeel(AWPrefs.getLookAndFeel()));
112         XJApplication.addDocumentType(CDocumentGrammar.class, CContainerGrammar.class, XJDataPlainText.class, "g",
113                 Localizable.getLocalizedString(Localizable.DOCUMENT_TYPE));
114         if(AWPrefs.getEnableProjectDocument()) {
115             XJApplication.addDocumentType(CDocumentProject.class, CContainerProject.class, XJDataXML.class, "awp",
116                     Localizable.getLocalizedString(Localizable.PROJECT_TYPE));
117         }
118
119         XJApplication.addScheduledTimer(new HelpManager(), 1, true);
120
121         AWPrefsDialog.applyCommonPrefs();
122
123         registerUser();
124         checkLibraries();
125         checkEnvironment();
126
127         if(args.length >= 2 && args[0].equals("-f")) {
128             XJApplication.shared().openDocument(args[1]);
129         } else if(documentsToOpenAtStartup != null && documentsToOpenAtStartup.size() > 0) {
130             XJApplication.shared().openDocuments(documentsToOpenAtStartup);
131         } else {
132             switch (AWPrefs.getStartupAction()) {
133                 case AWPrefs.STARTUP_NEW_DOC:
134                     sc.setVisible(false);
135                     XJApplication.shared().newDocument();
136                     break;
137
138                 case AWPrefs.STARTUP_OPEN_LAST_OPENED_DOC:
139                     if(XJApplication.shared().getDocuments().size() == 0) {
140                         if(!XJApplication.shared().openLastUsedDocument()) {
141                             sc.setVisible(false);
142                             XJApplication.shared().newDocument();
143                         }
144                     }
145                     break;
146
147                 case AWPrefs.STARTUP_OPEN_LAST_SAVED_DOC:
148                     if(XJApplication.shared().getDocuments().size() == 0) {
149                         if(!XJApplication.shared().openDocument(AWPrefs.getLastSavedDocument())) {
150                             sc.setVisible(false);
151                             XJApplication.shared().newDocument();
152                         }
153                     }
154                     break;
155
156                 case AWPrefs.STARTUP_OPEN_ALL_OPENED_DOC:
157                     sc.setVisible(false);
158                     if(!restoreAllOpenedDocuments()) {
159                         sc.setVisible(false);
160                         XJApplication.shared().newDocument();
161                     }
162                     break;
163             }
164         }
165
166         sc.setVisible(false);
167     }
168
169     public void registerUser() {
170         if(!AWPrefs.isUserRegistered()) {
171             sc.setVisible(false);
172             AWPrefs.setServerID("");
173             new DialogPersonalInfo(null).runModal();
174             AWPrefs.setUserRegistered(true);
175         }
176     }
177
178     public void checkLibraries() {
179         StringBuffer JavaDoc missing = new StringBuffer JavaDoc();
180
181         try {
182             Class.forName("org.antlr.Tool");
183         } catch (ClassNotFoundException JavaDoc e) {
184             missing.append("\n- ANTLR 3.x");
185         }
186
187         try {
188             Class.forName("org.antlr.stringtemplate.StringTemplate");
189         } catch (ClassNotFoundException JavaDoc e) {
190             missing.append("\n- StringTemplate");
191         } catch (NoClassDefFoundError JavaDoc e) {
192             missing.append("\n- StringTemplate");
193         }
194
195         if(missing.length()>0) {
196             sc.setVisible(false);
197             missing.insert(0, "ANTLRWorks cannot find the following libraries:");
198             missing.append("\nThey are required in order to use all the features of ANTLRWorks.\nDownload them from www.antlr.org and put them in the same directory as ANTLRWorks.");
199             XJAlert.display(null, "Missing Libraries", missing.toString());
200             System.exit(0);
201         }
202     }
203
204     public void checkEnvironment() {
205         // todo give a hint in the message - like "check that no previous version of ANTLR is in your classpath..."
206
// todo message for first-time user to go to tutorial
207
CheckStream bos = new CheckStream(System.err);
208         PrintStream JavaDoc ps = new PrintStream JavaDoc(bos);
209         PrintStream JavaDoc os = System.err;
210         System.setErr(ps);
211         try {
212             ErrorManager.setTool(new Tool());
213             //ErrorManager.setErrorListener(ErrorManager.getErrorListener());
214
ErrorManager.setErrorListener(ErrorListener.shared());
215         } catch (Throwable JavaDoc e) {
216             XJAlert.display(null, "Fatal Error", "ANTLRWorks will quit now because ANTLR reported an error:\n"+bos.getMessage());
217             System.exit(0);
218         }
219
220         if(ErrorListener.shared().hasErrors()) {
221             XJAlert.display(null, "Error", "ANTLRWorks will continue to launch but ANTLR reported an error:\n"+bos.getMessage());
222         }
223
224         System.setErr(os);
225         ps.close();
226     }
227
228     private class CheckStream extends ByteArrayOutputStream JavaDoc {
229
230         private PrintStream JavaDoc errorStream;
231         private StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
232
233         public CheckStream(PrintStream JavaDoc errorStream) {
234             this.errorStream = errorStream;
235         }
236
237         public synchronized void write(int b) {
238             super.write(b);
239             record();
240         }
241
242         public synchronized void write(byte b[], int off, int len) {
243             super.write(b, off, len);
244             record();
245         }
246
247         public synchronized void writeTo(OutputStream JavaDoc out) throws IOException JavaDoc {
248             super.writeTo(out);
249             record();
250         }
251
252         public void write(byte b[]) throws IOException JavaDoc {
253             super.write(b);
254             record();
255         }
256
257         private void record() {
258             errorStream.println(toString());
259             sb.append(toString());
260             reset();
261         }
262
263         public String JavaDoc getMessage() {
264             return sb.toString();
265         }
266     }
267
268     public static String JavaDoc getApplicationPath() {
269         Class JavaDoc<? extends Object JavaDoc> c = XJApplication.getAppDelegate().getClass();
270         URL JavaDoc url = c.getProtectionDomain().getCodeSource().getLocation();
271         String JavaDoc p;
272         if(url == null) {
273             // url can be null in some situation (i.e. plugin in IntelliJ). Let's try another
274
// way using getResource().
275
// Warning: use only '/' for the resource name even on Windows because internally
276
// Java uses '/'!
277
// See AW-35
278
String JavaDoc name = c.getName().replace('.', '/').concat(".class");
279             url = c.getClassLoader().getResource(name);
280             if(url == null) {
281                 System.err.println("IDE: unable to get the location of the XJApplicationDelegate");
282                 return null;
283             } else {
284                 // Remove the class fully qualified path from the path
285
p = url.getPath();
286                 p = p.substring(0, p.length()-name.length());
287             }
288         } else {
289             p = url.getPath();
290         }
291
292         if(p.startsWith("jar:"))
293             p = p.substring("jar:".length());
294
295         if(p.startsWith("file:"))
296             p = p.substring("file:".length());
297
298         int index = p.lastIndexOf("!");
299         if(index != -1)
300             p = p.substring(0, index);
301
302         if(XJSystem.isWindows()) {
303             // Note: on Windows, we can have something like "/C:/Document..."
304
if(p.charAt(0) == '/')
305                 p = p.substring(1);
306
307             // Change all '/' to '\'
308
StringBuffer JavaDoc sb = new StringBuffer JavaDoc(p);
309             for(int i=0; i<sb.length(); i++) {
310                 if(sb.charAt(i) == '/')
311                     sb.replace(i, i+1, "\\");
312             }
313             p = sb.toString();
314         }
315
316         // Replace all %20 with white space. Apparently inside IntelliJ 6, white space in a path
317
// are replaced by %20 but not in IntelliJ 5
318
p = p.replaceAll("%20", " ");
319
320         return p;
321     }
322
323     public static void debugVerbose(Console console, Class JavaDoc<? extends Object JavaDoc> c, String JavaDoc s) {
324         if(AWPrefs.getDebugVerbose()) {
325             String JavaDoc message = c.getName()+": "+s;
326             if(console != null)
327                 console.println(message);
328             System.out.println(message);
329         }
330     }
331
332     public void customizeHelpMenu(XJMenu menu) {
333         menu.insertItemAfter(new XJMenuItem("Check for Updates", EditorMenu.MI_CHECK_UPDATES, this), XJMainMenuBar.MI_HELP);
334         menu.insertItemAfter(new XJMenuItem("Send Feedback", EditorMenu.MI_SEND_FEEDBACK, this), XJMainMenuBar.MI_HELP);
335         menu.insertItemAfter(new XJMenuItem("Submit Statistics...", EditorMenu.MI_SUBMIT_STATS, this), XJMainMenuBar.MI_HELP);
336         menu.insertSeparatorAfter(XJMainMenuBar.MI_HELP);
337     }
338
339     public void handleMenuEvent(XJMenu menu, XJMenuItem item) {
340         switch(item.getTag()) {
341             case EditorMenu.MI_SUBMIT_STATS:
342                 submitStats(getDefaultParent());
343                 break;
344             case EditorMenu.MI_SEND_FEEDBACK:
345                 submitFeedback(getDefaultParent());
346                 break;
347             case EditorMenu.MI_CHECK_UPDATES:
348                 checkUpdates(getDefaultParent());
349                 break;
350         }
351     }
352
353     public Container getDefaultParent() {
354         return XJApplication.shared().getActiveWindow().getJavaContainer();
355     }
356
357     public static void checkUpdates(Container parent) {
358         StatisticsAW.shared().recordEvent(StatisticsAW.EVENT_CHECK_FOR_UPDATES);
359         HelpManager.checkUpdates(parent, false);
360     }
361
362     public static void submitFeedback(Container parent) {
363         HelpManager.sendFeedback(parent);
364     }
365
366     public static void submitStats(Container parent) {
367         HelpManager.submitStats(parent);
368     }
369
370     public static void showHelp(Container parent) {
371         StatisticsAW.shared().recordEvent(StatisticsAW.EVENT_SHOW_HELP);
372         String JavaDoc url = Localizable.getLocalizedString(Localizable.DOCUMENTATION_URL);
373         try {
374             BrowserLauncher.openURL(url);
375         } catch (IOException JavaDoc e) {
376             XJAlert.display(parent, "Cannot access the online help", "An error occurred when accessing the online help:\n"+e.toString()+"\n\nBrowse the online help at "+url+".");
377         }
378     }
379
380     public void appShowHelp() {
381         showHelp(getDefaultParent());
382     }
383
384     public void appWillTerminate() {
385         saveAllOpenedDocuments();
386
387         StatisticsAW.shared().close();
388     }
389
390     public Class JavaDoc appPreferencesPanelClass() {
391         return AWPrefsDialog.class;
392     }
393
394     public XJPanel appInstanciateAboutPanel() {
395         return new DialogAbout();
396     }
397
398     public boolean appHasPreferencesMenuItem() {
399         return true;
400     }
401
402     public boolean appShouldQuitAfterLastWindowClosed() {
403         return false;
404     }
405
406     public boolean useDesktopMode() {
407         return AWPrefs.getUseDesktopMode();
408     }
409
410     public Class JavaDoc appPreferencesClass() {
411         return IDE.class;
412     }
413
414     public String JavaDoc appName() {
415         return Localizable.getLocalizedString(Localizable.APP_NAME)+" "+appVersionShort();
416     }
417
418     public String JavaDoc appVersionShort() {
419         return Localizable.getLocalizedString(Localizable.APP_VERSION_SHORT);
420     }
421
422     public String JavaDoc appVersionLong() {
423         return Localizable.getLocalizedString(Localizable.APP_VERSION_LONG);
424     }
425
426     private boolean restoreAllOpenedDocuments() {
427         List JavaDoc<String JavaDoc> documents = AWPrefs.getAllOpenedDocuments();
428         if(documents == null) return false;
429
430         boolean success = false;
431         for (String JavaDoc docPath : documents) {
432             if(XJApplication.shared().openDocument(docPath)) {
433                 success = true;
434             }
435         }
436         return success;
437     }
438
439     private void saveAllOpenedDocuments() {
440         List JavaDoc<String JavaDoc> docPath = new ArrayList JavaDoc<String JavaDoc>();
441         for (Object JavaDoc o : XJApplication.shared().getDocuments()) {
442             XJDocument document = (XJDocument) o;
443             if (document instanceof CDocumentGrammar) {
444                 docPath.add(document.getDocumentPath());
445             }
446         }
447         AWPrefs.setAllOpenedDocuments(docPath);
448     }
449
450     /** Localized resource bundle */
451     protected static ResourceBundle JavaDoc resourceMenusBundle = ResourceBundle.getBundle("org.antlr.works.properties.menus");
452
453     public static ResourceBundle JavaDoc getMenusResourceBundle() {
454         return resourceMenusBundle;
455     }
456
457     /** Returns true if AW is running as a plugin */
458
459     public static boolean _isPlugin = false;
460     public static final String JavaDoc PLUGIN_PROPERTIES_PATH = "org/antlr/works/plugin/properties/strings";
461
462     public static boolean isPlugin() {
463         return _isPlugin;
464     }
465
466     public static String JavaDoc getPluginVersionShort() {
467         return XJLocalizable.getStringFromPath(PLUGIN_PROPERTIES_PATH, "VERSION_SHORT");
468     }
469
470 }
471
Popular Tags