Package org.cloudfoundry.ide.eclipse.server.core.internal

Source Code of org.cloudfoundry.ide.eclipse.server.core.internal.CloudFoundryPlugin

/*******************************************************************************
* Copyright (c) 2012, 2014 Pivotal Software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Apache License,
* Version 2.0 (the "License�); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*  Contributors:
*     Pivotal Software, Inc. - initial API and implementation
*     IBM - add appStateTracker extension support
********************************************************************************/
package org.cloudfoundry.ide.eclipse.server.core.internal;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.cloudfoundry.ide.eclipse.server.core.AbstractAppStateTracker;
import org.cloudfoundry.ide.eclipse.server.core.internal.client.CloudFoundryApplicationModule;
import org.cloudfoundry.ide.eclipse.server.core.internal.client.CloudFoundryClientFactory;
import org.cloudfoundry.ide.eclipse.server.core.internal.client.DeploymentConfiguration;
import org.cloudfoundry.ide.eclipse.server.core.internal.tunnel.CaldecottTunnelCache;
import org.cloudfoundry.ide.eclipse.server.core.internal.tunnel.CaldecottTunnelDescriptor;
import org.cloudfoundry.ide.eclipse.server.core.internal.tunnel.PredefinedServiceCommands;
import org.cloudfoundry.ide.eclipse.server.core.internal.tunnel.TunnelServiceCommandStore;
import org.eclipse.core.net.proxy.IProxyService;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.BundleContext;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.util.tracker.ServiceTracker;

/**
* @author Christian Dupuis
* @author Steffen Pingel
* @author Leo Dos Santos
* @author Terry Denney
*/
@SuppressWarnings("rawtypes")
public class CloudFoundryPlugin extends Plugin {

  // NOTE: Avoid adding API that accesses the plugin instance for CF
  // operations
  // (i.e. using CloudFoundryPlugin.getDefault()), as the plugin activator
  // may not always be available, in particular for background CF Eclipse jobs
  // that may
  // still be running while the workbench is shutting down. If adding API
  // to access the plugin instance (e.g. logging an error), always check
  // if the plugin activator is available (i.e not null)

  private static class ExtensionPointReader {

    private static final String ELEMENT_CALLBACK = "callback"; //$NON-NLS-1$

    private static final String ELEMENT_CLASS = "class"; //$NON-NLS-1$

    private static final String EXTENSION_ID_CALLBACK = PLUGIN_ID + ".callback"; //$NON-NLS-1$

    private static final String EXTENSION_ID_APP_STATE_TRACKER = "appStateTracker"; //$NON-NLS-1$

    public static CloudFoundryCallback readExtension() {
      IExtensionRegistry registry = Platform.getExtensionRegistry();
      IExtensionPoint extensionPoint = registry.getExtensionPoint(EXTENSION_ID_CALLBACK);
      IExtension[] extensions = extensionPoint.getExtensions();
      for (IExtension extension : extensions) {
        IConfigurationElement[] elements = extension.getConfigurationElements();
        for (IConfigurationElement element : elements) {
          if (element.getName().compareTo(ELEMENT_CALLBACK) == 0) {
            return readCallbackExtension(element);
          }
        }
      }
      return null;
    }

    private static CloudFoundryCallback readCallbackExtension(IConfigurationElement configurationElement) {
      try {
        Object object = configurationElement.createExecutableExtension(ELEMENT_CLASS);
        if (!(object instanceof CloudFoundryCallback)) {
          getDefault().getLog().log(
              new Status(IStatus.ERROR, PLUGIN_ID, "Could not load " //$NON-NLS-1$
                  + object.getClass().getCanonicalName() + " must implement " //$NON-NLS-1$
                  + CloudFoundryCallback.class.getCanonicalName()));
          return null;
        }

        return (CloudFoundryCallback) object;
      }
      catch (CoreException e) {
        getDefault().getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, "Could not load callback extension", e)); //$NON-NLS-1$
      }
      return null;
    }

    /**
     * Load the app state trackers.
     */
    private static synchronized void readAppStateTrackerExtension() {
      if (appStateTrackerEntries != null)
        return;

      // if (Trace.CONFIG) {
      // Trace.trace(Trace.STRING_CONFIG,
      // "->- Loading .appStateTracker extension point ->-");
      // }
      appStateTrackerEntries = new ArrayList<AppStateTrackerEntry>();
      IExtensionRegistry registry = Platform.getExtensionRegistry();
      IConfigurationElement[] cf = registry
          .getConfigurationElementsFor(PLUGIN_ID, EXTENSION_ID_APP_STATE_TRACKER);

      for (IConfigurationElement curConfigElement : cf) {
        // load the extension in a safe environment. If there are NPEs
        // or miss configurations they will be caught by try/catch
        String[] curServerTypeIds = tokenize(curConfigElement.getAttribute("serverTypeIds"), ","); //$NON-NLS-1$ //$NON-NLS-2$
        String[] curModuleTypeIds = tokenize(curConfigElement.getAttribute("moduleTypeIds"), ","); //$NON-NLS-1$ //$NON-NLS-2$
        appStateTrackerEntries.add(new AppStateTrackerEntry(curServerTypeIds, curModuleTypeIds,
            curConfigElement));
      }
      // if (Trace.CONFIG) {
      // Trace.trace(Trace.STRING_CONFIG,
      // "-<- Done loading .appStateTracker extension point -<-");
      // }
    }

    /**
     * Utility method to tokenize a string into an array.
     *
     * @param str a string to be parsed
     * @param delim the delimiters
     * @return an array containing the tokenized string
     */
    private static String[] tokenize(String str, String delim) {
      if (str == null)
        return new String[0];

      List<String> list = new ArrayList<String>();

      StringTokenizer st = new StringTokenizer(str, delim);
      while (st.hasMoreTokens()) {
        String s = st.nextToken();
        if (s != null && s.length() > 0)
          list.add(s.trim());
      }

      String[] s = new String[list.size()];
      list.toArray(s);
      return s;
    }
  }

  private static class NullCallback extends CloudFoundryCallback {

    @Override
    public void applicationStarted(CloudFoundryServer server, CloudFoundryApplicationModule cloudModule) {
      // ignore
    }

    @Override
    public void disconnecting(CloudFoundryServer server) {
      // ignore
    }

    @Override
    public void stopApplicationConsole(CloudFoundryApplicationModule cloudModule, CloudFoundryServer cloudServer) {

    }

    @Override
    public void getCredentials(CloudFoundryServer server) {
      throw new OperationCanceledException();
    }

    @Override
    public DeploymentConfiguration prepareForDeployment(CloudFoundryServer server,
        CloudFoundryApplicationModule module, IProgressMonitor monitor) throws CoreException {
      throw new OperationCanceledException();
    }

    @Override
    public void deleteServices(List<String> services, CloudFoundryServer server) {
      // ignore
    }

    @Override
    public void deleteApplication(CloudFoundryApplicationModule cloudModule, CloudFoundryServer cloudServer) {
      // ignore
    }

    @Override
    public void displayCaldecottTunnelConnections(CloudFoundryServer cloudServer,
        List<CaldecottTunnelDescriptor> descriptor) {
      // ignore
    }

    @Override
    public void applicationStarting(CloudFoundryServer server, CloudFoundryApplicationModule cloudModule) {
      // TODO Auto-generated method stub

    }
  }

  private static class AppStateTrackerEntry {
    private String[] serverTypeIds;

    private String[] moduleTypeIds;

    private IConfigurationElement configElement;

    private AppStateTrackerEntry(String[] curServerTypeIds, String[] curModuleTypeIds,
        IConfigurationElement curConfigElement) {
      serverTypeIds = curServerTypeIds;
      moduleTypeIds = curModuleTypeIds;
      configElement = curConfigElement;
    }

    private String[] getModuleTypeIds() {
      return moduleTypeIds;
    }

    private String[] getServerTypeIds() {
      return serverTypeIds;
    }

    private IConfigurationElement getConfigElement() {
      return configElement;
    }

    private AbstractAppStateTracker createAppStateTracker() {
      AbstractAppStateTracker tracker = null;
      try {
        tracker = (AbstractAppStateTracker) configElement.createExecutableExtension("class"); //$NON-NLS-1$
        // if (Trace.CONFIG) {
        // Trace.trace(Trace.STRING_CONFIG,
        // "  Loaded .appStateTracker: " +
        // curConfigElement.getAttribute("id")
        // + ", loaded class=" + tracker);
        // }
      }
      catch (Throwable t) {
        // if (Trace.SEVERE) {
        // Trace.trace(Trace.STRING_SEVERE,
        // "  Could not load .appStateTracker: " +
        // curConfigElement.getAttribute("id"), t);
        // }
        CloudFoundryPlugin.logError(("Internal Error: Failed to load application start tracker due to - " + t.getMessage()), t); //$NON-NLS-1$
      }
      return tracker;
    }
  }

  // public static final String CLOUD_CONTROLLER_DEFAULT_URL_ATTRIBUTE =
  // "cloudfoundry.cloudcontroller.url.default";

  public static final String PLUGIN_ID = "org.cloudfoundry.ide.eclipse.server.core"; //$NON-NLS-1$

  public static final String ENABLE_INCREMENTAL_PUBLISH_PREFERENCE = PLUGIN_ID + ".publish.incremental.properties"; //$NON-NLS-1$

  public static final boolean DEFAULT_INCREMENTAL_PUBLISH_PREFERENCE_VAL = true;

  private static CloudFoundryCallback callback;

  // Cached copy of app state tracker
  private static List<AppStateTrackerEntry> appStateTrackerEntries;

  private static ModuleCache moduleCache;

  private static CloudFoundryPlugin plugin;

  private static IProxyService proxyService;

  private DeployedResourceCache sha1Cache = new DeployedResourceCache();

  private InstanceScope INSTANCE_SCOPE = new InstanceScope();

  private static CaldecottTunnelCache caldecottCache = new CaldecottTunnelCache();

  private TunnelServiceCommandStore serviceCommandsStore;

  /**
   * Returns the app state tracker for a given server type. Only the first
   * matched tracker will be return in case there are multiple tracker defined
   * to support a particular server type.
   *
   * @return the app state tracker or null if no app state tracker has been
   * registered to support the given type.
   */
  public static AbstractAppStateTracker getAppStateTracker(String serverTypeId,
      CloudFoundryApplicationModule application) {
    if (serverTypeId == null || application == null || application.getLocalModule() == null) {
      return null;
    }

    if (appStateTrackerEntries == null) {
      ExtensionPointReader.readAppStateTrackerExtension();
    }

    String moduleTypeId = application.getLocalModule().getModuleType().getId();

    for (AppStateTrackerEntry curTrackerEntry : appStateTrackerEntries) {
      String[] curServerTypeIds = curTrackerEntry.getServerTypeIds();
      if (supportsType(serverTypeId, curServerTypeIds)) {
        String[] curModuleTypeIds = curTrackerEntry.getModuleTypeIds();
        if (supportsType(moduleTypeId, curModuleTypeIds)) {
          return curTrackerEntry.createAppStateTracker();
        }
      }
    }

    return null;
  }

  public static CaldecottTunnelCache getCaldecottTunnelCache() {
    return caldecottCache;
  }

  public static synchronized CloudFoundryCallback getCallback() {
    if (callback == null) {
      callback = ExtensionPointReader.readExtension();
      if (callback == null) {
        callback = new NullCallback();
      }
    }
    return callback;
  }

  public synchronized void setIncrementalPublish(boolean incrementalPublish) {
    IEclipsePreferences prefs = getPreferences();
    prefs.putBoolean(ENABLE_INCREMENTAL_PUBLISH_PREFERENCE, incrementalPublish);
    try {
      prefs.flush();
    }
    catch (BackingStoreException e) {
      logError(e);
    }
  }

  public synchronized boolean getIncrementalPublish() {
    return getPreferences().getBoolean(ENABLE_INCREMENTAL_PUBLISH_PREFERENCE,
        DEFAULT_INCREMENTAL_PUBLISH_PREFERENCE_VAL);
  }

  public IEclipsePreferences getPreferences() {
    return INSTANCE_SCOPE.getNode(PLUGIN_ID);
  }

  public synchronized DeployedResourceCache getDeployedResourcesCache() {
    return sha1Cache;
  }

  public static synchronized void setCallback(CloudFoundryCallback callback) {
    CloudFoundryPlugin.callback = callback;
  }

  public static CloudFoundryPlugin getDefault() {
    return plugin;
  }

  public static synchronized ModuleCache getModuleCache() {
    if (moduleCache == null) {
      moduleCache = new ModuleCache();
    }
    return moduleCache;
  }

  public synchronized TunnelServiceCommandStore getTunnelCommandsStore() {
    if (serviceCommandsStore == null) {
      serviceCommandsStore = new TunnelServiceCommandStore(new PredefinedServiceCommands());
    }
    return serviceCommandsStore;
  }

  private ServiceTracker tracker;

  private static CloudFoundryClientFactory factory;

  public CloudFoundryPlugin() {
  }

  /**
   * Returns a non-null client factory. A default factory is always used if a
   * factory has not been defined
   * @return non-null client factory
   */
  public static synchronized CloudFoundryClientFactory getCloudFoundryClientFactory() {
    if (factory == null) {
      factory = new CloudFoundryClientFactory();
    }
    return factory;
  }

  public static synchronized void setCloudFoundryClientFactory(CloudFoundryClientFactory factory) {
    CloudFoundryPlugin.factory = factory;
  }

  @SuppressWarnings("unchecked")
  public synchronized IProxyService getProxyService() {
    if (proxyService == null) {
      if (tracker == null) {
        tracker = new ServiceTracker(getBundle().getBundleContext(), IProxyService.class.getName(), null);
        tracker.open();
      }

      proxyService = (IProxyService) tracker.getService();
    }
    return proxyService;
  }

  @Override
  public void start(BundleContext context) throws Exception {
    super.start(context);
    plugin = this;
  }

  @Override
  public void stop(BundleContext context) throws Exception {
    if (tracker != null) {
      tracker.close();
      tracker = null;
    }

    if (moduleCache != null) {
      moduleCache.dispose();
      moduleCache = null;
    }

    plugin = null;
    super.stop(context);
  }

  private static boolean supportsType(String typeId, String[] supportedTypeIds) {
    if (typeId == null || typeId.length() == 0)
      return false;

    if (supportedTypeIds == null)
      return false;

    int size = supportedTypeIds.length;
    for (int i = 0; i < size; i++) {
      if (supportedTypeIds[i].endsWith("*")) { //$NON-NLS-1$
        if (typeId.length() >= supportedTypeIds[i].length()
            && typeId.startsWith(supportedTypeIds[i].substring(0, supportedTypeIds[i].length() - 1)))
          return true;
      }
      else if (typeId.equals(supportedTypeIds[i]))
        return true;
    }
    return false;
  }

  public static void trace(String string) {
    // System.err.println(string);
  }

  public static void log(CoreException ce) {
    log(ce.getStatus());
  }

  public static void logError(Throwable e) {
    log(getErrorStatus(e));
  }

  public static void logError(String message) {
    log(getErrorStatus(message));
  }

  public static void logError(String message, Throwable t) {
    log(getErrorStatus(message, t));
  }

  public static IStatus getErrorStatus(String message, Throwable t) {
    return new Status(IStatus.ERROR, PLUGIN_ID, message, t);
  }

  public static IStatus getErrorStatus(String message) {
    return new Status(IStatus.ERROR, PLUGIN_ID, message);
  }

  public static IStatus getStatus(String message, int type) {
    return new Status(type, PLUGIN_ID, message);
  }

  public static IStatus getErrorStatus(Throwable t) {
    return new Status(IStatus.ERROR, PLUGIN_ID, t.getMessage(), t);
  }

  public static void log(IStatus status) {
    if (plugin != null) {
      plugin.getLog().log(status);
    }
  }

  public static void logWarning(String message) {
    if (plugin != null && message != null) {
      plugin.getLog().log(getStatus(message, IStatus.WARNING));
    }
  }

}
TOP

Related Classes of org.cloudfoundry.ide.eclipse.server.core.internal.CloudFoundryPlugin

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.