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.NotificationTemplate; import gr.cite.notification.model.Tenant; import gr.cite.notification.model.builder.notificationtemplate.NotificationTemplateValueBuilder; 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 { private final BuilderFactory builderFactory; private final QueryFactory queryFactory; private final JsonHandlingService jsonHandlingService; private EnumSet 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 values){ this.authorize = values; return this; } @Override public List build(FieldSet fields, List 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 tenantMap = this.collectTenants(tenantFields, data); List 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(fields.hasField(this.asIndexer(NotificationTemplate._languageCode))) m.setLanguageCode(d.getLanguageCode()); 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 collectTenants(FieldSet fields, List datas) throws MyApplicationException { if (fields.isEmpty() || datas.isEmpty()) return null; this.logger.debug("checking related - {}", NotificationTemplate.class.getSimpleName()); Map 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; } }