add notification template entity

This commit is contained in:
amentis 2023-12-18 13:13:29 +02:00
parent f06d3de1ec
commit 18a1d43f01
43 changed files with 2888 additions and 3 deletions

View File

@ -0,0 +1,123 @@
package gr.cite.notification.web.controllers;
import gr.cite.notification.audit.AuditableAction;
import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.data.NotificationTemplateEntity;
import gr.cite.notification.model.NotificationTemplate;
import gr.cite.notification.model.builder.NotificationTemplateBuilder;
import gr.cite.notification.model.censorship.NotificationTemplateCensor;
import gr.cite.notification.model.persist.NotificationTemplatePersist;
import gr.cite.notification.query.NotificationTemplateQuery;
import gr.cite.notification.query.lookup.NotificationTemplateLookup;
import gr.cite.notification.service.notificationtemplate.NotificationTemplateService;
import gr.cite.notification.web.model.QueryResult;
import gr.cite.tools.auditing.AuditService;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.data.censor.CensorFactory;
import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.exception.MyForbiddenException;
import gr.cite.tools.exception.MyNotFoundException;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry;
import gr.cite.tools.validation.MyValidate;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*;
import javax.management.InvalidApplicationException;
import javax.transaction.Transactional;
import java.util.*;
@RestController
@RequestMapping(path = "api/notification-template")
public class NotificationTemplateController {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(NotificationTemplateController.class));
private final BuilderFactory builderFactory;
private final AuditService auditService;
private final NotificationTemplateService notificationTemplateService;
private final CensorFactory censorFactory;
private final QueryFactory queryFactory;
private final MessageSource messageSource;
@Autowired
public NotificationTemplateController(BuilderFactory builderFactory,
AuditService auditService,
NotificationTemplateService notificationTemplateService,
CensorFactory censorFactory,
QueryFactory queryFactory,
MessageSource messageSource) {
this.builderFactory = builderFactory;
this.auditService = auditService;
this.notificationTemplateService = notificationTemplateService;
this.censorFactory = censorFactory;
this.queryFactory = queryFactory;
this.messageSource = messageSource;
}
@PostMapping("query")
public QueryResult<NotificationTemplate> query(@RequestBody NotificationTemplateLookup lookup) throws MyApplicationException, MyForbiddenException {
logger.debug("querying {}", NotificationTemplate.class.getSimpleName());
this.censorFactory.censor(NotificationTemplateCensor.class).censor(lookup.getProject());
NotificationTemplateQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrPermission);
List<NotificationTemplateEntity> data = query.collectAs(lookup.getProject());
List<NotificationTemplate> models = this.builderFactory.builder(NotificationTemplateBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(lookup.getProject(), data);
long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size();
this.auditService.track(AuditableAction.Notification_Template_Query, "lookup", lookup);
return new QueryResult<>(models, count);
}
@GetMapping("{id}")
@Transactional
public NotificationTemplate get(@PathVariable UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
logger.debug(new MapLogEntry("retrieving" + NotificationTemplate.class.getSimpleName()).And("id", id).And("fields", fieldSet));
this.censorFactory.censor(NotificationTemplateCensor.class).censor(fieldSet);
NotificationTemplateQuery query = this.queryFactory.query(NotificationTemplateQuery.class).authorize(AuthorizationFlags.OwnerOrPermission).ids(id);
NotificationTemplate model = this.builderFactory.builder(NotificationTemplateBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(fieldSet, query.firstAs(fieldSet));
if (model == null)
throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, NotificationTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale()));
this.auditService.track(AuditableAction.Notification_Template_Lookup, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("id", id),
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
));
return model;
}
@PostMapping("persist")
@Transactional
public NotificationTemplate persist(@MyValidate @RequestBody NotificationTemplatePersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException {
logger.debug(new MapLogEntry("persisting" + NotificationTemplate.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet));
NotificationTemplate persisted = this.notificationTemplateService.persist(model, fieldSet);
this.auditService.track(AuditableAction.Notification_Template_Persist, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("model", model),
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
));
return persisted;
}
@DeleteMapping("{id}")
@Transactional
public void delete(@PathVariable("id") UUID id) throws MyForbiddenException, InvalidApplicationException {
logger.debug(new MapLogEntry("deleting" + NotificationTemplate.class.getSimpleName()).And("id", id));
this.notificationTemplateService.deleteAndSave(id);
this.auditService.track(AuditableAction.Notification_Template_Delete, "id", id);
}
}

View File

@ -76,7 +76,7 @@ notification:
optional: [ ]
body-path: classpath:notification_templates/dmpinvitationexistinguser/email/body.{language}.html
body-field-options:
mandatory: [ "{dmpname}", "{dmprole}", "{reasonName}", "{id}"]
mandatory: [ "{dmpname}", "{dmprole}", "{reasonName}", "{installation-url}", "{id}"]
optional:
- key: "{recipient}"
value:

View File

@ -140,4 +140,24 @@ permissions:
- ic-sti-superuser
clients: [ ]
allowAnonymous: false
allowAuthenticated: false
# ViewPage Permissions
BrowseNotificationTemplate:
roles:
- Admin
clients: [ ]
allowAnonymous: false
allowAuthenticated: false
EditNotificationTemplate:
roles:
- Admin
clients: [ ]
allowAnonymous: false
allowAuthenticated: false
DeleteNotificationTemplate:
roles:
- Admin
clients: [ ]
allowAnonymous: false
allowAuthenticated: false

View File

@ -76,7 +76,7 @@ notification:
optional: [ ]
body-path: classpath:notification_templates/dmpinvitationexistinguser/email/body.{language}.html
body-field-options:
mandatory: [ "{dmpname}", "{dmprole}", "{reasonName}" ]
mandatory: [ "{dmpname}", "{dmprole}", "{reasonName}", "{installation-url}", "{id}"]
optional:
- key: "{recipient}"
value:

View File

@ -140,4 +140,24 @@ permissions:
- ic-sti-superuser
clients: [ ]
allowAnonymous: false
allowAuthenticated: false
# ViewPage Permissions
BrowseNotificationTemplate:
roles:
- Admin
clients: [ ]
allowAnonymous: false
allowAuthenticated: false
EditNotificationTemplate:
roles:
- Admin
clients: [ ]
allowAnonymous: false
allowAuthenticated: false
DeleteNotificationTemplate:
roles:
- Admin
clients: [ ]
allowAnonymous: false
allowAuthenticated: false

View File

@ -262,6 +262,23 @@
<td>
<p>Dear {recipient},</p>
<p>{reasonName} just add you to collaborate to Data Management plan {dmpname} with role {dmprole}.</p>
<p>Click the button to redirect to {dmpname}.</p>
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
<tbody>
<tr>
<td align="left">
<table border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td> <a href="{installation-url}/plans/edit/{id}" target="_blank">Join</a> </td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>

View File

@ -20,12 +20,19 @@ public class AuditableAction {
public static final EventId InApp_Notification_Delete = new EventId(20003, "InApp_Notification_Delete");
public static final EventId InApp_Notification_Read = new EventId(20003, "InApp_Notification_Read");
public static final EventId InApp_Notification_Read_All = new EventId(20003, "InApp_Notification_Read_All");
public static final EventId Tenant_Configuration_Query = new EventId(21000, "Tenant_Configuration_Query");
public static final EventId Tenant_Configuration_Lookup = new EventId(21001, "Tenant_Configuration_Lookup");
public static final EventId Tenant_Configuration_Persist = new EventId(21002, "Tenant_Configuration_Persist");
public static final EventId Tenant_Configuration_Delete = new EventId(21003, "Tenant_Configuration_Delete");
public static final EventId User_Notification_Preference_Query = new EventId(22000, "User_Notification_Preference_Query");
public static final EventId User_Notification_Preference_Lookup = new EventId(22001, "User_Notification_Preference_Lookup");
public static final EventId User_Notification_Preference_Persist = new EventId(22002, "User_Notification_Preference_Persist");
public static final EventId User_Notification_Preference_Delete = new EventId(22003, "User_Notification_Preference_Delete");
public static final EventId Notification_Template_Query = new EventId(23000, "Notification_Template_Query");
public static final EventId Notification_Template_Lookup = new EventId(23001, "Notification_Template_Lookup");
public static final EventId Notification_Template_Persist = new EventId(23002, "Notification_Template_Persist");
public static final EventId Notification_Template_Delete = new EventId(23003, "Notification_Template_Delete");
}

View File

