Package org.eclipse.egit.core

Source Code of org.eclipse.egit.core.Activator$AutoShareProjects

/*******************************************************************************
* Copyright (C) 2008, 2013 Shawn O. Pearce <spearce@spearce.org> 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
*******************************************************************************/
package org.eclipse.egit.core;

import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.egit.core.internal.CoreText;
import org.eclipse.egit.core.internal.indexdiff.IndexDiffCache;
import org.eclipse.egit.core.internal.job.JobUtil;
import org.eclipse.egit.core.internal.trace.GitTraceLocation;
import org.eclipse.egit.core.op.ConnectProviderOperation;
import org.eclipse.egit.core.op.IgnoreOperation;
import org.eclipse.egit.core.project.GitProjectData;
import org.eclipse.egit.core.project.RepositoryFinder;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.egit.core.securestorage.EGitSecureStore;
import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.util.FS;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.debug.DebugOptionsListener;
import org.eclipse.team.core.RepositoryProvider;
import org.osgi.framework.BundleContext;

/**
* The plugin class for the org.eclipse.egit.core plugin. This
* is a singleton class.
*/
public class Activator extends Plugin implements DebugOptionsListener {
  private static Activator plugin;
  private static String pluginId;
  private RepositoryCache repositoryCache;
  private IndexDiffCache indexDiffCache;
  private RepositoryUtil repositoryUtil;
  private EGitSecureStore secureStore;
  private AutoShareProjects shareGitProjectsJob;
  private IResourceChangeListener preDeleteProjectListener;
  private IgnoreDerivedResources ignoreDerivedResourcesListener;

  /**
   * @return the singleton {@link Activator}
   */
  public static Activator getDefault() {
    return plugin;
  }

  /**
   * @return the name of this plugin
   */
  public static String getPluginId() {
    return pluginId;
  }

  /**
   * Utility to create an error status for this plug-in.
   *
   * @param message User comprehensible message
   * @param thr cause
   * @return an initialized error status
   */
  public static IStatus error(final String message, final Throwable thr) {
    return new Status(IStatus.ERROR, getPluginId(), 0,  message, thr);
  }

  /**
   * Utility method to log errors in the Egit plugin.
   * @param message User comprehensible message
   * @param thr The exception through which we noticed the error
   */
  public static void logError(final String message, final Throwable thr) {
    getDefault().getLog().log(
        new Status(IStatus.ERROR, getPluginId(), 0, message, thr));
  }

  /**
   * Construct the {@link Activator} singleton instance
   */
  public Activator() {
    Activator.setActivator(this);
  }

  private static void setActivator(Activator a) {
    plugin = a;
  }

  public void start(final BundleContext context) throws Exception {

    super.start(context);

    pluginId = context.getBundle().getSymbolicName();

    // we want to be notified about debug options changes
    Dictionary<String, String> props = new Hashtable<String, String>(4);
    props.put(DebugOptions.LISTENER_SYMBOLICNAME, pluginId);
    context.registerService(DebugOptionsListener.class.getName(), this,
        props);

    repositoryCache = new RepositoryCache();
    indexDiffCache = new IndexDiffCache();
    try {
      GitProjectData.reconfigureWindowCache();
    } catch (RuntimeException e) {
      logError(CoreText.Activator_ReconfigureWindowCacheError, e);
    }
    GitProjectData.attachToWorkspace(true);

    IEclipsePreferences node = InstanceScope.INSTANCE.getNode(Activator.getPluginId());
    String gitPrefix = node.get(GitCorePreferences.core_gitPrefix, null);
    if (gitPrefix != null)
      FS.DETECTED.setGitPrefix(new File(gitPrefix));

    repositoryUtil = new RepositoryUtil();

    secureStore = new EGitSecureStore(SecurePreferencesFactory.getDefault());

    registerAutoShareProjects();
    registerAutoIgnoreDerivedResources();
    registerPreDeleteResourceChangeListener();
  }

