Package ccw

Source Code of ccw.CCWPlugin

/*******************************************************************************
* Copyright (c) 2009 Casey Marshall and others.
* 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.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    Casey Marshall  - initial API and implementation
*    Thomas Ettinger - paren matching generic code
*    Stephan Muehlstrasser - preference support for syntax coloring
*******************************************************************************/
package ccw;

import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.FontRegistry;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.resource.StringConverter;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.texteditor.ChainedPreferenceStore;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;

import ccw.editors.clojure.IScanContext;
import ccw.launching.LaunchUtils;
import ccw.nature.AutomaticNatureAdder;
import ccw.preferences.PreferenceConstants;
import ccw.preferences.SyntaxColoringHelper;
import ccw.repl.REPLView;
import ccw.repl.SafeConnection;
import ccw.util.BundleUtils;
import ccw.util.DisplayUtil;
import ccw.util.ITracer;
import ccw.util.NullTracer;
import ccw.util.Tracer;
import clojure.lang.Keyword;
import clojure.lang.Var;

/**
* The activator class controls the plug-in life cycle
*/
public class CCWPlugin extends AbstractUIPlugin {

    /** The plug-in ID */
    public static final String PLUGIN_ID = "ccw.core";
   
    /** Leiningen project nature */
    public static final String LEININGEN_NATURE_ID = "ccw.leiningen.nature";

    /**
     * @param swtKey a key from SWT.COLOR_xxx
     * @return a system managed color (callers must not dispose
     *         the color themselves)
     */
  public static Color getSystemColor(int swtKey) {
    return Display.getDefault().getSystemColor(swtKey);
  }
 
 
  //SHOULD LOG INFO / WARN / ERROR WHEN THE APPROPRIATE FLAGS ARE SET SO THAT ONE DOES NOT HAVE
  //TO GO FROM ONE FILE TO ANOTHER
  //ALSO CONSIDER VARIANTS FOR STACKTRACE,
  //RAW STRING (no format), etc.
 
    /** The shared instance */
    private static CCWPlugin plugin;

    private ColorRegistry colorCache;
   
    private FontRegistry fontRegistry;
   
    private ServerSocket ackREPLServer;
   
  private AutomaticNatureAdder synchronizedNatureAdapter;

  private ITracer tracer = NullTracer.INSTANCE;
 
  public static ITracer getTracer() {
    CCWPlugin plugin = getDefault();
    if (plugin != null && plugin.tracer != null)
      return plugin.tracer;
    else
      return NullTracer.INSTANCE;
  }
   
    public synchronized void startREPLServer() {
      if (ackREPLServer == null) {
          try {
            // TODO use ClojureOSGi.withBundle instead
            Var startServer = BundleUtils.requireAndGetVar(getBundle().getSymbolicName(), "clojure.tools.nrepl.server/start-server");
            Object defaultHandler = BundleUtils.requireAndGetVar(
                    getBundle().getSymbolicName(),
                    "clojure.tools.nrepl.server/default-handler").invoke();
            Object handler = BundleUtils.requireAndGetVar(
                    getBundle().getSymbolicName(),
                    "clojure.tools.nrepl.ack/handle-ack").invoke(defaultHandler);
              ackREPLServer = (ServerSocket)((Map)startServer.invoke(Keyword.intern("handler"), handler)).get(Keyword.intern("server-socket"));
              CCWPlugin.log("Started ccw nREPL server: nrepl://127.0.0.1:" + ackREPLServer.getLocalPort());
          } catch (Exception e) {
              CCWPlugin.logError("Could not start plugin-hosted REPL server", e);
              throw new RuntimeException("Could not start plugin-hosted REPL server", e);
          }
      }
    }
   
    public int getREPLServerPort() {
      if (ackREPLServer == null) {
        startREPLServer();
      }
      return ackREPLServer.getLocalPort();
    }

    public CCWPlugin() {
      System.out.println("CCWPlugin instanciated");
    }
   
