001: package net.sourceforge.squirrel_sql.plugins.syntax;
002:
003: /*
004: * Copyright (C) 2003 Colin Bell
005: * colbell@users.sourceforge.net
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021: import java.beans.PropertyChangeEvent;
022: import java.beans.PropertyChangeListener;
023: import java.io.File;
024: import java.io.FileNotFoundException;
025: import java.io.IOException;
026: import java.util.HashMap;
027: import java.util.Iterator;
028: import java.util.Map;
029:
030: import javax.swing.Action;
031: import javax.swing.JComponent;
032: import javax.swing.JMenu;
033: import javax.swing.JMenuItem;
034: import javax.swing.JOptionPane;
035: import javax.swing.text.JTextComponent;
036:
037: import net.sourceforge.squirrel_sql.client.IApplication;
038: import net.sourceforge.squirrel_sql.client.action.ActionCollection;
039: import net.sourceforge.squirrel_sql.client.gui.session.ObjectTreeInternalFrame;
040: import net.sourceforge.squirrel_sql.client.gui.session.SQLInternalFrame;
041: import net.sourceforge.squirrel_sql.client.gui.session.SessionInternalFrame;
042: import net.sourceforge.squirrel_sql.client.plugin.DefaultSessionPlugin;
043: import net.sourceforge.squirrel_sql.client.plugin.PluginException;
044: import net.sourceforge.squirrel_sql.client.plugin.PluginResources;
045: import net.sourceforge.squirrel_sql.client.plugin.PluginSessionCallback;
046: import net.sourceforge.squirrel_sql.client.preferences.INewSessionPropertiesPanel;
047: import net.sourceforge.squirrel_sql.client.session.ISQLEntryPanel;
048: import net.sourceforge.squirrel_sql.client.session.ISQLEntryPanelFactory;
049: import net.sourceforge.squirrel_sql.client.session.ISQLPanelAPI;
050: import net.sourceforge.squirrel_sql.client.session.ISession;
051: import net.sourceforge.squirrel_sql.client.session.properties.ISessionPropertiesPanel;
052: import net.sourceforge.squirrel_sql.fw.id.IIdentifier;
053: import net.sourceforge.squirrel_sql.fw.util.Resources;
054: import net.sourceforge.squirrel_sql.fw.util.StringManager;
055: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
056: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
057: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
058: import net.sourceforge.squirrel_sql.fw.xml.XMLBeanReader;
059: import net.sourceforge.squirrel_sql.fw.xml.XMLBeanWriter;
060: import net.sourceforge.squirrel_sql.plugins.syntax.netbeans.FindAction;
061: import net.sourceforge.squirrel_sql.plugins.syntax.netbeans.NetbeansSQLEditorPane;
062: import net.sourceforge.squirrel_sql.plugins.syntax.netbeans.NetbeansSQLEntryPanel;
063: import net.sourceforge.squirrel_sql.plugins.syntax.netbeans.ReplaceAction;
064: import net.sourceforge.squirrel_sql.plugins.syntax.netbeans.SQLKit;
065: import net.sourceforge.squirrel_sql.plugins.syntax.netbeans.SQLSettingsInitializer;
066: import net.sourceforge.squirrel_sql.plugins.syntax.oster.OsterSQLEntryPanel;
067:
068: import org.netbeans.editor.BaseKit;
069:
070: /**
071: * The Ostermiller plugin class. This plugin adds syntax highlighting to the
072: * SQL entry area.
073: *
074: * @author <A HREF="mailto:colbell@users.sourceforge.net">Colin Bell</A>
075: */
076: public class SyntaxPugin extends DefaultSessionPlugin {
077: private static final StringManager s_stringMgr = StringManagerFactory
078: .getStringManager(SyntaxPugin.class);
079:
080: static interface i18n {
081: //i18n[SyntaxPlugin.touppercase=touppercase]
082: String TO_UPPER_CASE = s_stringMgr
083: .getString("SyntaxPlugin.touppercase");
084: //i18n[SyntaxPlugin.tolowercase=tolowercase]
085: String TO_LOWER_CASE = s_stringMgr
086: .getString("SyntaxPlugin.tolowercase");
087: //i18n[SyntaxPlugin.find=find]
088: String FIND = s_stringMgr.getString("SyntaxPlugin.find");
089: //i18n[SyntaxPlugin.replace=replace]
090: String REPLACE = s_stringMgr.getString("SyntaxPlugin.replace");
091: //i18n[SyntaxPlugin.autocorr=autocorr]
092: String AUTO_CORR = s_stringMgr
093: .getString("SyntaxPlugin.autocorr");
094: //i18n[SyntaxPlugin.duplicateline=duplicateline]
095: String DUP_LINE = s_stringMgr
096: .getString("SyntaxPlugin.duplicateline");
097: //i18n[SyntaxPlugin.comment=comment]
098: String COMMENT = s_stringMgr.getString("SyntaxPlugin.comment");
099: //i18n[SyntaxPlugin.uncomment=uncomment]
100: String UNCOMMENT = s_stringMgr
101: .getString("SyntaxPlugin.uncomment");
102:
103: }
104:
105: /** Logger for this class. */
106: private static final ILogger s_log = LoggerController
107: .createLogger(SyntaxPugin.class);
108:
109: /** SyntaxPreferences for new sessions. */
110: private SyntaxPreferences _newSessionPrefs;
111:
112: /** Folder to store user settings in. */
113: private File _userSettingsFolder;
114:
115: /** Factory that creates text controls. */
116: private SQLEntryPanelFactoryProxy _sqlEntryFactoryProxy;
117:
118: /** Listeners to the preferences object in each open session. */
119: private Map<IIdentifier, SessionPreferencesListener> _prefListeners = new HashMap<IIdentifier, SessionPreferencesListener>();
120:
121: /** Resources for this plugin. */
122: private SyntaxPluginResources _resources;
123: private AutoCorrectProviderImpl _autoCorrectProvider;
124:
125: private interface IMenuResourceKeys {
126: String MENU = "syntax";
127: }
128:
129: /**
130: * Return the internal name of this plugin.
131: *
132: * @return the internal name of this plugin.
133: */
134: public String getInternalName() {
135: return "syntax";
136: }
137:
138: /**
139: * Return the descriptive name of this plugin.
140: *
141: * @return the descriptive name of this plugin.
142: */
143: public String getDescriptiveName() {
144: return "Syntax Highlighting Plugin";
145: }
146:
147: /**
148: * Returns the current version of this plugin.
149: *
150: * @return the current version of this plugin.
151: */
152: public String getVersion() {
153: return "1.0";
154: }
155:
156: /**
157: * Returns the authors name.
158: *
159: * @return the authors name.
160: */
161: public String getAuthor() {
162: return "Gerd Wagner, Colin Bell";
163: }
164:
165: /**
166: * Returns the name of the change log for the plugin. This should
167: * be a text or HTML file residing in the <TT>getPluginAppSettingsFolder</TT>
168: * directory.
169: *
170: * @return the changelog file name or <TT>null</TT> if plugin doesn't have
171: * a change log.
172: */
173: public String getChangeLogFileName() {
174: return "changes.txt";
175: }
176:
177: /**
178: * Returns the name of the Help file for the plugin. This should
179: * be a text or HTML file residing in the <TT>getPluginAppSettingsFolder</TT>
180: * directory.
181: *
182: * @return the Help file name or <TT>null</TT> if plugin doesn't have
183: * a help file.
184: */
185: public String getHelpFileName() {
186: return "readme.html";
187: }
188:
189: /**
190: * Returns the name of the Licence file for the plugin. This should
191: * be a text or HTML file residing in the <TT>getPluginAppSettingsFolder</TT>
192: * directory.
193: *
194: * @return the Licence file name or <TT>null</TT> if plugin doesn't have
195: * a licence file.
196: */
197: public String getLicenceFileName() {
198: return "licence.txt";
199: }
200:
201: /**
202: * Initialize this plugin.
203: */
204: public synchronized void initialize() throws PluginException {
205: super .initialize();
206:
207: _resources = new SyntaxPluginResources(this );
208:
209: // Folder to store user settings.
210: try {
211: _userSettingsFolder = getPluginUserSettingsFolder();
212: } catch (IOException ex) {
213: throw new PluginException(ex);
214: }
215:
216: // Load plugin preferences.
217: loadPrefs();
218:
219: // Install the factory for creating SQL entry text controls.
220: final IApplication app = getApplication();
221: final ISQLEntryPanelFactory originalFactory = app
222: .getSQLEntryPanelFactory();
223: //_sqlEntryFactoryProxy = new OsterSQLEntryAreaFactory(this, originalFactory);
224:
225: _sqlEntryFactoryProxy = new SQLEntryPanelFactoryProxy(this ,
226: originalFactory);
227:
228: app.setSQLEntryPanelFactory(_sqlEntryFactoryProxy);
229:
230: _autoCorrectProvider = new AutoCorrectProviderImpl(
231: _userSettingsFolder);
232:
233: createMenu();
234: }
235:
236: private void createMenu() {
237: IApplication app = getApplication();
238: ActionCollection coll = app.getActionCollection();
239:
240: JMenu menu = _resources.createMenu(IMenuResourceKeys.MENU);
241: app.addToMenu(IApplication.IMenuIDs.SESSION_MENU, menu);
242:
243: Action act = new ConfigureAutoCorrectAction(app, _resources,
244: this );
245: coll.add(act);
246: _resources.addToMenu(act, menu);
247:
248: act = new FindAction(getApplication(), _resources);
249: coll.add(act);
250: _resources.addToMenu(act, menu);
251:
252: act = new ReplaceAction(getApplication(), _resources);
253: coll.add(act);
254: _resources.addToMenu(act, menu);
255:
256: act = new DuplicateLineAction(getApplication(), _resources);
257: coll.add(act);
258: _resources.addToMenu(act, menu);
259:
260: act = new CommentAction(getApplication(), _resources);
261: coll.add(act);
262: _resources.addToMenu(act, menu);
263:
264: act = new UncommentAction(getApplication(), _resources);
265: coll.add(act);
266: _resources.addToMenu(act, menu);
267:
268: }
269:
270: /**
271: * Application is shutting down so save preferences.
272: */
273: public void unload() {
274: savePrefs();
275: super .unload();
276: }
277:
278: /**
279: * Called when a session created but the UI hasn't been built for the
280: * session.
281: *
282: * @param session The session that is starting.
283: */
284: public void sessionCreated(ISession session) {
285: SyntaxPreferences prefs = null;
286:
287: try {
288: prefs = (SyntaxPreferences) _newSessionPrefs.clone();
289: } catch (CloneNotSupportedException ex) {
290: throw new InternalError(
291: "CloneNotSupportedException for SyntaxPreferences");
292: }
293:
294: session.putPluginObject(this , IConstants.ISessionKeys.PREFS,
295: prefs);
296:
297: SessionPreferencesListener lis = new SessionPreferencesListener(
298: this , session);
299: prefs.addPropertyChangeListener(lis);
300: _prefListeners.put(session.getIdentifier(), lis);
301: }
302:
303: public PluginSessionCallback sessionStarted(final ISession session) {
304: PluginSessionCallback ret = new PluginSessionCallback() {
305: public void sqlInternalFrameOpened(
306: SQLInternalFrame sqlInternalFrame, ISession sess) {
307: initSqlInternalFrame(sqlInternalFrame);
308: }
309:
310: public void objectTreeInternalFrameOpened(
311: ObjectTreeInternalFrame objectTreeInternalFrame,
312: ISession sess) {
313: }
314: };
315:
316: initSessionSheet(session);
317:
318: return ret;
319: }
320:
321: private void initSessionSheet(ISession session) {
322: ActionCollection coll = getApplication().getActionCollection();
323: session.addSeparatorToToolbar();
324: session.addToToolbar(coll.get(FindAction.class));
325: session.addToToolbar(coll.get(ReplaceAction.class));
326: session
327: .addToToolbar(coll
328: .get(ConfigureAutoCorrectAction.class));
329:
330: SessionInternalFrame sif = session.getSessionInternalFrame();
331:
332: ISQLPanelAPI sqlPanelAPI = sif.getSQLPanelAPI();
333: ISQLEntryPanel sep = sqlPanelAPI.getSQLEntryPanel();
334: JComponent septc = sep.getTextComponent();
335:
336: new ToolsPopupHandler(this ).initToolsPopup(sif, coll);
337:
338: JMenuItem mnuComment = sqlPanelAPI.addToSQLEntryAreaMenu(coll
339: .get(CommentAction.class));
340: JMenuItem mnuUncomment = sqlPanelAPI.addToSQLEntryAreaMenu(coll
341: .get(UncommentAction.class));
342: _resources.configureMenuItem(coll.get(CommentAction.class),
343: mnuComment);
344: _resources.configureMenuItem(coll.get(UncommentAction.class),
345: mnuUncomment);
346: }
347:
348: private void initSqlInternalFrame(SQLInternalFrame sqlInternalFrame) {
349: ActionCollection coll = getApplication().getActionCollection();
350: FindAction findAction = ((FindAction) coll
351: .get(FindAction.class));
352: ReplaceAction replaceAction = (ReplaceAction) coll
353: .get(ReplaceAction.class);
354:
355: sqlInternalFrame.addSeparatorToToolbar();
356: sqlInternalFrame.addToToolbar(findAction);
357: sqlInternalFrame.addToToolbar(replaceAction);
358: sqlInternalFrame.addToToolbar(coll
359: .get(ConfigureAutoCorrectAction.class));
360:
361: new ToolsPopupHandler(this ).initToolsPopup(sqlInternalFrame,
362: coll);
363:
364: ISQLPanelAPI sqlPanelAPI = sqlInternalFrame.getSQLPanelAPI();
365:
366: JMenuItem mnuComment = sqlPanelAPI.addToSQLEntryAreaMenu(coll
367: .get(CommentAction.class));
368: JMenuItem mnuUncomment = sqlPanelAPI.addToSQLEntryAreaMenu(coll
369: .get(UncommentAction.class));
370: _resources.configureMenuItem(coll.get(CommentAction.class),
371: mnuComment);
372: _resources.configureMenuItem(coll.get(UncommentAction.class),
373: mnuUncomment);
374:
375: }
376:
377: /**
378: * Called when a session shutdown.
379: *
380: * @param session The session that is ending.
381: */
382: public void sessionEnding(ISession session) {
383: super .sessionEnding(session);
384:
385: session.removePluginObject(this , IConstants.ISessionKeys.PREFS);
386: _prefListeners.remove(session.getIdentifier());
387: _sqlEntryFactoryProxy.sessionEnding(session);
388: }
389:
390: /**
391: * Create preferences panel for the New Session Properties dialog.
392: *
393: * @return preferences panel.
394: */
395: public INewSessionPropertiesPanel[] getNewSessionPropertiesPanels() {
396: return new INewSessionPropertiesPanel[] { new SyntaxPreferencesPanel(
397: _newSessionPrefs, _resources) };
398: }
399:
400: /**
401: * Create panels for the Session Properties dialog.
402: *
403: * @return Array of panels for the properties dialog.
404: */
405: public ISessionPropertiesPanel[] getSessionPropertiesPanels(
406: ISession session) {
407: SyntaxPreferences sessionPrefs = (SyntaxPreferences) session
408: .getPluginObject(this , IConstants.ISessionKeys.PREFS);
409:
410: return new ISessionPropertiesPanel[] { new SyntaxPreferencesPanel(
411: sessionPrefs, _resources) };
412: }
413:
414: SyntaxPluginResources getResources() {
415: return _resources;
416: }
417:
418: ISQLEntryPanelFactory getSQLEntryAreaFactory() {
419: return _sqlEntryFactoryProxy;
420: }
421:
422: /**
423: * Load from preferences file.
424: */
425: private void loadPrefs() {
426: try {
427: final XMLBeanReader doc = new XMLBeanReader();
428: final File file = new File(_userSettingsFolder,
429: IConstants.USER_PREFS_FILE_NAME);
430: doc.load(file, getClass().getClassLoader());
431:
432: Iterator<?> it = doc.iterator();
433:
434: if (it.hasNext()) {
435: _newSessionPrefs = (SyntaxPreferences) it.next();
436: }
437: } catch (FileNotFoundException ignore) {
438: // property file not found for user - first time user ran pgm.
439: } catch (Exception ex) {
440: final String msg = "Error occured reading from preferences file: "
441: + IConstants.USER_PREFS_FILE_NAME;
442: s_log.error(msg, ex);
443: }
444:
445: if (_newSessionPrefs == null) {
446: _newSessionPrefs = new SyntaxPreferences();
447: }
448: }
449:
450: /**
451: * Save preferences to disk.
452: */
453: private void savePrefs() {
454: try {
455: final XMLBeanWriter wtr = new XMLBeanWriter(
456: _newSessionPrefs);
457: wtr.save(new File(_userSettingsFolder,
458: IConstants.USER_PREFS_FILE_NAME));
459: } catch (Exception ex) {
460: final String msg = "Error occured writing to preferences file: "
461: + IConstants.USER_PREFS_FILE_NAME;
462: s_log.error(msg, ex);
463: }
464: }
465:
466: public Object getExternalService() {
467: return getAutoCorrectProviderImpl();
468: }
469:
470: public AutoCorrectProviderImpl getAutoCorrectProviderImpl() {
471: return _autoCorrectProvider;
472: }
473:
474: private static final class SessionPreferencesListener implements
475: PropertyChangeListener {
476: private SyntaxPugin _plugin;
477: private ISession _session;
478:
479: SessionPreferencesListener(SyntaxPugin plugin, ISession session) {
480: super ();
481: _plugin = plugin;
482: _session = session;
483: }
484:
485: public void propertyChange(PropertyChangeEvent evt) {
486: String propName = evt.getPropertyName();
487:
488: if (false == SyntaxPreferences.IPropertyNames.USE_NETBEANS_CONTROL
489: .equals(propName)
490: && false == SyntaxPreferences.IPropertyNames.USE_OSTER_CONTROL
491: .equals(propName)) {
492:
493: // Not the Textcontrol itself changed but some other of the Syntax Preferences, for example a color.
494: // So we tell the current control to update the preferences.
495: Object pluginObject = _session.getPluginObject(_plugin,
496: IConstants.ISessionKeys.SQL_ENTRY_CONTROL);
497:
498: if (pluginObject instanceof NetbeansSQLEntryPanel) {
499: ((NetbeansSQLEntryPanel) pluginObject)
500: .updateFromPreferences();
501: }
502:
503: if (pluginObject instanceof OsterSQLEntryPanel) {
504: ((OsterSQLEntryPanel) pluginObject)
505: .updateFromPreferences();
506: }
507: } else {
508: /*
509: We don't support switching the entry control during a session
510: because serveral things, that are attached to the entry control
511: from outside this plugin would need to reinitialze too.
512: For example code completion and edit extras.
513:
514: synchronized (_session)
515: {
516: ISQLEntryPanelFactory factory = _plugin.getSQLEntryAreaFactory();
517: ISQLEntryPanel pnl = factory.createSQLEntryPanel(_session);
518: _session.getSQLPanelAPI(_plugin).installSQLEntryPanel(pnl);
519: }
520: */
521:
522: String msg =
523: // i18n[syntax.switchingNotSupported=Switching the editor of a runninig session is not supported.\nYou may switch the entry area in the New Session Properties dialog]
524: s_stringMgr.getString("syntax.switchingNotSupported");
525:
526: JOptionPane.showMessageDialog(_session.getApplication()
527: .getMainFrame(), msg);
528:
529: throw new SyntaxPrefChangeNotSupportedException();
530:
531: }
532:
533: }
534: }
535: }
|