<commit_before>package fr.openwide.maven.artifact.notifier.core.business.user.service;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import fr.openwide.core.jpa.exception.SecurityServiceException;
import fr.openwide.core.jpa.exception.ServiceException;
import fr.openwide.core.jpa.search.service.IHibernateSearchService;
import fr.openwide.core.jpa.security.business.person.service.AbstractPersonServiceImpl;
import fr.openwide.maven.artifact.notifier.core.business.artifact.model.Artifact;
import fr.openwide.maven.artifact.notifier.core.business.artifact.model.ArtifactGroup;
import fr.openwide.maven.artifact.notifier.core.business.artifact.model.ArtifactKey;
import fr.openwide.maven.artifact.notifier.core.business.artifact.model.ArtifactVersionNotification;
import fr.openwide.maven.artifact.notifier.core.business.artifact.model.FollowedArtifact;
import fr.openwide.maven.artifact.notifier.core.business.artifact.service.IArtifactGroupService;
import fr.openwide.maven.artifact.notifier.core.business.artifact.service.IArtifactService;
import fr.openwide.maven.artifact.notifier.core.business.artifact.service.IFollowedArtifactService;
import fr.openwide.maven.artifact.notifier.core.business.notification.service.INotificationService;
import fr.openwide.maven.artifact.notifier.core.business.search.model.ArtifactBean;
import fr.openwide.maven.artifact.notifier.core.business.user.dao.IUserDao;
import fr.openwide.maven.artifact.notifier.core.business.user.exception.AlreadyFollowedArtifactException;
import fr.openwide.maven.artifact.notifier.core.business.user.model.AuthenticationType;
import fr.openwide.maven.artifact.notifier.core.business.user.model.EmailAddress;
import fr.openwide.maven.artifact.notifier.core.business.user.model.EmailStatus;
import fr.openwide.maven.artifact.notifier.core.business.user.model.User;
import fr.openwide.maven.artifact.notifier.core.business.user.model.User_;
import fr.openwide.maven.artifact.notifier.core.config.application.MavenArtifactNotifierConfigurer;
import fr.openwide.maven.artifact.notifier.core.util.binding.Binding;

@Service("personService")
public class UserServiceImpl extends AbstractPersonServiceImpl<User> implements IUserService {

