Create the import wizard question checkbox properly
[egit/imyousuf.git] / org.spearce.egit.ui / src / org / spearce / egit / ui / Activator.java
blobfced6435c02260b7ddec45c79d2c0ee4d653cf1d
1 /*******************************************************************************
2 * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * See LICENSE for the full license text, also available.
8 *******************************************************************************/
9 package org.spearce.egit.ui;
11 import java.net.Authenticator;
12 import java.net.ProxySelector;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.LinkedHashSet;
16 import java.util.Set;
18 import org.eclipse.core.net.proxy.IProxyService;
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.core.resources.ResourcesPlugin;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IProgressMonitor;
24 import org.eclipse.core.runtime.IStatus;
25 import org.eclipse.core.runtime.Platform;
26 import org.eclipse.core.runtime.Status;
27 import org.eclipse.core.runtime.SubProgressMonitor;
28 import org.eclipse.core.runtime.jobs.ISchedulingRule;
29 import org.eclipse.core.runtime.jobs.Job;
30 import org.eclipse.jsch.core.IJSchService;
31 import org.eclipse.swt.graphics.Font;
32 import org.eclipse.ui.plugin.AbstractUIPlugin;
33 import org.eclipse.ui.themes.ITheme;
34 import org.osgi.framework.BundleContext;
35 import org.osgi.framework.ServiceReference;
36 import org.spearce.egit.core.project.RepositoryMapping;
37 import org.spearce.jgit.lib.IndexChangedEvent;
38 import org.spearce.jgit.lib.RefsChangedEvent;
39 import org.spearce.jgit.lib.Repository;
40 import org.spearce.jgit.lib.RepositoryListener;
41 import org.spearce.jgit.transport.SshSessionFactory;
43 /**
44 * This is a plugin singleton mostly controlling logging.
46 public class Activator extends AbstractUIPlugin {
47 private static Activator plugin;
49 /**
50 * @return the {@link Activator} singleton.
52 public static Activator getDefault() {
53 return plugin;
56 /**
57 * @return the id of the egit ui plugin
59 public static String getPluginId() {
60 return getDefault().getBundle().getSymbolicName();
63 /**
64 * Instantiate an error exception.
66 * @param message
67 * description of the error
68 * @param thr
69 * cause of the error or null
70 * @return an initialized {@link CoreException}
72 public static CoreException error(final String message, final Throwable thr) {
73 return new CoreException(new Status(IStatus.ERROR, getPluginId(), 0,
74 message, thr));
77 /**
78 * Log an error via the Eclipse logging routines.
80 * @param message
81 * @param thr
82 * cause of error
84 public static void logError(final String message, final Throwable thr) {
85 getDefault().getLog().log(
86 new Status(IStatus.ERROR, getPluginId(), 0, message, thr));
89 /**
90 * @param optionId
91 * name of debug option
92 * @return whether a named debug option is set
94 private static boolean isOptionSet(final String optionId) {
95 final String option = getPluginId() + optionId;
96 final String value = Platform.getDebugOption(option);
97 return value != null && value.equals("true");
101 * Log a debug message
103 * @param what
104 * message to log
106 public static void trace(final String what) {
107 if (getDefault().traceVerbose) {
108 System.out.println("[" + getPluginId() + "] " + what);
113 * Get the theme used by this plugin.
115 * @return our theme.
117 public static ITheme getTheme() {
118 return plugin.getWorkbench().getThemeManager().getCurrentTheme();
122 * Get a font known to this plugin.
124 * @param id
125 * one of our THEME_* font preference ids (see
126 * {@link UIPreferences});
127 * @return the configured font, borrowed from the registry.
129 public static Font getFont(final String id) {
130 return getTheme().getFontRegistry().get(id);
134 * Get a font known to this plugin, but with bold style applied over top.
136 * @param id
137 * one of our THEME_* font preference ids (see
138 * {@link UIPreferences});
139 * @return the configured font, borrowed from the registry.
141 public static Font getBoldFont(final String id) {
142 return getTheme().getFontRegistry().getBold(id);
145 private boolean traceVerbose;
146 private RCS rcs;
147 private RIRefresh refreshJob;
150 * Constructor for the egit ui plugin singleton
152 public Activator() {
153 plugin = this;
156 public void start(final BundleContext context) throws Exception {
157 super.start(context);
158 traceVerbose = isOptionSet("/trace/verbose");
159 setupSSH(context);
160 setupProxy(context);
161 setupRepoChangeScanner();
162 setupRepoIndexRefresh();
165 private void setupRepoIndexRefresh() {
166 refreshJob = new RIRefresh();
167 Repository.addAnyRepositoryChangedListener(refreshJob);
170 static class RIRefresh extends Job implements RepositoryListener {
172 RIRefresh() {
173 super("Git index refresh Job");
176 private Set<IProject> projectsToScan = new LinkedHashSet<IProject>();
178 @Override
179 protected IStatus run(IProgressMonitor monitor) {
180 IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
181 monitor.beginTask("Refreshing git managed projects", projects.length);
183 while (projectsToScan.size() > 0) {
184 IProject p;
185 synchronized (projectsToScan) {
186 if (projectsToScan.size() == 0)
187 break;
188 Iterator<IProject> i = projectsToScan.iterator();
189 p = i.next();
190 i.remove();
192 ISchedulingRule rule = p.getWorkspace().getRuleFactory().refreshRule(p);
193 try {
194 getJobManager().beginRule(rule, monitor);
195 p.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 1));
196 } catch (CoreException e) {
197 logError("Failed to refresh projects from index changes", e);
198 return new Status(IStatus.ERROR, getPluginId(), e.getMessage());
199 } finally {
200 getJobManager().endRule(rule);
203 monitor.done();
204 return Status.OK_STATUS;
207 public void indexChanged(IndexChangedEvent e) {
208 // Check the workspace setting "refresh automatically" setting first
209 if (!ResourcesPlugin.getPlugin().getPluginPreferences().getBoolean(
210 ResourcesPlugin.PREF_AUTO_REFRESH))
211 return;
213 IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
214 Set<IProject> toRefresh= new HashSet<IProject>();
215 for (IProject p : projects) {
216 RepositoryMapping mapping = RepositoryMapping.getMapping(p);
217 if (mapping != null && mapping.getRepository() == e.getRepository()) {
218 toRefresh.add(p);
221 synchronized (projectsToScan) {
222 projectsToScan.addAll(toRefresh);
224 if (projectsToScan.size() > 0)
225 schedule();
228 public void refsChanged(RefsChangedEvent e) {
229 // Do not react here
234 static class RCS extends Job {
235 RCS() {
236 super("Repository Change Scanner");
239 // FIXME, need to be more intelligent about this to avoid too much work
240 private static final long REPO_SCAN_INTERVAL = 10000L;
242 @Override
243 protected IStatus run(IProgressMonitor monitor) {
244 try {
245 // A repository can contain many projects, only scan once
246 // (a project could in theory be distributed among many
247 // repositories. We discard that as being ugly and stupid for
248 // the moment.
249 IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
250 monitor.beginTask("Scanning Git repositories for changes", projects.length);
251 Set<Repository> scanned = new HashSet<Repository>();
252 for (IProject p : projects) {
253 RepositoryMapping mapping = RepositoryMapping.getMapping(p);
254 if (mapping != null) {
255 Repository r = mapping.getRepository();
256 if (!scanned.contains(r)) {
257 if (monitor.isCanceled())
258 break;
259 trace("Scanning " + r + " for changes");
260 scanned.add(r);
261 ISchedulingRule rule = p.getWorkspace().getRuleFactory().modifyRule(p);
262 getJobManager().beginRule(rule, monitor);
263 try {
264 r.scanForRepoChanges();
265 } finally {
266 getJobManager().endRule(rule);
270 monitor.worked(1);
272 monitor.done();
273 trace("Rescheduling " + getName() + " job");
274 schedule(REPO_SCAN_INTERVAL);
275 } catch (Exception e) {
276 trace("Stopped rescheduling " + getName() + "job");
277 return new Status(
278 IStatus.ERROR,
279 getPluginId(),
281 "An error occurred while scanning for changes. Scanning aborted",
284 return Status.OK_STATUS;
288 private void setupRepoChangeScanner() {
289 rcs = new RCS();
290 rcs.schedule(RCS.REPO_SCAN_INTERVAL);
293 private void setupSSH(final BundleContext context) {
294 final ServiceReference ssh;
296 ssh = context.getServiceReference(IJSchService.class.getName());
297 if (ssh != null) {
298 SshSessionFactory.setInstance(new EclipseSshSessionFactory(
299 (IJSchService) context.getService(ssh)));
303 private void setupProxy(final BundleContext context) {
304 final ServiceReference proxy;
306 proxy = context.getServiceReference(IProxyService.class.getName());
307 if (proxy != null) {
308 ProxySelector.setDefault(new EclipseProxySelector(
309 (IProxyService) context.getService(proxy)));
310 Authenticator.setDefault(new EclipseAuthenticator(
311 (IProxyService) context.getService(proxy)));
315 public void stop(final BundleContext context) throws Exception {
316 trace("Trying to cancel " + rcs.getName() + " job");
317 rcs.cancel();
318 trace("Trying to cancel " + refreshJob.getName() + " job");
319 refreshJob.cancel();
321 rcs.join();
322 refreshJob.join();
324 trace("Jobs terminated");
325 super.stop(context);
326 plugin = null;