@ -25,10 +25,15 @@ public final class Permission {
public static final String BrowseTenantConfiguration = "BrowseTenantConfiguration";
public static final String EditTenantConfiguration = "EditTenantConfiguration";
//Notification
//Notification Preference
public static final String BrowseUserNotificationPreference = "BrowseUserNotificationPreference";
public static final String EditUserNotificationPreference = "EditUserNotificationPreference";
//Notification Template
public static final String BrowseNotificationTemplate = "BrowseNotificationTemplate";
public static String EditNotificationTemplate = "EditNotificationTemplate";
public static String DeleteNotificationTemplate = "DeleteNotificationTemplate";
// UI Pages
public static String ViewTenantConfigurationPage = "ViewTenantConfigurationPage";
public static String ViewNotificationPage = "ViewNotificationPage";

View File

@ -0,0 +1,30 @@
package gr.cite.notification.common.enums;
import com.fasterxml.jackson.annotation.JsonValue;
import gr.cite.notification.data.conventers.DatabaseEnum;
import java.util.Map;
public enum NotificationTemplateChannel implements DatabaseEnum<Short> {
Email((short)0),
InApp((short)1);
private final Short value;
NotificationTemplateChannel(Short value) {
this.value = value;
}
@JsonValue
public Short getValue() {
return value;
}
private static final Map<Short, NotificationTemplateChannel> map = EnumUtils.getEnumValueMap(NotificationTemplateChannel.class);
public static NotificationTemplateChannel of(Short i) {
return map.get(i);
}
}

View File

@ -0,0 +1,30 @@
package gr.cite.notification.common.enums;
import com.fasterxml.jackson.annotation.JsonValue;
import gr.cite.notification.data.conventers.DatabaseEnum;
import java.util.Map;
public enum NotificationTemplateKind implements DatabaseEnum<Short> {
Draft((short)0),
Primary((short)1);
private final Short value;
NotificationTemplateKind(Short value) {
this.value = value;
}
@JsonValue
public Short getValue() {
return value;
}
private static final Map<Short, NotificationTemplateKind> map = EnumUtils.getEnumValueMap(NotificationTemplateKind.class);
public static NotificationTemplateKind of(Short i) {
return map.get(i);
}
}

View File

@ -2,8 +2,11 @@ package gr.cite.notification.common.types.notification;
public class FieldInfo {
private String key;
public final static String _key = "key";
private DataType type;
public final static String _type = "type";
private String value;
public final static String _value = "value";
public FieldInfo(String key, DataType type, String value) {
this.key = key;

View File

@ -0,0 +1,42 @@
package gr.cite.notification.common.types.notificationtemplate;
import gr.cite.notification.common.types.notification.DataType;
public class FieldInfoEntity {
private String key;
private DataType type;
private String value;
public FieldInfoEntity(String key, DataType type, String value) {
this.key = key;
this.type = type;
this.value = value;
}
public FieldInfoEntity() {
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public DataType getType() {
return type;
}
public void setType(DataType type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@ -0,0 +1,38 @@
package gr.cite.notification.common.types.notificationtemplate;
import java.util.Dictionary;
import java.util.List;
public class FieldOptionsEntity {
private List<String> mandatory;
private List<FieldInfoEntity> optional;
private Dictionary<String, String> formatting;
public List<String> getMandatory() {
return mandatory;
}
public void setMandatory(List<String> mandatory) {
this.mandatory = mandatory;
}
public List<FieldInfoEntity> getOptional() {
return optional;
}
public void setOptional(List<FieldInfoEntity> optional) {
this.optional = optional;
}
public Dictionary<String, String> getFormatting() {
return formatting;
}
public void setFormatting(Dictionary<String, String> formatting) {
this.formatting = formatting;
}
}

View File

@ -0,0 +1,126 @@
package gr.cite.notification.common.types.notificationtemplate;
import gr.cite.notification.common.types.notification.EmailOverrideMode;
import java.util.List;
public class NotificationTemplateValueEntity {
private String subjectText;
private String subjectKey;
private FieldOptionsEntity subjectFieldOptions;
private String bodyText;
private String bodyKey;
private String priorityKey;
private Boolean allowAttachments;
private List<String> cc;
private EmailOverrideMode ccMode;
private List<String> bcc;
private EmailOverrideMode bccMode;
private List<String> extraDataKeys;
private FieldOptionsEntity bodyFieldOptions;
public String getSubjectText() {
return subjectText;
}
public void setSubjectText(String subjectText) {
this.subjectText = subjectText;
}
public String getSubjectKey() {
return subjectKey;
}
public void setSubjectKey(String subjectKey) {
this.subjectKey = subjectKey;
}
public FieldOptionsEntity getSubjectFieldOptions() {
return subjectFieldOptions;
}
public void setSubjectFieldOptions(FieldOptionsEntity subjectFieldOptions) {
this.subjectFieldOptions = subjectFieldOptions;
}
public String getBodyText() {
return bodyText;
}
public void setBodyText(String bodyText) {
this.bodyText = bodyText;
}
public String getBodyKey() {
return bodyKey;
}
public void setBodyKey(String bodyKey) {
this.bodyKey = bodyKey;
}
public String getPriorityKey() {
return priorityKey;
}
public void setPriorityKey(String priorityKey) {
this.priorityKey = priorityKey;
}
public Boolean getAllowAttachments() {
return allowAttachments;
}
public void setAllowAttachments(Boolean allowAttachments) {
this.allowAttachments = allowAttachments;
}
public List<String> getCc() {
return cc;
}
public void setCc(List<String> cc) {
this.cc = cc;
}
public EmailOverrideMode getCcMode() {
return ccMode;
}
public void setCcMode(EmailOverrideMode ccMode) {
this.ccMode = ccMode;
}
public List<String> getBcc() {
return bcc;
}
public void setBcc(List<String> bcc) {
this.bcc = bcc;
}
public EmailOverrideMode getBccMode() {
return bccMode;
}
public void setBccMode(EmailOverrideMode bccMode) {
this.bccMode = bccMode;
}
public List<String> getExtraDataKeys() {
return extraDataKeys;
}
public void setExtraDataKeys(List<String> extraDataKeys) {
this.extraDataKeys = extraDataKeys;
}
public FieldOptionsEntity getBodyFieldOptions() {
return bodyFieldOptions;
}
public void setBodyFieldOptions(FieldOptionsEntity bodyFieldOptions) {
this.bodyFieldOptions = bodyFieldOptions;
}
}

View File

@ -0,0 +1,100 @@
package gr.cite.notification.data;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.data.conventers.IsActiveConverter;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import java.time.Instant;
import java.util.UUID;
@Entity
@Table(name = "\"Language\"")
public class LanguageEntity extends TenantScopedBaseEntity {
@Id
@Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false)
private UUID id;
public static final String _id = "id";
@Column(name = "code", length = 20, nullable = false)
private String code;
public static final String _code = "code";
@Column(name = "payload")
private String payload;
public static final String _payload = "payload";
@Column(name = "\"created_at\"", nullable = false)
private Instant createdAt;
public static final String _createdAt = "createdAt";
@Column(name = "\"updated_at\"", nullable = false)
private Instant updatedAt;
public static final String _updatedAt = "updatedAt";
@Column(name = "is_active", nullable = false)
@Convert(converter = IsActiveConverter.class)
private IsActive isActive;
public static final String _isActive = "isActive";
@Column(name = "ordinal")
private Integer ordinal;
public static final String _ordinal = "ordinal";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPayload() {
return payload;
}
public void setPayload(String payload) {
this.payload = payload;
}
public Instant getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Instant createdAt) {
this.createdAt = createdAt;
}
public Instant getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Instant updatedAt) {
this.updatedAt = updatedAt;
}
public IsActive getIsActive() {
return isActive;
}
public void setIsActive(IsActive isActive) {
this.isActive = isActive;
}
public Integer getOrdinal() {
return ordinal;
}
public void setOrdinal(Integer ordinal) {
this.ordinal = ordinal;
}
}

View File

@ -0,0 +1,126 @@
package gr.cite.notification.data;
import gr.cite.notification.common.enums.*;
import gr.cite.notification.data.conventers.*;
import gr.cite.notification.data.tenant.TenantScopedBaseEntity;
import javax.persistence.*;
import java.time.Instant;
import java.util.UUID;
@Entity
@Table(name = "\"ntf_NotificationTemplate\"")
public class NotificationTemplateEntity extends TenantScopedBaseEntity {
@Id
@Column(name = "\"id\"", columnDefinition = "uuid", updatable = false, nullable = false)
private UUID id;
public final static String _id = "id";
@Column(name = "\"channel\"", nullable = false)
@Convert(converter = NotificationTemplateChannelConverter.class)
private NotificationTemplateChannel channel;
public final static String _channel = "channel";
@Column(name = "\"notification_type\"", columnDefinition = "uuid", nullable = false)
private UUID notificationType;
public final static String _notificationType = "notificationType";
@Column(name = "\"kind\"", nullable = false)
@Convert(converter = NotificationTemplateKindConverter.class)
private NotificationTemplateKind kind;
public final static String _kind = "kind";
@Column(name = "\"language\"", columnDefinition = "uuid", nullable = false)
private UUID languageId;
public final static String _language = "language";
@Column(name = "\"value\"", nullable = false)
private String value;
public final static String _value = "value";
@Column(name = "\"is_active\"", nullable = false)
@Convert(converter = IsActiveConverter.class)
private IsActive isActive;
public final static String _isActive = "isActive";
@Column(name = "\"created_at\"", nullable = false)
private Instant createdAt;
public final static String _createdAt = "createdAt";
@Column(name = "\"updated_at\"", nullable = false)
private Instant updatedAt;
public final static String _updatedAt = "updatedAt";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public NotificationTemplateChannel getChannel() {
return channel;
}
public void setChannel(NotificationTemplateChannel channel) {
this.channel = channel;
}
public UUID getNotificationType() {
return notificationType;
}
public void setNotificationType(UUID notificationType) {
this.notificationType = notificationType;
}
public NotificationTemplateKind getKind() {
return kind;
}
public void setKind(NotificationTemplateKind kind) {
this.kind = kind;
}
public UUID getLanguageId() {
return languageId;
}
public void setLanguageId(UUID languageId) {
this.languageId = languageId;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public IsActive getIsActive() {
return isActive;
}
public void setIsActive(IsActive isActive) {
this.isActive = isActive;
}
public Instant getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Instant createdAt) {
this.createdAt = createdAt;
}
public Instant getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Instant updatedAt) {
this.updatedAt = updatedAt;
}
}

View File

@ -0,0 +1,25 @@
package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.NotificationTemplateChannel;
import javax.persistence.Converter;
@Converter
public class NotificationTemplateChannelConverter extends DatabaseEnumConverter<NotificationTemplateChannel, Short> {
public NotificationTemplateChannel of(Short i) {
return NotificationTemplateChannel.of(i);
}
@Override
public Short convertToDatabaseColumn(NotificationTemplateChannel value) {
if (value == null) return null;
return value.getValue();
}
@Override
public NotificationTemplateChannel convertToEntityAttribute(Short dbData) {
return dbData == null ? null : this.of(dbData);
}
}

View File

@ -0,0 +1,24 @@
package gr.cite.notification.data.conventers;
import gr.cite.notification.common.enums.NotificationTemplateKind;
import javax.persistence.Converter;
@Converter
public class NotificationTemplateKindConverter extends DatabaseEnumConverter<NotificationTemplateKind, Short> {
public NotificationTemplateKind of(Short i) {
return NotificationTemplateKind.of(i);
}
@Override
public Short convertToDatabaseColumn(NotificationTemplateKind value) {
if (value == null) return null;
return value.getValue();
}
@Override
public NotificationTemplateKind convertToEntityAttribute(Short dbData) {
return dbData == null ? null : this.of(dbData);
}
}

View File

@ -0,0 +1,97 @@
package gr.cite.notification.model;
import gr.cite.notification.common.enums.IsActive;
import java.time.Instant;
import java.util.UUID;
public class Language {
private UUID id;
public static final String _id = "id";
private String code;
public static final String _code = "code";
private String payload;
public static final String _payload = "payload";
private Instant createdAt;
public static final String _createdAt = "createdAt";
private Instant updatedAt;
public static final String _updatedAt = "updatedAt";
private IsActive isActive;
public static final String _isActive = "isActive";
private Integer ordinal;
public static final String _ordinal = "ordinal";
private String hash;
public final static String _hash = "hash";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPayload() {
return payload;
}
public void setPayload(String payload) {
this.payload = payload;
}
public Instant getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Instant createdAt) {
this.createdAt = createdAt;
}
public Instant getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Instant updatedAt) {
this.updatedAt = updatedAt;
}
public IsActive getIsActive() {
return isActive;
}
public void setIsActive(IsActive isActive) {
this.isActive = isActive;
}
public Integer getOrdinal() {
return ordinal;
}
public void setOrdinal(Integer ordinal) {
this.ordinal = ordinal;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
}

View File

@ -0,0 +1,134 @@
package gr.cite.notification.model;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.enums.NotificationTemplateChannel;
import gr.cite.notification.common.enums.NotificationTemplateKind;
import gr.cite.notification.model.notificationtemplate.NotificationTemplateValue;
import java.time.Instant;
import java.util.UUID;
public class NotificationTemplate {
private UUID id;
public final static String _id = "id";
private NotificationTemplateChannel channel;
public final static String _channel = "channel";
private UUID notificationType;
public final static String _notificationType = "notificationType";
private NotificationTemplateKind kind;
public final static String _kind = "kind";
private Language language;
public final static String _language = "language";
private NotificationTemplateValue value;
public final static String _value = "value";
private IsActive isActive;
public final static String _isActive = "isActive";
private Instant createdAt;
public final static String _createdAt = "createdAt";
private Instant updatedAt;
public final static String _updatedAt = "updatedAt";
private Tenant tenant;
public final static String _tenant = "tenant";
private String hash;
public final static String _hash = "hash";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public NotificationTemplateChannel getChannel() {
return channel;
}
public void setChannel(NotificationTemplateChannel channel) {
this.channel = channel;
}
public UUID getNotificationType() {
return notificationType;
}
public void setNotificationType(UUID notificationType) {
this.notificationType = notificationType;
}
public NotificationTemplateKind getKind() {
return kind;
}
public void setKind(NotificationTemplateKind kind) {
this.kind = kind;
}
public Language getLanguage() {
return language;
}
public void setLanguage(Language language) {
this.language = language;
}
public NotificationTemplateValue getValue() {
return value;
}
public void setValue(NotificationTemplateValue value) {
this.value = value;
}
public IsActive getIsActive() {
return isActive;
}
public void setIsActive(IsActive isActive) {
this.isActive = isActive;
}
public Instant getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Instant createdAt) {
this.createdAt = createdAt;
}
public Instant getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Instant updatedAt) {
this.updatedAt = updatedAt;
}
public Tenant getTenant() {
return tenant;
}
public void setTenant(Tenant tenant) {
this.tenant = tenant;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
}

View File

@ -0,0 +1,59 @@
package gr.cite.notification.model.builder;
import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.convention.ConventionService;
import gr.cite.notification.data.LanguageEntity;
import gr.cite.notification.model.Language;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class LanguageBuilder extends BaseBuilder<Language, LanguageEntity>{
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public LanguageBuilder(
ConventionService conventionService) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(LanguageBuilder.class)));
}
public LanguageBuilder authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
public List<Language> build(FieldSet fields, List<LanguageEntity> data) throws MyApplicationException {
this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0));
this.logger.trace(new DataLogEntry("requested fields", fields));
if (fields == null || data == null || fields.isEmpty())
return new ArrayList<>();
List<Language> models = new ArrayList<>();
for (LanguageEntity d : data) {
Language m = new Language();
if (fields.hasField(this.asIndexer(Language._id))) m.setId(d.getId());
if (fields.hasField(this.asIndexer(Language._code))) m.setCode(d.getCode());
if (fields.hasField(this.asIndexer(Language._payload))) m.setPayload(d.getPayload());
if (fields.hasField(this.asIndexer(Language._ordinal))) m.setOrdinal(d.getOrdinal());
if (fields.hasField(this.asIndexer(Language._createdAt))) m.setCreatedAt(d.getCreatedAt());
if (fields.hasField(this.asIndexer(Language._updatedAt))) m.setUpdatedAt(d.getUpdatedAt());
if (fields.hasField(this.asIndexer(Language._isActive))) m.setIsActive(d.getIsActive());
if (fields.hasField(this.asIndexer(Language._hash))) m.setHash(this.hashValue(d.getUpdatedAt()));
models.add(m);
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
return models;
}
}

View File

@ -0,0 +1,145 @@
package gr.cite.notification.model.builder;
import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.common.JsonHandlingService;
import gr.cite.notification.common.types.notificationtemplate.NotificationTemplateValueEntity;
import gr.cite.notification.convention.ConventionService;
import gr.cite.notification.data.NotificationTemplateEntity;
import gr.cite.notification.model.Language;
import gr.cite.notification.model.NotificationTemplate;
import gr.cite.notification.model.Tenant;
import gr.cite.notification.model.builder.notificationtemplate.NotificationTemplateValueBuilder;
import gr.cite.notification.model.notificationtemplate.NotificationTemplateValue;
import gr.cite.notification.query.LanguageQuery;
import gr.cite.notification.query.TenantQuery;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.fieldset.BaseFieldSet;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class NotificationTemplateBuilder extends BaseBuilder<NotificationTemplate, NotificationTemplateEntity> {
private final BuilderFactory builderFactory;
private final QueryFactory queryFactory;
private final JsonHandlingService jsonHandlingService;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public NotificationTemplateBuilder(ConventionService conventionService, BuilderFactory builderFactory, QueryFactory queryFactory, JsonHandlingService jsonHandlingService) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(NotificationTemplateBuilder.class)));
this.builderFactory = builderFactory;
this.queryFactory = queryFactory;
this.jsonHandlingService = jsonHandlingService;
}
public NotificationTemplateBuilder authorize(EnumSet<AuthorizationFlags> values){
this.authorize = values;
return this;
}
@Override
public List<NotificationTemplate> build(FieldSet fields, List<NotificationTemplateEntity> data) throws MyApplicationException {
this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0),Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size) .orElse(0));
this.logger.trace(new DataLogEntry("requested fields",fields));
if(fields == null || data == null || fields.isEmpty()) return new ArrayList<>();
FieldSet valueFields = fields.extractPrefixed(this.asPrefix(NotificationTemplate._value));
FieldSet tenantFields = fields.extractPrefixed(this.asPrefix(NotificationTemplate._tenant));
Map<UUID, Tenant> tenantMap = this.collectTenants(tenantFields, data);
FieldSet languageFields = fields.extractPrefixed(this.asPrefix(NotificationTemplate._language));
Map<UUID, Language> languageMap = this.collectLanguages(tenantFields, data);
List<NotificationTemplate> models = new ArrayList<>();
for(NotificationTemplateEntity d : data){
NotificationTemplate m = new NotificationTemplate();
if(fields.hasField(this.asIndexer(NotificationTemplate._id))) m.setId(d.getId());
if(fields.hasField(this.asIndexer(NotificationTemplate._channel))) m.setChannel(d.getChannel());
if(fields.hasField(this.asIndexer(NotificationTemplate._notificationType))) m.setNotificationType(d.getNotificationType());
if(fields.hasField(this.asIndexer(NotificationTemplate._kind))) m.setKind(d.getKind());
if (!languageFields.isEmpty() && languageMap != null && languageMap.containsKey(d.getLanguageId())) m.setLanguage(languageMap.get(d.getLanguageId()));
if (!valueFields.isEmpty() && d.getValue() != null){
NotificationTemplateValueEntity value = this.jsonHandlingService.fromJsonSafe(NotificationTemplateValueEntity.class, d.getValue());
m.setValue(this.builderFactory.builder(NotificationTemplateValueBuilder.class).authorize(this.authorize).build(valueFields, value));
}
if(fields.hasField(this.asIndexer(NotificationTemplate._isActive))) m.setIsActive(d.getIsActive());
if(fields.hasField(this.asIndexer(Tenant._createdAt))) m.setCreatedAt(d.getCreatedAt());
if(fields.hasField(this.asIndexer(Tenant._updatedAt))) m.setUpdatedAt(d.getUpdatedAt());
if(fields.hasField(this.asIndexer(NotificationTemplate._hash))) m.setHash(this.hashValue(d.getUpdatedAt()));
if (!tenantFields.isEmpty() && tenantMap != null && tenantMap.containsKey(d.getTenantId())) m.setTenant(tenantMap.get(d.getTenantId()));
models.add(m);
}
this.logger.debug("build {} items",Optional.of(models).map(List::size).orElse(0));
return models;
}
private Map<UUID, Language> collectLanguages(FieldSet fields, List<NotificationTemplateEntity> datas) throws MyApplicationException {
if (fields.isEmpty() || datas.isEmpty()) return null;
this.logger.debug("checking related - {}", NotificationTemplate.class.getSimpleName());
Map<UUID, Language> itemMap = null;
if (!fields.hasOtherField(this.asIndexer(Language._id))) {
itemMap = this.asEmpty(
datas.stream().map(x -> x.getLanguageId()).distinct().collect(Collectors.toList()),
x -> {
Language item = new Language();
item.setId(x);
return item;
},
x -> x.getId());
} else {
FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(Language._id);
LanguageQuery q = this.queryFactory.query(LanguageQuery.class).authorize(this.authorize).ids(datas.stream().map(x -> x.getLanguageId()).distinct().collect(Collectors.toList()));
itemMap = this.builderFactory.builder(LanguageBuilder.class).authorize(this.authorize).asForeignKey(q, clone, x -> x.getId());
}
if (!fields.hasField(Tenant._id)) {
itemMap.values().stream().filter(x -> x != null).map(x -> {
x.setId(null);
return x;
}).collect(Collectors.toList());
}
return itemMap;
}
private Map<UUID, Tenant> collectTenants(FieldSet fields, List<NotificationTemplateEntity> datas) throws MyApplicationException {
if (fields.isEmpty() || datas.isEmpty()) return null;
this.logger.debug("checking related - {}", NotificationTemplate.class.getSimpleName());
Map<UUID, Tenant> itemMap = null;
if (!fields.hasOtherField(this.asIndexer(Tenant._id))) {
itemMap = this.asEmpty(
datas.stream().map(x -> x.getTenantId()).distinct().collect(Collectors.toList()),
x -> {
Tenant item = new Tenant();
item.setId(x);
return item;
},
x -> x.getId());
} else {
FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(Tenant._id);
TenantQuery q = this.queryFactory.query(TenantQuery.class).authorize(this.authorize).ids(datas.stream().map(x -> x.getTenantId()).distinct().collect(Collectors.toList()));
itemMap = this.builderFactory.builder(TenantBuilder.class).authorize(this.authorize).asForeignKey(q, clone, x -> x.getId());
}
if (!fields.hasField(Tenant._id)) {
itemMap.values().stream().filter(x -> x != null).map(x -> {
x.setId(null);
return x;
}).collect(Collectors.toList());
}
return itemMap;
}
}

