/*
* Copyright 2000-2016 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 com.intellij.vcs.log.impl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.vcs.log.VcsCommitMetadata;
import com.intellij.vcs.log.VcsLogUserFilter;
import com.intellij.vcs.log.VcsUser;
import com.intellij.vcs.log.util.VcsUserUtil;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
public class VcsLogUserFilterImpl implements VcsLogUserFilter {
private static final Logger LOG = Logger.getInstance(VcsLogUserFilterImpl.class);
@NotNull public static final String ME = "me";
@NotNull private final Collection<String> myUsers;
@NotNull private final Map<VirtualFile, VcsUser> myData;
@NotNull private final MultiMap<String, VcsUser> myAllUsersByNames = MultiMap.create();
@NotNull private final MultiMap<String, VcsUser> myAllUsersByEmails = MultiMap.create();
public VcsLogUserFilterImpl(@NotNull Collection<String> users,
@NotNull Map<VirtualFile, VcsUser> meData,
@NotNull Set<VcsUser> allUsers) {
myUsers = users;
myData = meData;
for (VcsUser user : allUsers) {
String name = user.getName();
if (!name.isEmpty()) {
myAllUsersByNames.putValue(VcsUserUtil.getNameInStandardForm(name), user);
}
String email = user.getEmail();
String nameFromEmail = VcsUserUtil.getNameFromEmail(email);
if (nameFromEmail != null) {
myAllUsersByEmails.putValue(VcsUserUtil.getNameInStandardForm(nameFromEmail), user);
}
}
}
@NotNull
public Collection<VcsUser> getUsers(@NotNull VirtualFile root) {
Set<VcsUser> result = ContainerUtil.newHashSet();
for (String user : myUsers) {
result.addAll(getUsers(root, user));
}
return result;
}
@NotNull
private Set<VcsUser> getUsers(@NotNull VirtualFile root, @NotNull String name) {
Set<VcsUser> users = ContainerUtil.newHashSet();
if (ME.equals(name)) {
VcsUser vcsUser = myData.get(root);
if (vcsUser != null) {
users.addAll(getUsers(vcsUser.getName())); // do not just add vcsUser, also add synonyms
String emailNamePart = VcsUserUtil.getNameFromEmail(vcsUser.getEmail());
if (emailNamePart != null) {
users.addAll(getUsers(emailNamePart));
}
}
}
else {
users.addAll(getUsers(name));
}
return users;
}
@NotNull
public Collection<String> getUserNamesForPresentation() {
return myUsers;
}
@Override
public boolean matches(@NotNull final VcsCommitMetadata commit) {
return ContainerUtil.exists(myUsers, name -> {
Set<VcsUser> users = getUsers(commit.getRoot(), name);
if (!users.isEmpty()) {
return users.contains(commit.getAuthor());
}
else if (!name.equals(ME)) {
String lowerUser = VcsUserUtil.nameToLowerCase(name);
boolean result = VcsUserUtil.nameToLowerCase(commit.getAuthor().getName()).equals(lowerUser) ||
VcsUserUtil.emailToLowerCase(commit.getAuthor().getEmail()).startsWith(lowerUser + "@");
if (result) {
LOG.warn("Unregistered author " + commit.getAuthor() + " for commit " + commit.getId().asString() + "; search pattern " + name);
}
return result;
}
return false;
});
}
private Set<VcsUser> getUsers(@NotNull String name) {
Set<VcsUser> result = ContainerUtil.newHashSet();
result.addAll(myAllUsersByNames.get(VcsUserUtil.getNameInStandardForm(name)));
result.addAll(myAllUsersByEmails.get(VcsUserUtil.getNameInStandardForm(name)));
return result;
}
@Override
public String toString() {
return "author: " + StringUtil.join(myUsers, ", ");
}
}