    public void start(BundleContext context) throws Exception {
        super.start(context);
        System.out.println("CCWPlugin.start: ENTER");
        plugin = this;
       
        context.addBundleListener(new BundleListener() {
     
      @Override
      public void bundleChanged(BundleEvent evt) {
        if (evt.getBundle() == CCWPlugin.this.getBundle()
          &&  evt.getType() == BundleEvent.STARTED) {
         
          tracer = new Tracer(evt.getBundle().getBundleContext(), TraceOptions.getTraceOptions());
         
          // We immediately give control back to the OSGi framework application
          // by starting the code in a new thread
          new Thread(new Runnable() {
            @Override public void run() {
              // Some Eclipse plugins, such as LaunchingResourceManager
              // call PlatformUI.getWorbench() and checking for null,
              // even though null is not a valid return value
              // (instead, an exception is thrown), resulting
              // in the whole Eclipse to collapse.
                // Let's protect this code once and for all by ensuring
              // That the Workbench has been initialized before calling
              // the initialization code
              while(!PlatformUI.isWorkbenchRunning()) {
                try {
                  if (CCWPlugin.this.getBundle().getState()!=Bundle.ACTIVE)
                    return;
                  Thread.sleep(200);
                } catch (InterruptedException e) {
                  e.printStackTrace();
                }
              }

              // The Workbench may not be initialized, causing weird issues e.g. in Kepler
              // WorkbenchThemeManager.getInstance() in Kepler for instance does
              // not ensure the instance is created in the UI Thread
              // Once the Workbench is initialized, WorkbenchThemeManager & all
              // are ensured to be created, so this removes a bunch of plugin startup
              // race conditions
              final IWorkbench workbench = PlatformUI.getWorkbench();
              final AtomicBoolean isWorkbenchInitialized = new AtomicBoolean();
              while (true) {
                workbench.getDisplay().syncExec(new Runnable() {
                  @Override public void run() {
                    if (workbench.getActiveWorkbenchWindow() != null) {
                      // we've got an active window, so workbench is initialized!
                      isWorkbenchInitialized.set(true);
                    }
                  }});
                if (isWorkbenchInitialized.get()) {
                  break;
                } else {
                  try {
                    Thread.sleep(200);
                  } catch (InterruptedException e) {
                    e.printStackTrace();
                  }
                }
              }

              // Here, the workbench is initialized
                  if (System.getProperty("ccw.autostartnrepl") != null) {
                    try {
                  startREPLServer();
                } catch (Exception e) {
                  e.printStackTrace();
                }
                  }
                 
                  getNatureAdapter().start();
            }
           
          }).start();
        }
      }
    });
       

       
        System.out.println("CCWPlugin.start: EXIT");
    }
   
    private synchronized AutomaticNatureAdder getNatureAdapter() {
      if (synchronizedNatureAdapter == null) {
        synchronizedNatureAdapter = new AutomaticNatureAdder();
      }
      return synchronizedNatureAdapter;
    }
   
    private synchronized void createColorCache() {
      if (colorCache == null) {
        colorCache = new ColorRegistry(getWorkbench().getDisplay());
        colorCache.put("ccw.repl.expressionBackground", new RGB(0xf0, 0xf0, 0xf0));
      }
    }
   
    /**
     * Must be called from the UI thread only
     */
    public ColorRegistry getColorCache() {
      if (colorCache == null) {
        createColorCache();
      }
      return colorCache;
    }
   
    private synchronized void createFontRegistry() {
      if (fontRegistry == null) {
        DisplayUtil.syncExec(new Runnable() {
          public void run() {
            fontRegistry = new FontRegistry(getWorkbench().getDisplay());
           
                    // Forces initializations
                    fontRegistry.getItalic(""); // readOnlyFont
                    fontRegistry.getBold("");   // abstractFont
          }
        });
      }
    }

    private FontRegistry getFontRegistry() {
      if (fontRegistry == null) {
        createFontRegistry();
      }
      return fontRegistry;
    }

    public final Font getJavaSymbolFont() {
        return getFontRegistry().getItalic("");
    }

    private IPreferenceStore prefs;
   