View File

@ -0,0 +1,57 @@
package gr.cite.notification.model.builder.notificationtemplate;
import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.common.types.notification.FieldInfo;
import gr.cite.notification.common.types.notificationtemplate.FieldInfoEntity;
import gr.cite.notification.convention.ConventionService;
import gr.cite.notification.model.builder.BaseBuilder;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class FieldInfoBuilder extends BaseBuilder<FieldInfo, FieldInfoEntity> {
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public FieldInfoBuilder(
ConventionService conventionService, BuilderFactory builderFactory) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(FieldInfoBuilder.class)));
}
public FieldInfoBuilder authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
public List<FieldInfo> build(FieldSet fields, List<FieldInfoEntity> data) throws MyApplicationException {
this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0));
this.logger.trace(new DataLogEntry("requested fields", fields));
if (fields == null || data == null || fields.isEmpty())
return new ArrayList<>();
List<FieldInfo> models = new ArrayList<>();
for (FieldInfoEntity d : data) {
FieldInfo m = new FieldInfo();
if (fields.hasField(this.asIndexer(FieldInfo._key))) m.setKey(d.getKey());
if (fields.hasField(this.asIndexer(FieldInfo._value))) m.setValue(d.getValue());
if (fields.hasField(this.asIndexer(FieldInfo._type))) m.setType(d.getType());
models.add(m);
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
return models;
}
}

View File

@ -0,0 +1,64 @@
package gr.cite.notification.model.builder.notificationtemplate;
import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.common.types.notificationtemplate.FieldOptionsEntity;
import gr.cite.notification.convention.ConventionService;
import gr.cite.notification.model.builder.BaseBuilder;
import gr.cite.notification.model.notificationtemplate.FieldOptions;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class FieldOptionsBuilder extends BaseBuilder<FieldOptions, FieldOptionsEntity> {
private final BuilderFactory builderFactory;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public FieldOptionsBuilder(
ConventionService conventionService, BuilderFactory builderFactory) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(FieldOptionsBuilder.class)));
this.builderFactory = builderFactory;
}
public FieldOptionsBuilder authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
public List<FieldOptions> build(FieldSet fields, List<FieldOptionsEntity> data) throws MyApplicationException {
this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0));
this.logger.trace(new DataLogEntry("requested fields", fields));
if (fields == null || data == null || fields.isEmpty())
return new ArrayList<>();
FieldSet optionalFields = fields.extractPrefixed(this.asPrefix(FieldOptions._optional));
List<FieldOptions> models = new ArrayList<>();
for (FieldOptionsEntity d : data) {
FieldOptions m = new FieldOptions();
if (fields.hasField(this.asIndexer(FieldOptions._mandatory))) m.setMandatory(d.getMandatory());
if (!optionalFields.isEmpty() && d.getOptional() != null) {
m.setOptional(this.builderFactory.builder(FieldInfoBuilder.class).authorize(this.authorize).build(optionalFields, d.getOptional()));
}
if (fields.hasField(this.asIndexer(FieldOptions._formatting))) m.setFormatting(d.getFormatting());
models.add(m);
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
return models;
}
}

View File

@ -0,0 +1,78 @@
package gr.cite.notification.model.builder.notificationtemplate;
import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.common.types.notificationtemplate.NotificationTemplateValueEntity;
import gr.cite.notification.convention.ConventionService;
import gr.cite.notification.model.builder.BaseBuilder;
import gr.cite.notification.model.notificationtemplate.FieldOptions;
import gr.cite.notification.model.notificationtemplate.NotificationTemplateValue;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class NotificationTemplateValueBuilder extends BaseBuilder<NotificationTemplateValue, NotificationTemplateValueEntity> {
private final BuilderFactory builderFactory;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public NotificationTemplateValueBuilder(
ConventionService conventionService, BuilderFactory builderFactory) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(NotificationTemplateValueBuilder.class)));
this.builderFactory = builderFactory;
}
public NotificationTemplateValueBuilder authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
public List<NotificationTemplateValue> build(FieldSet fields, List<NotificationTemplateValueEntity> data) throws MyApplicationException {
this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0));
this.logger.trace(new DataLogEntry("requested fields", fields));
if (fields == null || data == null || fields.isEmpty())
return new ArrayList<>();
FieldSet subjectFieldOptionsFields = fields.extractPrefixed(this.asPrefix(NotificationTemplateValue._subjectFieldOptions));
FieldSet bodyFieldOptionsFields = fields.extractPrefixed(this.asPrefix(NotificationTemplateValue._bodyFieldOptions));
List<NotificationTemplateValue> models = new ArrayList<>();
for (NotificationTemplateValueEntity d : data) {
NotificationTemplateValue m = new NotificationTemplateValue();
if (fields.hasField(this.asIndexer(NotificationTemplateValue._subjectText))) m.setSubjectText(d.getSubjectText());
if (fields.hasField(this.asIndexer(NotificationTemplateValue._subjectKey))) m.setSubjectKey(d.getSubjectKey());
if (!subjectFieldOptionsFields.isEmpty() && d.getSubjectFieldOptions() != null) {
m.setSubjectFieldOptions(this.builderFactory.builder(FieldOptionsBuilder.class).authorize(this.authorize).build(subjectFieldOptionsFields, d.getSubjectFieldOptions()));
}
if (fields.hasField(this.asIndexer(NotificationTemplateValue._bodyText))) m.setBodyText(d.getBodyText());
if (fields.hasField(this.asIndexer(NotificationTemplateValue._bodyKey))) m.setBodyKey(d.getBodyKey());
if (fields.hasField(this.asIndexer(NotificationTemplateValue._priorityKey))) m.setPriorityKey(d.getPriorityKey());
if (fields.hasField(this.asIndexer(NotificationTemplateValue._allowAttachments))) m.setAllowAttachments(d.getAllowAttachments());
if (fields.hasField(this.asIndexer(NotificationTemplateValue._cc))) m.setCc(d.getCc());
if (fields.hasField(this.asIndexer(NotificationTemplateValue._ccMode))) m.setCcMode(d.getCcMode());
if (fields.hasField(this.asIndexer(NotificationTemplateValue._bcc))) m.setBcc(d.getBcc());
if (fields.hasField(this.asIndexer(NotificationTemplateValue._bccMode))) m.setBccMode(d.getBccMode());
if (fields.hasField(this.asIndexer(NotificationTemplateValue._extraDataKeys))) m.setExtraDataKeys(d.getExtraDataKeys());
if (!bodyFieldOptionsFields.isEmpty() && d.getBodyFieldOptions() != null) {
m.setBodyFieldOptions(this.builderFactory.builder(FieldOptionsBuilder.class).authorize(this.authorize).build(bodyFieldOptionsFields, d.getBodyFieldOptions()));
}
models.add(m);
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
return models;
}
}

View File

@ -0,0 +1,32 @@
package gr.cite.notification.model.censorship;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.notification.authorization.Permission;
import gr.cite.notification.convention.ConventionService;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class NotificationTemplateCensor extends BaseCensor {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(NotificationTemplateCensor.class));
private final AuthorizationService authService;
@Autowired
public NotificationTemplateCensor(ConventionService conventionService, AuthorizationService authService) {
super(conventionService);
this.authService = authService;
}
public void censor(FieldSet fields) {
logger.debug(new DataLogEntry("censoring fields", fields));
if (this.isEmpty(fields)) return;
this.authService.authorizeForce(Permission.BrowseNotificationTemplate);
}
}