  private void registerPreDeleteResourceChangeListener() {
    if (preDeleteProjectListener == null) {
      preDeleteProjectListener = new IResourceChangeListener() {

        public void resourceChanged(IResourceChangeEvent event) {
          IResource resource = event.getResource();
          if (resource instanceof IProject) {
            IProject project = (IProject) resource;
            if (project.isAccessible()) {
              if (RepositoryProvider.getProvider(project) instanceof GitProvider) {
                IResource dotGit = project
                    .findMember(Constants.DOT_GIT);
                if (dotGit != null
                    && dotGit.getType() == IResource.FOLDER)
                  GitProjectData.reconfigureWindowCache();
              }
            } else {
              // bug 419706: project is closed - use java.io API
              IPath locationPath = project.getLocation();
              if (locationPath != null) {
                File locationDir = locationPath.toFile();
                File dotGit = new File(locationDir,
                    Constants.DOT_GIT);
                if (dotGit.exists() && dotGit.isDirectory()) {
                  GitProjectData.reconfigureWindowCache();
                }
              }
            }
          }
        }
      };
      ResourcesPlugin.getWorkspace().addResourceChangeListener(preDeleteProjectListener, IResourceChangeEvent.PRE_DELETE);
    }
  }

  public void optionsChanged(DebugOptions options) {
    // initialize the trace stuff
    GitTraceLocation.initializeFromOptions(options, isDebugging());
  }

  /**
   *  @return cache for Repository objects
   */
  public RepositoryCache getRepositoryCache() {
    return repositoryCache;
  }

  /**
   *  @return cache for index diffs
   */
  public IndexDiffCache getIndexDiffCache() {
    return indexDiffCache;
  }

  /**
   * @return the {@link RepositoryUtil} instance
   */
  public RepositoryUtil getRepositoryUtil() {
    return repositoryUtil;
  }

  /**
   * @return the secure store
   */
  public EGitSecureStore getSecureStore() {
    return secureStore;
  }

  public void stop(final BundleContext context) throws Exception {
    GitProjectData.detachFromWorkspace();
    repositoryCache = null;
    indexDiffCache.dispose();
    indexDiffCache = null;
    repositoryUtil.dispose();
    repositoryUtil = null;
    secureStore = null;
    super.stop(context);
    plugin = null;
    if (preDeleteProjectListener != null) {
      ResourcesPlugin.getWorkspace().removeResourceChangeListener(preDeleteProjectListener);
      preDeleteProjectListener = null;
    }
    if (ignoreDerivedResourcesListener != null) {
      ResourcesPlugin.getWorkspace().removeResourceChangeListener(
          ignoreDerivedResourcesListener);
      ignoreDerivedResourcesListener = null;
    }
    if (shareGitProjectsJob != null) {
      ResourcesPlugin.getWorkspace().removeResourceChangeListener(
          shareGitProjectsJob);
      shareGitProjectsJob = null;
    }
  }

  private void registerAutoShareProjects() {
    shareGitProjectsJob = new AutoShareProjects();
    ResourcesPlugin.getWorkspace().addResourceChangeListener(
        shareGitProjectsJob, IResourceChangeEvent.POST_CHANGE);
  }

