package mobi.hsz.idea.vcswatch.core; import com.intellij.concurrency.JobScheduler; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.VcsRoot; import com.intellij.util.containers.ContainerUtil; import mobi.hsz.idea.vcswatch.requests.VcsWatchRequest; import mobi.hsz.idea.vcswatch.requests.VcsWatchRequestFactory; import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; /** * Manager that checks for the changes in the registered VCS repositories. * * @author Jakub Chrzanowski <jakub@hsz.mobi> * @since 0.1 */ public class VcsWatchManager { /** * TODO: don't use static delay */ private static final long DELAY = 600; /** * Project VCS manager. */ private final ProjectLevelVcsManager vcsManager; /** * An {@link java.util.concurrent.ExecutorService} that can schedule commands. */ private final ScheduledExecutorService scheduler; /** * List of the scheduled futures. */ private final List<ScheduledFuture<?>> scheduledFutureList = ContainerUtil.newArrayList(); /** * {@link OnCommitListener} event listeners list. */ private final List<OnCommitListener> onCommitListeners = ContainerUtil.newArrayList(); /** * Commits map. */ private final Map<String, Commit> commits = ContainerUtil.newHashMap(); private VcsWatchManager(@NotNull Project project) { this.vcsManager = ProjectLevelVcsManager.getInstance(project); this.scheduler = JobScheduler.getScheduler(); } public static VcsWatchManager getInstance(@NotNull Project project) { return ServiceManager.getService(project, VcsWatchManager.class); } /** * Fetches available project VCS roots and starts listening. */ public void init() { stop(); VcsRoot[] roots = vcsManager.getAllVcsRoots(); for (VcsRoot root : roots) { VcsWatchRequest request = VcsWatchRequestFactory.create(root); if (request != null) { // scheduledFutureList.add(scheduler.schedule(request, DELAY, TimeUnit.SECONDS)); scheduledFutureList.add(scheduler.scheduleWithFixedDelay(request, 0, DELAY, TimeUnit.SECONDS)); } } } /** * Cancels all elements from {#link #scheduledFutureList} and clears the list. */ public void stop() { for (ScheduledFuture<?> scheduledFuture : scheduledFutureList) { scheduledFuture.cancel(true); } scheduledFutureList.clear(); } /** * Adds new commit to the {@link #commits} stack if doesn't exist. * * @param commit to add */ public void add(@NotNull Commit commit) { if (!this.commits.containsKey(commit.getId())) { this.commits.put(commit.getId(), commit); for (OnCommitListener listener : onCommitListeners) { listener.onCommit(commit); } } } /** * Adds new {@link OnCommitListener}. * * @param listener to add */ public void setOnCommitListener(@NotNull OnCommitListener listener) { this.onCommitListeners.add(listener); } /** * Removes {@link OnCommitListener}. * * @param listener to remove */ public void removeOnCommitListener(@NotNull OnCommitListener listener) { this.onCommitListeners.remove(listener); } /** Listener that is fired when new {@link Commit} appears. */ public interface OnCommitListener { public void onCommit(@NotNull Commit commit); } }