View File

@ -0,0 +1,33 @@
package gr.cite.notification.model.censorship.notificationtemplate;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.notification.authorization.Permission;
import gr.cite.notification.convention.ConventionService;
import gr.cite.notification.model.censorship.BaseCensor;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class FieldInfoCensor extends BaseCensor {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(FieldInfoCensor.class));
private final AuthorizationService authService;
@Autowired
public FieldInfoCensor(ConventionService conventionService, AuthorizationService authService) {
super(conventionService);
this.authService = authService;
}
public void censor(FieldSet fields) {
logger.debug(new DataLogEntry("censoring fields", fields));
if (this.isEmpty(fields)) return;
this.authService.authorizeForce(Permission.BrowseNotificationTemplate);
}
}

View File

@ -0,0 +1,39 @@
package gr.cite.notification.model.censorship.notificationtemplate;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.notification.authorization.Permission;
import gr.cite.notification.convention.ConventionService;
import gr.cite.notification.model.censorship.BaseCensor;
import gr.cite.notification.model.notificationtemplate.FieldOptions;
import gr.cite.tools.data.censor.CensorFactory;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class FieldOptionsCensor extends BaseCensor {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(FieldOptionsCensor.class));
protected final AuthorizationService authService;
protected final CensorFactory censorFactory;
@Autowired
public FieldOptionsCensor(ConventionService conventionService, AuthorizationService authService, CensorFactory censorFactory) {
super(conventionService);
this.authService = authService;
this.censorFactory = censorFactory;
}
public void censor(FieldSet fields) {
logger.debug(new DataLogEntry("censoring fields", fields));
if (this.isEmpty(fields)) return;
this.authService.authorizeForce(Permission.BrowseNotificationTemplate);
FieldSet optionalFields = fields.extractPrefixed(this.asIndexerPrefix(FieldOptions._optional));
this.censorFactory.censor(FieldInfoCensor.class).censor(optionalFields);
}
}

View File

@ -0,0 +1,43 @@
package gr.cite.notification.model.censorship.notificationtemplate;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.notification.authorization.Permission;
import gr.cite.notification.convention.ConventionService;
import gr.cite.notification.model.NotificationTemplate;
import gr.cite.notification.model.censorship.BaseCensor;
import gr.cite.notification.model.notificationtemplate.FieldOptions;
import gr.cite.notification.model.notificationtemplate.NotificationTemplateValue;
import gr.cite.tools.data.censor.CensorFactory;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class NotificationTemplateValueCensor extends BaseCensor {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(NotificationTemplateValueCensor.class));
protected final AuthorizationService authService;
protected final CensorFactory censorFactory;
@Autowired
public NotificationTemplateValueCensor(ConventionService conventionService, AuthorizationService authService, CensorFactory censorFactory) {
super(conventionService);
this.authService = authService;
this.censorFactory = censorFactory;
}
public void censor(FieldSet fields) {
logger.debug(new DataLogEntry("censoring fields", fields));
if (this.isEmpty(fields)) return;
this.authService.authorizeForce(Permission.BrowseNotificationTemplate);
FieldSet subjectFieldOptionsFields = fields.extractPrefixed(this.asIndexerPrefix(NotificationTemplateValue._subjectFieldOptions));
this.censorFactory.censor(FieldOptionsCensor.class).censor(subjectFieldOptionsFields);
FieldSet bodyFieldOptionsFields = fields.extractPrefixed(this.asIndexerPrefix(NotificationTemplateValue._bodyFieldOptions));
this.censorFactory.censor(FieldOptionsCensor.class).censor(bodyFieldOptionsFields);
}
}

View File

@ -0,0 +1,78 @@
package gr.cite.notification.model.deleter;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.data.NotificationTemplateEntity;
import gr.cite.notification.data.TenantScopedEntityManager;
import gr.cite.notification.query.NotificationTemplateQuery;
import gr.cite.tools.data.deleter.Deleter;
import gr.cite.tools.data.deleter.DeleterFactory;
import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.management.InvalidApplicationException;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class NotificationTemplateDeleter implements Deleter {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(NotificationTemplateDeleter.class));
private final TenantScopedEntityManager entityManager;
protected final QueryFactory queryFactory;
private final DeleterFactory deleterFactory;
@Autowired
public NotificationTemplateDeleter(
TenantScopedEntityManager entityManager,
QueryFactory queryFactory,
DeleterFactory deleterFactory
) {
this.entityManager = entityManager;
this.queryFactory = queryFactory;
this.deleterFactory = deleterFactory;
}
public void deleteAndSaveByIds(List<UUID> ids) throws InvalidApplicationException {
logger.debug(new MapLogEntry("collecting to delete").And("count", Optional.ofNullable(ids).map(List::size).orElse(0)).And("ids", ids));
List<NotificationTemplateEntity> data = this.queryFactory.query(NotificationTemplateQuery.class).ids(ids).collect();
logger.trace("received {} items", Optional.of(data).map(List::size).orElse(0));
this.deleteAndSave(data);
}
public void deleteAndSave(List<NotificationTemplateEntity> data) throws InvalidApplicationException {
logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0));
this.delete(data);
logger.trace("saving changes");
this.entityManager.flush();
logger.trace("changes saved");
}
public void delete(List<NotificationTemplateEntity> datas) throws InvalidApplicationException {
logger.debug("will delete {} items", Optional.ofNullable(datas).map(List::size).orElse(0));
if (datas == null || datas.isEmpty()) return;
List<UUID> ids = datas.stream().map(NotificationTemplateEntity::getId).distinct().collect(Collectors.toList());
Instant now = Instant.now();
for (NotificationTemplateEntity item : datas) {
logger.trace("deleting item {}", item.getId());
item.setIsActive(IsActive.Inactive);
item.setUpdatedAt(now);
logger.trace("updating item");
this.entityManager.merge(item);
logger.trace("updated item");
}
}
}

View File

@ -0,0 +1,42 @@
package gr.cite.notification.model.notificationtemplate;
import gr.cite.notification.common.types.notification.FieldInfo;
import java.util.Dictionary;
import java.util.List;
public class FieldOptions {
private List<String> mandatory;
public final static String _mandatory = "mandatory";
private List<FieldInfo> optional;
public final static String _optional = "optional";
private Dictionary<String, String> formatting;
public final static String _formatting = "formatting";
public List<String> getMandatory() {
return mandatory;
}
public void setMandatory(List<String> mandatory) {
this.mandatory = mandatory;
}
public List<FieldInfo> getOptional() {
return optional;
}
public void setOptional(List<FieldInfo> optional) {
this.optional = optional;
}
public Dictionary<String, String> getFormatting() {
return formatting;
}
public void setFormatting(Dictionary<String, String> formatting) {
this.formatting = formatting;
}
}

View File

@ -0,0 +1,139 @@
package gr.cite.notification.model.notificationtemplate;
import gr.cite.notification.common.types.notification.EmailOverrideMode;
import java.util.List;
public class NotificationTemplateValue {
private String subjectText;
public final static String _subjectText = "subjectText";
private String subjectKey;
public final static String _subjectKey = "subjectKey";
private FieldOptions subjectFieldOptions;
public final static String _subjectFieldOptions = "subjectFieldOptions";
private String bodyText;
public final static String _bodyText = "bodyText";
private String bodyKey;
public final static String _bodyKey = "bodyKey";
private String priorityKey;
public final static String _priorityKey = "priorityKey";
private Boolean allowAttachments;
public final static String _allowAttachments = "allowAttachments";
private List<String> cc;
public final static String _cc = "cc";
private EmailOverrideMode ccMode;
public final static String _ccMode = "ccMode";
private List<String> bcc;
public final static String _bcc = "bcc";
private EmailOverrideMode bccMode;
public final static String _bccMode = "bccMode";
private List<String> extraDataKeys;
public final static String _extraDataKeys = "extraDataKeys";
private FieldOptions bodyFieldOptions;
public final static String _bodyFieldOptions = "bodyFieldOptions";
public String getSubjectText() {
return subjectText;
}
public void setSubjectText(String subjectText) {
this.subjectText = subjectText;
}
public String getSubjectKey() {
return subjectKey;
}
public void setSubjectKey(String subjectKey) {
this.subjectKey = subjectKey;
}
public FieldOptions getSubjectFieldOptions() {
return subjectFieldOptions;
}
public void setSubjectFieldOptions(FieldOptions subjectFieldOptions) {
this.subjectFieldOptions = subjectFieldOptions;
}
public String getBodyText() {
return bodyText;
}
public void setBodyText(String bodyText) {
this.bodyText = bodyText;
}
public String getBodyKey() {
return bodyKey;
}
public void setBodyKey(String bodyKey) {
this.bodyKey = bodyKey;
}
public String getPriorityKey() {
return priorityKey;
}
public void setPriorityKey(String priorityKey) {
this.priorityKey = priorityKey;
}
public Boolean getAllowAttachments() {
return allowAttachments;
}
public void setAllowAttachments(Boolean allowAttachments) {
this.allowAttachments = allowAttachments;
}
public List<String> getCc() {
return cc;
}
public void setCc(List<String> cc) {
this.cc = cc;
}
public EmailOverrideMode getCcMode() {
return ccMode;
}
public void setCcMode(EmailOverrideMode ccMode) {
this.ccMode = ccMode;
}
public List<String> getBcc() {
return bcc;
}
public void setBcc(List<String> bcc) {
this.bcc = bcc;
}
public EmailOverrideMode getBccMode() {
return bccMode;
}
public void setBccMode(EmailOverrideMode bccMode) {
this.bccMode = bccMode;
}
public List<String> getExtraDataKeys() {
return extraDataKeys;
}
public void setExtraDataKeys(List<String> extraDataKeys) {
this.extraDataKeys = extraDataKeys;
}
public FieldOptions getBodyFieldOptions() {
return bodyFieldOptions;
}
public void setBodyFieldOptions(FieldOptions bodyFieldOptions) {
this.bodyFieldOptions = bodyFieldOptions;
}
}

