diff --git a/core/api/src/main/java/com/blazebit/notify/Channel.java b/core/api/src/main/java/com/blazebit/notify/Channel.java index e4864b91..65433f01 100644 --- a/core/api/src/main/java/com/blazebit/notify/Channel.java +++ b/core/api/src/main/java/com/blazebit/notify/Channel.java @@ -27,6 +27,8 @@ */ public interface Channel, M extends NotificationMessage> extends AutoCloseable { + String SERVICE_PROVIDER_PROPERTY = "serviceProvider"; + /** * Returns the notification message type class. * diff --git a/core/api/src/main/java/com/blazebit/notify/NotificationJobContext.java b/core/api/src/main/java/com/blazebit/notify/NotificationJobContext.java index ad893e1e..d33cef42 100644 --- a/core/api/src/main/java/com/blazebit/notify/NotificationJobContext.java +++ b/core/api/src/main/java/com/blazebit/notify/NotificationJobContext.java @@ -625,7 +625,12 @@ public NotificationMessageResolver getNotific if (channelFactory == null) { throw new NotificationException("No channel factory for channel key available: " + channelKey); } - return channelFactory.createChannel(this, configurationSource); + return channelFactory.createChannel(this, (key) -> { + if (Channel.SERVICE_PROVIDER_PROPERTY.equals(key)) { + return this; + } + return configurationSource.getProperty(key); + }); } ); } diff --git a/email/message/src/main/java/com/blazebit/notify/email/message/EmailNotificationMessageResolver.java b/email/message/src/main/java/com/blazebit/notify/email/message/EmailNotificationMessageResolver.java index be4a72fd..b6570a5d 100644 --- a/email/message/src/main/java/com/blazebit/notify/email/message/EmailNotificationMessageResolver.java +++ b/email/message/src/main/java/com/blazebit/notify/email/message/EmailNotificationMessageResolver.java @@ -16,6 +16,7 @@ package com.blazebit.notify.email.message; import com.blazebit.job.ConfigurationSource; +import com.blazebit.job.ServiceProvider; import com.blazebit.notify.Notification; import com.blazebit.notify.NotificationException; import com.blazebit.notify.NotificationJobContext; @@ -33,7 +34,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Optional; import java.util.ResourceBundle; import java.util.function.Function; @@ -134,17 +134,32 @@ public EmailNotificationMessageResolver(NotificationJobContext jobContext, Confi this.envelopeFrom = configurationSource.getPropertyOrDefault(EMAIL_MESSAGE_ENVELOP_FROM_PROPERTY, String.class, Function.identity(), o -> null); this.resourceBundleAccessor = configurationSource.getPropertyOrDefault(EMAIL_MESSAGE_RESOURCE_BUNDLE_PROPERTY, Function.class, EmailNotificationMessageResolver::resourceBundleByName, o -> null); TemplateContext templateContext = configurationSource.getPropertyOrDefault(EMAIL_TEMPLATE_CONTEXT_PROPERTY, TemplateContext.class, null, o -> jobContext.getService(TemplateContext.class)); - Function>> templateProcessorFunction = templateProcessorFactoryNameProperty -> templateName -> + TemplateProcessorFactory templateProcessorFactory = configurationSource.getPropertyOrDefault( + EMAIL_TEMPLATE_PROCESSOR_TYPE_PROPERTY, TemplateProcessorFactory.class, s -> { + if (templateContext == null) { + throw new NotificationException("No template context given!"); + } + return templateContext.getTemplateProcessorFactory(s, String.class); + }, o -> null); + Function> attachmentTemplateProcessorFactory = templateProcessorFactoryKey -> { + if (templateContext == null) { + throw new NotificationException("No template context given!"); + } + return templateContext.getTemplateProcessorFactory(templateProcessorFactoryKey, Attachment.class); + }; + Function> templateProcessorFunction = templateName -> templateProcessorByType( templateContext, templateProcessorFactory, configurationSource, - templateName); - Function> attachmentTemplateProcessorFunction = templateProcessorKey -> templateProcessorByKey( + templateName, + jobContext); + Function> attachmentTemplateProcessorFunction = templateProcessorType -> templateProcessorByType( templateContext, attachmentTemplateProcessorFactory.apply(templateProcessorType), configurationSource, - null); + null, + jobContext); String literalSubject = (String) configurationSource.getProperty(EMAIL_MESSAGE_SUBJECT_PROPERTY); this.subjectTemplateProcessor = literalSubject == null ? templateProcessorFunction.apply((String) configurationSource.getProperty(EMAIL_MESSAGE_SUBJECT_TEMPLATE_PROPERTY)) : TemplateProcessor.of(literalSubject); String literalBodyText = (String) configurationSource.getProperty(EMAIL_MESSAGE_TEXT_PROPERTY); @@ -213,7 +228,7 @@ private static Function resourceBundleByName(String name return locale -> ResourceBundle.getBundle(name, locale); } - private static TemplateProcessor templateProcessorByType(TemplateContext templateContext, TemplateProcessorFactory templateProcessorFactory, ConfigurationSource configurationSource, String templateName) { + private static TemplateProcessor templateProcessorByType(TemplateContext templateContext, TemplateProcessorFactory templateProcessorFactory, ConfigurationSource configurationSource, String templateName, ServiceProvider serviceProvider) { if (templateName == null) { return null; } @@ -223,12 +238,7 @@ private static TemplateProcessor templateProcessorByType(TemplateContext if (templateProcessorFactory == null) { throw new NotificationException("No template processor factory given!"); } - return templateProcessorFactory.createTemplateProcessor(templateContext, key -> { - if (TemplateProcessor.TEMPLATE_NAME_PROPERTY.equals(key)) { - return templateName; - } - return configurationSource.getProperty(key); - }); + return templateProcessorFactory.createTemplateProcessor(templateContext, templateName, configurationSource::getProperty, serviceProvider); } @Override diff --git a/email/model/memory/src/main/java/com/blazebit/notify/email/model/memory/EmailNotification.java b/email/model/memory/src/main/java/com/blazebit/notify/email/model/memory/EmailNotification.java deleted file mode 100644 index fa130dc4..00000000 --- a/email/model/memory/src/main/java/com/blazebit/notify/email/model/memory/EmailNotification.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2018 - 2023 Blazebit. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.blazebit.notify.email.model.memory; - -import com.blazebit.notify.ConfigurationSourceProvider; - -/** - * A simple E-Mail notification. - * - * @author Christian Beikov - * @since 1.0.0 - */ -public class EmailNotification extends AbstractEmailNotification implements ConfigurationSourceProvider { - - private static final long serialVersionUID = 1L; - - /** - * Creates a E-Mail notification with the given id. - * - * @param id The notification id - */ - public EmailNotification(Long id) { - super(id); - } - - @Override - public Long getPartitionKey() { - return getId(); - } -} diff --git a/jpa/model/base/src/main/java/com/blazebit/notify/jpa/model/base/AbstractNotificationRecipient.java b/jpa/model/base/src/main/java/com/blazebit/notify/jpa/model/base/AbstractNotificationRecipient.java index b6203204..280f3f81 100644 --- a/jpa/model/base/src/main/java/com/blazebit/notify/jpa/model/base/AbstractNotificationRecipient.java +++ b/jpa/model/base/src/main/java/com/blazebit/notify/jpa/model/base/AbstractNotificationRecipient.java @@ -19,10 +19,8 @@ import com.blazebit.job.jpa.model.BaseEntity; import com.blazebit.notify.NotificationRecipient; +import java.util.TimeZone; import javax.persistence.Column; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; import javax.persistence.MappedSuperclass; import java.util.Locale; @@ -36,6 +34,7 @@ public abstract class AbstractNotificationRecipient extends BaseEntity implements NotificationRecipient { private Locale locale; + private TimeZone timeZone; /** * Creates an empty notification recipient. @@ -52,12 +51,6 @@ public AbstractNotificationRecipient(Long id) { super(id); } - @Id - @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "idGenerator") - public Long getId() { - return id(); - } - @Override @Column(nullable = false) public Locale getLocale() { @@ -72,4 +65,14 @@ public Locale getLocale() { public void setLocale(Locale locale) { this.locale = locale; } + + @Override + @Column(nullable = false) + public TimeZone getTimeZone() { + return timeZone; + } + + public void setTimeZone(TimeZone timeZone) { + this.timeZone = timeZone; + } } diff --git a/memory/model/src/main/java/com/blazebit/notify/memory/model/AbstractNotificationRecipient.java b/memory/model/src/main/java/com/blazebit/notify/memory/model/AbstractNotificationRecipient.java index 06724f20..b25ef04f 100644 --- a/memory/model/src/main/java/com/blazebit/notify/memory/model/AbstractNotificationRecipient.java +++ b/memory/model/src/main/java/com/blazebit/notify/memory/model/AbstractNotificationRecipient.java @@ -20,6 +20,7 @@ import com.blazebit.notify.NotificationRecipient; import java.util.Locale; +import java.util.TimeZone; /** * An abstract base class implementing the {@link NotificationRecipient} interface. @@ -27,9 +28,10 @@ * @author Christian Beikov * @since 1.0.0 */ -public class AbstractNotificationRecipient extends BaseEntity implements NotificationRecipient { +public abstract class AbstractNotificationRecipient extends BaseEntity implements NotificationRecipient { private Locale locale; + private TimeZone timeZone; /** * Creates an empty notification recipient. @@ -59,4 +61,13 @@ public Locale getLocale() { public void setLocale(Locale locale) { this.locale = locale; } + + @Override + public TimeZone getTimeZone() { + return timeZone; + } + + public void setTimeZone(TimeZone timeZone) { + this.timeZone = timeZone; + } } diff --git a/template/api/pom.xml b/template/api/pom.xml index 896a2d81..d009abb8 100644 --- a/template/api/pom.xml +++ b/template/api/pom.xml @@ -10,4 +10,11 @@ blaze-notify-template-api + + + com.blazebit + blaze-job-core-api + ${version.blaze-job} + + \ No newline at end of file diff --git a/template/api/src/main/java/com/blazebit/notify/template/api/TemplateProcessor.java b/template/api/src/main/java/com/blazebit/notify/template/api/TemplateProcessor.java index e8912be8..6d56df76 100644 --- a/template/api/src/main/java/com/blazebit/notify/template/api/TemplateProcessor.java +++ b/template/api/src/main/java/com/blazebit/notify/template/api/TemplateProcessor.java @@ -27,8 +27,6 @@ */ public interface TemplateProcessor extends Serializable { - String TEMPLATE_NAME_PROPERTY = "template"; - /** * Processes this template based on the given map model. * diff --git a/template/api/src/main/java/com/blazebit/notify/template/api/TemplateProcessorFactory.java b/template/api/src/main/java/com/blazebit/notify/template/api/TemplateProcessorFactory.java index ca1e7de7..2ae7c637 100644 --- a/template/api/src/main/java/com/blazebit/notify/template/api/TemplateProcessorFactory.java +++ b/template/api/src/main/java/com/blazebit/notify/template/api/TemplateProcessorFactory.java @@ -15,6 +15,8 @@ */ package com.blazebit.notify.template.api; +import com.blazebit.job.ServiceProvider; + /** * A factory for template processors of a specific type. * @@ -34,9 +36,11 @@ public interface TemplateProcessorFactory { /** * Creates a new template processor for the given template context and configuration source. * - * @param templateContext The template context + * @param templateContext The template context + * @param templateName The name of the template to retrieve a template processor for * @param configurationSource The configuration source + * @param serviceProvider The service provider of the job context * @return the template processor */ - TemplateProcessor createTemplateProcessor(TemplateContext templateContext, ConfigurationSource configurationSource); + TemplateProcessor createTemplateProcessor(TemplateContext templateContext, String templateName, ConfigurationSource configurationSource, ServiceProvider serviceProvider); } diff --git a/template/freemarker/src/main/java/com/blazebit/notify/template/freemarker/FreemarkerTemplateProcessor.java b/template/freemarker/src/main/java/com/blazebit/notify/template/freemarker/FreemarkerTemplateProcessor.java index 1a0eb855..2c861bde 100644 --- a/template/freemarker/src/main/java/com/blazebit/notify/template/freemarker/FreemarkerTemplateProcessor.java +++ b/template/freemarker/src/main/java/com/blazebit/notify/template/freemarker/FreemarkerTemplateProcessor.java @@ -55,7 +55,7 @@ public class FreemarkerTemplateProcessor implements TemplateProcessor, S /** * The configuration property for the Freemarker {@link Template}. */ - public static final String FREEMARKER_TEMPLATE_PROPERTY = TEMPLATE_NAME_PROPERTY; + public static final String FREEMARKER_TEMPLATE_PROPERTY = "template"; /** * The configuration property for the {@link ResourceBundle}. @@ -73,9 +73,10 @@ public class FreemarkerTemplateProcessor implements TemplateProcessor, S /** * Creates a new Freemarker template processor from the given configuration source. * + * @param templateName The template name * @param configurationSource The configuration source */ - public FreemarkerTemplateProcessor(ConfigurationSource configurationSource) { + public FreemarkerTemplateProcessor(String templateName, ConfigurationSource configurationSource) { Function templateAccessor = name -> (Locale locale) -> { Configuration configuration = configurationSource.getPropertyOrDefault(FREEMARKER_CONFIGURATION_PROPERTY, Configuration.class, null, o -> { Configuration c = new Configuration(Configuration.VERSION_2_3_28); @@ -89,7 +90,7 @@ public FreemarkerTemplateProcessor(ConfigurationSource configurationSource) { throw new TemplateException("", e); } }; - this.freemarkerTemplateLookup = configurationSource.getPropertyOrFail(FREEMARKER_TEMPLATE_PROPERTY, FreemarkerTemplateLookup.class, templateAccessor); + this.freemarkerTemplateLookup = configurationSource.getPropertyOrDefault(FREEMARKER_TEMPLATE_PROPERTY, FreemarkerTemplateLookup.class, templateAccessor, o -> templateAccessor.apply(templateName)); Function resourceBundleAccessor = name -> (Locale locale) -> ResourceBundle.getBundle(name, locale); this.resourceBundleLookup = configurationSource.getPropertyOrDefault(RESOURCE_BUNDLE_KEY, TemplateResourceBundleLookup.class, resourceBundleAccessor, o -> locale -> null); } diff --git a/template/freemarker/src/main/java/com/blazebit/notify/template/freemarker/FreemarkerTemplateProcessorFactory.java b/template/freemarker/src/main/java/com/blazebit/notify/template/freemarker/FreemarkerTemplateProcessorFactory.java index b0a12fde..e3afe9b7 100644 --- a/template/freemarker/src/main/java/com/blazebit/notify/template/freemarker/FreemarkerTemplateProcessorFactory.java +++ b/template/freemarker/src/main/java/com/blazebit/notify/template/freemarker/FreemarkerTemplateProcessorFactory.java @@ -37,7 +37,7 @@ public TemplateProcessorKey getTemplateProcessorKey() { } @Override - public TemplateProcessor createTemplateProcessor(TemplateContext templateContext, ConfigurationSource configurationSource) { - return new FreemarkerTemplateProcessor(configurationSource); + public TemplateProcessor createTemplateProcessor(TemplateContext templateContext, String templateName, ConfigurationSource configurationSource, com.blazebit.job.ServiceProvider serviceProvider) { + return new FreemarkerTemplateProcessor(templateName, configurationSource); } } diff --git a/template/thymeleaf/src/main/java/com/blazebit/template/thymeleaf/ThymeleafTemplateProcessor.java b/template/thymeleaf/src/main/java/com/blazebit/template/thymeleaf/ThymeleafTemplateProcessor.java index 6a5a687a..183aff0d 100644 --- a/template/thymeleaf/src/main/java/com/blazebit/template/thymeleaf/ThymeleafTemplateProcessor.java +++ b/template/thymeleaf/src/main/java/com/blazebit/template/thymeleaf/ThymeleafTemplateProcessor.java @@ -15,14 +15,13 @@ */ package com.blazebit.template.thymeleaf; -import com.blazebit.notify.template.api.ConfigurationSource; +import com.blazebit.job.ServiceProvider; import com.blazebit.notify.template.api.TemplateException; import com.blazebit.notify.template.api.TemplateProcessor; import com.blazebit.notify.template.api.TemplateProcessorKey; import java.io.Serializable; import java.util.Locale; import java.util.Map; -import java.util.function.Function; import org.thymeleaf.ITemplateEngine; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.Context; @@ -38,8 +37,6 @@ public class ThymeleafTemplateProcessor implements TemplateProcessor, Se public static final TemplateProcessorKey KEY = TemplateProcessorKey.of("thymeleaf", String.class); - public static final String THYMELEAF_TEMPLATE_ENGINE_PROPERTY = "templateEngine"; - public static final String THYMELEAF_TEMPLATE_NAME_PROPERTY = TEMPLATE_NAME_PROPERTY; public static final String LOCALE_MODEL_KEY = "locale"; private final ITemplateEngine templateEngine; @@ -48,11 +45,14 @@ public class ThymeleafTemplateProcessor implements TemplateProcessor, Se /** * Creates a new Thymeleaf template processor from the given configuration source. * - * @param configurationSource The configuration source + * @param templateName The template name + * @param serviceProvider The service provider of the job context + * */ - public ThymeleafTemplateProcessor(ConfigurationSource configurationSource) { - this.templateEngine = configurationSource.getPropertyOrDefault(THYMELEAF_TEMPLATE_ENGINE_PROPERTY, ITemplateEngine.class, val -> null, val -> new TemplateEngine()); - this.templateName = configurationSource.getPropertyOrFail(THYMELEAF_TEMPLATE_NAME_PROPERTY, String.class, Function.identity()); + public ThymeleafTemplateProcessor(String templateName, ServiceProvider serviceProvider) { + ITemplateEngine templateEngine = serviceProvider.getService(ITemplateEngine.class); + this.templateEngine = templateEngine == null ? new TemplateEngine() : templateEngine; + this.templateName = templateName; } @Override diff --git a/template/thymeleaf/src/main/java/com/blazebit/template/thymeleaf/ThymeleafTemplateProcessorFactory.java b/template/thymeleaf/src/main/java/com/blazebit/template/thymeleaf/ThymeleafTemplateProcessorFactory.java index b958396a..41b2a93e 100644 --- a/template/thymeleaf/src/main/java/com/blazebit/template/thymeleaf/ThymeleafTemplateProcessorFactory.java +++ b/template/thymeleaf/src/main/java/com/blazebit/template/thymeleaf/ThymeleafTemplateProcessorFactory.java @@ -37,7 +37,7 @@ public TemplateProcessorKey getTemplateProcessorKey() { } @Override - public TemplateProcessor createTemplateProcessor(TemplateContext templateContext, ConfigurationSource configurationSource) { - return new ThymeleafTemplateProcessor(configurationSource); + public TemplateProcessor createTemplateProcessor(TemplateContext templateContext, String templateName, ConfigurationSource configurationSource, com.blazebit.job.ServiceProvider serviceProvider) { + return new ThymeleafTemplateProcessor(templateName, serviceProvider); } }