    /**
     * Create a preference store combined from the Clojure, the EditorsUI and
     * the PlatformUI preference stores to inherit all the default text editor
     * settings from the Eclipse preferences.
     *
     * <p>Beware, the combined preference store can only be instanciated from the
     *    UI Thread.</p>
     *
     * @return the combined preference store.
     */
    public IPreferenceStore getCombinedPreferenceStore() {
        if (prefs == null) {
            prefs = new ChainedPreferenceStore(new IPreferenceStore[] {
                    CCWPlugin.getDefault().getPreferenceStore(),
                    EditorsUI.getPreferenceStore(),
                    PlatformUI.getPreferenceStore()});
        }
        return prefs;
    }

    public void stop(BundleContext context) throws Exception {
     
      // We don't remove colors when deregistered, because, well, we don't have a
      // corresponding method on the ColorRegistry instance!
      // We also don't remove fonts when deregistered
      stopREPLServer();
     
      this.getNatureAdapter().stop();
     
        plugin = null;
        super.stop(context);
    }
   
    private void stopREPLServer() {
      if (ackREPLServer != null) {
        try {
        ackREPLServer.close();
      } catch (IOException e) {
        logError("Error while trying to close ccw internal nrepl server", e);
      }
      }
    }
   
    /**
     * @return the shared instance
     */
    public static CCWPlugin getDefault() {
        return plugin;
    }