View File

@ -0,0 +1,93 @@
package gr.cite.notification.model.persist;
import gr.cite.notification.common.enums.NotificationTemplateChannel;
import gr.cite.notification.common.enums.NotificationTemplateKind;
import gr.cite.notification.common.validation.ValidEnum;
import gr.cite.notification.common.validation.ValidId;
import gr.cite.notification.model.persist.notificationtemplate.NotificationTemplateValuePersist;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.UUID;
public class NotificationTemplatePersist {
@ValidId(message = "{validation.invalidid}")
private UUID id;
@ValidEnum
private NotificationTemplateChannel channel;
@NotNull(message = "{validation.empty}")
@Valid
private UUID notificationType;
@ValidEnum
private NotificationTemplateKind kind;
@NotNull(message = "{validation.empty}")
@ValidId(message = "{validation.invalidid}")
private UUID languageId;
@NotNull(message = "{validation.empty}")
@Valid
private NotificationTemplateValuePersist value;
private String hash;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public NotificationTemplateChannel getChannel() {
return channel;
}
public void setChannel(NotificationTemplateChannel channel) {
this.channel = channel;
}
public UUID getNotificationType() {
return notificationType;
}
public void setNotificationType(UUID notificationType) {
this.notificationType = notificationType;
}
public NotificationTemplateKind getKind() {
return kind;
}
public void setKind(NotificationTemplateKind kind) {
this.kind = kind;
}
public UUID getLanguageId() {
return languageId;
}
public void setLanguageId(UUID languageId) {
this.languageId = languageId;
}
public NotificationTemplateValuePersist getValue() {
return value;
}
public void setValue(NotificationTemplateValuePersist value) {
this.value = value;
}
public String getHash() {
return hash;
}
public void setHash(String hash) {
this.hash = hash;
}
}

View File

@ -0,0 +1,54 @@
package gr.cite.notification.model.persist.notificationtemplate;
import gr.cite.notification.common.types.notification.DataType;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
public class FieldInfoPersist {
@NotNull
@NotEmpty
private String key;
@NotNull
@NotEmpty
private DataType type;
@NotNull
@NotEmpty
private String value;
public FieldInfoPersist(String key, DataType type, String value) {
this.key = key;
this.type = type;
this.value = value;
}
public FieldInfoPersist() {
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public DataType getType() {
return type;
}
public void setType(DataType type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@ -0,0 +1,44 @@
package gr.cite.notification.model.persist.notificationtemplate;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.Dictionary;
import java.util.List;
public class FieldOptionsPersist {
@NotNull(message = "{validation.empty}")
@Valid
private List<String> mandatory;
@Valid
private List<FieldInfoPersist> optional;
@Valid
private Dictionary<String, String> formatting;
public List<String> getMandatory() {
return mandatory;
}
public void setMandatory(List<String> mandatory) {
this.mandatory = mandatory;
}
public List<FieldInfoPersist> getOptional() {
return optional;
}
public void setOptional(List<FieldInfoPersist> optional) {
this.optional = optional;
}
public Dictionary<String, String> getFormatting() {
return formatting;
}
public void setFormatting(Dictionary<String, String> formatting) {
this.formatting = formatting;
}
}

View File

@ -0,0 +1,150 @@
package gr.cite.notification.model.persist.notificationtemplate;
import gr.cite.notification.common.types.notification.EmailOverrideMode;
import gr.cite.notification.common.validation.ValidEnum;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
public class NotificationTemplateValuePersist {
@NotNull
@NotEmpty
private String subjectText;
@NotNull
@NotEmpty
private String subjectKey;
@Valid
private FieldOptionsPersist subjectFieldOptions;
@NotNull
@NotEmpty
private String bodyText;
@NotNull
@NotEmpty
private String bodyKey;
private String priorityKey;
@NotNull
private Boolean allowAttachments = false;
private List<String> cc;
@ValidEnum
private EmailOverrideMode ccMode;
private List<String> bcc;
@ValidEnum
private EmailOverrideMode bccMode;
private List<String> extraDataKeys;
@Valid
private FieldOptionsPersist bodyFieldOptions;
public String getSubjectText() {
return subjectText;
}
public void setSubjectText(String subjectText) {
this.subjectText = subjectText;
}
public String getSubjectKey() {
return subjectKey;
}
public void setSubjectKey(String subjectKey) {
this.subjectKey = subjectKey;
}
public FieldOptionsPersist getSubjectFieldOptions() {
return subjectFieldOptions;
}
public void setSubjectFieldOptions(FieldOptionsPersist subjectFieldOptions) {
this.subjectFieldOptions = subjectFieldOptions;
}
public String getBodyText() {
return bodyText;
}
public void setBodyText(String bodyText) {
this.bodyText = bodyText;
}
public String getBodyKey() {
return bodyKey;
}
public void setBodyKey(String bodyKey) {
this.bodyKey = bodyKey;
}
public String getPriorityKey() {
return priorityKey;
}
public void setPriorityKey(String priorityKey) {
this.priorityKey = priorityKey;
}
public Boolean getAllowAttachments() {
return allowAttachments;
}
public void setAllowAttachments(Boolean allowAttachments) {
this.allowAttachments = allowAttachments;
}
public List<String> getCc() {
return cc;
}
public void setCc(List<String> cc) {
this.cc = cc;
}
public EmailOverrideMode getCcMode() {
return ccMode;
}
public void setCcMode(EmailOverrideMode ccMode) {
this.ccMode = ccMode;
}
public List<String> getBcc() {
return bcc;
}
public void setBcc(List<String> bcc) {
this.bcc = bcc;
}
public EmailOverrideMode getBccMode() {
return bccMode;
}
public void setBccMode(EmailOverrideMode bccMode) {
this.bccMode = bccMode;
}
public List<String> getExtraDataKeys() {
return extraDataKeys;
}
public void setExtraDataKeys(List<String> extraDataKeys) {
this.extraDataKeys = extraDataKeys;
}
public FieldOptionsPersist getBodyFieldOptions() {
return bodyFieldOptions;
}
public void setBodyFieldOptions(FieldOptionsPersist bodyFieldOptions) {
this.bodyFieldOptions = bodyFieldOptions;
}
}

View File

@ -0,0 +1,184 @@
package gr.cite.notification.query;
import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.data.LanguageEntity;
import gr.cite.notification.model.Language;
import gr.cite.tools.data.query.FieldResolver;
import gr.cite.tools.data.query.QueryBase;
import gr.cite.tools.data.query.QueryContext;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import java.time.Instant;
import java.util.*;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class LanguageQuery extends QueryBase<LanguageEntity> {
private String like;
private Collection<UUID> ids;
private Collection<IsActive> isActives;
private Collection<String> codes;
private Collection<UUID> excludedIds;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
public LanguageQuery like(String value) {
this.like = value;
return this;
}
public LanguageQuery ids(UUID value) {
this.ids = List.of(value);
return this;
}
public LanguageQuery ids(UUID... value) {
this.ids = Arrays.asList(value);
return this;
}
public LanguageQuery ids(Collection<UUID> values) {
this.ids = values;
return this;
}
public LanguageQuery isActive(IsActive value) {
this.isActives = List.of(value);
return this;
}
public LanguageQuery isActive(IsActive... value) {
this.isActives = Arrays.asList(value);
return this;
}
public LanguageQuery isActive(Collection<IsActive> values) {
this.isActives = values;
return this;
}
public LanguageQuery codes(String value) {
this.codes = List.of(value);
return this;
}
public LanguageQuery codes(String... value) {
this.codes = Arrays.asList(value);
return this;
}
public LanguageQuery codes(Collection<String> values) {
this.codes = values;
return this;
}
public LanguageQuery excludedIds(Collection<UUID> values) {
this.excludedIds = values;
return this;
}
public LanguageQuery excludedIds(UUID value) {
this.excludedIds = List.of(value);
return this;
}
public LanguageQuery excludedIds(UUID... value) {
this.excludedIds = Arrays.asList(value);
return this;
}
public LanguageQuery authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
public LanguageQuery(
) {
}
@Override
protected Class<LanguageEntity> entityClass() {
return LanguageEntity.class;
}
@Override
protected Boolean isFalseQuery() {
return this.isEmpty(this.ids) || this.isEmpty(this.isActives) || this.isEmpty(this.excludedIds) || this.isEmpty(this.codes);
}
@Override
protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) {
List<Predicate> predicates = new ArrayList<>();
if (this.ids != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LanguageEntity._id));
for (UUID item : this.ids)
inClause.value(item);
predicates.add(inClause);
}
if (this.like != null && !this.like.isEmpty()) {
predicates.add(queryContext.CriteriaBuilder.like(queryContext.Root.get(LanguageEntity._code), this.like));
}
if (this.isActives != null) {
CriteriaBuilder.In<IsActive> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LanguageEntity._isActive));
for (IsActive item : this.isActives)
inClause.value(item);
predicates.add(inClause);
}
if (this.codes != null) {
CriteriaBuilder.In<String> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LanguageEntity._code));
for (String item : this.codes)
inClause.value(item);
predicates.add(inClause);
}
if (this.excludedIds != null) {
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LanguageEntity._id));
for (UUID item : this.excludedIds)
notInClause.value(item);
predicates.add(notInClause.not());
}
if (!predicates.isEmpty()) {
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
return queryContext.CriteriaBuilder.and(predicatesArray);
} else {
return null;
}
}
@Override
protected LanguageEntity convert(Tuple tuple, Set<String> columns) {
LanguageEntity item = new LanguageEntity();
item.setId(QueryBase.convertSafe(tuple, columns, LanguageEntity._id, UUID.class));
item.setCode(QueryBase.convertSafe(tuple, columns, LanguageEntity._code, String.class));
item.setPayload(QueryBase.convertSafe(tuple, columns, LanguageEntity._payload, String.class));
item.setOrdinal(QueryBase.convertSafe(tuple, columns, LanguageEntity._ordinal, Integer.class));
item.setCreatedAt(QueryBase.convertSafe(tuple, columns, LanguageEntity._createdAt, Instant.class));
item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, LanguageEntity._updatedAt, Instant.class));
item.setIsActive(QueryBase.convertSafe(tuple, columns, LanguageEntity._isActive, IsActive.class));
return item;
}
@Override
protected String fieldNameOf(FieldResolver item) {
if (item.match(Language._id)) return LanguageEntity._id;
else if (item.match(Language._code)) return LanguageEntity._code;
else if (item.match(Language._payload)) return LanguageEntity._payload;
else if (item.match(Language._ordinal)) return LanguageEntity._ordinal;
else if (item.match(Language._createdAt)) return LanguageEntity._createdAt;
else if (item.match(Language._updatedAt)) return LanguageEntity._updatedAt;
else if (item.match(Language._hash)) return LanguageEntity._updatedAt;
else if (item.match(Language._isActive)) return LanguageEntity._isActive;
else return null;
}
}

