blob: 6203f259b9bcb832ddff5eb43835489de0c70e28 [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under 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.
*/
package org.zmlx.hg4idea.repo;
import com.intellij.dvcs.repo.RepositoryImpl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcs.log.Hash;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.zmlx.hg4idea.HgNameWithHashInfo;
import org.zmlx.hg4idea.HgVcs;
import org.zmlx.hg4idea.command.HgBranchesCommand;
import org.zmlx.hg4idea.execution.HgCommandResult;
import org.zmlx.hg4idea.util.HgUtil;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
/**
* @author Nadya Zabrodina
*/
public class HgRepositoryImpl extends RepositoryImpl implements HgRepository {
private static final Logger LOG = Logger.getInstance(HgRepositoryImpl.class);
@NotNull private final HgRepositoryReader myReader;
@NotNull private final VirtualFile myHgDir;
@NotNull private volatile HgRepoInfo myInfo;
@NotNull private Set<String> myOpenedBranches = Collections.emptySet();
@NotNull private volatile HgConfig myConfig;
private boolean myIsFresh = true;
@SuppressWarnings("ConstantConditions")
private HgRepositoryImpl(@NotNull VirtualFile rootDir, @NotNull HgVcs vcs,
@NotNull Disposable parentDisposable) {
super(vcs.getProject(), rootDir, parentDisposable);
myHgDir = rootDir.findChild(HgUtil.DOT_HG);
assert myHgDir != null : ".hg directory wasn't found under " + rootDir.getPresentableUrl();
myReader = new HgRepositoryReader(vcs, VfsUtilCore.virtualToIoFile(myHgDir));
myConfig = HgConfig.getInstance(getProject(), rootDir);
update();
}
@NotNull
public static HgRepository getInstance(@NotNull VirtualFile root, @NotNull Project project,
@NotNull Disposable parentDisposable) {
HgVcs vcs = HgVcs.getInstance(project);
if (vcs == null) {
throw new IllegalArgumentException("Vcs not found for project " + project);
}
HgRepositoryImpl repository = new HgRepositoryImpl(root, vcs, parentDisposable);
repository.setupUpdater();
return repository;
}
private void setupUpdater() {
HgRepositoryUpdater updater = new HgRepositoryUpdater(this);
Disposer.register(this, updater);
}
@NotNull
@Override
public VirtualFile getHgDir() {
return myHgDir;
}
@NotNull
@Override
public State getState() {
return myInfo.getState();
}
@Nullable
@Override
/**
* Return active bookmark name if exist or heavy branch name otherwise
*/
public String getCurrentBranchName() {
String branchOrBookMarkName = getCurrentBookmark();
if (StringUtil.isEmptyOrSpaces(branchOrBookMarkName)) {
branchOrBookMarkName = getCurrentBranch();
}
return branchOrBookMarkName;
}
@Nullable
@Override
public AbstractVcs getVcs() {
return HgVcs.getInstance(getProject());
}
@Override
@NotNull
public String getCurrentBranch() {
return myInfo.getCurrentBranch();
}
@Override
@Nullable
public String getCurrentRevision() {
return myInfo.getCurrentRevision();
}
@Nullable
public String getTipRevision() {
return myInfo.getTipRevision();
}
@Override
@NotNull
public Map<String, Set<Hash>> getBranches() {
return myInfo.getBranches();
}
@Override
@NotNull
public Set<String> getOpenedBranches() {
return myOpenedBranches;
}
@NotNull
@Override
public Collection<HgNameWithHashInfo> getBookmarks() {
return myInfo.getBookmarks();
}
@Nullable
@Override
public String getCurrentBookmark() {
return myInfo.getCurrentBookmark();
}
@NotNull
@Override
public Collection<HgNameWithHashInfo> getTags() {
return myInfo.getTags();
}
@NotNull
@Override
public Collection<HgNameWithHashInfo> getLocalTags() {
return myInfo.getLocalTags();
}
@NotNull
@Override
public HgConfig getRepositoryConfig() {
return myConfig;
}
@Override
public boolean hasSubrepos() {
return myInfo.hasSubrepos();
}
@NotNull
public Collection<HgNameWithHashInfo> getSubrepos() {
return myInfo.getSubrepos();
}
@Override
public boolean isFresh() {
return myIsFresh;
}
@Override
public void update() {
HgRepoInfo currentInfo = readRepoInfo();
// update only if something changed!!! if update every time - new log will be refreshed every time, too.
// Then blinking and do not work properly;
if (!Disposer.isDisposed(getProject()) && !currentInfo.equals(myInfo)) {
myInfo = currentInfo;
HgCommandResult branchCommandResult = new HgBranchesCommand(getProject(), getRoot()).collectBranches();
if (branchCommandResult == null || branchCommandResult.getExitValue() != 0) {
LOG.warn("Could not collect hg opened branches."); // hg executable is not valid
myOpenedBranches = myInfo.getBranches().keySet();
}
else {
myOpenedBranches = HgBranchesCommand.collectNames(branchCommandResult);
}
getProject().getMessageBus().syncPublisher(HgVcs.STATUS_TOPIC).update(getProject(), getRoot());
}
}
@NotNull
@Override
public String toLogString() {
return String.format("HgRepository " + getRoot() + " : " + myInfo);
}
@NotNull
private HgRepoInfo readRepoInfo() {
myIsFresh = myIsFresh && myReader.isFresh();
//in GitRepositoryImpl there are temporary state object for reader fields storing! Todo Check;
return
new HgRepoInfo(myReader.readCurrentBranch(), myReader.readCurrentRevision(), myReader.readCurrentTipRevision(), myReader.readState(),
myReader.readBranches(),
myReader.readBookmarks(), myReader.readCurrentBookmark(), myReader.readTags(), myReader.readLocalTags(),
myReader.readSubrepos());
}
public void updateConfig() {
myConfig = HgConfig.getInstance(getProject(), getRoot());
}
}