Commit 9fd83237 by jhrabal

WIP

parent 13ec164f
package com.jh.boot;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import com.jh.boot.email.LocalEmailService;
import com.jh.boot.security.utils.TemplateEmailAuthServiceListener;
public class JhBootApplication {
@Bean
@ConditionalOnProperty(value = "email.local.enabled", havingValue = "true", matchIfMissing = true)
public LocalEmailService emailService() {
return new LocalEmailService();
}
@Bean
@ConditionalOnProperty(value = "security.auth.listener.email.enabled", havingValue = "true", matchIfMissing = true)
public TemplateEmailAuthServiceListener authServiceListener() {
return new TemplateEmailAuthServiceListener();
}
}
package com.jh.common.domain; package com.jh.boot.domain;
public enum DateType { public enum DateType {
......
package com.jh.common.domain; package com.jh.boot.domain;
public class NamedValue<T> { public class NamedValue<T> {
......
package com.jh.common.email; package com.jh.boot.email;
import java.util.Set; import java.util.Set;
...@@ -8,7 +8,7 @@ import javax.persistence.Entity; ...@@ -8,7 +8,7 @@ import javax.persistence.Entity;
import javax.persistence.OneToMany; import javax.persistence.OneToMany;
import javax.persistence.Table; import javax.persistence.Table;
import com.jh.common.jpa.AbstractIdEntity; import com.jh.boot.jpa.AbstractIdEntity;
/** /**
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 8. 8. 2017 8:36:15 * Created on 8. 8. 2017 8:36:15
* *
*/ */
package com.jh.common.email; package com.jh.boot.email;
import java.util.Base64; import java.util.Base64;
import java.util.Base64.Encoder; import java.util.Base64.Encoder;
...@@ -14,7 +14,7 @@ import javax.persistence.ManyToOne; ...@@ -14,7 +14,7 @@ import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.jh.common.jpa.AbstractIdEntity; import com.jh.boot.jpa.AbstractIdEntity;
/** /**
* The Class EmailAttachment. * The Class EmailAttachment.
......
package com.jh.common.email; package com.jh.boot.email;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
......
package com.jh.common.email; package com.jh.boot.email;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
...@@ -9,7 +9,7 @@ import javax.persistence.ManyToOne; ...@@ -9,7 +9,7 @@ import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.jh.common.jpa.AbstractIdEntity; import com.jh.boot.jpa.AbstractIdEntity;
/** /**
* The Class EmailRecipient. * The Class EmailRecipient.
......
package com.jh.common.email; package com.jh.boot.email;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
...@@ -10,7 +10,7 @@ import javax.persistence.Query; ...@@ -10,7 +10,7 @@ import javax.persistence.Query;
import org.hibernate.query.NativeQuery; import org.hibernate.query.NativeQuery;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.jh.common.jpa.AbstractHibernateRepository; import com.jh.boot.jpa.AbstractHibernateRepository;
/** /**
* The Class EmailRepository. * The Class EmailRepository.
......
package com.jh.common.email; package com.jh.boot.email;
/** /**
* The Interface EmailService. * The Interface EmailService.
......
package com.jh.common.email; package com.jh.boot.email;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
......
package com.jh.common.email; package com.jh.boot.email;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64; import java.util.Base64;
......
package com.jh.common.email; package com.jh.boot.email;
/** /**
* The Enum RecipientType. * The Enum RecipientType.
......
package com.jh.common.email; package com.jh.boot.email;
import java.net.URI; import java.net.URI;
......
package com.jh.common.i18n; package com.jh.boot.i18n;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols; import java.text.DecimalFormatSymbols;
...@@ -261,4 +261,78 @@ public class I18nUtils { ...@@ -261,4 +261,78 @@ public class I18nUtils {
public static I18nUtils getInstance() { public static I18nUtils getInstance() {
return instance; return instance;
} }
class NumberFormatKey {
/** The thousand delimiter. */
private String thousandDelimiter;
/** The decimal delimiter. */
private String decimalDelimiter;
/** The fixed. */
private int fixed;
/**
* Instantiates a new number format key.
*
* @param decimalDelimiter the decimal delimiter
* @param thousandDelimiter the thousand delimiter
* @param fixed the fixed
*/
public NumberFormatKey(String decimalDelimiter, String thousandDelimiter, int fixed) {
super();
this.thousandDelimiter = thousandDelimiter;
this.decimalDelimiter = decimalDelimiter;
this.fixed = fixed;
}
/**
* @return
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((decimalDelimiter == null) ? 0 : decimalDelimiter.hashCode());
result = prime * result + fixed;
result = prime * result + ((thousandDelimiter == null) ? 0 : thousandDelimiter.hashCode());
return result;
}
/**
* @param obj
* @return
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NumberFormatKey other = (NumberFormatKey) obj;
if (decimalDelimiter == null) {
if (other.decimalDelimiter != null)
return false;
} else if (!decimalDelimiter.equals(other.decimalDelimiter))
return false;
if (fixed != other.fixed)
return false;
if (thousandDelimiter == null) {
if (other.thousandDelimiter != null)
return false;
} else if (!thousandDelimiter.equals(other.thousandDelimiter))
return false;
return true;
}
}
} }
package com.jh.common.jpa; package com.jh.boot.jpa;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
...@@ -25,10 +25,10 @@ import org.hibernate.criterion.Restrictions; ...@@ -25,10 +25,10 @@ import org.hibernate.criterion.Restrictions;
import org.hibernate.query.NativeQuery; import org.hibernate.query.NativeQuery;
import org.hibernate.transform.Transformers; import org.hibernate.transform.Transformers;
import com.jh.common.web.list.Page; import com.jh.boot.web.list.Page;
import com.jh.common.web.list.PagingInfo; import com.jh.boot.web.list.PagingInfo;
import com.jh.common.web.list.SortTrend; import com.jh.boot.web.list.SortTrend;
import com.jh.common.web.list.SortingInfo; import com.jh.boot.web.list.SortingInfo;
/** /**
......
package com.jh.common.jpa; package com.jh.boot.jpa;
import java.io.Serializable; import java.io.Serializable;
......
package com.jh.common.jpa; package com.jh.boot.jpa;
import java.time.LocalDate; import java.time.LocalDate;
import java.sql.Date; import java.sql.Date;
......
package com.jh.common.security; package com.jh.boot.security;
/** /**
* The Class AuthError. * The Class AuthError.
......
package com.jh.common.security; package com.jh.boot.security;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
......
package com.jh.common.security; package com.jh.boot.security;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.AuthenticationProvider;
......
package com.jh.boot.security;
import com.jh.boot.security.model.AppUser;
public interface AuthServiceListener {
void registerUser(AppUser user);
void generateResetToken(AppUser user);
}
package com.jh.common.security; package com.jh.boot.security;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
......
package com.jh.common.security; package com.jh.boot.security;
import java.io.IOException; import java.io.IOException;
...@@ -14,8 +14,8 @@ import org.springframework.security.config.http.SessionCreationPolicy; ...@@ -14,8 +14,8 @@ import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.AuthenticationEntryPoint;
import com.jh.common.security.repository.AppUserRepository; import com.jh.boot.security.repository.AppUserRepository;
import com.jh.common.security.service.AppUserAuthService; import com.jh.boot.security.service.AppUserAuthService;
/** /**
* The Class ReactApplicationSecurityContext. * The Class ReactApplicationSecurityContext.
......
package com.jh.common.security; package com.jh.boot.security;
/** /**
* The Class PasswordHash. * The Class PasswordHash.
......
package com.jh.common.security; package com.jh.boot.security;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 28. 7. 2017 9:44:08 * Created on 28. 7. 2017 9:44:08
* *
*/ */
package com.jh.common.security.api; package com.jh.boot.security.api;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64; import java.util.Base64;
...@@ -26,14 +26,14 @@ import org.springframework.web.bind.annotation.RequestMethod; ...@@ -26,14 +26,14 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
import com.jh.common.security.AuthError; import com.jh.boot.security.AuthError;
import com.jh.common.security.AuthService; import com.jh.boot.security.AuthService;
import com.jh.common.security.PasswordUtils; import com.jh.boot.security.PasswordUtils;
import com.jh.common.utils.Utils; import com.jh.boot.utils.Utils;
import com.jh.common.web.error.BadRequestException; import com.jh.boot.web.error.BadRequestException;
import com.jh.common.web.error.ErrorMessage; import com.jh.boot.web.error.ErrorMessage;
import com.jh.common.web.error.NotFoundException; import com.jh.boot.web.error.NotFoundException;
import com.jh.common.web.error.RestApiException; import com.jh.boot.web.error.RestApiException;
/** /**
* The Class AuthController. * The Class AuthController.
......
package com.jh.common.security.api; package com.jh.boot.security.api;
public class LoginRequest { public class LoginRequest {
......
package com.jh.common.security.api; package com.jh.boot.security.api;
public class LoginResponse { public class LoginResponse {
......
package com.jh.common.security.api; package com.jh.boot.security.api;
public class ResetPassword { public class ResetPassword {
......
package com.jh.common.security.api; package com.jh.boot.security.api;
public class Signup { public class Signup {
......
...@@ -2,13 +2,13 @@ ...@@ -2,13 +2,13 @@
* Created on 24. 1. 2018 9:08:52 * Created on 24. 1. 2018 9:08:52
* *
*/ */
package com.jh.common.security.model; package com.jh.boot.security.model;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Table; import javax.persistence.Table;
import com.jh.common.jpa.AbstractIdEntity; import com.jh.boot.jpa.AbstractIdEntity;
/** /**
* The Class AppRole. * The Class AppRole.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 27. 7. 2017 15:46:57 * Created on 27. 7. 2017 15:46:57
* *
*/ */
package com.jh.common.security.model; package com.jh.boot.security.model;
import java.util.Set; import java.util.Set;
...@@ -14,7 +14,7 @@ import javax.persistence.ManyToMany; ...@@ -14,7 +14,7 @@ import javax.persistence.ManyToMany;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Version; import javax.persistence.Version;
import com.jh.common.jpa.AbstractIdEntity; import com.jh.boot.jpa.AbstractIdEntity;
/** /**
......
package com.jh.common.security.model; package com.jh.boot.security.model;
import java.util.Date; import java.util.Date;
...@@ -6,7 +6,7 @@ import javax.persistence.Column; ...@@ -6,7 +6,7 @@ import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Table; import javax.persistence.Table;
import com.jh.common.jpa.AbstractIdEntity; import com.jh.boot.jpa.AbstractIdEntity;
@Entity @Entity
@Table(name = "RESET_PASSWORD_TOKEN") @Table(name = "RESET_PASSWORD_TOKEN")
......
package com.jh.common.security.repository; package com.jh.boot.security.repository;
import javax.persistence.Query; import javax.persistence.Query;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.jh.common.jpa.AbstractHibernateRepository; import com.jh.boot.jpa.AbstractHibernateRepository;
import com.jh.common.security.PasswordHash; import com.jh.boot.security.PasswordHash;
import com.jh.common.security.PasswordUtils; import com.jh.boot.security.PasswordUtils;
import com.jh.common.security.model.AppUser; import com.jh.boot.security.model.AppUser;
import com.jh.common.security.model.ResetPasswordToken; import com.jh.boot.security.model.ResetPasswordToken;
public class AppUserRepository extends AbstractHibernateRepository { public class AppUserRepository extends AbstractHibernateRepository {
......
package com.jh.common.security.service; package com.jh.boot.security.service;
import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
...@@ -15,14 +16,14 @@ import org.springframework.security.core.AuthenticationException; ...@@ -15,14 +16,14 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import com.jh.common.email.EmailService; import com.jh.boot.security.AuthService;
import com.jh.common.security.AuthService; import com.jh.boot.security.AuthServiceListener;
import com.jh.common.security.GrantedRole; import com.jh.boot.security.GrantedRole;
import com.jh.common.security.PasswordHash; import com.jh.boot.security.PasswordHash;
import com.jh.common.security.PasswordUtils; import com.jh.boot.security.PasswordUtils;
import com.jh.common.security.model.AppUser; import com.jh.boot.security.model.AppUser;
import com.jh.common.security.model.ResetPasswordToken; import com.jh.boot.security.model.ResetPasswordToken;
import com.jh.common.security.repository.AppUserRepository; import com.jh.boot.security.repository.AppUserRepository;
...@@ -32,7 +33,7 @@ public class AppUserAuthService implements AuthService { ...@@ -32,7 +33,7 @@ public class AppUserAuthService implements AuthService {
private AppUserRepository appUserRepository; private AppUserRepository appUserRepository;
private EmailService emailService; private Collection<AuthServiceListener> authListeners;
@Override @Override
...@@ -62,7 +63,11 @@ public class AppUserAuthService implements AuthService { ...@@ -62,7 +63,11 @@ public class AppUserAuthService implements AuthService {
if (!StringUtils.hasText(login) || !StringUtils.hasText(password)) { if (!StringUtils.hasText(login) || !StringUtils.hasText(password)) {
throw new BadCredentialsException("Bad username or password"); throw new BadCredentialsException("Bad username or password");
} }
appUserRepository.registerUser(login, password); AppUser appUser = appUserRepository.registerUser(login, password);
if (authListeners != null) {
authListeners.forEach(al -> al.registerUser(appUser));
}
} }
@Override @Override
...@@ -76,11 +81,8 @@ public class AppUserAuthService implements AuthService { ...@@ -76,11 +81,8 @@ public class AppUserAuthService implements AuthService {
ResetPasswordToken token = new ResetPasswordToken(login, new Date(), UUID.randomUUID().toString()); ResetPasswordToken token = new ResetPasswordToken(login, new Date(), UUID.randomUUID().toString());
appUserRepository.saveResetPasswordToken(token); appUserRepository.saveResetPasswordToken(token);
//TODO send email if (authListeners != null) {
if (emailService == null) { authListeners.forEach(al -> al.generateResetToken(user));
LOG.warn("Reset password email cannot be sent: no email service configured");
} else {
} }
return token.getToken(); return token.getToken();
...@@ -112,8 +114,8 @@ public class AppUserAuthService implements AuthService { ...@@ -112,8 +114,8 @@ public class AppUserAuthService implements AuthService {
} }
@Autowired(required = false) @Autowired(required = false)
public void setEmailService(EmailService emailService) { public void setAuthListeners(Collection<AuthServiceListener> authListeners) {
this.emailService = emailService; this.authListeners = authListeners;
} }
} }
package com.jh.boot.security.utils;
import java.io.StringWriter;
import java.util.Collections;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import com.jh.boot.email.Email;
import com.jh.boot.email.EmailService;
import com.jh.boot.security.AuthServiceListener;
import com.jh.boot.security.model.AppUser;
import com.jh.boot.template.TemplateService;
//TODO make it configurable
public class TemplateEmailAuthServiceListener implements AuthServiceListener {
@Autowired
private EmailService emailService;
@Autowired
private TemplateService templateService;
@Value("${security.auth.template.signup:security.auth.signup}")
private String signupTemplateCode;
@Value("${security.auth.template.signup.html:security.auth.signup.html}")
private String signupTemplateHtmlCode;
@Value("${security.auth.template.resetPassword:security.auth.resetPassword}")
private String resetPasswordTemplateCode;
@Override
public void registerUser(AppUser user) {
StringWriter sw = new StringWriter();
templateService.evaluate(sw, signupTemplateCode, Collections.singletonMap("user", user), Locale.ENGLISH);
Email email = new Email();
email.setText(sw.toString());
emailService.sendEmail(email);
}
@Override
public void generateResetToken(AppUser user) {
StringWriter sw = new StringWriter();
templateService.evaluate(sw, resetPasswordTemplateCode, Collections.singletonMap("user", user), Locale.ENGLISH);
}
}
package com.jh.common.template; package com.jh.boot.template;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
......
package com.jh.common.template; package com.jh.boot.template;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Table; import javax.persistence.Table;
import com.jh.common.jpa.AbstractIdEntity; import com.jh.boot.jpa.AbstractIdEntity;
@Entity @Entity
@Table(name = "CUSTOMIZABLE_TEMPLATE") @Table(name = "CUSTOMIZABLE_TEMPLATE")
......
package com.jh.boot.template;
import java.io.Writer;
import java.util.Map;
public interface TemplateEngine {
void evaluate(Writer writer, String templateCode, Map<String, Object> data);
void evaluateInline(Writer writer, String template, Map<String, Object> data);
}
\ No newline at end of file
package com.jh.common.template; package com.jh.boot.template;
public interface TemplateLoader { public interface TemplateLoader {
String loadTemplate(String code);
} }
package com.jh.common.template; package com.jh.boot.template;
import java.io.Writer; import java.io.Writer;
import java.util.Locale; import java.util.Locale;
...@@ -8,6 +8,4 @@ public interface TemplateService { ...@@ -8,6 +8,4 @@ public interface TemplateService {
void evaluate(Writer writer, String templateCode, Map<String, Object> data, Locale locale); void evaluate(Writer writer, String templateCode, Map<String, Object> data, Locale locale);
void evaluateInline(Writer writer, String template, Map<String, Object> data, Locale locale);
} }
package com.jh.common.template.customizable; package com.jh.boot.template.customizable;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
...@@ -7,8 +7,8 @@ import javax.persistence.Query; ...@@ -7,8 +7,8 @@ import javax.persistence.Query;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.jh.common.jpa.AbstractHibernateRepository; import com.jh.boot.jpa.AbstractHibernateRepository;
import com.jh.common.template.Template; import com.jh.boot.template.Template;
@Repository @Repository
...@@ -25,10 +25,10 @@ public class CustomizableLabelsRepository extends AbstractHibernateRepository { ...@@ -25,10 +25,10 @@ public class CustomizableLabelsRepository extends AbstractHibernateRepository {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<CustomizableTemplateLabel> findCustomizedTemplateLabels(Long templateId, Long unitId) { public List<CustomizableTemplateLabel> findCustomizedTemplateLabels(String templateCode, Long unitId) {
Query q = entityManager.createQuery("select tl from TemplateLabel tl left join tl.template t where t.id = :templateId and tl.unitId = :unitId order by tl.position asc"); Query q = entityManager.createQuery("select tl from TemplateLabel tl left join tl.template t where t.code = :templateCode and tl.unitId = :unitId order by tl.position asc");
q.setParameter("template.id", templateId); q.setParameter("templateCode", templateCode);
q.setParameter("unitId", unitId); q.setParameter("unitId", unitId);
return q.getResultList(); return q.getResultList();
...@@ -36,9 +36,9 @@ public class CustomizableLabelsRepository extends AbstractHibernateRepository { ...@@ -36,9 +36,9 @@ public class CustomizableLabelsRepository extends AbstractHibernateRepository {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public List<CustomizableTemplateLabel> findDefaultTemplateLabels(Long templateId) { public List<CustomizableTemplateLabel> findDefaultTemplateLabels(String templateCode) {
Query q = entityManager.createQuery("select tl from TemplateLabel tl left join tl.template t where t.id = :templateId and tl.unitId is null"); Query q = entityManager.createQuery("select tl from TemplateLabel tl left join tl.template t where t.code = :templateCode and tl.unitId is null");
q.setParameter("template.id", templateId); q.setParameter("templateCode", templateCode);
return q.getResultList(); return q.getResultList();
} }
......
package com.jh.common.template.customizable; package com.jh.boot.template.customizable;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
...@@ -13,29 +13,21 @@ import org.springframework.beans.factory.annotation.Value; ...@@ -13,29 +13,21 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import com.jh.common.template.Template;
@Service @Service
public class CustomizableLabelsService { public class CustomizableLabelsService {
private CustomizableLabelsRepository repo; private CustomizableLabelsRepository repo;
private Map<Long, CustomizableTemplateLabels> templateLabelsCache = new HashMap<>(); private Map<String, CustomizableTemplateLabels> templateLabelsCache = new HashMap<>();
private boolean useCache; private boolean useCache;
@Transactional @Transactional
public Template getTemplateContent(String code) { public Map<String, CustomizableTemplateLabel> getCustomizationTemplateLabels(String templateCode, Long unitId, String defaultLanguage) {
return repo.fetchTemplate(code); TemplateLabels templateLabels = getTemplateDefaultLabels(templateCode);
} List<CustomizableTemplateLabel> labels = repo.findCustomizedTemplateLabels(templateCode, unitId);
@Transactional
public Map<String, CustomizableTemplateLabel> getCustomizationTemplateLabels(Long templateId, Long unitId, String defaultLanguage) {
TemplateLabels templateLabels = getTemplateDefaultLabels(templateId);
List<CustomizableTemplateLabel> labels = repo.findCustomizedTemplateLabels(templateId, unitId);
Map<String, CustomizableTemplateLabel> defaultMap = templateLabels.getLanguages().get(defaultLanguage); Map<String, CustomizableTemplateLabel> defaultMap = templateLabels.getLanguages().get(defaultLanguage);
if (defaultMap == null) { if (defaultMap == null) {
...@@ -70,9 +62,9 @@ public class CustomizableLabelsService { ...@@ -70,9 +62,9 @@ public class CustomizableLabelsService {
} }
@Transactional @Transactional
public Map<String, String> getTranslatedTemplateLabels(Long templateId, Long unitId, String defaultLanguage) { public Map<String, String> getTranslatedTemplateLabels(String templateCode, Long unitId, String defaultLanguage) {
TemplateLabels templateLabels = getTemplateDefaultLabels(templateId); TemplateLabels templateLabels = getTemplateDefaultLabels(templateCode);
List<CustomizableTemplateLabel> labels = repo.findCustomizedTemplateLabels(templateId, unitId); List<CustomizableTemplateLabel> labels = repo.findCustomizedTemplateLabels(templateCode, unitId);
Map<String, CustomizableTemplateLabel> defaultMap = templateLabels.getLanguages().get(defaultLanguage); Map<String, CustomizableTemplateLabel> defaultMap = templateLabels.getLanguages().get(defaultLanguage);
if (defaultMap == null) { if (defaultMap == null) {
...@@ -98,14 +90,14 @@ public class CustomizableLabelsService { ...@@ -98,14 +90,14 @@ public class CustomizableLabelsService {
} }
@Transactional @Transactional
public List<CustomizableTemplateLabel> fetchLabels(Long templateId, Long unitId) { public List<CustomizableTemplateLabel> fetchLabels(String templateCode, Long unitId) {
return repo.findCustomizedTemplateLabels(templateId, unitId); return repo.findCustomizedTemplateLabels(templateCode, unitId);
} }
@Transactional @Transactional
public TemplateLabels getTemplateDefaultLabels(Long templateId) { public TemplateLabels getTemplateDefaultLabels(String templateCode) {
CustomizableTemplateLabels labels = useCache ? templateLabelsCache.get(templateId) : null; CustomizableTemplateLabels labels = useCache ? templateLabelsCache.get(templateCode) : null;
if (labels != null) { if (labels != null) {
return labels; return labels;
} }
...@@ -115,7 +107,7 @@ public class CustomizableLabelsService { ...@@ -115,7 +107,7 @@ public class CustomizableLabelsService {
Map<String, Map<String, CustomizableTemplateLabel>> maps = new HashMap<>(); Map<String, Map<String, CustomizableTemplateLabel>> maps = new HashMap<>();
Map<String, CustomizableTemplateLabel> fallbackMap = new HashMap<>(); Map<String, CustomizableTemplateLabel> fallbackMap = new HashMap<>();
List<CustomizableTemplateLabel> defaultLabels = repo.findDefaultTemplateLabels(templateId); List<CustomizableTemplateLabel> defaultLabels = repo.findDefaultTemplateLabels(templateCode);
//keep order //keep order
...@@ -160,7 +152,7 @@ public class CustomizableLabelsService { ...@@ -160,7 +152,7 @@ public class CustomizableLabelsService {
} }
if (useCache) { if (useCache) {
templateLabelsCache.put(templateId, labels); templateLabelsCache.put(templateCode, labels);
} }
return labels; return labels;
} }
...@@ -171,32 +163,32 @@ public class CustomizableLabelsService { ...@@ -171,32 +163,32 @@ public class CustomizableLabelsService {
repo.saveCustomizedLabels(labels); repo.saveCustomizedLabels(labels);
} }
//
@Transactional // @Transactional
public void saveCustomizedLabels(Long unitId, Long templateId, Map<String, String> labels) { // public void saveCustomizedLabels(Long unitId, String templateCode, Map<String, String> labels) {
Map<String, String> map = new HashMap<>(labels); // Map<String, String> map = new HashMap<>(labels);
List<CustomizableTemplateLabel> list = repo.findCustomizedTemplateLabels(templateId, unitId); // List<CustomizableTemplateLabel> list = repo.findCustomizedTemplateLabels(templateCode, unitId);
//
for (CustomizableTemplateLabel label : list) { // for (CustomizableTemplateLabel label : list) {
String s = map.get(label.getCode()); // String s = map.get(label.getCode());
if (s == null) { // if (s == null) {
repo.delete(label); // repo.delete(label);
} else { // } else {
label.setLabel(s); // label.setLabel(s);
repo.save(label); // repo.save(label);
map.remove(label.getCode()); // map.remove(label.getCode());
} // }
} // }
//
for (Entry<String, String> e : map.entrySet()) { // for (Entry<String, String> e : map.entrySet()) {
CustomizableTemplateLabel label = new CustomizableTemplateLabel(); // CustomizableTemplateLabel label = new CustomizableTemplateLabel();
label.setUnitId(unitId); // label.setUnitId(unitId);
label.setTemplate(new Template(templateId)); // label.setTemplate(new Template(templateCode));
label.setCode(e.getKey()); // label.setCode(e.getKey());
label.setLabel(e.getValue()); // label.setLabel(e.getValue());
repo.save(label); // repo.save(label);
} // }
} // }
@Autowired(required = false) @Autowired(required = false)
......
package com.jh.common.template.customizable; package com.jh.boot.template.customizable;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
...@@ -8,8 +8,8 @@ import javax.persistence.Table; ...@@ -8,8 +8,8 @@ import javax.persistence.Table;
import javax.persistence.Transient; import javax.persistence.Transient;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.jh.common.jpa.AbstractIdEntity; import com.jh.boot.jpa.AbstractIdEntity;
import com.jh.common.template.Template; import com.jh.boot.template.Template;
@Entity @Entity
......
package com.jh.boot.template.customizable;
import java.io.Writer;
import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import com.jh.boot.template.TemplateEngine;
import com.jh.boot.template.TemplateService;
public class CustomizableTemplateService implements TemplateService {
@Autowired
private TemplateEngine engine;
@Autowired
private CustomizableLabelsService labelsService;
@Override
public void evaluate(Writer writer, String templateCode, Map<String, Object> data, Locale locale) {
if (data == null) {
data = Collections.emptyMap();
}
Map<String, String> labels = labelsService.getTranslatedTemplateLabels(templateCode, null, locale.toString());
data = new HashMap<String, Object>(data);
data.put("labels", locale);
engine.evaluate(writer, templateCode, data);
}
}
package com.jh.common.template.customizable; package com.jh.boot.template.customizable;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
......
package com.jh.common.template.customizable; package com.jh.boot.template.customizable;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import com.jh.common.jpa.AbstractIdEntity; import com.jh.boot.jpa.AbstractIdEntity;
import com.jh.common.template.Template; import com.jh.boot.template.Template;
//@Entity //@Entity
//@Table(name = "CUSTOMIZABLE_TEMPLATE_PARAM") //@Table(name = "CUSTOMIZABLE_TEMPLATE_PARAM")
......
package com.jh.common.template.customizable; package com.jh.boot.template.customizable;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import com.jh.common.jpa.AbstractIdEntity; import com.jh.boot.jpa.AbstractIdEntity;
import com.jh.common.template.Template; import com.jh.boot.template.Template;
//@Entity //@Entity
//@Table(name = "CUSTOMIZABLE_TEMPLATE_PARAM") //@Table(name = "CUSTOMIZABLE_TEMPLATE_PARAM")
......
package com.jh.common.template.customizable; package com.jh.boot.template.customizable;
import javax.persistence.Column; import javax.persistence.Column;
import com.jh.common.jpa.AbstractIdEntity; import com.jh.boot.jpa.AbstractIdEntity;
//@Entity //@Entity
//@Table(name = "CUSTOMIZABLE_TEMPLATE_SETTINGS") //@Table(name = "CUSTOMIZABLE_TEMPLATE_SETTINGS")
......
package com.jh.common.template.handlebars; package com.jh.boot.template.handlebars;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.Writer; import java.io.Writer;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
...@@ -23,9 +20,10 @@ import com.github.jknack.handlebars.Options; ...@@ -23,9 +20,10 @@ import com.github.jknack.handlebars.Options;
import com.github.jknack.handlebars.Template; import com.github.jknack.handlebars.Template;
import com.github.jknack.handlebars.context.JavaBeanValueResolver; import com.github.jknack.handlebars.context.JavaBeanValueResolver;
import com.github.jknack.handlebars.context.MapValueResolver; import com.github.jknack.handlebars.context.MapValueResolver;
import com.jh.common.i18n.I18nContext; import com.jh.boot.i18n.I18nContext;
import com.jh.common.i18n.I18nUtils; import com.jh.boot.i18n.I18nUtils;
import com.jh.common.template.TemplateService; import com.jh.boot.template.TemplateEngine;
import com.jh.boot.template.TemplateLoader;
/** /**
...@@ -64,16 +62,16 @@ import com.jh.common.template.TemplateService; ...@@ -64,16 +62,16 @@ import com.jh.common.template.TemplateService;
* *
* @author Jan Hrabal * @author Jan Hrabal
*/ */
public class HandlebarsTemplateService implements TemplateService { public class HandlebarsTemplateEngine implements TemplateEngine {
/** The use cache. */
private boolean useCache = false; private boolean useCache = false;
/** The template cache. */
private Map<String, Template> templateCache; private Map<String, Template> templateCache;
private Handlebars handlebars; private Handlebars handlebars;
private TemplateLoader templateLoader;
/** /**
* Initializes instance. * Initializes instance.
...@@ -151,30 +149,32 @@ public class HandlebarsTemplateService implements TemplateService { ...@@ -151,30 +149,32 @@ public class HandlebarsTemplateService implements TemplateService {
@Override @Override
public void evaluate(Writer writer, String templateCode, Map<String, Object> data, Locale locale) { public void evaluate(Writer writer, String templateCode, Map<String, Object> data) {
String name = "template://" + templateCode; String name = "template://" + templateCode;
Template template = useCache ? templateCache.get(name) : null; Template template = useCache ? templateCache.get(name) : null;
//TODO read template
if (template == null) { if (template == null) {
String s = templateLoader.loadTemplate(templateCode);
if (s == null) {
throw new RuntimeException(String.format("Template %s not found", templateCode));
}
try {
template = handlebars.compileInline(s); template = handlebars.compileInline(s);
} catch (IOException e) {
throw new RuntimeException("Cannot evaluate template", e);
}
if (useCache) { if (useCache) {
templateCache.put(name, template); templateCache.put(name, template);
} }
} }
evaluateTemplate(template, data, locale, writer); evaluateTemplate(template, data, writer);
} }
@Override @Override
public void evaluateInline(Writer writer, String template, Map<String, Object> data, Locale locale) { public void evaluateInline(Writer writer, String template, Map<String, Object> data) {
if (locale == null) {
locale = Locale.ENGLISH;
}
String name = "inline://" + template; String name = "inline://" + template;
Template t = useCache ? templateCache.get(name) : null; Template t = useCache ? templateCache.get(name) : null;
...@@ -189,11 +189,11 @@ public class HandlebarsTemplateService implements TemplateService { ...@@ -189,11 +189,11 @@ public class HandlebarsTemplateService implements TemplateService {
} }
} }
evaluateTemplate(t, data, locale, writer); evaluateTemplate(t, data, writer);
} }
protected void evaluateTemplate(Template t, Map<String, Object> data, Locale locale, Writer writer) { protected void evaluateTemplate(Template t, Map<String, Object> data, Writer writer) {
Context context = Context Context context = Context
.newBuilder(data) .newBuilder(data)
.combine(data) .combine(data)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 19. 12. 2017 12:29:34 * Created on 19. 12. 2017 12:29:34
* *
*/ */
package com.jh.common.utils; package com.jh.boot.utils;
import java.util.Base64; import java.util.Base64;
import java.util.Base64.Encoder; import java.util.Base64.Encoder;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 27. 8. 2017 20:53:14 * Created on 27. 8. 2017 20:53:14
* *
*/ */
package com.jh.common.utils; package com.jh.boot.utils;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalTime; import java.time.LocalTime;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 2. 8. 2017 9:50:42 * Created on 2. 8. 2017 9:50:42
* *
*/ */
package com.jh.common.utils; package com.jh.boot.utils;
import java.io.InputStream; import java.io.InputStream;
import java.util.Scanner; import java.util.Scanner;
......
package com.jh.common.utils; package com.jh.boot.utils;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 29. 1. 2018 13:40:45 * Created on 29. 1. 2018 13:40:45
* *
*/ */
package com.jh.common.web; package com.jh.boot.web;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Locale; import java.util.Locale;
......
package com.jh.common.web; package com.jh.boot.web;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException; import org.springframework.orm.hibernate5.HibernateOptimisticLockingFailureException;
......
package com.jh.common.web; package com.jh.boot.web;
import java.util.List; import java.util.List;
...@@ -20,8 +20,8 @@ import com.fasterxml.jackson.databind.SerializationFeature; ...@@ -20,8 +20,8 @@ import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module; import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module.Feature; import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module.Feature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.jh.common.web.list.PagingArgumentResolver; import com.jh.boot.web.list.PagingArgumentResolver;
import com.jh.common.web.list.SortingArgumentResolver; import com.jh.boot.web.list.SortingArgumentResolver;
public class JhWebConfig implements WebMvcConfigurer { public class JhWebConfig implements WebMvcConfigurer {
......
package com.jh.common.web; package com.jh.boot.web;
import java.beans.PropertyEditorSupport; import java.beans.PropertyEditorSupport;
import java.time.LocalDate; import java.time.LocalDate;
......
package com.jh.common.web.error; package com.jh.boot.web.error;
import java.util.Collection; import java.util.Collection;
......
package com.jh.common.web.error; package com.jh.boot.web.error;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 9. 10. 2017 14:36:28 * Created on 9. 10. 2017 14:36:28
* *
*/ */
package com.jh.common.web.error; package com.jh.boot.web.error;
/** /**
* The Interface ErrorMessages. * The Interface ErrorMessages.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 9. 11. 2017 10:26:30 * Created on 9. 11. 2017 10:26:30
* *
*/ */
package com.jh.common.web.error; package com.jh.boot.web.error;
import java.util.Collection; import java.util.Collection;
......
package com.jh.common.web.error; package com.jh.boot.web.error;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
......
package com.jh.common.web.error; package com.jh.boot.web.error;
import java.util.Collection; import java.util.Collection;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 24. 1. 2018 8:46:58 * Created on 24. 1. 2018 8:46:58
* *
*/ */
package com.jh.common.web.error; package com.jh.boot.web.error;
import java.util.Collection; import java.util.Collection;
...@@ -48,7 +48,7 @@ public class RestApiException extends ErrorMessagesException implements ErrorSta ...@@ -48,7 +48,7 @@ public class RestApiException extends ErrorMessagesException implements ErrorSta
* Gets the error status. * Gets the error status.
* *
* @return the error status * @return the error status
* @see com.jh.common.web.error.ErrorStatus#getErrorStatus() * @see com.jh.boot.web.error.ErrorStatus#getErrorStatus()
*/ */
@Override @Override
public HttpStatus getErrorStatus() { public HttpStatus getErrorStatus() {
......
package com.jh.common.web.error; package com.jh.boot.web.error;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 25. 8. 2017 18:29:24 * Created on 25. 8. 2017 18:29:24
* *
*/ */
package com.jh.common.web.list; package com.jh.boot.web.list;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
......
package com.jh.common.web.list; package com.jh.boot.web.list;
/** /**
* Default implementation of {@link SortingInfo}. * Default implementation of {@link SortingInfo}.
...@@ -27,7 +27,7 @@ public class DefaultSortingInfo implements SortingInfo { ...@@ -27,7 +27,7 @@ public class DefaultSortingInfo implements SortingInfo {
/** /**
* @return * @return
* @see com.jh.common.web.list.SortingInfo#getField() * @see com.jh.boot.web.list.SortingInfo#getField()
*/ */
@Override @Override
public String getField() { public String getField() {
...@@ -36,7 +36,7 @@ public class DefaultSortingInfo implements SortingInfo { ...@@ -36,7 +36,7 @@ public class DefaultSortingInfo implements SortingInfo {
/** /**
* @return * @return
* @see com.jh.common.web.list.SortingInfo#getTrend() * @see com.jh.boot.web.list.SortingInfo#getTrend()
*/ */
@Override @Override
public SortTrend getTrend() { public SortTrend getTrend() {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 3. 11. 2016 9:19:23 * Created on 3. 11. 2016 9:19:23
* *
*/ */
package com.jh.common.web.list; package com.jh.boot.web.list;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
...@@ -13,7 +13,7 @@ import org.springframework.http.ResponseEntity; ...@@ -13,7 +13,7 @@ import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.NativeWebRequest;
import com.jh.common.utils.Utils; import com.jh.boot.utils.Utils;
/** /**
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 12. 10. 2016 13:01:20 * Created on 12. 10. 2016 13:01:20
* *
*/ */
package com.jh.common.web.list; package com.jh.boot.web.list;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
......
package com.jh.common.web.list; package com.jh.boot.web.list;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.bind.support.WebDataBinderFactory;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 13. 10. 2016 17:11:34 * Created on 13. 10. 2016 17:11:34
* *
*/ */
package com.jh.common.web.list; package com.jh.boot.web.list;
/** /**
* TODO. * TODO.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 30. 10. 2016 7:32:25 * Created on 30. 10. 2016 7:32:25
* *
*/ */
package com.jh.common.web.list; package com.jh.boot.web.list;
/** /**
* The Enum SortTrend. * The Enum SortTrend.
......
package com.jh.common.web.list; package com.jh.boot.web.list;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.bind.support.WebDataBinderFactory;
...@@ -6,7 +6,7 @@ import org.springframework.web.context.request.NativeWebRequest; ...@@ -6,7 +6,7 @@ import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.method.support.ModelAndViewContainer;
import com.jh.common.utils.Utils; import com.jh.boot.utils.Utils;
/** /**
* The Class SortingArgumentResolver. * The Class SortingArgumentResolver.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Created on 13. 10. 2016 17:11:34 * Created on 13. 10. 2016 17:11:34
* *
*/ */
package com.jh.common.web.list; package com.jh.boot.web.list;
/** /**
* TODO. * TODO.
......
package com.jh.common.template;
import java.io.Writer;
import java.util.Locale;
import java.util.Map;
public interface TemplateEngine {
/**
* TODO.
*
* @param templateName the template name
* @param clazz the clazz
* @param data the data
* @param locale the locale
* @param writer the writer
*/
void evaluateTemplate(String templateName, Class<?> clazz, Map<String, Object> data, Locale locale, Writer writer);
/**
* TODO.
*
* @param template the template
* @param data the data
* @param locale the locale
* @param writer the writer
*/
void evaluateTemplate(String template, Map<String, Object> data, Locale locale, Writer writer);
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment