PageRenderTime 86ms CodeModel.GetById 50ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/bundles/plugins-trunk/InfoViewer/infoviewer/InfoViewerPlugin.java

#
Java | 456 lines | 364 code | 36 blank | 56 comment | 62 complexity | 82feb04c3041cf82fda0bba599f78c38 MD5 | raw file
  1/*
  2 * InfoViewerPlugin.java - an info viewer plugin for jEdit
  3 * Copyright (C) 1999-2002 Dirk Moebius
  4 * based on the original jEdit HelpViewer by Slava Pestov.
  5 *
  6 * This program is free software; you can redistribute it and/or
  7 * modify it under the terms of the GNU General Public License
  8 * as published by the Free Software Foundation; either version 2
  9 * of the License, or any later version.
 10 *
 11 * This program is distributed in the hope that it will be useful,
 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14 * GNU General Public License for more details.
 15 *
 16 * You should have received a copy of the GNU General Public License
 17 * along with this program; if not, write to the Free Software
 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 19 * 
 20 * Updated for Jedit 4.3 on 2005-09-09 by Alan Ezust
 21 * 
 22 */
 23
 24package infoviewer;
 25
 26import java.awt.Component;
 27import java.awt.Frame;
 28import java.awt.Window;
 29import java.lang.reflect.Constructor;
 30import java.lang.reflect.Method;
 31import java.net.URL;
 32import java.util.Vector;
 33
 34import javax.swing.JComponent;
 35import javax.swing.JFrame;
 36
 37import org.gjt.sp.jedit.Buffer;
 38import org.gjt.sp.jedit.EditPlugin;
 39import org.gjt.sp.jedit.GUIUtilities;
 40import org.gjt.sp.jedit.OperatingSystem;
 41import org.gjt.sp.jedit.OptionGroup;
 42import org.gjt.sp.jedit.View;
 43import org.gjt.sp.jedit.jEdit;
 44import org.gjt.sp.jedit.gui.DockableWindowManager;
 45import org.gjt.sp.jedit.gui.OptionsDialog;
 46import org.gjt.sp.jedit.help.HelpViewerInterface;
 47import org.gjt.sp.jedit.help.HelpViewer;
 48import org.gjt.sp.jedit.io.FileVFS;
 49import org.gjt.sp.util.Log;
 50
 51public class InfoViewerPlugin extends EditPlugin
 52{
 53
 54	// begin EditPlugin implementation
 55	public void start()
 56	{
 57
 58	}
 59
 60	static private boolean firstTime = true;
 61	public static void showHelp()
 62	{
 63		if (jEdit.getBooleanProperty("infoviewer.useforhelp")) 
 64		{
 65			View v = jEdit.getActiveView();
 66			DockableWindowManager dwm = v.getDockableWindowManager();
 67			dwm.showDockableWindow("helpviewer");
 68			if (firstTime) 
 69			{
 70				JComponent dockable = dwm.getDockable("helpviewer");
 71				dockable.setVisible(true);
 72				HelpViewerInterface viewer = (HelpViewerInterface) dockable;
 73				viewer.gotoURL("welcome.html", false, -1);
 74				firstTime = false;
 75			}
 76			dwm.showDockableWindow("helpviewer");
 77		}
 78		else new HelpViewer();
 79	}
 80	// end EditPlugin implementation
 81	/**
 82	 * Open selected text with preferred browser. The selected text should
 83	 * be an URL.
 84	 */
 85	public static void openSelectedText(View view)
 86	{
 87		String selection = view.getTextArea().getSelectedText();
 88
 89		if (selection == null)
 90			GUIUtilities.error(view, "infoviewer.error.noselection", null);
 91		else
 92			openURL(view, selection);
 93	}
 94
 95	/**
 96	 * Open current jEdit buffer with preferred browser.
 97	 */
 98	public static void openCurrentBuffer(View view)
 99	{
100		Buffer buffer = view.getBuffer();
101		String url = buffer.getPath();
102
103		if (buffer.getVFS() instanceof FileVFS)
104			url = "file:" + url;
105
106		if (buffer.isDirty())
107		{
108			int result = GUIUtilities.confirm(view, "notsaved", new String[] { buffer
109				.getName() }, javax.swing.JOptionPane.YES_NO_CANCEL_OPTION,
110				javax.swing.JOptionPane.WARNING_MESSAGE);
111
112			if (result == javax.swing.JOptionPane.YES_OPTION)
113				buffer.save(view, null);
114			else if (result != javax.swing.JOptionPane.NO_OPTION)
115				return;
116		}
117
118		openURL(view, url);
119	}
120
121	/**
122	 * Open an URL with the preferred browser.
123	 * 
124	 * @param view
125	 *                where to display error messages.
126	 * @param url
127	 *                the URL. If null or empty, open an empty browser
128	 *                window.
129	 */
130	public static void openURL(View view, String url)
131	{
132		String browsertype = jEdit.getProperty("infoviewer.browsertype");
133
134		if (url == null)
135			url = "";
136
137		if (url.startsWith("jeditresource:"))
138			browsertype = "internal";
139
140		Log.log(Log.DEBUG, InfoViewerPlugin.class, "(" +
141                 browsertype + "): openURL: "	+ url);
142
143		if ("external".equals(browsertype))
144			openURLWithOtherBrowser(view, url);
145		else if ("class".equals(browsertype))
146			openURLWithJavaMethod(view, url);
147		else if ("firefox".equals(browsertype))
148			openURLWithFirefox(view, url);
149		else
150			openURLWithInfoViewer(view, url);
151	}
152
153	public static void openURLWithInfoViewer(View view, String url)
154	{
155		DockableWindowManager mgr = view.getDockableWindowManager();
156		mgr.showDockableWindow("infoviewer");
157		InfoViewer iv = (InfoViewer) mgr.getDockable("infoviewer");
158		iv.gotoURL(url, true, 0);
159	}
160
161	public static void openURLWithFirefox(View view, String url)
162	{
163		String[] args = new String[4];
164		if (OperatingSystem.isWindows()) 
165		{
166			args[0]="cmd";
167			args[1]="/C";
168		} 
169		else 
170		{
171			args[0] = "sh";
172			args[1] = "-c";
173		}
174		args[2] = "firefox";
175		args[3] = url;
176		execProcess(view, args);
177	}
178
179	public static void openURLWithOtherBrowser(View view, String url)
180	{
181		String cmd = jEdit.getProperty("infoviewer.otherBrowser");
182		String[] args = convertCommandString(cmd, url);
183		execProcess(view, args);
184	}
185
186	public static void openURLWithJavaMethod(View view, String url)
187	{
188		String clazz = jEdit.getProperty("infoviewer.class");
189		String method = jEdit.getProperty("infoviewer.method");
190		Class c = null;
191		Object obj = null;
192
193		try
194		{
195			c = Class.forName(clazz);
196		}
197		catch (Throwable e)
198		{
199			GUIUtilities.error(view, "infoviewer.error.classnotfound",
200				new Object[] { clazz });
201			return;
202		}
203
204		if (method == null || (method != null && method.length() == 0))
205		{
206			// no method: try to find URL or String or empty
207			// constructor
208			Constructor constr = null;
209			try
210			{
211				constr = c.getConstructor(new Class[] { URL.class });
212				if (constr != null)
213					obj = constr.newInstance(new Object[] { new URL(url) });
214			}
215			catch (Exception ex)
216			{
217				Log.log(Log.DEBUG, InfoViewerPlugin.class, ex);
218			}
219
220			if (obj == null)
221			{
222				try
223				{
224					constr = c.getConstructor(new Class[] { String.class });
225					if (constr != null)
226						obj = constr.newInstance(new Object[] { url });
227				}
228				catch (Exception ex)
229				{
230					Log.log(Log.DEBUG, InfoViewerPlugin.class, ex);
231				}
232			}
233
234			if (obj == null)
235			{
236				try
237				{
238					constr = c.getConstructor(new Class[0]);
239					if (constr != null)
240						obj = constr.newInstance(new Object[0]);
241				}
242				catch (Exception ex)
243				{
244					Log.log(Log.DEBUG, InfoViewerPlugin.class, ex);
245				}
246			}
247
248			if (obj == null)
249			{
250				GUIUtilities.error(view, "infoviewer.error.classnotfound",
251					new Object[] { clazz });
252				return;
253			}
254		}
255		else
256		{
257			// there is a method name:
258			Method meth = null;
259			boolean ok = false;
260
261			try
262			{
263				meth = c.getDeclaredMethod(method, new Class[] { URL.class });
264				if (meth != null)
265				{
266					obj = meth.invoke(null, new Object[] { new URL(url) });
267					ok = true;
268				}
269			}
270			catch (Exception ex)
271			{
272				Log.log(Log.DEBUG, InfoViewerPlugin.class, ex);
273			}
274
275			if (!ok)
276			{
277				try
278				{
279					meth = c.getDeclaredMethod(method,
280						new Class[] { String.class });
281					if (meth != null)
282					{
283						obj = meth.invoke(null, new Object[] { url });
284						ok = true;
285					}
286				}
287				catch (Exception ex)
288				{
289					Log.log(Log.DEBUG, InfoViewerPlugin.class, ex);
290				}
291			}
292
293			if (!ok)
294			{
295				try
296				{
297					meth = c.getDeclaredMethod(method, new Class[0]);
298					if (meth != null)
299					{
300						obj = meth.invoke(null, new Object[0]);
301						ok = true;
302					}
303				}
304				catch (Exception ex)
305				{
306					Log.log(Log.DEBUG, InfoViewerPlugin.class, ex);
307				}
308			}
309
310			if (!ok)
311			{
312				GUIUtilities.error(view, "infoviewer.error.methodnotfound",
313					new Object[] { clazz, method });
314				return;
315			}
316		}
317
318		if (obj != null)
319		{
320			if (obj instanceof Window)
321			{
322				((Window) obj).setVisible(true);
323			}
324			else if (obj instanceof JComponent)
325			{
326				JFrame f = new JFrame("Infoviewer JWrapper");
327				f.getContentPane().add((JComponent) obj);
328				f.pack();
329				f.setVisible(true);
330			}
331			else if (obj instanceof Component)
332			{
333				Frame f = new Frame("Infoviewer Wrapper");
334				f.add((Component) obj);
335				f.pack();
336				f.setVisible(true);
337			}
338		}
339	}
340
341	/**
342	 * converts the command string, which may contain "$u" as placeholders
343	 * for an url, into an array of strings, tokenized at the space char.
344	 * Characters in the command string may be escaped with '\\', which in
345	 * the case of space prevents tokenization.
346	 * 
347	 * @param command
348	 *                the command string.
349	 * @param url
350	 *                the URL, as String.
351	 * @return the space separated parts of the command string, as array of
352	 *         Strings.
353	 */
354	private static String[] convertCommandString(String command, String url)
355	{
356		Vector args = new Vector();
357		StringBuffer arg = new StringBuffer();
358		boolean foundDollarU = false;
359		boolean inQuotes = false;
360		int end = command.length() - 1;
361
362		for (int i = 0; i <= end; i++)
363		{
364			char c = command.charAt(i);
365			switch (c)
366			{
367			case '$':
368				if (i == end)
369					arg.append(c);
370				else
371				{
372					char c2 = command.charAt(++i);
373					if (c2 == 'u')
374					{
375						arg.append(url);
376						foundDollarU = true;
377					}
378					else
379					{
380						arg.append(c);
381						arg.append(c2);
382					}
383				}
384				break;
385
386			case '"':
387				inQuotes = !inQuotes;
388				break;
389
390			case ' ':
391				if (inQuotes)
392					arg.append(c);
393				else
394				{
395					String newArg = arg.toString().trim();
396					if (newArg.length() > 0)
397						args.addElement(newArg);
398					arg = new StringBuffer();
399				}
400				break;
401
402			case '\\': // quote char, only for backwards
403					// compatibility
404				if (i == end)
405					arg.append(c);
406				else
407				{
408					char c2 = command.charAt(++i);
409					if (c2 != '\\')
410						arg.append(c);
411					arg.append(c2);
412				}
413				break;
414
415			default:
416				arg.append(c);
417				break;
418			}
419		}
420
421		String newArg = arg.toString().trim();
422		if (newArg.length() > 0)
423			args.addElement(newArg);
424
425		if (!foundDollarU && url.length() > 0)
426			args.addElement(url);
427
428		String[] result = new String[args.size()];
429		args.copyInto(result);
430
431		for (int i = 0; i < result.length; i++)
432			Log.log(Log.DEBUG, InfoViewerPlugin.class, "args[" + i + "]=" + result[i]);
433
434		return result;
435	}
436
437	private static void execProcess(View view, String[] args)
438	{
439		try
440		{
441			Runtime.getRuntime().exec(args);
442		}
443		catch (Exception ex)
444		{
445			StringBuffer buf = new StringBuffer();
446			for (int i = 0; i < args.length; i++)
447			{
448				buf.append(args[i]);
449				buf.append('\n');
450			}
451			GUIUtilities.error(view, "infoviewer.error.invokeBrowser", new Object[] {
452				ex, buf.toString() });
453		}
454	}
455
456}