Package org.rssowl.ui.internal

Source Code of org.rssowl.ui.internal.Activator

/*   **********************************************************************  **
**   Copyright notice                                                       **
**                                                                          **
**   (c) 2005-2006 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.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.rssowl.core.Owl;
import org.rssowl.core.internal.InternalOwl;
import org.rssowl.core.util.LoggingSafeRunnable;
import org.rssowl.core.util.LongOperationMonitor;

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):\\/\\/[\\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;

  /**
   * 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);

    /*
     * 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 {
            Controller.getDefault().shutdown(true);
          }
        });

        /* Shutdown Core */
        SafeRunner.run(new LoggingSafeRunnable() {
          public void run() throws Exception {
            Owl.getPersistenceService().shutdown(true);
          }
        });
      }
    };
    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 {
        Controller.getDefault().startup();
      }
    });

    /* Propagate post-ui startup to Controller */
    SafeRunner.run(new LoggingSafeRunnable() {
      public void run() throws Exception {
        Display.getDefault().asyncExec(new Runnable() {
          public void run() {
            Controller.getDefault().postUIStartup();
          }
        });
      }
    });
  }

  private void startCore() {

    /* Dialog to show progress */
    final ProgressMonitorDialog dialog = new ProgressMonitorDialog(new Shell(Display.getDefault())) {
      @Override
      protected Point getInitialLocation(Point initialSize) {
        Rectangle displayBounds = getParentShell().getDisplay().getPrimaryMonitor().getBounds();
        Point shellSize = getInitialSize();
        int x = displayBounds.x + (displayBounds.width - shellSize.x) >> 1;
        int y = displayBounds.y + (displayBounds.height - shellSize.y) >> 1;

        return new Point(x, y);
      }
    };
    dialog.setOpenOnRun(false);

    /* Runnable to start core */
    IRunnableWithProgress runnable = new IRunnableWithProgress() {
      public void run(IProgressMonitor monitor) {
        LongOperationMonitor callbackMonitor = new LongOperationMonitor(monitor) {
          @Override
          public void beginLongOperation() {
            Display.getDefault().syncExec(new Runnable() {
              public void run() {
                dialog.open();
              }
            });
          }
        };

        /* Start Core */
        InternalOwl.getDefault().startup(callbackMonitor);
      }
    };

    /* Execute the Runnable */
    try {
      dialog.run(false, false, runnable);
    } catch (InvocationTargetException e) {
      Activator.getDefault().logError(e.getMessage(), e);
    } catch (InterruptedException e) {
      Activator.getDefault().logError(e.getMessage(), e);
    }
  }

  /* 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) {
      Activator.getDefault().logError("handleSocketBound()", e);
    } catch (IOException e) {
      Activator.getDefault().logError("handleSocketBound()", 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 {
        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 AbstractUIPlugin.imageDescriptorFromPlugin("org.rssowl.ui", path); //$NON-NLS-1$
  }

  /**
   * Log an Info Message.
   *
   * @param msg The message to log as Info.
   */
  public void logInfo(@SuppressWarnings("unused")
  String msg) {
  // TODO Need a better logging facility here
  // getLog().log(new Status(IStatus.INFO, 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 void logError(String msg, Exception e) {
    if (msg == null)
      msg = ""; //$NON-NLS-1$

    getLog().log(new Status(IStatus.ERROR, getBundle().getSymbolicName(), IStatus.ERROR, 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);
  }
}
TOP

Related Classes of org.rssowl.ui.internal.Activator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.