/* * VcsState.java * * Copyright (C) 2009-12 by RStudio, Inc. * * Unless you have received this program directly from RStudio pursuant * to the terms of a commercial license agreement with RStudio, then * this program is licensed to you under the terms of version 3 of the * GNU Affero General Public License. This program is distributed WITHOUT * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT, * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details. * */ package org.rstudio.studio.client.workbench.views.vcs.common.model; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.RepeatingCommand; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.event.shared.HandlerManager; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.ui.Widget; import org.rstudio.core.client.HandlerRegistrations; import org.rstudio.core.client.StringUtil; import org.rstudio.core.client.WidgetHandlerRegistration; import org.rstudio.core.client.files.FileSystemItem; import org.rstudio.studio.client.application.events.EventBus; import org.rstudio.studio.client.common.GlobalDisplay; import org.rstudio.studio.client.common.vcs.StatusAndPath; import org.rstudio.studio.client.common.vcs.StatusAndPathInfo; import org.rstudio.studio.client.workbench.model.Session; import org.rstudio.studio.client.workbench.views.files.events.FileChangeEvent; import org.rstudio.studio.client.workbench.views.files.events.FileChangeHandler; import org.rstudio.studio.client.workbench.views.files.model.FileChange; import org.rstudio.studio.client.workbench.views.vcs.common.events.VcsRefreshEvent; import org.rstudio.studio.client.workbench.views.vcs.common.events.VcsRefreshEvent.Reason; import org.rstudio.studio.client.workbench.views.vcs.common.events.VcsRefreshHandler; import java.util.ArrayList; public abstract class VcsState { public VcsState(EventBus eventBus, GlobalDisplay globalDisplay, final Session session) { eventBus_ = eventBus; globalDisplay_ = globalDisplay; session_ = session; final HandlerRegistrations registrations = new HandlerRegistrations(); registrations.add(eventBus_.addHandler(VcsRefreshEvent.TYPE, new VcsRefreshHandler() { @Override public void onVcsRefresh(VcsRefreshEvent event) { if (!session.getSessionInfo().isVcsEnabled()) registrations.removeHandler(); if (event.getDelayMs() > 0) { Scheduler.get().scheduleFixedDelay(new RepeatingCommand() { @Override public boolean execute() { refresh(false); return false; } }, event.getDelayMs()); } else { Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { refresh(false); } }); } } })); registrations.add(eventBus_.addHandler(FileChangeEvent.TYPE, new FileChangeHandler() { @Override public void onFileChange(FileChangeEvent event) { if (!session.getSessionInfo().isVcsEnabled()) registrations.removeHandler(); FileChange fileChange = event.getFileChange(); FileSystemItem file = fileChange.getFile(); StatusAndPath status = StatusAndPath.fromInfo( getStatusFromFile(file)); if (needsFullRefresh(file)) { refresh(false); return; } if (status_ != null && status != null) { for (int i = 0; i < status_.size(); i++) { if (status.getRawPath().equals(status_.get(i).getRawPath())) { if (StringUtil.notNull(status.getStatus()).trim().length() == 0) status_.remove(i); else status_.set(i, status); handlers_.fireEvent(new VcsRefreshEvent(Reason.FileChange)); return; } } if (status.getStatus().trim().length() != 0) { status_.add(status); handlers_.fireEvent(new VcsRefreshEvent(Reason.FileChange)); return; } } } })); Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { refresh(false); } }); } public void bindRefreshHandler(Widget owner, final VcsRefreshHandler handler) { new WidgetHandlerRegistration(owner) { @Override protected HandlerRegistration doRegister() { return addVcsRefreshHandler(handler); } }; } public HandlerRegistration addVcsRefreshHandler(VcsRefreshHandler handler) { return addVcsRefreshHandler(handler, true); } public HandlerRegistration addVcsRefreshHandler(VcsRefreshHandler handler, boolean fireOnAdd) { HandlerRegistration hreg = handlers_.addHandler( VcsRefreshEvent.TYPE, handler); if (fireOnAdd && isInitialized()) handler.onVcsRefresh(new VcsRefreshEvent(Reason.VcsOperation)); return hreg; } public ArrayList<StatusAndPath> getStatus() { return status_; } public void refresh() { if (session_.getSessionInfo().isVcsEnabled()) refresh(true); } protected abstract StatusAndPathInfo getStatusFromFile(FileSystemItem file); protected abstract boolean needsFullRefresh(FileSystemItem file); public abstract void refresh(final boolean showError); protected abstract boolean isInitialized(); protected final HandlerManager handlers_ = new HandlerManager(this); protected ArrayList<StatusAndPath> status_; protected final EventBus eventBus_; protected final GlobalDisplay globalDisplay_; protected final Session session_; }