PageRenderTime 185ms CodeModel.GetById 152ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/bundles/plugins-trunk/SideKick/sidekick/SideKickPlugin.java

#
Java | 434 lines | 302 code | 47 blank | 85 comment | 63 complexity | 943cc9d3791be5cb2b8302d3e04b1b6d MD5 | raw file
  1/*
  2 * SideKickPlugin.java
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2003 Slava Pestov
  7 *
  8 * This program is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU General Public License
 10 * as published by the Free Software Foundation; either version 2
 11 * of the License, or 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 21 */
 22
 23package sidekick;
 24
 25//{{{ Imports
 26import org.gjt.sp.jedit.*;
 27import org.gjt.sp.jedit.EditBus.EBHandler;
 28import org.gjt.sp.jedit.msg.BufferUpdate;
 29import org.gjt.sp.jedit.msg.EditPaneUpdate;
 30import org.gjt.sp.jedit.msg.PluginUpdate;
 31import org.gjt.sp.jedit.msg.PropertiesChanged;
 32import org.gjt.sp.jedit.msg.ViewUpdate;
 33import org.gjt.sp.jedit.textarea.JEditTextArea;
 34
 35import java.util.HashMap;
 36import java.util.HashSet;
 37import java.util.Iterator;
 38import java.util.Map;
 39import java.util.Set;
 40import java.util.concurrent.Executor;
 41import java.util.concurrent.Executors;
 42import javax.swing.SwingWorker;
 43//}}}
 44
 45/**
 46 * SideKick plugin core class
 47 * Manages a mapping of View to SideKick instances, creating/destroying
 48 * SideKick objects whenever Views are created/destroyed.  
 49 * 
 50 * @version $Id: SideKickPlugin.java 20353 2011-11-16 08:04:45Z kpouer $
 51 */
 52public class SideKickPlugin extends EditPlugin
 53{
 54	private static final String MARKER_SETS_PLUGIN = "marker.MarkerSetsPlugin";
 55	private static final String SHOW_TOOL_BAR = "sidekick.showToolBar";
 56
 57	/** The name of the dockable */
 58	public static final String NAME = "sidekick-tree";
 59	
 60	//{{{ Some constants
 61	public static final String PARSER_MODE_PROPERTY = "sidekick.parser-mode";
 62	public static final String PARSER_PROPERTY = "sidekick.parser";
 63	public static final String PARSED_DATA_PROPERTY = "sidekick.parsed-data";
 64	public static final String PARSE_COUNT = "sidekick.parse-count";
 65	//}}}
 66	public static final String NONE="None";
 67	public static final String DEFAULT = "default parser";
 68
 69	//{{{ Private members
 70	private static final String MACRO_PATH = "/macros";
 71	private static Map<View, SideKick> sidekicks;
 72	private static Map<String, SideKickParser> parsers;
 73	private static Executor executor;
 74	private static Set<Buffer> parsedBufferSet;
 75	private static Map<View, SideKickToolBar> toolBars;
 76	private static boolean toolBarsEnabled;
 77	private static Map<View, SwingWorker<SideKickParsedData, Object>> workers;
 78	private static EditPlugin markerSetsPlugin;
 79
 80	//{{{ start() method
 81	public void start()
 82	{
 83		BeanShell.getNameSpace().addCommandPath(MACRO_PATH, getClass());
 84		markerSetsPlugin = jEdit.getPlugin(MARKER_SETS_PLUGIN, false);
 85		sidekicks = new HashMap<View, SideKick>();
 86		parsers = new HashMap<String, SideKickParser>();
 87		workers = new HashMap<View, SwingWorker<SideKickParsedData, Object>>();
 88		parsedBufferSet = new HashSet<Buffer>();
 89		toolBars = new HashMap<View, SideKickToolBar>();
 90		toolBarsEnabled = jEdit.getBooleanProperty(SHOW_TOOL_BAR);
 91		View view = jEdit.getFirstView();
 92		while(view != null)
 93		{
 94			initView(view);
 95			EditPane[] panes = view.getEditPanes();
 96			for(int i = 0; i < panes.length; i++)
 97				initTextArea(panes[i].getTextArea());
 98			view = view.getNext();
 99		}
100		jEdit.addActionSet(SideKickMenuProvider.getParserSwitchers());
101		SideKickActions.propertiesChanged();
102		EditBus.addToBus(this);
103	} //}}}
104
105	//{{{ stop() method
106	public void stop()
107	{
108		EditBus.removeFromBus(this);
109		jEdit.removeActionSet(SideKickMenuProvider.getParserSwitchers());
110		View view = jEdit.getFirstView();
111		while(view != null)
112		{
113			uninitView(view);
114			SideKickParsedData.setParsedData(view,null);
115
116			EditPane[] panes = view.getEditPanes();
117			for(int i = 0; i < panes.length; i++)
118				uninitTextArea(panes[i].getTextArea());
119			view = view.getNext();
120		}
121		
122		Buffer buffer = jEdit.getFirstBuffer();
123		while(buffer != null)
124		{
125			buffer.setProperty(PARSED_DATA_PROPERTY,null);
126			buffer = buffer.getNext();
127		}
128		sidekicks = null;
129		parsers = null;
130		parsedBufferSet = null;
131		toolBars = null;
132		workers = null;
133	} //}}}
134
135	//{{{ handleViewUpdate() method
136	@EBHandler
137	public void handleViewUpdate(ViewUpdate vu)
138	{
139		View view = vu.getView();
140
141		if(vu.getWhat() == ViewUpdate.CREATED)
142			initView(view);
143		else if(vu.getWhat() == ViewUpdate.CLOSED)
144			uninitView(view);
145	} //}}}
146
147	//{{{ handleEditPaneUpdate() method
148	@EBHandler
149	public void handleEditPaneUpdate(EditPaneUpdate epu)
150	{
151		EditPane editPane = epu.getEditPane();
152
153		if(epu.getWhat() == EditPaneUpdate.CREATED)
154			initTextArea(editPane.getTextArea());
155		else if(epu.getWhat() == EditPaneUpdate.DESTROYED)
156			uninitTextArea(editPane.getTextArea());
157	} //}}}
158
159	//{{{ handleBufferUpdate() method
160	@EBHandler
161	public void handleBufferUpdate(BufferUpdate bu)
162	{
163		if(bu.getWhat() == BufferUpdate.CLOSED)
164			finishParsingBuffer(bu.getBuffer());
165	} //}}}
166
167	//{{{ handlePropertiesChanged() method
168	@EBHandler
169	public void handlePropertiesChanged(PropertiesChanged msg)
170	{
171		SideKickActions.propertiesChanged();
172		boolean showToolBar = jEdit.getBooleanProperty(SHOW_TOOL_BAR);
173		if (showToolBar != toolBarsEnabled)
174		{
175			toolBarsEnabled = showToolBar;
176			for (View v: jEdit.getViews())
177			{
178				if (toolBarsEnabled)
179					attachToolBar(v);
180				else
181					detachToolBar(v);
182			}
183		}
184	} //}}}
185
186    // {{{ handlePluginUpdate() method
187    @EBHandler
188    public void handlePluginUpdate(PluginUpdate msg)
189    {
190    	EditPlugin plugin = msg.getPluginJAR().getPlugin();
191    	if (plugin == null)
192    		return;
193    	if (plugin.getClassName().equals(MARKER_SETS_PLUGIN))
194    	{
195            if (msg.getWhat() == PluginUpdate.ACTIVATED)
196            	markerSetsPlugin = plugin;
197            else if (msg.getWhat() == PluginUpdate.DEACTIVATED)
198            	markerSetsPlugin = null;
199    	}
200    } //}}}
201
202    // {{{ getMarkerSetsPlugin() method
203    public static EditPlugin getMarkerSetsPlugin()
204    {
205    	return markerSetsPlugin;
206    } //}}}
207
208	/**
209	 * Returns the parser for the given mode.
210	 *
211	 * @param m the mode (it must not be null)
212	 * @return the parser associated to this mode (or null if there is no parser)
213	 */
214	public static SideKickParser getParserForMode(Mode m) {
215		String modeStr = m.getName();
216		String propName = "mode." + modeStr + '.' + SideKickPlugin.PARSER_PROPERTY;
217		String parserName = jEdit.getProperty(propName);
218
219		if (parserName == null)
220			return null;
221		
222		SideKickParser parser = (SideKickParser) ServiceManager.getService(
223			SideKickParser.SERVICE, parserName);
224		return parser;
225	}
226	
227
228	//{{{ getParser() method
229	/**
230	 * @param name - the name of the parser, as defined in services.xml
231	 */
232	public static SideKickParser getParser(String name)
233	{
234		SideKickParser parser = (SideKickParser)ServiceManager
235			.getService(SideKickParser.SERVICE,name);
236		if(parser != null)
237			return parser;
238		else
239			return parsers.get(name);
240	} //}}}
241
242	//{{{ getParserForView() method
243	public static SideKickParser getParserForView(View view)
244	{
245		SideKick sidekick = sidekicks.get(view);
246		if(sidekick == null)
247			return null;
248		else
249			return sidekick.getParser();
250	} //}}}
251
252	/**
253	 * 
254	 * @param buffer
255	 * @param parserName the new parser we want to use
256	 * @since Sidekick 0.6
257	 */
258	public static void setParserForBuffer(Buffer buffer, String parserName) 
259	{
260		if (parserName.equals(NONE) ) {
261			buffer.setStringProperty(PARSER_PROPERTY, parserName);
262			return;
263		}
264		if (parserName.equals(DEFAULT)) {
265			buffer.unsetProperty(PARSER_PROPERTY);
266			return;
267		}
268		SideKickParser newParser = getParser(parserName);
269		if (newParser != null) {
270			buffer.setStringProperty(PARSER_PROPERTY, parserName);
271		}
272		else throw new RuntimeException("Unknown parser: " + parserName);
273	}
274	
275	//{{{ getParserForBuffer() method
276	public static SideKickParser getParserForBuffer(Buffer buffer)
277	{
278		String parserName = buffer.getStringProperty(PARSER_PROPERTY);
279		Mode mode = buffer.getMode();
280		String modeName = (mode != null) ? mode.getName() : "";
281		buffer.setStringProperty(PARSER_MODE_PROPERTY, modeName);
282		if(parserName == null || parserName.equals(DEFAULT) || parserName.length() == 0) {
283			if (mode != null) 
284				return getParserForMode(mode);
285			else return null;
286		}
287		if (parserName.equals(NONE)) {
288			return null;
289		}
290		return getParser(parserName);
291	} //}}}
292
293	//{{{ parse() method
294	/**
295	 * Immediately begins parsing the current buffer in a background thread.
296	 * @param view The view
297	 * @param showParsingMessage Clear the tree and show a status message
298	 * there?
299	 */
300	public static void parse(View view, boolean showParsingMessage)
301	{
302		SideKick sidekick = sidekicks.get(view);
303		if (sidekick == null) return;
304		// Had to remove this 
305		sidekick.setParser(view.getBuffer());
306		sidekick.parse(showParsingMessage);
307	} //}}}
308
309	public static void execute(Runnable runnable)
310	{
311		if (executor == null)
312		{
313			executor = Executors.newSingleThreadExecutor();
314		}
315		executor.execute(runnable);
316	}
317	
318	public static void execute(View view, SwingWorker<SideKickParsedData, Object> worker) 
319	{
320		// QUESTION: there should be only one worker per view. Is it possible
321		// there could be more than one?
322		// ANSWER: No. 
323		workers.put(view, worker);
324		worker.execute();
325	}
326
327	public static void cleanup(View view)
328	{
329		workers.remove(view);
330	}
331
332	//{{{ isParsingBuffer()
333	public static boolean isParsingBuffer(Buffer buffer)
334	{
335		return parsedBufferSet.contains(buffer);
336	} //}}}
337
338	//{{{ Package-private members
339
340	//{{{ startParsingBuffer()
341	static void startParsingBuffer(Buffer buffer)
342	{
343		parsedBufferSet.add(buffer);
344	} //}}}
345
346	//{{{ finishParsingBuffer()
347	static void finishParsingBuffer(Buffer buffer)
348	{
349		parsedBufferSet.remove(buffer);
350	} //}}}
351
352	//}}}
353
354	//{{{ attachToolBar() method
355	private static void attachToolBar(View view)
356	{
357		SideKickToolBar toolBar = new SideKickToolBar(view);
358		view.addToolBar(toolBar);
359		toolBars.put(view, toolBar);
360	} //}}}
361
362	//{{{ detachToolBar() method
363	private static void detachToolBar(View view)
364	{
365		SideKickToolBar toolBar = toolBars.remove(view);
366		if (toolBar != null)
367		{
368			view.removeToolBar(toolBar);
369			toolBar.dispose();
370		}
371	} //}}}
372	
373	//{{{ initView() method
374	private static void initView(View view)
375	{
376		SideKick sideKick = new SideKick(view);
377		sidekicks.put(view, sideKick);
378		sideKick.parse(true);
379		if (toolBarsEnabled)
380			attachToolBar(view);
381	} //}}}
382
383	// {{{ getSideKick() method
384	static SideKick getSideKick(View v) {
385		return sidekicks.get(v);
386	}
387	// }}}
388	
389	//{{{ uninitView() method
390	private static void uninitView(View view)
391	{
392		SideKick sidekick = sidekicks.get(view);
393		sidekick.dispose();
394		sidekicks.remove(view);
395		stop(view);
396		workers.remove(view);
397		detachToolBar(view);
398	} //}}}
399
400	
401	
402	//{{{ initTextArea() method
403	private static void initTextArea(JEditTextArea textArea)
404	{
405		SideKickBindings b = new SideKickBindings();
406		textArea.putClientProperty(SideKickBindings.class,b);
407		textArea.addKeyListener(b);
408	} //}}}
409
410	//{{{ uninitTextArea() method
411	private static void uninitTextArea(JEditTextArea textArea)
412	{
413		SideKickBindings b = (SideKickBindings)
414			textArea.getClientProperty(
415			SideKickBindings.class);
416		textArea.putClientProperty(SideKickBindings.class,null);
417		textArea.removeKeyListener(b);
418		SideKickTree.CaretHandler caretHandler = (SideKickTree.CaretHandler) textArea.getClientProperty(SideKickTree.CaretHandler.class);
419		if (caretHandler != null)
420		{
421			textArea.putClientProperty(SideKickTree.CaretHandler.class, null);
422			textArea.removeCaretListener(caretHandler);
423		}
424	} //}}}
425
426	public static void stop(View view) {
427		SwingWorker<SideKickParsedData, Object> worker = workers.get(view);
428		if (worker != null && !worker.isCancelled() && !worker.isDone()) {
429			worker.cancel(true);	
430		}
431	}
432
433	//}}}
434}