View File

@ -0,0 +1,202 @@
package gr.cite.notification.query;
import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.common.enums.*;
import gr.cite.notification.data.NotificationTemplateEntity;
import gr.cite.notification.model.NotificationTemplate;
import gr.cite.tools.data.query.FieldResolver;
import gr.cite.tools.data.query.QueryBase;
import gr.cite.tools.data.query.QueryContext;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import java.time.Instant;
import java.util.*;
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class NotificationTemplateQuery extends QueryBase<NotificationTemplateEntity> {
private Collection<UUID> ids;
private Collection<UUID> excludedIds;
private Collection<IsActive> isActives;
private List<NotificationTemplateChannel> channels;
private List<NotificationTemplateKind> kinds;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
public NotificationTemplateQuery ids(UUID value) {
this.ids = List.of(value);
return this;
}
public NotificationTemplateQuery ids(UUID... value) {
this.ids = Arrays.asList(value);
return this;
}
public NotificationTemplateQuery ids(Collection<UUID> values) {
this.ids = values;
return this;
}
public NotificationTemplateQuery isActive(IsActive value) {
this.isActives = List.of(value);
return this;
}
public NotificationTemplateQuery isActive(IsActive... value) {
this.isActives = Arrays.asList(value);
return this;
}
public NotificationTemplateQuery isActive(Collection<IsActive> values) {
this.isActives = values;
return this;
}
public NotificationTemplateQuery channels(NotificationTemplateChannel... channels) {
this.channels = List.of(channels);
return this;
}
public NotificationTemplateQuery channels(NotificationTemplateChannel channels) {
this.channels = List.of(channels);
return this;
}
public NotificationTemplateQuery channels(List<NotificationTemplateChannel> channels) {
this.channels = channels;
return this;
}
public NotificationTemplateQuery kinds(NotificationTemplateKind... kinds) {
this.kinds = List.of(kinds);
return this;
}
public NotificationTemplateQuery kinds(NotificationTemplateKind kinds) {
this.kinds = List.of(kinds);
return this;
}
public NotificationTemplateQuery kinds(List<NotificationTemplateKind> kinds) {
this.kinds = kinds;
return this;
}
public NotificationTemplateQuery excludedIds(Collection<UUID> values) {
this.excludedIds = values;
return this;
}
public NotificationTemplateQuery excludedIds(UUID value) {
this.excludedIds = List.of(value);
return this;
}
public NotificationTemplateQuery excludedIds(UUID... value) {
this.excludedIds = Arrays.asList(value);
return this;
}
public NotificationTemplateQuery authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
protected Boolean isFalseQuery() {
return this.isNullOrEmpty(this.ids)
&& this.isNullOrEmpty(this.isActives)
&& this.isNullOrEmpty(this.kinds)
&& this.isNullOrEmpty(this.channels);
}
@Override
protected Class<NotificationTemplateEntity> entityClass() {
return NotificationTemplateEntity.class;
}
@Override
protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) {
List<Predicate> predicates = new ArrayList<>();
if (this.ids != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(NotificationTemplateEntity._id));
for (UUID item : this.ids)
inClause.value(item);
predicates.add(inClause);
}
if (this.isActives != null) {
CriteriaBuilder.In<IsActive> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(NotificationTemplateEntity._isActive));
for (IsActive item : this.isActives)
inClause.value(item);
predicates.add(inClause);
}
if (this.channels != null) {
CriteriaBuilder.In<NotificationTemplateChannel> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(NotificationTemplateEntity._channel));
for (NotificationTemplateChannel item : this.channels)
inClause.value(item);
predicates.add(inClause); }
if (this.kinds != null) {
CriteriaBuilder.In<NotificationTemplateKind> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(NotificationTemplateEntity._kind));
for (NotificationTemplateKind item : this.kinds)
inClause.value(item);
predicates.add(inClause);
}
if (this.excludedIds != null) {
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(NotificationTemplateEntity._id));
for (UUID item : this.excludedIds)
notInClause.value(item);
predicates.add(notInClause.not());
}
if (predicates.size() > 0) {
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
return queryContext.CriteriaBuilder.and(predicatesArray);
} else {
return null;
}
}
@Override
protected String fieldNameOf(FieldResolver item) {
if (item.match(NotificationTemplate._id)) return NotificationTemplateEntity._id;
else if (item.match(NotificationTemplate._channel)) return NotificationTemplateEntity._channel;
else if (item.match(NotificationTemplate._kind)) return NotificationTemplateEntity._kind;
else if (item.match(NotificationTemplate._notificationType)) return NotificationTemplateEntity._notificationType;
else if (item.prefix(NotificationTemplate._value)) return NotificationTemplateEntity._value;
else if (item.prefix(NotificationTemplate._language)) return NotificationTemplateEntity._language;
else if (item.match(NotificationTemplate._createdAt)) return NotificationTemplateEntity._createdAt;
else if (item.match(NotificationTemplate._updatedAt)) return NotificationTemplateEntity._updatedAt;
else if (item.match(NotificationTemplate._isActive)) return NotificationTemplateEntity._isActive;
else if (item.match(NotificationTemplate._tenant)) return NotificationTemplateEntity._tenantId;
else return null;
}
@Override
protected NotificationTemplateEntity convert(Tuple tuple, Set<String> columns) {
NotificationTemplateEntity item = new NotificationTemplateEntity();
item.setId(QueryBase.convertSafe(tuple, columns, NotificationTemplateEntity._id, UUID.class));
item.setChannel(QueryBase.convertSafe(tuple, columns, NotificationTemplateEntity._channel, NotificationTemplateChannel.class));
item.setKind(QueryBase.convertSafe(tuple, columns, NotificationTemplateEntity._kind, NotificationTemplateKind.class));
item.setNotificationType(QueryBase.convertSafe(tuple, columns, NotificationTemplateEntity._notificationType, UUID.class));
item.setValue(QueryBase.convertSafe(tuple, columns, NotificationTemplateEntity._value, String.class));
item.setLanguageId(QueryBase.convertSafe(tuple, columns, NotificationTemplateEntity._language, UUID.class));
item.setCreatedAt(QueryBase.convertSafe(tuple, columns, NotificationTemplateEntity._createdAt, Instant.class));
item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, NotificationTemplateEntity._updatedAt, Instant.class));
item.setIsActive(QueryBase.convertSafe(tuple, columns, NotificationTemplateEntity._isActive, IsActive.class));
item.setTenantId(QueryBase.convertSafe(tuple, columns, NotificationTemplateEntity._tenantId, UUID.class));
return item;
}
}

View File

@ -0,0 +1,76 @@
package gr.cite.notification.query.lookup;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.query.LanguageQuery;
import gr.cite.tools.data.query.Lookup;
import gr.cite.tools.data.query.QueryFactory;
import java.util.List;
import java.util.UUID;
public class LanguageLookup extends Lookup {
private String like;
private List<IsActive> isActive;
private List<String> codes;
private List<UUID> ids;
private List<UUID> excludedIds;
public String getLike() {
return like;
}
public void setLike(String like) {
this.like = like;
}
public List<IsActive> getIsActive() {
return isActive;
}
public void setIsActive(List<IsActive> isActive) {
this.isActive = isActive;
}
public List<UUID> getIds() {
return ids;
}
public void setIds(List<UUID> ids) {
this.ids = ids;
}
public List<UUID> getExcludedIds() {
return excludedIds;
}
public void setExcludedIds(List<UUID> excludeIds) {
this.excludedIds = excludeIds;
}
public List<String> getCodes() {
return codes;
}
public void setCodes(List<String> codes) {
this.codes = codes;
}
public LanguageQuery enrich(QueryFactory queryFactory) {
LanguageQuery query = queryFactory.query(LanguageQuery.class);
if (this.like != null) query.like(this.like);
if (this.isActive != null) query.isActive(this.isActive);
if (this.codes != null) query.codes(this.codes);
if (this.ids != null) query.ids(this.ids);
if (this.excludedIds != null) query.excludedIds(this.excludedIds);
this.enrichCommon(query);
return query;
}
}

View File