	private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);
	
	private static final String GOOGLE_OPENID_PREFIX = "https://www.google.com/";
	
	@Autowired
	private IHibernateSearchService hibernateSearchService;
	
	@Autowired
	private IArtifactService artifactService;
	
	@Autowired
	private IArtifactGroupService artifactGroupService;
	
	@Autowired
	private IFollowedArtifactService followedArtifactService;
	
	@Autowired
	private INotificationService notificationService;
	
	@Autowired
	private IEmailAddressService emailAddressService;
	
	@Autowired
	private MavenArtifactNotifierConfigurer configurer;
	
	private IUserDao userDao;
	
	@Autowired
	public UserServiceImpl(IUserDao userDao) {
		super(userDao);
		this.userDao = userDao;
	} 

	@Override
	public List<User> listByUserName(String userName) {
		return listByField(User_.userName, userName);
	}
	
	@Override
	public List<User> search(String searchPattern) throws ServiceException, SecurityServiceException {
		String[] searchFields = new String[] { Binding.user().userName().getPath(), Binding.user().fullName().getPath() };
		
		return hibernateSearchService.search(getObjectClass(), searchFields, searchPattern);
	}
	
	@Override
	public List<User> searchAutocomplete(String searchPattern) throws ServiceException, SecurityServiceException {
		String[] searchFields = new String[] { Binding.user().userName().getPath(), Binding.user().fullName().getPath() };
		
		return hibernateSearchService.searchAutocomplete(getObjectClass(), searchFields, searchPattern);
	}
	
	@Override
	public FollowedArtifact followArtifact(User user, Artifact artifact) throws ServiceException, SecurityServiceException {
		FollowedArtifact followedArtifact = getFollowedArtifact(user, artifact);
		if (followedArtifact != null) {
			LOGGER.info("Artifact " + artifact.getDisplayName() + " is already followed by user " + user.getDisplayName() + ".");
			throw new AlreadyFollowedArtifactException();
		} else {
			followedArtifact = new FollowedArtifact(artifact);
			followedArtifactService.create(followedArtifact);
			
			artifact.setFollowersCount(artifact.getFollowersCount() + 1);
			
			user.addFollowedArtifact(followedArtifact);
			update(user);
		}
		return followedArtifact;
	}
	
	@Override
	public FollowedArtifact followArtifactBean(User user, ArtifactBean artifactBean) throws ServiceException, SecurityServiceException {
		ArtifactGroup artifactGroup = artifactGroupService.getByGroupId(artifactBean.getGroupId());
		if (artifactGroup == null) {
			artifactGroup = new ArtifactGroup(artifactBean.getGroupId());
			artifactGroupService.create(artifactGroup);
		}
		
		Artifact artifact = artifactService.getByArtifactKey(artifactBean.getArtifactKey());
		if (artifact == null) {
			artifact = new Artifact(artifactBean.getArtifactId());
			artifactGroup.addArtifact(artifact);
			artifactService.create(artifact);
		}
		
		return followArtifact(user, artifact);
	}
	
	@Override
	public boolean unfollowArtifact(User user, FollowedArtifact followedArtifact) throws ServiceException, SecurityServiceException {
		Artifact artifact = followedArtifact.getArtifact();
		artifact.setFollowersCount(Math.max(0, artifact.getFollowersCount() - 1));
		
		user.getFollowedArtifacts().remove(followedArtifact);
		update(user);
		
		followedArtifactService.delete(followedArtifact);
		return true;
	}
	
	@Override
	public boolean unfollowArtifact(User user, Artifact artifact) throws ServiceException, SecurityServiceException {
		FollowedArtifact followedArtifact = getFollowedArtifact(user, artifact);
		if (followedArtifact == null) {
			LOGGER.info("Artifact " + artifact.getDisplayName() + " is not followed by user " + user.getDisplayName() + ".");
			return false;
		} else {
			return unfollowArtifact(user, followedArtifact);
		}
	}
	
	@Override
	public List<ArtifactVersionNotification> listRecentNotifications(User user) {
		int limit = configurer.getLastNotificationsLimit();
		int dayCount = configurer.getLastNotificationsDayCount();
		
		List<ArtifactVersionNotification> notificationList = userDao.listLastNotifications(user, limit);
		
		ArtifactVersionNotification oldestNotification = Iterables.getLast(notificationList, null);
		
		if (oldestNotification != null) {
			Calendar calendar = GregorianCalendar.getInstance();
			calendar.add(Calendar.DAY_OF_MONTH, -dayCount);
			
			if (oldestNotification.getCreationDate().after(calendar.getTime())) {
				notificationList = userDao.listNotificationsAfterDate(user, calendar.getTime());
			}
		}
		return notificationList;<commit_msg>Remove logs from common error cases (follow/unfollow an artifact).<commit_after>package fr.openwide.maven.artifact.notifier.core.business.user.service;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import fr.openwide.core.jpa.exception.SecurityServiceException;
import fr.openwide.core.jpa.exception.ServiceException;
import fr.openwide.core.jpa.search.service.IHibernateSearchService;
import fr.openwide.core.jpa.security.business.person.service.AbstractPersonServiceImpl;
import fr.openwide.maven.artifact.notifier.core.business.artifact.model.Artifact;
import fr.openwide.maven.artifact.notifier.core.business.artifact.model.ArtifactGroup;
import fr.openwide.maven.artifact.notifier.core.business.artifact.model.ArtifactKey;
import fr.openwide.maven.artifact.notifier.core.business.artifact.model.ArtifactVersionNotification;
import fr.openwide.maven.artifact.notifier.core.business.artifact.model.FollowedArtifact;
import fr.openwide.maven.artifact.notifier.core.business.artifact.service.IArtifactGroupService;
import fr.openwide.maven.artifact.notifier.core.business.artifact.service.IArtifactService;
import fr.openwide.maven.artifact.notifier.core.business.artifact.service.IFollowedArtifactService;
import fr.openwide.maven.artifact.notifier.core.business.notification.service.INotificationService;
import fr.openwide.maven.artifact.notifier.core.business.search.model.ArtifactBean;
import fr.openwide.maven.artifact.notifier.core.business.user.dao.IUserDao;
import fr.openwide.maven.artifact.notifier.core.business.user.exception.AlreadyFollowedArtifactException;
import fr.openwide.maven.artifact.notifier.core.business.user.model.AuthenticationType;
import fr.openwide.maven.artifact.notifier.core.business.user.model.EmailAddress;
import fr.openwide.maven.artifact.notifier.core.business.user.model.EmailStatus;
import fr.openwide.maven.artifact.notifier.core.business.user.model.User;
import fr.openwide.maven.artifact.notifier.core.business.user.model.User_;
import fr.openwide.maven.artifact.notifier.core.config.application.MavenArtifactNotifierConfigurer;
import fr.openwide.maven.artifact.notifier.core.util.binding.Binding;

@Service("personService")
public class UserServiceImpl extends AbstractPersonServiceImpl<User> implements IUserService {

	private static final String GOOGLE_OPENID_PREFIX = "https://www.google.com/";
	
	@Autowired
	private IHibernateSearchService hibernateSearchService;
	
	@Autowired
	private IArtifactService artifactService;
	
	@Autowired
	private IArtifactGroupService artifactGroupService;
	
	@Autowired
	private IFollowedArtifactService followedArtifactService;
	
	@Autowired
	private INotificationService notificationService;
	
	@Autowired
	private IEmailAddressService emailAddressService;
	
	@Autowired
	private MavenArtifactNotifierConfigurer configurer;
	
	private IUserDao userDao;
	
	@Autowired
	public UserServiceImpl(IUserDao userDao) {
		super(userDao);
		this.userDao = userDao;
	} 

	@Override
	public List<User> listByUserName(String userName) {
		return listByField(User_.userName, userName);
	}
	
	@Override
	public List<User> search(String searchPattern) throws ServiceException, SecurityServiceException {
		String[] searchFields = new String[] { Binding.user().userName().getPath(), Binding.user().fullName().getPath() };
		
		return hibernateSearchService.search(getObjectClass(), searchFields, searchPattern);
	}
	
	@Override
	public List<User> searchAutocomplete(String searchPattern) throws ServiceException, SecurityServiceException {
		String[] searchFields = new String[] { Binding.user().userName().getPath(), Binding.user().fullName().getPath() };
		
		return hibernateSearchService.searchAutocomplete(getObjectClass(), searchFields, searchPattern);
	}
	
	@Override
	public FollowedArtifact followArtifact(User user, Artifact artifact) throws ServiceException, SecurityServiceException {
		FollowedArtifact followedArtifact = getFollowedArtifact(user, artifact);
		if (followedArtifact != null) {
			throw new AlreadyFollowedArtifactException();
		} else {
			followedArtifact = new FollowedArtifact(artifact);
			followedArtifactService.create(followedArtifact);
			
			artifact.setFollowersCount(artifact.getFollowersCount() + 1);
			
			user.addFollowedArtifact(followedArtifact);
			update(user);
		}
		return followedArtifact;
	}
	
	@Override
	public FollowedArtifact followArtifactBean(User user, ArtifactBean artifactBean) throws ServiceException, SecurityServiceException {
		ArtifactGroup artifactGroup = artifactGroupService.getByGroupId(artifactBean.getGroupId());
		if (artifactGroup == null) {
			artifactGroup = new ArtifactGroup(artifactBean.getGroupId());
			artifactGroupService.create(artifactGroup);
		}
		
		Artifact artifact = artifactService.getByArtifactKey(artifactBean.getArtifactKey());
		if (artifact == null) {
			artifact = new Artifact(artifactBean.getArtifactId());
			artifactGroup.addArtifact(artifact);
			artifactService.create(artifact);
		}
		
		return followArtifact(user, artifact);
	}
	
	@Override
	public boolean unfollowArtifact(User user, FollowedArtifact followedArtifact) throws ServiceException, SecurityServiceException {
		Artifact artifact = followedArtifact.getArtifact();
		artifact.setFollowersCount(Math.max(0, artifact.getFollowersCount() - 1));
		
		user.getFollowedArtifacts().remove(followedArtifact);
		update(user);
		
		followedArtifactService.delete(followedArtifact);
		return true;
	}
	
	@Override
	public boolean unfollowArtifact(User user, Artifact artifact) throws ServiceException, SecurityServiceException {
		FollowedArtifact followedArtifact = getFollowedArtifact(user, artifact);
		if (followedArtifact == null) {
			return false;
		} else {
			return unfollowArtifact(user, followedArtifact);
		}
	}
	
	@Override
	public List<ArtifactVersionNotification> listRecentNotifications(User user) {
		int limit = configurer.getLastNotificationsLimit();
		int dayCount = configurer.getLastNotificationsDayCount();
		
		List<ArtifactVersionNotification> notificationList = userDao.listLastNotifications(user, limit);
		
		ArtifactVersionNotification oldestNotification = Iterables.getLast(notificationList, null);
		
		if (oldestNotification != null) {
			Calendar calendar = GregorianCalendar.getInstance();
			calendar.add(Calendar.DAY_OF_MONTH, -dayCount);
			
			if (oldestNotification.getCreationDate().after(calendar.getTime())) {
				notificationList = userDao.listNotificationsAfterDate(user, calendar.getTime());
			}
		}
		return notificationList;
{'fraction_non_alphanumeric': 0.09803642572566876, 'fraction_numerical': 0.0007114399544678429, 'mean_word_length': 6.44150344097406, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1572394', 'n_tokens_mistral': 4399, 'n_tokens_neox': 3955, 'n_words': 647}