package managers;
import controllers.Component;
import models.*;
import models.base.FileOperationException;
import models.enums.AccountRole;
import models.enums.LinkType;
import models.services.ElasticsearchService;
import play.Configuration;
import play.Logger;
import play.db.jpa.JPA;
import play.db.jpa.JPAApi;
import javax.inject.Inject;
import javax.persistence.NoResultException;
import java.io.IOException;
import java.util.List;
/**
* Created by Iven on 17.12.2015.
*/
public class AccountManager implements BaseManager {
ElasticsearchService elasticsearchService;
PostManager postManager;
GroupManager groupManager;
GroupAccountManager groupAccountManager;
FriendshipManager friendshipManager;
MediaManager mediaManager;
NotificationManager notificationManager;
AvatarManager avatarManager;
FolderManager folderManager;
Configuration configuration;
JPAApi jpaApi;
@Inject
public AccountManager(ElasticsearchService elasticsearchService,
PostManager postManager,
GroupManager groupManager,
GroupAccountManager groupAccountManager,
FriendshipManager friendshipManager,
MediaManager mediaManager,
NotificationManager notificationManager,
AvatarManager avatarManager,
FolderManager folderManager,
Configuration configuration, JPAApi jpaApi) {
this.elasticsearchService = elasticsearchService;
this.postManager = postManager;
this.groupManager = groupManager;
this.groupAccountManager = groupAccountManager;
this.friendshipManager = friendshipManager;
this.mediaManager = mediaManager;
this.notificationManager = notificationManager;
this.avatarManager = avatarManager;
this.folderManager = folderManager;
this.configuration = configuration;
this.jpaApi = jpaApi;
}
@Override
public void create(Object model) {
Account account = (Account) model;
account.name = account.firstname + " " + account.lastname;
account.rootFolder = new Folder("_"+account.name, account, null, null, account);
folderManager.create(account.rootFolder);
jpaApi.em().persist(account);
try {
elasticsearchService.index(account);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void update(Object model) {
Account account = (Account) model;
account.name = account.firstname + " " + account.lastname;
jpaApi.em().merge(account);
try {
elasticsearchService.index(account);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void delete(Object model) {
Account account = (Account) model;
Account dummy = findByEmail(configuration.getString("htwplus.dummy.mail"));
if (dummy == null) {
Logger.error("Couldn't delete account because there is no Dummy Account! (mail=" + configuration.getString("htwplus.dummy.mail") + ")");
throw new RuntimeException("Couldn't delete account because there is no Dummy Account!");
}
// Anonymize Posts //
List<Post> owned = postManager.listAllPostsOwnedBy(account.id);
for (Post post : owned) {
post.owner = dummy;
postManager.create(post); // elastic search indexing
postManager.update(post);
}
List<Post> pinned = postManager.listAllPostsPostedOnAccount(account.id);
for (Post post : pinned) {
post.account = dummy;
postManager.create(post); // elastic search indexing
postManager.update(post);
}
// Anonymize created groups //
List<Group> groups = groupManager.listAllGroupsOwnedBy(account.id);
for (Group group : groups) {
if (groupAccountManager.findAccountsByGroup(group, LinkType.establish).size() == 1) { // if the owner is the only member of the group
Logger.info("Group '" + group.title + "' is now empty, so it will be deleted!");
groupManager.delete(group);
} else {
group.owner = dummy;
groupManager.update(group);
}
}
// Delete Friendships //
List<Friendship> friendships = friendshipManager.listAllFriendships(account.id);
for (Friendship friendship : friendships) {
friendshipManager.delete(friendship);
}
// Anonymize media //
List<Media> media = mediaManager.listAllOwnedBy(account.id);
for (Media med : media) {
med.owner = dummy;
mediaManager.update(med);
}
// transfer root folder (change it to a subfolder for our dummy account)
Folder rootFolder = account.rootFolder;
rootFolder.account = null;
rootFolder.parent = dummy.rootFolder;
rootFolder.owner = dummy;
// Delete incoming notifications //
notificationManager.deleteNotificationsForAccount(account.id);
// Delete outgoing notifications //
List<Notification> notifications = notificationManager.findBySenderId(account.id);
for (Notification not : notifications) {
notificationManager.delete(not);
}
elasticsearchService.delete(account);
jpaApi.em().remove(account);
}
/**
* Returns an account by account ID.
*
* @param id Account ID
* @return Account instance
*/
public Account findById(Long id) {
return jpaApi.em().find(Account.class, id);
}
@SuppressWarnings("unchecked")
public List<Account> findAll(){
return jpaApi.em().createQuery("SELECT a FROM Account a ORDER BY a.name").getResultList();
}
/**
* Retrieve a User from email.
*/
public Account findByEmail(String email) {
if(email.isEmpty()) {
return null;
}
try{
return (Account) jpaApi.em()
.createQuery("from Account a where a.email = :email")
.setParameter("email", email).getSingleResult();
} catch (NoResultException exp) {
return null;
}
}
/**
* Retrieve a User by loginname
*/
public Account findByLoginName(String loginName) {
try{
return (Account) jpaApi.em()
.createQuery("from Account a where a.loginname = :loginname")
.setParameter("loginname", loginName).getSingleResult();
} catch (NoResultException exp) {
return null;
}
}
public boolean isAccountValid(String email, String password) {
try {
final Account result = (Account) jpaApi.em()
.createQuery("from Account a where a.email = :email")
.setParameter("email", email).getSingleResult();
if (result != null && Component.md5(password).equals(result.password)) {
return true;
}
} catch (NoResultException exp) {
return false;
}
return false;
}
/**
* Try to get all accounts...
* @return List of accounts.
*/
@SuppressWarnings("unchecked")
public List<Account> all() {
return jpaApi.em().createQuery("FROM Account").getResultList();
}
/**
* Returns a list of account instances by an ID collection of Strings.
*
* @param accountIds String array of account IDs
* @return List of accounts
*/
public List<Account> getAccountListByIdCollection(final List<String> accountIds) {
StringBuilder joinedAccountIds = new StringBuilder();
for (int i = 0; i < accountIds.size(); i++) {
if (i > 0) {
joinedAccountIds.append(",");
}
joinedAccountIds.append(accountIds.get(i));
}
return jpaApi.em()
.createQuery("FROM Account a WHERE a.id IN (" + joinedAccountIds.toString() + ")", Account.class)
.getResultList();
}
/**
* Index the current account
*/
public void indexAccount(Account account) {
try {
elasticsearchService.index(account);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Index all accounts
*/
public long indexAllAccounts() throws IOException {
final long start = System.currentTimeMillis();
for (Account account: all()) {
if(account.role != AccountRole.DUMMY)
elasticsearchService.index(account);
}
return (System.currentTimeMillis() - start) / 1000;
}
public void saveAvatar(Avatar avatar, Account account) throws FileOperationException {
avatarManager.saveAvatar(avatar, account.id);
account.avatar = AvatarManager.AVATAR_CUSTOM;
this.update(account);
}
}