    public static void logError(String msg) {
      getTracer().trace(TraceOptions.LOG_ERROR, "ERROR  - " + msg);
        plugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, msg));
    }

    public static void logError(String msg, Throwable e) {
      getTracer().trace(TraceOptions.LOG_ERROR, e, "ERROR  - " + msg);
        plugin.getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, msg, e));
    }

    public static void logError(Throwable e) {
      getTracer().trace(TraceOptions.LOG_ERROR, e, "ERROR  - ");
        plugin.getLog().log(
                new Status(IStatus.ERROR, PLUGIN_ID, e.getMessage(), e));
    }
   
    public static IStatus createErrorStatus(String message, Throwable e) {
      return new Status(IStatus.ERROR, PLUGIN_ID, message, e);
    }

    public static IStatus createErrorStatus(String message) {
      return new Status(IStatus.ERROR, PLUGIN_ID, message);
    }
   
    public static void logWarning(String msg) {
      getTracer().trace(TraceOptions.LOG_WARNING, "WARNING - " + msg);
        plugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, msg));
    }

    public static void logWarning(String msg, Throwable e) {
      getTracer().trace(TraceOptions.LOG_WARNING, e, "WARNING - " + msg);
        plugin.getLog().log(new Status(IStatus.WARNING, PLUGIN_ID, msg, e));
    }

    public static void logWarning(Throwable e) {
      getTracer().trace(TraceOptions.LOG_WARNING, e);
        plugin.getLog().log(
                new Status(IStatus.WARNING, PLUGIN_ID, e.getMessage(), e));
    }

    public static void log (String msg) {
      getTracer().trace(TraceOptions.LOG_INFO, "INFO   - " + msg);
        plugin.getLog().log(new Status(IStatus.INFO, PLUGIN_ID, msg));
    }
   
    @Override
    protected void initializeImageRegistry(ImageRegistry reg) {
      reg.put(NS, ImageDescriptor.createFromURL(getBundle().getEntry("/icons/jdt/package_obj.gif")));
      reg.put(PUBLIC_FUNCTION, ImageDescriptor.createFromURL(getBundle().getEntry("/icons/jdt/methpub_obj.gif")));
        reg.put(PRIVATE_FUNCTION, ImageDescriptor.createFromURL(getBundle().getEntry("/icons/jdt/methpri_obj.gif")));
        reg.put(CLASS, ImageDescriptor.createFromURL(getBundle().getEntry("/icons/jdt/class_obj.gif")));
        reg.put(SORT, ImageDescriptor.createFromURL(getBundle().getEntry("/icons/jdt/alphab_sort_co.gif")));
    }
    public static final String NS = "icon.namespace";
    public static final String PUBLIC_FUNCTION = "icon.function.public";
    public static final String PRIVATE_FUNCTION = "icon.function.private";
  public static final String CLASS = "class_obj.gif";
  public static final String SORT = "alphab_sort_co.gif";

  public static boolean isAutoReloadOnStartupSaveEnabled() {
    return CCWPlugin.getDefault().getPreferenceStore().getBoolean(PreferenceConstants.CCW_GENERAL_AUTO_RELOAD_ON_STARTUP_SAVE);
  }
 
  public static boolean isAutoReloadOnStartupSaveEnabled(ILaunch launch) {
    return (Boolean.parseBoolean(launch.getAttribute(LaunchUtils.ATTR_IS_AUTO_RELOAD_ENABLED)));
  }
   
    public static REPLView[] getREPLViews() {
      final ArrayList<REPLView> ret = new ArrayList<REPLView>(5);
     
      DisplayUtil.syncExec(new Runnable() {
      public void run() {
            IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
            if (window != null) {
                IWorkbenchPage page = window.getActivePage();
                if (page != null) {
                    for (IViewReference r : page.getViewReferences()) {
                        IViewPart v = r.getView(false);
                        if (REPLView.class.isInstance(v)) {
                            ret.add((REPLView) v);
                        }
                    }
                }
            }
      }
    });
       
        return ret.toArray(new REPLView[ret.size()]);
    }

    public static REPLView getProjectREPL (final IProject project) {
      REPLView[] repls = getREPLViews();
     
      for (REPLView replView : repls) {
            ILaunch launch = replView.getLaunch();
            if (launch!=null && !launch.isTerminated()) {
                String launchProject = LaunchUtils.getProjectName(launch);
                if (launchProject != null && launchProject.equals(project.getName())) {
                  return replView;
                }
            }
        };
       
        return null;
    }
   
    public SafeConnection getProjectREPLSafeConnection (IProject project) {
        REPLView repl = getProjectREPL(project);
        return repl == null ? null : repl.getSafeToolingConnection();
    }
 
  private IScanContext scanContext;

  public synchronized IScanContext getDefaultScanContext() {
    if (scanContext == null) {
      scanContext = new StaticScanContext();
    }
    return scanContext;
  }
 
  public static RGB getPreferenceRGB(IPreferenceStore store, String preferenceKey, RGB defaultColor) {
      return
          store.getBoolean(SyntaxColoringHelper.getEnabledPreferenceKey(preferenceKey))
                ? PreferenceConverter.getColor(store, preferenceKey)
                : defaultColor;
  }
 
  /**
   * Not thread safe, but should only be called from the UI Thread, so it's
   * not really a problem.
   * @param rgb
   * @return The <code>Color</code> instance cached for this rgb value, creating
   *         it along the way if required.
   */
  public static Color getColor(RGB rgb) {
    ColorRegistry r = getDefault().getColorCache();
    String rgbString = StringConverter.asString(rgb);
    if (!r.hasValueFor(rgbString)) {
      r.put(rgbString, rgb);
    }
    return r.get(rgbString);
  }
 
  public static Color getPreferenceColor(IPreferenceStore store, String preferenceKey, RGB defaultColor) {
    return getColor(getPreferenceRGB(store, preferenceKey, defaultColor));
  }
 
    public static void registerEditorColors(IPreferenceStore store, RGB foregroundColor) {
        final ColorRegistry colorCache = getDefault().getColorCache();
       
        for (Keyword token: PreferenceConstants.colorizableTokens) {
          PreferenceConstants.ColorizableToken tokenStyle = PreferenceConstants.getColorizableToken(store, token, foregroundColor);
          colorCache.put(tokenStyle.rgb.toString(), tokenStyle.rgb);
        }
       
    }
   
  public static IWorkbenchPage getActivePage() {
    return getDefault().internalGetActivePage();
  }

    // copied from JavaPlugin
  private IWorkbenchPage internalGetActivePage() {
    IWorkbenchWindow window= getWorkbench().getActiveWorkbenchWindow();
    if (window == null)
      return null;
    return window.getActivePage();
  }
}
TOP

Related Classes of ccw.CCWPlugin

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.