  private static class AutoShareProjects implements
      IResourceChangeListener {

    private static int INTERESTING_CHANGES = IResourceDelta.ADDED
        | IResourceDelta.OPEN;

    public AutoShareProjects() {
      // empty
    }

    private boolean doAutoShare() {
      IEclipsePreferences d = DefaultScope.INSTANCE.getNode(Activator
          .getPluginId());
      IEclipsePreferences p = InstanceScope.INSTANCE.getNode(Activator
          .getPluginId());
      return p.getBoolean(GitCorePreferences.core_autoShareProjects, d
          .getBoolean(GitCorePreferences.core_autoShareProjects,
              true));
    }

    public void resourceChanged(IResourceChangeEvent event) {
      try {

        final Map<IProject, File> projects = new HashMap<IProject, File>();

        event.getDelta().accept(new IResourceDeltaVisitor() {
          public boolean visit(IResourceDelta delta)
              throws CoreException {
            return visitConnect(delta, projects);
          }
        });

        if (projects.size() > 0) {
          ConnectProviderOperation op = new ConnectProviderOperation(
              projects);
          JobUtil.scheduleUserJob(op,
              CoreText.Activator_AutoShareJobName,
              JobFamilies.AUTO_SHARE);
        }

      } catch (CoreException e) {
        Activator.logError(e.getMessage(), e);
        return;
      }
    }

    private boolean visitConnect(IResourceDelta delta,
        final Map<IProject, File> projects) throws CoreException {
      if (!doAutoShare())
        return false;
      if (delta.getKind() == IResourceDelta.CHANGED
          && (delta.getFlags() & INTERESTING_CHANGES) == 0)
        return true;
      final IResource resource = delta.getResource();
      if (!resource.exists() || !resource.isAccessible() ||
          resource.isLinked(IResource.CHECK_ANCESTORS))
        return false;
      if (resource.getType() != IResource.PROJECT)
        return true;
      if (RepositoryMapping.getMapping(resource) != null)
        return false;
      final IProject project = (IProject) resource;
      RepositoryProvider provider = RepositoryProvider
          .getProvider(project);
      // respect if project is already shared with another
      // team provider
      if (provider != null)
        return false;
      RepositoryFinder f = new RepositoryFinder(project);
      f.setFindInChildren(false);
      Collection<RepositoryMapping> mappings = f.find(new NullProgressMonitor());
      if (mappings.size() != 1)
        return false;

      RepositoryMapping m = mappings.iterator().next();
      IPath gitDirPath = m.getGitDirAbsolutePath();
      if (gitDirPath.segmentCount() == 0)
        return false;

      IPath workingDir = gitDirPath.removeLastSegments(1);
      // Don't connect "/" or "C:\"
      if (workingDir.isRoot())
        return false;

      File userHome = FS.DETECTED.userHome();
      if (userHome != null) {
        Path userHomePath = new Path(userHome.getAbsolutePath());
        // Don't connect "/home" or "/home/username"
        if (workingDir.isPrefixOf(userHomePath))
          return false;
      }

      // connect
      final File repositoryDir = gitDirPath.toFile();
      projects.put(project, repositoryDir);

      try {
        Activator.getDefault().getRepositoryUtil()
            .addConfiguredRepository(repositoryDir);
      } catch (IllegalArgumentException e) {
        logError(CoreText.Activator_AutoSharingFailed, e);
      }
      return false;
    }
  }

  private void registerAutoIgnoreDerivedResources() {
    ignoreDerivedResourcesListener = new IgnoreDerivedResources();
    ResourcesPlugin.getWorkspace().addResourceChangeListener(
        ignoreDerivedResourcesListener,
        IResourceChangeEvent.POST_CHANGE);
  }

  private static class IgnoreDerivedResources implements
      IResourceChangeListener {

    protected boolean autoIgnoreDerived() {
      IEclipsePreferences d = DefaultScope.INSTANCE.getNode(Activator
          .getPluginId());
      IEclipsePreferences p = InstanceScope.INSTANCE.getNode(Activator
          .getPluginId());
      return p.getBoolean(
          GitCorePreferences.core_autoIgnoreDerivedResources,
          d.getBoolean(
              GitCorePreferences.core_autoIgnoreDerivedResources,
              true));
    }

    public void resourceChanged(IResourceChangeEvent event) {
      try {
        IResourceDelta d = event.getDelta();
        if (d == null || !autoIgnoreDerived())
          return;

        final Set<IPath> toBeIgnored = new LinkedHashSet<IPath>();

        d.accept(new IResourceDeltaVisitor() {

          public boolean visit(IResourceDelta delta)
              throws CoreException {
            if ((delta.getKind() & (IResourceDelta.ADDED | IResourceDelta.CHANGED)) == 0)
              return false;
            int flags = delta.getFlags();
            if ((flags != 0)
                && ((flags & IResourceDelta.DERIVED_CHANGED) == 0))
              return false;

            final IResource r = delta.getResource();
            // don't consider resources contained in a project not
            // shared with Git team provider
            if ((r.getProject() != null)
                && (RepositoryMapping.getMapping(r) == null))
              return false;
            if (r.isTeamPrivateMember())
              return false;

            if (r.isDerived()) {
              try {
                if (!RepositoryUtil.isIgnored(r.getLocation()))
                  toBeIgnored.add(r.getLocation());
              } catch (IOException e) {
                logError(
                    MessageFormat.format(
                        CoreText.Activator_ignoreResourceFailed,
                        r.getFullPath()), e);
              }
              return false;
            }
            return true;
          }
        });
        if (toBeIgnored.size() > 0)
          JobUtil.scheduleUserJob(new IgnoreOperation(toBeIgnored),
              CoreText.Activator_autoIgnoreDerivedResources,
              JobFamilies.AUTO_IGNORE);
      } catch (CoreException e) {
        Activator.logError(e.getMessage(), e);
        return;
      }
    }
  }
}
TOP

Related Classes of org.eclipse.egit.core.Activator$AutoShareProjects

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.