@ -0,0 +1,78 @@
package gr.cite.notification.query.lookup;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.enums.NotificationTemplateChannel;
import gr.cite.notification.common.enums.NotificationTemplateKind;
import gr.cite.notification.query.NotificationTemplateQuery;
import gr.cite.tools.data.query.Lookup;
import gr.cite.tools.data.query.QueryFactory;
import java.util.List;
import java.util.UUID;
public class NotificationTemplateLookup extends Lookup {
private List<IsActive> isActive;
private List<NotificationTemplateChannel> channels;
private List<NotificationTemplateKind> kinds;
private List<UUID> ids;
private List<UUID> excludedIds;
public List<IsActive> getIsActive() {
return isActive;
}
public void setIsActive(List<IsActive> isActive) {
this.isActive = isActive;
}
public List<NotificationTemplateChannel> getChannels() {
return channels;
}
public void setChannels(List<NotificationTemplateChannel> channels) {
this.channels = channels;
}
public List<NotificationTemplateKind> getKinds() {
return kinds;
}
public void setKinds(List<NotificationTemplateKind> kinds) {
this.kinds = kinds;
}
public List<UUID> getIds() {
return ids;
}
public void setIds(List<UUID> ids) {
this.ids = ids;
}
public List<UUID> getExcludedIds() {
return excludedIds;
}
public void setExcludedIds(List<UUID> excludedIds) {
this.excludedIds = excludedIds;
}
public NotificationTemplateQuery enrich(QueryFactory queryFactory) {
NotificationTemplateQuery query = queryFactory.query(NotificationTemplateQuery.class);
if (this.ids != null) query.ids(this.ids);
if (this.excludedIds != null) query.excludedIds(this.excludedIds);
if (this.isActive != null) query.isActive(this.isActive);
if (this.channels != null) query.channels(this.channels);
if (this.kinds != null) query.kinds(this.kinds);
this.enrichCommon(query);
return query;
}
}

View File

@ -0,0 +1,176 @@
package gr.cite.notification.service.notificationtemplate;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.notification.authorization.AuthorizationFlags;
import gr.cite.notification.authorization.Permission;
import gr.cite.notification.common.JsonHandlingService;
import gr.cite.notification.common.enums.IsActive;
import gr.cite.notification.common.types.notificationtemplate.FieldInfoEntity;
import gr.cite.notification.common.types.notificationtemplate.FieldOptionsEntity;
import gr.cite.notification.common.types.notificationtemplate.NotificationTemplateValueEntity;
import gr.cite.notification.convention.ConventionService;
import gr.cite.notification.data.NotificationTemplateEntity;
import gr.cite.notification.data.TenantScopedEntityManager;
import gr.cite.notification.errorcode.ErrorThesaurusProperties;
import gr.cite.notification.model.NotificationTemplate;
import gr.cite.notification.model.builder.NotificationTemplateBuilder;
import gr.cite.notification.model.deleter.NotificationTemplateDeleter;
import gr.cite.notification.model.persist.NotificationTemplatePersist;
import gr.cite.notification.model.persist.notificationtemplate.FieldInfoPersist;
import gr.cite.notification.model.persist.notificationtemplate.FieldOptionsPersist;
import gr.cite.notification.model.persist.notificationtemplate.NotificationTemplateValuePersist;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.data.deleter.DeleterFactory;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.exception.MyForbiddenException;
import gr.cite.tools.exception.MyNotFoundException;
import gr.cite.tools.exception.MyValidationException;
import gr.cite.tools.fieldset.BaseFieldSet;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry;
import org.jetbrains.annotations.NotNull;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.annotation.RequestScope;
import javax.management.InvalidApplicationException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Service
@RequestScope
public class NotificationServiceTemplateImpl implements NotificationTemplateService {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(NotificationServiceTemplateImpl.class));
private final TenantScopedEntityManager entityManager;
private final AuthorizationService authService;
private final AuthorizationService authorizationService;
private final DeleterFactory deleterFactory;
private final BuilderFactory builderFactory;
private final ConventionService conventionService;
private final ErrorThesaurusProperties errors;
private final MessageSource messageSource;
private final JsonHandlingService jsonHandlingService;
@Autowired
public NotificationServiceTemplateImpl(
TenantScopedEntityManager entityManager,
AuthorizationService authService, AuthorizationService authorizationService,
DeleterFactory deleterFactory,
BuilderFactory builderFactory,
ConventionService conventionService,
ErrorThesaurusProperties errors,
MessageSource messageSource,
JsonHandlingService jsonHandlingService) {
this.entityManager = entityManager;
this.authService = authService;
this.authorizationService = authorizationService;
this.deleterFactory = deleterFactory;
this.builderFactory = builderFactory;
this.conventionService = conventionService;
this.errors = errors;
this.messageSource = messageSource;
this.jsonHandlingService = jsonHandlingService;
}
@Override
public NotificationTemplate persist(NotificationTemplatePersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException {
logger.debug(new MapLogEntry("persisting notification template").And("model", model).And("fields", fields));
this.authorizationService.authorizeForce(Permission.EditNotificationTemplate);
Boolean isUpdate = this.conventionService.isValidGuid(model.getId());
NotificationTemplateEntity data = null;
if (isUpdate) {
data = this.entityManager.find(NotificationTemplateEntity.class, model.getId());
if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), NotificationTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale()));
if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage());
} else {
data = new NotificationTemplateEntity();
data.setId(UUID.randomUUID());
data.setIsActive(IsActive.Active);
data.setCreatedAt(Instant.now());
}
data.setChannel(model.getChannel());
data.setKind(model.getKind());
data.setNotificationType(model.getNotificationType());
data.setLanguageId(model.getLanguageId());
data.setValue(this.jsonHandlingService.toJsonSafe(this.buildNotificationTemplateValueEntity(model.getValue())));
data.setUpdatedAt(Instant.now());
if (isUpdate) this.entityManager.merge(data);
else this.entityManager.persist(data);
this.entityManager.flush();
return this.builderFactory.builder(NotificationTemplateBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(BaseFieldSet.build(fields, NotificationTemplate._id, NotificationTemplate._hash), data);
}
private @NotNull NotificationTemplateValueEntity buildNotificationTemplateValueEntity(NotificationTemplateValuePersist persist) {
NotificationTemplateValueEntity data = new NotificationTemplateValueEntity();
if (persist == null) return data;
data.setSubjectText(persist.getSubjectText());
data.setSubjectKey(persist.getSubjectKey());
if (!this.conventionService.isListNullOrEmpty(List.of(persist.getSubjectFieldOptions()))) {
data.setSubjectFieldOptions(this.buildFieldOptionsEntity(persist.getSubjectFieldOptions()));
}
data.setBodyText(persist.getBodyText());
data.setBodyKey(persist.getBodyKey());
data.setPriorityKey(persist.getPriorityKey());
data.setAllowAttachments(persist.getAllowAttachments());
data.setCc(persist.getCc());
data.setCcMode(persist.getCcMode());
data.setBcc(persist.getBcc());
data.setBccMode(persist.getBccMode());
data.setExtraDataKeys(persist.getExtraDataKeys());
if (!this.conventionService.isListNullOrEmpty(List.of(persist.getBodyFieldOptions()))) {
data.setBodyFieldOptions(this.buildFieldOptionsEntity(persist.getBodyFieldOptions()));
}
return data;
}
private @NotNull FieldOptionsEntity buildFieldOptionsEntity(FieldOptionsPersist persist) {
FieldOptionsEntity data = new FieldOptionsEntity();
if (persist == null) return data;
data.setMandatory(persist.getMandatory());
if (!this.conventionService.isListNullOrEmpty(persist.getOptional())) {
data.setOptional(new ArrayList<>());
for (FieldInfoPersist optionalPersist : persist.getOptional()) {
data.getOptional().add(this.buildFieldInfoEntity(optionalPersist));
}
}
data.setFormatting(persist.getFormatting());
return data;
}
private @NotNull FieldInfoEntity buildFieldInfoEntity(FieldInfoPersist persist) {
FieldInfoEntity data = new FieldInfoEntity();
if (persist == null) return data;
data.setKey(persist.getKey());
data.setType(persist.getType());
data.setValue(persist.getValue());
return data;
}
@Override
public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException {
logger.debug("deleting notification template: {}", id);
this.authService.authorizeForce(Permission.DeleteNotificationTemplate);
this.deleterFactory.deleter(NotificationTemplateDeleter.class).deleteAndSaveByIds(List.of(id));
}
}

View File

@ -0,0 +1,18 @@
package gr.cite.notification.service.notificationtemplate;
import gr.cite.notification.model.NotificationTemplate;
import gr.cite.notification.model.persist.NotificationTemplatePersist;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.exception.MyForbiddenException;
import gr.cite.tools.exception.MyNotFoundException;
import gr.cite.tools.exception.MyValidationException;
import gr.cite.tools.fieldset.FieldSet;
import javax.management.InvalidApplicationException;
import java.util.UUID;
public interface NotificationTemplateService {
NotificationTemplate persist(NotificationTemplatePersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException;
void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException;
}

View File

@ -0,0 +1,34 @@
DO $$DECLARE
this_version CONSTANT varchar := '00.01.041';
BEGIN
PERFORM * FROM "DBVersion" WHERE version = this_version;
IF FOUND THEN RETURN; END IF;
CREATE TABLE public."ntf_NotificationTemplate"
(
id uuid NOT NULL,
channel smallint NOT NULL,
notification_type uuid NOT NULL,
kind smallint NOT NULL,
language uuid NOT NULL,
value text NOT NULL,
is_active smallint NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
tenant uuid,
CONSTRAINT "NotificationTemplate_pkey" PRIMARY KEY (id),
CONSTRAINT "NotificationTemplate_language_fkey" FOREIGN KEY (language)
REFERENCES public."Language" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID,
CONSTRAINT "NotificationTemplate_tenant_fkey" FOREIGN KEY (tenant)
REFERENCES public."Tenant" (id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
NOT VALID
);
INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.01.041', '2023-12-15 12:00:00.000000+02', now(), 'Add ntf_NotificationTemplate table.');
END$$;