/* * Copyright 2000-2009 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.community.intellij.plugins.communitycase.changes; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.*; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.committed.DecoratorManager; import com.intellij.openapi.vcs.changes.committed.VcsCommittedListsZipper; import com.intellij.openapi.vcs.changes.committed.VcsCommittedViewAuxiliary; import com.intellij.openapi.vcs.history.VcsFileRevision; import com.intellij.openapi.vcs.history.VcsRevisionNumber; import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings; import com.intellij.openapi.vcs.versionBrowser.ChangesBrowserSettingsEditor; import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.AsynchConsumer; import com.intellij.util.Consumer; import org.community.intellij.plugins.communitycase.Branch; import org.community.intellij.plugins.communitycase.FileRevision; import org.community.intellij.plugins.communitycase.Remote; import org.community.intellij.plugins.communitycase.Util; import org.community.intellij.plugins.communitycase.commands.SimpleHandler; import org.community.intellij.plugins.communitycase.history.HistoryUtils; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.Nullable; import java.io.DataInput; import java.io.DataOutput; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; /** * The provider for committed change lists */ public class CommittedChangeListProvider implements CommittedChangesProvider<CommittedChangeList, ChangeBrowserSettings> { /** * the logger */ private static final Logger LOG = Logger.getInstance("#"+CommittedChangeListProvider.class.getName()); /** * The project for the service */ private final Project myProject; /** * The constructor * * @param project the project instance for this provider */ public CommittedChangeListProvider(Project project) { myProject = project; } /** * {@inheritDoc} */ public ChangeBrowserSettings createDefaultSettings() { return new ChangeBrowserSettings(); } /** * {@inheritDoc} */ public ChangesBrowserSettingsEditor<ChangeBrowserSettings> createFilterUI(boolean showDateFilter) { return new VersionFilterComponent(showDateFilter); } /** * {@inheritDoc} */ public RepositoryLocation getLocationFor(FilePath root) { // TODO !!! consider some caching for the case when we do not have tracked remote branch // TODO - in this case returned NULL is NOT cached (in ProjectKeyComponent) VirtualFile Root = Util.getRootOrNull(root); if (Root == null) { return null; } try { Branch c = Branch.current(myProject, Root); if (c == null) { return null; } String remote = c.getTrackedRemoteName(myProject, Root); if (StringUtil.isEmpty(remote)) { return null; } File rootFile = new File(Root.getPath()); if (".".equals(remote)) { return new RepositoryLocation(Root.getUrl(), rootFile); } else { Remote r = Remote.find(myProject, Root, remote); return r == null ? null : new RepositoryLocation(r.fetchUrl(), rootFile); } } catch (VcsException e) { if (LOG.isDebugEnabled()) { LOG.debug("Exception for determining repository location", e); } return null; } } /** * {@inheritDoc} */ public RepositoryLocation getLocationFor(FilePath root, String repositoryPath) { return getLocationFor(root); } /** * {@inheritDoc} */ public VcsCommittedListsZipper getZipper() { return null; } @Override public void loadCommittedChanges(ChangeBrowserSettings settings, com.intellij.openapi.vcs.RepositoryLocation location, int maxCount, AsynchConsumer<CommittedChangeList> consumer) throws VcsException { try { getCommittedChangesImpl(settings, location, maxCount, consumer); } finally { consumer.finished(); } } /** * {@inheritDoc} */ @Override public List<CommittedChangeList> getCommittedChanges(ChangeBrowserSettings settings, com.intellij.openapi.vcs.RepositoryLocation location, final int maxCount) throws VcsException { final List<CommittedChangeList> result = new ArrayList<CommittedChangeList>(); getCommittedChangesImpl(settings, location, maxCount, new Consumer<CommittedChangeList>() { public void consume(CommittedChangeList committedChangeList) { result.add(committedChangeList); } }); return result; } private void getCommittedChangesImpl(ChangeBrowserSettings settings, com.intellij.openapi.vcs.RepositoryLocation location, final int maxCount, final Consumer<CommittedChangeList> consumer) throws VcsException { RepositoryLocation l = (RepositoryLocation)location; final Long beforeRev = settings.getChangeBeforeFilter(); final Long afterRev = settings.getChangeBeforeFilter(); final Date beforeDate = settings.getDateBeforeFilter(); final Date afterDate = settings.getDateBeforeFilter(); final String author = settings.getUserFilter(); VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(l.getRoot()); if (root == null) { throw new VcsException("The repository does not exists anymore: " + l.getRoot()); } Util.getLocalCommittedChanges(myProject, root, new Consumer<SimpleHandler>() { public void consume(SimpleHandler h) { if (!StringUtil.isEmpty(author)) { h.addParameters("--author=" + author); } if (beforeDate != null) { h.addParameters("--before=" + Util.vcsTime(beforeDate)); } if (afterDate != null) { h.addParameters("--after=" + Util.vcsTime(afterDate)); } if (maxCount != getUnlimitedCountValue()) { h.addParameters("-n" + maxCount); } if (beforeRev != null && afterRev != null) { h.addParameters(Util.formatLongRev(afterRev) + ".." + Util.formatLongRev(beforeRev)); } else if (beforeRev != null) { h.addParameters(Util.formatLongRev(beforeRev)); } else if (afterRev != null) { h.addParameters(Util.formatLongRev(afterRev) + ".."); } } }, consumer, false); } /** * {@inheritDoc} */ public ChangeListColumn[] getColumns() { return new ChangeListColumn[]{ChangeListColumn.NUMBER, ChangeListColumn.DATE, ChangeListColumn.DESCRIPTION, ChangeListColumn.NAME}; } /** * {@inheritDoc} */ @Override public VcsCommittedViewAuxiliary createActions(DecoratorManager manager, com.intellij.openapi.vcs.RepositoryLocation location) { return null; } /** * {@inheritDoc} */ public int getUnlimitedCountValue() { return -1; } @Override public Pair<CommittedChangeList, FilePath> getOneList(final VirtualFile file, final VcsRevisionNumber number) throws VcsException { final FilePathImpl filePath = new FilePathImpl(file); final RepositoryLocation l = (RepositoryLocation) getLocationFor(filePath); final VirtualFile root = LocalFileSystem.getInstance().findFileByIoFile(l.getRoot()); if (root == null) { throw new VcsException("The repository does not exists anymore: " + l.getRoot()); } final CommittedChangeList[] result = new CommittedChangeList[1]; Util.getLocalCommittedChanges(myProject, root, new Consumer<SimpleHandler>() { public void consume(final SimpleHandler h) { h.addParameters("-n1"); h.addParameters("-M"); h.addParameters(number.asString()); } }, new Consumer<CommittedChangeList>() { @Override public void consume(final CommittedChangeList committedChangeList) { result[0] = committedChangeList; } }, false); final Collection<Change> changes = result[0].getChanges(); if (changes.size() == 1) { return new Pair<CommittedChangeList, FilePath>(result[0], changes.iterator().next().getAfterRevision().getFile()); } for (Change change : changes) { if (change.getAfterRevision() != null && filePath.getIOFile().equals(change.getAfterRevision().getFile().getIOFile())) { return new Pair<CommittedChangeList, FilePath>(result[0], filePath); } } final List<VcsFileRevision> history = HistoryUtils.history(myProject, filePath, root, number.asString() + "^.."); return new Pair<CommittedChangeList, FilePath>(result[0], ((FileRevision) history.get(history.size() - 1)).getPath()); } public int getFormatVersion() { return 0; } public void writeChangeList(DataOutput stream, CommittedChangeList list) throws IOException { } public CommittedChangeList readChangeList(RepositoryLocation location, DataInput stream) throws IOException { return null; } public boolean isMaxCountSupported() { return false; } public Collection<FilePath> getIncomingFiles(RepositoryLocation location) throws VcsException { return null; } public boolean refreshCacheByNumber() { return false; } @Nls public String getChangelistTitle() { return null; } public boolean isChangeLocallyAvailable(FilePath filePath, @Nullable VcsRevisionNumber localRevision, VcsRevisionNumber changeRevision, CommittedChangeList changeList) { return false; } public boolean refreshIncomingWithCommitted() { return false; } }