/projects/rssowl-2.0.5/org.rssowl.ui/src/org/rssowl/ui/internal/Activator.java
Java | 509 lines | 289 code | 67 blank | 153 comment | 41 complexity | cc6e06dba08cf1d591c248ebebb9572a MD5 | raw file
- /* ********************************************************************** **
- ** Copyright notice **
- ** **
- ** (c) 2005-2009 RSSOwl Development Team **
- ** http://www.rssowl.org/ **
- ** **
- ** All rights reserved **
- ** **
- ** This program and the accompanying materials are made available under **
- ** the terms of the Eclipse Public License v1.0 which accompanies this **
- ** distribution, and is available at: **
- ** http://www.rssowl.org/legal/epl-v10.html **
- ** **
- ** A copy is found in the file epl-v10.html and important notices to the **
- ** license from the team is found in the textfile LICENSE.txt distributed **
- ** in this package. **
- ** **
- ** This copyright notice MUST APPEAR in all copies of the file! **
- ** **
- ** Contributors: **
- ** RSSOwl Development Team - initial API and implementation **
- ** **
- ** ********************************************************************** */
-
- package org.rssowl.ui.internal;
-
- import org.eclipse.core.runtime.CoreException;
- import org.eclipse.core.runtime.IProgressMonitor;
- import org.eclipse.core.runtime.ISafeRunnable;
- import org.eclipse.core.runtime.IStatus;
- import org.eclipse.core.runtime.Platform;
- import org.eclipse.core.runtime.SafeRunner;
- import org.eclipse.core.runtime.Status;
- import org.eclipse.jface.operation.IRunnableWithProgress;
- import org.eclipse.jface.resource.ImageDescriptor;
- import org.eclipse.swt.widgets.Display;
- import org.eclipse.ui.plugin.AbstractUIPlugin;
- import org.osgi.framework.BundleContext;
- import org.rssowl.core.Owl;
- import org.rssowl.core.util.CoreUtils;
- import org.rssowl.core.util.LoggingSafeRunnable;
- import org.rssowl.core.util.LongOperationMonitor;
- import org.rssowl.ui.internal.dialogs.StartupProgressDialog;
-
- import java.io.IOException;
- import java.io.OutputStreamWriter;
- import java.io.PrintWriter;
- import java.lang.reflect.InvocationTargetException;
- import java.net.BindException;
- import java.net.InetAddress;
- import java.net.MalformedURLException;
- import java.net.Socket;
- import java.net.URL;
- import java.net.UnknownHostException;
- import java.util.regex.Pattern;
-
- /**
- * The main plugin class to be used in the desktop.
- */
- public class Activator extends AbstractUIPlugin {
-
- /** ID of this Plugin */
- public static final String PLUGIN_ID = "org.rssowl.ui"; //$NON-NLS-1$
-
- /* The reg. expression for an URL */
- private static final String URL_REGEX = "(www([\\wv\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#])?)|(http|ftp|https|feed):\\/\\/[\\w]+(.[\\w]+)([\\wv\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#])?"; //$NON-NLS-1$
-
- /* The compiled pattern to match an URL */
- private static final Pattern URL_REGEX_PATTERN = Pattern.compile(URL_REGEX);
-
- /* Singleton Instance of this Plugin */
- private static Activator fgPlugin;
-
- private Thread fShutdownHook;
- private IStatus fStartupStatus = Status.OK_STATUS;
- private String fVersion;
- private String fNl;
-
- /**
- * The constructor.
- */
- public Activator() {
- fgPlugin = this;
- }
-
- /**
- * This method is called upon plug-in activation
- */
- @Override
- public void start(BundleContext context) throws Exception {
- super.start(context);
- fVersion = (String) fgPlugin.getBundle().getHeaders().get("Bundle-Version"); //$NON-NLS-1$
- fNl = System.getProperty("line.separator"); //$NON-NLS-1$
- if (fNl == null)
- fNl = "\n"; //$NON-NLS-1$
-
- /* Log Version Information */
- try {
- safeLogInfo("RSSOwl Starting Up (" + getUserAgent() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
- } catch (Exception e) {
- /* Something seriously went wrong using the Platform Log */
- }
-
- /*
- * Start internal Server (chance that System.exit() gets called!). It is cruicial
- * that no class from org.rssowl.core is loaded to avoid that a second instance
- * that is launching, starts up the core for a second time.
- */
- SafeRunner.run(new ISafeRunnable() {
- public void run() throws Exception {
- startServer();
- }
-
- public void handleException(Throwable e) {
- if (e instanceof CoreException)
- Activator.getDefault().getLog().log(((CoreException) e).getStatus());
- }
- });
-
- /* Register a Shutdown Hook */
- fShutdownHook = new Thread() {
- @Override
- public void run() {
-
- /* Shutdown UI */
- SafeRunner.run(new LoggingSafeRunnable() {
- public void run() throws Exception {
- if (Owl.isStarted() || Controller.isInitialized())
- Controller.getDefault().shutdown(true);
- }
- });
-
- /* Shutdown Core */
- SafeRunner.run(new LoggingSafeRunnable() {
- public void run() throws Exception {
- Owl.shutdown(true);
- }
- });
-
- /* Check for Log Message from Core */
- String logMessages = CoreUtils.getAndFlushLogMessages();
- if (logMessages != null && logMessages.length() > 0)
- safeLogError(logMessages, null);
-
- /* Log Shutdown Info */
- safeLogInfo("RSSOwl Shutting Down (emergency)" + fNl); //$NON-NLS-1$
- }
- };
- fShutdownHook.setPriority(Thread.MAX_PRIORITY);
- Runtime.getRuntime().addShutdownHook(fShutdownHook);
-
- /* Activate the Core Bundle */
- SafeRunner.run(new LoggingSafeRunnable() {
- public void run() throws Exception {
- startCore();
- }
- });
-
- /* Propagate startup to Controller */
- SafeRunner.run(new LoggingSafeRunnable() {
- public void run() throws Exception {
-
- /* Startup Controller */
- if (Owl.isStarted())
- Controller.getDefault().startup();
- }
- });
-
- /* Propagate post-ui startup to Controller (Eclipse Integration) */
- if (Application.IS_ECLIPSE) {
- SafeRunner.run(new LoggingSafeRunnable() {
- public void run() throws Exception {
- Display.getDefault().asyncExec(new Runnable() {
- public void run() {
- if (Owl.isStarted())
- Controller.getDefault().postWindowOpen();
- }
- });
- }
- });
- }
- }
-
- private void startCore() {
-
- /* Dialog to show progress */
- Display.setAppName("RSSOwl"); //$NON-NLS-1$
- Display.getDefault(); //Create the Display
- final StartupProgressDialog dialog = new StartupProgressDialog();
- dialog.setOpenOnRun(false);
-
- /* Runnable to start core */
- IRunnableWithProgress runnable = new IRunnableWithProgress() {
- public void run(IProgressMonitor monitor) {
- LongOperationMonitor callbackMonitor = new LongOperationMonitor(monitor) {
- private boolean updateUi = true;
-
- @Override
- public void beginLongOperation(boolean isCancelable) {
- if (!isLongOperationRunning()) {
- super.beginLongOperation(isCancelable);
- dialog.open();
- }
- }
-
- @Override
- public void worked(int work) {
- super.worked(work);
- if (updateUi)
- updateUi();
- }
-
- @Override
- public void subTask(String name) {
- super.subTask(name);
- if (updateUi)
- updateUi();
- }
-
- private void updateUi() {
- Display display = Display.getDefault();
- try {
- if (!isCanceled() && !display.isDisposed() && dialog.getShell() != null && !dialog.getShell().isDisposed()) {
- display.readAndDispatch();
- display.update();
- }
- }
-
- /*
- * Ensure to catch any Exception here and disable the update of the
- * UI given that the operation being performed can be a critical one.
- */
- catch (Exception e) {
- updateUi = false;
- logError(e.getMessage(), e);
- }
- }
- };
-
- /* Start Core */
- try {
- Owl.startup(callbackMonitor);
- }
-
- /* Handle OOM Error */
- catch (OutOfMemoryError e) {
- Activator.this.fStartupStatus = createErrorStatus(e.getMessage());
- Activator.getDefault().getLog().log(Activator.this.fStartupStatus);
- }
-
- /* Handle Exception (because any exception here is a show stopper) */
- catch (Exception e) {
- Activator.this.fStartupStatus = createErrorStatus(e.getMessage(), e);
- Activator.getDefault().getLog().log(Activator.this.fStartupStatus);
- }
- }
- };
-
- /* Execute the Runnable */
- try {
- dialog.run(false, true, runnable);
- } catch (InvocationTargetException e) {
- logError(e.getMessage(), e);
- } catch (InterruptedException e) {
- logError(e.getMessage(), e);
- }
- }
-
- IStatus getStartupStatus() {
- return fStartupStatus;
- }
-
- /* Start the Application Server */
- private void startServer() {
- ApplicationServer server = ApplicationServer.getDefault();
- try {
- server.startup();
- }
-
- /* Server alredady bound - perform hand-shake */
- catch (BindException e) {
- String link = parseLink(Platform.getCommandLineArgs());
- doHandshake(link);
- }
-
- /* Log any IOException */
- catch (IOException e) {
- logError(e.getMessage(), e);
- }
- }
-
- /* Return the first Link in this Array or NULL otherwise */
- private String parseLink(String[] commandLineArgs) {
- for (String arg : commandLineArgs) {
- if (looksLikeLink(arg))
- return arg;
- }
-
- return null;
- }
-
- /*
- * Return TRUE in case the given String looks like a Link.
- */
- private boolean looksLikeLink(String str) {
-
- /* Is empty or null? */
- if (!isSet(str))
- return false;
-
- /* Contains whitespaces ? */
- if (str.indexOf(' ') >= 0)
- return false;
-
- /* RegEx Link check */
- if (URL_REGEX_PATTERN.matcher(str).matches())
- return true;
-
- /* Try creating an URL object */
- try {
- new URL(str);
- } catch (MalformedURLException e) {
- return false;
- }
-
- /* String is an URL */
- return true;
- }
-
- /*
- * Returns TRUE in case the given String has a value that is not "" or <code>NULL</code>.
- */
- private boolean isSet(String str) {
- return (str != null && str.length() > 0);
- }
-
- /* Server already running. Pass a message to the running Server and exit. */
- private void doHandshake(String message) {
- try {
- Socket socket = new Socket(InetAddress.getByName(ApplicationServer.LOCALHOST), ApplicationServer.DEFAULT_SOCKET_PORT);
- PrintWriter writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
- writer.println(isSet(message) ? message : ApplicationServer.STARTUP_HANDSHAKE);
- writer.flush();
-
- /*
- * Send a message to the other running instance of RSSOwl and wait some
- * time, so that is has a chance to read the message. After that, the
- * other running instance will restore from taskbar or tray to show the
- * user. Then exit this instance consequently.
- */
- try {
- Thread.sleep(200);
- } catch (InterruptedException e) {
- System.exit(0);
- } finally {
- System.exit(0);
- }
- } catch (UnknownHostException e) {
- logError(Messages.Activator_ERROR_STARTUP, e);
- } catch (IOException e) {
- logError(Messages.Activator_ERROR_STARTUP, e);
- }
- }
-
- /**
- * This method is called when the plug-in is stopped
- */
- @Override
- public void stop(BundleContext context) throws Exception {
-
- /* Remove Shutdown Hook first that would run too otherwise */
- Runtime.getRuntime().removeShutdownHook(fShutdownHook);
-
- /* Propagate shutdown to Controller */
- SafeRunner.run(new LoggingSafeRunnable() {
- public void run() throws Exception {
- if (Owl.isStarted() || Controller.isInitialized())
- Controller.getDefault().shutdown(false);
- }
- });
-
- /* Proceed */
- super.stop(context);
- fgPlugin = null;
- }
-
- /**
- * Returns the shared instance.
- *
- * @return The shared instance.
- */
- public static Activator getDefault() {
- return fgPlugin;
- }
-
- /**
- * Returns an image descriptor for the image file at the given plug-in
- * relative path.
- *
- * @param path the path
- * @return the image descriptor
- */
- public static ImageDescriptor getImageDescriptor(String path) {
- return getImageDescriptor(PLUGIN_ID, path);
- }
-
- /**
- * Returns an image descriptor for the image file at the given plug-in
- * relative path.
- *
- * @param pluginId the ID of the plugin to load the image from.
- * @param path the path
- * @return the image descriptor
- */
- public static ImageDescriptor getImageDescriptor(String pluginId, String path) {
- return AbstractUIPlugin.imageDescriptorFromPlugin(pluginId, path);
- }
-
- /**
- * Log an Info Message.
- *
- * @param msg The message to log as Info.
- */
- public static void safeLogInfo(String msg) {
- Activator activator = fgPlugin;
- if (activator != null)
- activator.getLog().log(new Status(IStatus.INFO, activator.getBundle().getSymbolicName(), IStatus.OK, msg, null));
- }
-
- /**
- * Log an Error Message.
- *
- * @param msg The message to log as Error.
- * @param e The occuring Exception to log.
- */
- public static void safeLogError(String msg, Throwable e) {
- if (fgPlugin != null)
- fgPlugin.logError(msg, e);
- }
-
- /**
- * Log an Error Message.
- *
- * @param msg The message to log as Error.
- * @param e The occuring Exception to log.
- */
- public void logError(String msg, Throwable e) {
- if (msg == null)
- msg = ""; //$NON-NLS-1$
-
- getLog().log(new Status(IStatus.ERROR, getBundle().getSymbolicName(), IStatus.ERROR, msg, e));
- }
-
- /**
- * Log a Warning Message.
- *
- * @param msg The message to log as Warning.
- * @param e The occuring Exception to log.
- */
- public void logWarning(String msg, Exception e) {
- if (msg == null)
- msg = ""; //$NON-NLS-1$
-
- getLog().log(new Status(IStatus.WARNING, getBundle().getSymbolicName(), IStatus.WARNING, msg, e));
- }
-
- /**
- * Create a IStatus out of the given message and exception.
- *
- * @param msg The message describing the error.
- * @param e The Exception that occured.
- * @return An IStatus out of the given message and exception.
- */
- public IStatus createErrorStatus(String msg, Exception e) {
- return new Status(IStatus.ERROR, Activator.getDefault().getBundle().getSymbolicName(), IStatus.ERROR, msg, e);
- }
-
- /**
- * Create a IStatus out of the given message.
- *
- * @param msg The message describing the error.
- * @return An IStatus out of the given message and exception.
- */
- public IStatus createErrorStatus(String msg) {
- return new Status(IStatus.ERROR, Activator.getDefault().getBundle().getSymbolicName(), msg);
- }
-
- /**
- * Create a IStatus out of the given message and exception.
- *
- * @param msg The message describing the info.
- * @param e The Exception that occured.
- * @return An IStatus out of the given message and exception.
- */
- public IStatus createInfoStatus(String msg, Exception e) {
- return new Status(IStatus.INFO, Activator.getDefault().getBundle().getSymbolicName(), IStatus.INFO, msg, e);
- }
-
- private String getUserAgent() {
- String os = Platform.getOS();
- if (Platform.OS_WIN32.equals(os))
- return "RSSOwl/" + fVersion + " (Windows; U; en)"; //$NON-NLS-1$ //$NON-NLS-2$
- else if (Platform.OS_LINUX.equals(os))
- return "RSSOwl/" + fVersion + " (X11; U; en)"; //$NON-NLS-1$//$NON-NLS-2$
- else if (Platform.OS_MACOSX.equals(os))
- return "RSSOwl/" + fVersion + " (Macintosh; U; en)"; //$NON-NLS-1$ //$NON-NLS-2$
- return "RSSOwl/" + fVersion; //$NON-NLS-1$
- }
- }