Skip to content

Commit

Permalink
Add email domains (#7063)
Browse files Browse the repository at this point in the history
* fix typos

* add db table

* add togglz

* add email domain logic

* improve new domain logic

* add another toggle

* improve readability, add transactions, cleanup

* remove todo

* add indexes to profile email domain table

* fix new domain visibility bug
  • Loading branch information
auumgn authored Aug 10, 2024
1 parent 3aec5ec commit 06d7026
Show file tree
Hide file tree
Showing 26 changed files with 925 additions and 375 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public interface EmailDomainManager {

boolean updateCategory(long id, EmailDomainEntity.DomainCategory category);

EmailDomainEntity findByEmailDoman(String emailDomain);
EmailDomainEntity findByEmailDomain(String emailDomain);

List<EmailDomainEntity> findByCategory(EmailDomainEntity.DomainCategory category);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ public boolean updateCategory(long id, DomainCategory category) {
}

@Override
public EmailDomainEntity findByEmailDoman(String emailDomain) {
public EmailDomainEntity findByEmailDomain(String emailDomain) {
if (emailDomain == null || emailDomain.isBlank()) {
throw new IllegalArgumentException("Email Domain must not be empty");
}
return emailDomainDaoReadOnly.findByEmailDoman(emailDomain);
return emailDomainDaoReadOnly.findByEmailDomain(emailDomain);
}

@Override
Expand All @@ -65,7 +65,7 @@ public List<EmailDomainEntity> findByCategory(DomainCategory category) {

@Override
public STATUS createOrUpdateEmailDomain(String emailDomain, String rorId) {
EmailDomainEntity existingEntity = emailDomainDaoReadOnly.findByEmailDoman(emailDomain);
EmailDomainEntity existingEntity = emailDomainDaoReadOnly.findByEmailDomain(emailDomain);
if(existingEntity != null) {
if(!rorId.equals(existingEntity.getRorId())) {
boolean updated = emailDomainDao.updateRorId(existingEntity.getId(), rorId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public List<PeerReview> findPeerReviews(String orcid) {
}

/**
* Get the list of peer reivews that belongs to a user
* Get the list of peer reviews that belongs to a user
*
* @param userOrcid
* @param lastModified
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.orcid.core.manager.v3;

import org.orcid.core.manager.v3.read_only.ProfileEmailDomainManagerReadOnly;
import org.orcid.persistence.jpa.entities.EmailEntity;

import java.util.List;

/**
*
* @author Andrej Romanov
*
*/
public interface ProfileEmailDomainManager extends ProfileEmailDomainManagerReadOnly {
void updateEmailDomains(String orcid, org.orcid.pojo.ajaxForm.Emails emails);
void processDomain(String orcid, String email);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
import org.apache.commons.lang3.StringUtils;
import org.orcid.core.manager.EncryptionManager;
import org.orcid.core.manager.v3.EmailManager;
import org.orcid.core.manager.v3.ProfileEmailDomainManager;
import org.orcid.core.manager.v3.SourceManager;
import org.orcid.core.manager.v3.read_only.impl.EmailManagerReadOnlyImpl;
import org.orcid.core.togglz.Features;
import org.orcid.jaxb.model.v3.release.common.Visibility;
import org.orcid.jaxb.model.v3.release.record.Email;
import org.orcid.persistence.aop.UpdateProfileLastModifiedAndIndexingStatus;
Expand All @@ -38,6 +40,9 @@ public class EmailManagerImpl extends EmailManagerReadOnlyImpl implements EmailM
@Resource(name = "sourceManagerV3")
private SourceManager sourceManager;

@Resource(name = "profileEmailDomainManager")
private ProfileEmailDomainManager profileEmailDomainManager;

@Resource
private TransactionTemplate transactionTemplate;

Expand All @@ -62,17 +67,27 @@ public void removeEmail(String orcid, String email) {
}

@Override
@Transactional
@UpdateProfileLastModifiedAndIndexingStatus
public boolean verifyEmail(String orcid, String email) {
return emailDao.verifyEmail(email);
boolean result = emailDao.verifyEmail(email);
if (result && Features.EMAIL_DOMAINS.isActive()) {
profileEmailDomainManager.processDomain(orcid, email);
}
return result;
}

@Override
@Transactional
public boolean verifyPrimaryEmail(String orcid) {
try {
String primaryEmail = emailDao.findPrimaryEmail(orcid).getEmail();
return emailDao.verifyEmail(primaryEmail);

boolean result = emailDao.verifyEmail(primaryEmail);
if (result && Features.EMAIL_DOMAINS.isActive()) {
profileEmailDomainManager.processDomain(orcid, primaryEmail);
}
return result;
} catch (javax.persistence.NoResultException nre) {
String alternativePrimaryEmail = emailDao.findNewestVerifiedOrNewestEmail(orcid);
emailDao.updatePrimary(orcid, alternativePrimaryEmail);
Expand All @@ -99,12 +114,17 @@ public boolean moveEmailToOtherAccount(String email, String origin, String desti
}

@Override
@Transactional
public boolean verifySetCurrentAndPrimary(String orcid, String email) {
if (PojoUtil.isEmpty(orcid) || PojoUtil.isEmpty(email)) {
throw new IllegalArgumentException("orcid or email param is empty or null");
}

return emailDao.updateVerifySetCurrentAndPrimary(orcid, email);
boolean result = emailDao.updateVerifySetCurrentAndPrimary(orcid, email);
if (result && Features.EMAIL_DOMAINS.isActive()) {
profileEmailDomainManager.processDomain(orcid, email);
}
return result;
}

/***
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package org.orcid.core.manager.v3.impl;


import org.orcid.core.manager.v3.ProfileEmailDomainManager;
import org.orcid.core.manager.v3.read_only.impl.ProfileEmailDomainManagerReadOnlyImpl;
import org.orcid.jaxb.model.v3.release.common.Visibility;
import org.orcid.persistence.dao.EmailDao;
import org.orcid.persistence.dao.EmailDomainDao;
import org.orcid.persistence.dao.ProfileEmailDomainDao;
import org.orcid.persistence.jpa.entities.EmailDomainEntity;
import org.orcid.persistence.jpa.entities.ProfileEmailDomainEntity;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
*
* @author Andrej Romanov
*
*/
public class ProfileEmailDomainManagerImpl extends ProfileEmailDomainManagerReadOnlyImpl implements ProfileEmailDomainManager {
@Resource
protected ProfileEmailDomainDao profileEmailDomainDao;

@Resource
protected EmailDomainDao emailDomainDao;

@Resource
protected EmailDao emailDao;

private static final String DEFAULT_DOMAIN_VISIBILITY = Visibility.PRIVATE.toString().toUpperCase();

@Transactional
public void updateEmailDomains(String orcid, org.orcid.pojo.ajaxForm.Emails newEmails) {
List<ProfileEmailDomainEntity> existingEmailDomains = profileEmailDomainDao.findByOrcid(orcid);

if (existingEmailDomains != null) {
// VISIBILITY UPDATE FOR EXISTING DOMAINS
for (org.orcid.pojo.ajaxForm.ProfileEmailDomain emailDomain : newEmails.getEmailDomains()) {
for (ProfileEmailDomainEntity existingEmailDomain : existingEmailDomains) {
if (existingEmailDomain.getEmailDomain().equals(emailDomain.getValue())) {
if (!existingEmailDomain.getVisibility().equals(emailDomain.getVisibility())) {
profileEmailDomainDao.updateVisibility(orcid, emailDomain.getValue(), emailDomain.getVisibility());
}
}
}
}

// REMOVE DOMAINS
for (ProfileEmailDomainEntity existingEmailDomain : existingEmailDomains) {
boolean deleteEmail = true;
for (org.orcid.pojo.ajaxForm.ProfileEmailDomain emailDomain : newEmails.getEmailDomains()) {
if (existingEmailDomain.getEmailDomain().equals(emailDomain.getValue())) {
deleteEmail = false;
break;
}
}
if (deleteEmail) {
profileEmailDomainDao.removeEmailDomain(orcid, existingEmailDomain.getEmailDomain());
}
}
}
}

public void processDomain(String orcid, String email) {
String domain = email.split("@")[1];
EmailDomainEntity domainInfo = emailDomainDao.findByEmailDomain(domain);
// Check if email is professional
if (domainInfo != null && domainInfo.getCategory().equals(EmailDomainEntity.DomainCategory.PROFESSIONAL)) {
ProfileEmailDomainEntity existingDomain = profileEmailDomainDao.findByEmailDomain(orcid, domain);
// ADD NEW DOMAIN IF ONE DOESN'T EXIST
if (existingDomain == null) {
profileEmailDomainDao.addEmailDomain(orcid, domain, DEFAULT_DOMAIN_VISIBILITY);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.orcid.core.manager.v3.read_only;


import org.orcid.persistence.jpa.entities.ProfileEmailDomainEntity;

import java.util.List;

/**
*
* @author Andrej Romanov
*
*/
public interface ProfileEmailDomainManagerReadOnly {
List<ProfileEmailDomainEntity> getEmailDomains(String orcid);
List<ProfileEmailDomainEntity> getPublicEmailDomains(String orcid);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.orcid.core.manager.v3.read_only.impl;


import org.orcid.core.manager.read_only.impl.ManagerReadOnlyBaseImpl;
import org.orcid.core.manager.v3.read_only.ProfileEmailDomainManagerReadOnly;
import org.orcid.persistence.dao.ProfileEmailDomainDao;
import org.orcid.persistence.jpa.entities.ProfileEmailDomainEntity;

import javax.annotation.Resource;
import java.util.List;

/**
*
* @author Andrej Romanov
*
*/
public class ProfileEmailDomainManagerReadOnlyImpl extends ManagerReadOnlyBaseImpl implements ProfileEmailDomainManagerReadOnly {
@Resource
protected ProfileEmailDomainDao profileEmailDomainDao;

public void setProfileEmailDomainDao(ProfileEmailDomainDao profileEmailDomainDao) {
this.profileEmailDomainDao = profileEmailDomainDao;
}

public List<ProfileEmailDomainEntity> getEmailDomains(String orcid) {
return profileEmailDomainDao.findByOrcid(orcid);
};

public List<ProfileEmailDomainEntity> getPublicEmailDomains(String orcid) {
return profileEmailDomainDao.findPublicEmailDomains(orcid);
};
}
8 changes: 7 additions & 1 deletion orcid-core/src/main/java/org/orcid/core/togglz/Features.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,13 @@ public enum Features implements Feature {
PAPI_EVENTS,

@Label("Enable summary endpoint in the Members API")
MAPI_SUMMARY_ENDPOINT;
MAPI_SUMMARY_ENDPOINT,

@Label("Enable email domains")
EMAIL_DOMAINS,

@Label("Enable email domains in the UI")
EMAIL_DOMAINS_UI;

public boolean isActive() {
return FeatureContext.getFeatureManager().isActive(this);
Expand Down
16 changes: 15 additions & 1 deletion orcid-core/src/main/java/org/orcid/pojo/ajaxForm/Emails.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,33 @@
package org.orcid.pojo.ajaxForm;

import org.orcid.core.togglz.Features;
import org.orcid.persistence.jpa.entities.ProfileEmailDomainEntity;

import java.util.ArrayList;
import java.util.List;

public class Emails implements ErrorsInterface {
private List<Email> emails = null;
private List<ProfileEmailDomain> emailDomains = null;
@SuppressWarnings("unused")
private static final long serialVersionUID = 1L;

private List<String> errors = new ArrayList<String>();

public static Emails valueOf(org.orcid.jaxb.model.v3.release.record.Emails e) {
public static Emails valueOf(org.orcid.jaxb.model.v3.release.record.Emails e, List<ProfileEmailDomainEntity> domains) {
Emails emails = new Emails();
if (e != null && !e.getEmails().isEmpty()) {
emails.setEmails(new ArrayList<Email>());
for (org.orcid.jaxb.model.v3.release.record.Email v3Email : e.getEmails()) {
emails.getEmails().add(Email.valueOf(v3Email));
}
}
if (domains != null && !domains.isEmpty() && Features.EMAIL_DOMAINS.isActive()) {
emails.setEmailDomains(new ArrayList<ProfileEmailDomain>());
for (ProfileEmailDomainEntity domain : domains) {
emails.getEmailDomains().add(ProfileEmailDomain.valueOf(domain));
}
}
return emails;
}

Expand Down Expand Up @@ -46,4 +56,8 @@ public List<Email> getEmails() {
public void setEmails(List<Email> emails) {
this.emails = emails;
}

public List<ProfileEmailDomain> getEmailDomains() { return emailDomains; }

public void setEmailDomains(List<ProfileEmailDomain> emailDomains) { this.emailDomains = emailDomains;}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package org.orcid.pojo.ajaxForm;

import org.orcid.persistence.jpa.entities.ProfileEmailDomainEntity;

import java.time.LocalDate;
import java.time.ZoneId;

public class ProfileEmailDomain {

protected String value;

protected String visibility;

private Date createdDate;

private Date lastModified;

public static ProfileEmailDomain valueOf(ProfileEmailDomainEntity ed) {
ProfileEmailDomain emailDomain = new ProfileEmailDomain();

if (ed != null) {
emailDomain.setValue(ed.getEmailDomain());
emailDomain.setVisibility(ed.getVisibility());

if (ed.getDateCreated() != null) {
Date createdDate = new Date();
LocalDate date = ed.getDateCreated().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
createdDate.setYear(String.valueOf(date.getYear()));
createdDate.setMonth(String.valueOf(date.getMonth()));
createdDate.setDay(String.valueOf(date.getDayOfMonth()));
createdDate.setTimestamp(ed.getDateCreated().toInstant().toEpochMilli());
emailDomain.setCreatedDate(createdDate);
}

if (ed.getLastModified() != null) {
Date lastModifiedDate = new Date();
LocalDate date = ed.getLastModified().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
lastModifiedDate.setYear(String.valueOf(date.getYear()));
lastModifiedDate.setMonth(String.valueOf(date.getMonth()));
lastModifiedDate.setDay(String.valueOf(date.getDayOfMonth()));
emailDomain.setLastModified(lastModifiedDate);
}
}
return emailDomain;
}


public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

public String getVisibility() {
return visibility;
}

public void setVisibility(String visibility) {
this.visibility = visibility;
}

public Date getCreatedDate() {
return createdDate;
}

public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}

public Date getLastModified() {
return lastModified;
}

public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
}
Loading

0 comments on commit 06d7026

Please sign in to comment.