diff --git a/src/net/datenwerke/rs/ReportServerServiceConfig.java b/src/net/datenwerke/rs/ReportServerServiceConfig.java index 5f191c96f..ae142d9a3 100755 --- a/src/net/datenwerke/rs/ReportServerServiceConfig.java +++ b/src/net/datenwerke/rs/ReportServerServiceConfig.java @@ -273,7 +273,7 @@ public class ReportServerServiceConfig extends DwGwtFrameworkBase { private final Logger logger = LoggerFactory.getLogger(getClass().getName()); - public static final String CODE_VERSION = "2024-09-02-10-04-32"; + public static final String CODE_VERSION = "2024-09-18-12-15-33"; public static final String ENTERPRISE_MODULE_LOCATION = "net.datenwerke.rsenterprise.main.service.RsEnterpriseModule"; private static final String ENTERPRISE_MODULE_LOAD_MODULE_METHOD = "getEnterpriseModules"; diff --git a/src/net/datenwerke/rs/core/service/mail/SimpleMail.java b/src/net/datenwerke/rs/core/service/mail/SimpleMail.java index fd446ba5e..41ecac901 100755 --- a/src/net/datenwerke/rs/core/service/mail/SimpleMail.java +++ b/src/net/datenwerke/rs/core/service/mail/SimpleMail.java @@ -126,7 +126,8 @@ public void setHtml(String html, SimpleAttachment... attachments) { for (SimpleAttachment att : attachments) { MimeBodyPart mbp = new MimeBodyPart(); mbp.setContent(att.getAttachment(), att.getMimeType()); - mbp.setFileName(MimeUtility.encodeText(att.getFileName(), CHARSET_UTF8, null)); + // encoding: "B" == "BASE64" || "Q" == "Quoted-Printable" + mbp.setFileName(MimeUtility.encodeText(att.getFileName(), CHARSET_UTF8, "B")); multipart.addBodyPart(mbp); } @@ -164,7 +165,8 @@ public void setContent(String text, SimpleAttachment... attachements) { protected MimeBodyPart createAttachmentPart(SimpleAttachment att) throws UnsupportedEncodingException, MessagingException { MimeBodyPart mbp = new MimeBodyPart(); - mbp.setFileName(MimeUtility.encodeText(att.getFileName(), CHARSET_UTF8, null)); + // encoding: "B" == "BASE64" || "Q" == "Quoted-Printable" + mbp.setFileName(MimeUtility.encodeText(att.getFileName(), CHARSET_UTF8, "B")); Object data = att.getAttachment(); if (data instanceof String) { diff --git a/src/net/datenwerke/rs/core/service/reportmanager/ReportServiceImpl.java b/src/net/datenwerke/rs/core/service/reportmanager/ReportServiceImpl.java index 6ce590628..e3804abdc 100755 --- a/src/net/datenwerke/rs/core/service/reportmanager/ReportServiceImpl.java +++ b/src/net/datenwerke/rs/core/service/reportmanager/ReportServiceImpl.java @@ -14,8 +14,6 @@ import javax.persistence.EntityManager; -import org.apache.commons.lang3.StringUtils; - import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; @@ -180,28 +178,15 @@ public List getReportsByDatasource(@Named("ds") DatasourceDefinition ds) @UpdateOwner(name = "node") @FirePersistEntityEvents public void persist(@Named("node") AbstractReportManagerNode node) { - ensureKeyIsUnique(node); - super.persist(node); } @Override @FireMergeEntityEvents public AbstractReportManagerNode merge(AbstractReportManagerNode node) { - ensureKeyIsUnique(node); - return super.merge(node); } - protected void ensureKeyIsUnique(AbstractReportManagerNode node) { - if (node instanceof Report && !StringUtils.isEmpty(((Report) node).getKey())) { - Report report = getReportByKey(((Report) node).getKey()); - if (null != report && !report.equals(node)) - throw new IllegalArgumentException( - "Report key must be unique: " + node.getId() + ", " + ((Report) node).getKey()); - } - } - @Override public void persist(ReportMetadata reportMetadata) { entityManagerProvider.get().persist(reportMetadata); diff --git a/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/EmailDatasinkServiceImpl.java b/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/EmailDatasinkServiceImpl.java index e8de2bb39..ce98caf2c 100755 --- a/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/EmailDatasinkServiceImpl.java +++ b/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/EmailDatasinkServiceImpl.java @@ -16,6 +16,7 @@ import net.datenwerke.rs.core.service.mail.SimpleMail; import net.datenwerke.rs.emaildatasink.service.emaildatasink.annotations.DefaultEmailDatasink; import net.datenwerke.rs.emaildatasink.service.emaildatasink.configs.DatasinkEmailConfig; +import net.datenwerke.rs.emaildatasink.service.emaildatasink.configs.DatasinkEmailConfig2; import net.datenwerke.rs.emaildatasink.service.emaildatasink.definitions.EmailDatasink; import net.datenwerke.rs.scheduleasfile.client.scheduleasfile.StorageType; import net.datenwerke.rs.utils.misc.MimeUtils; @@ -67,7 +68,13 @@ public void doExportIntoDatasink(Object data, User user, DatasinkDefinition data mimeUtilsProvider.get().getMimeTypeByExtension(emailConfig.getFilename()), emailConfig.getFilename()))) .build(); - + if (config instanceof DatasinkEmailConfig2 && ((DatasinkEmailConfig2) config).isHtml()) { + /* override setContent with setHtml */ + mail.setHtml(emailConfig.getBody(), new SimpleAttachment(data, + mimeUtilsProvider.get().getMimeTypeByExtension(emailConfig.getFilename()), + emailConfig.getFilename())); + } + if (emailConfig.isSendSyncEmail()) mailServiceProvider.get().sendMailSync(Optional.of(emailDatasink), mail); else diff --git a/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/action/ScheduleAsEmailFileAction.java b/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/action/ScheduleAsEmailFileAction.java index c572476a0..eb224135b 100755 --- a/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/action/ScheduleAsEmailFileAction.java +++ b/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/action/ScheduleAsEmailFileAction.java @@ -1,5 +1,10 @@ package net.datenwerke.rs.emaildatasink.service.emaildatasink.action; +import static net.datenwerke.rs.scheduler.service.scheduler.RsSchedulerModule.PROPERTY_EMAIL_ATTACHEMENT_NAME; +import static net.datenwerke.rs.scheduler.service.scheduler.RsSchedulerModule.PROPERTY_EMAIL_HTML; +import static net.datenwerke.rs.scheduler.service.scheduler.RsSchedulerModule.PROPERTY_EMAIL_SUBJECT; +import static net.datenwerke.rs.scheduler.service.scheduler.RsSchedulerModule.PROPERTY_EMAIL_TEXT; + import java.util.List; import javax.persistence.Entity; @@ -11,17 +16,21 @@ import javax.persistence.Table; import javax.persistence.Transient; +import org.apache.commons.configuration2.Configuration; import org.hibernate.annotations.Type; import com.google.inject.Inject; +import net.datenwerke.gf.service.localization.RemoteMessageService; import net.datenwerke.rs.core.service.datasinkmanager.DatasinkService; import net.datenwerke.rs.core.service.reportmanager.entities.reports.Report; -import net.datenwerke.rs.emaildatasink.service.emaildatasink.configs.DatasinkEmailConfig; +import net.datenwerke.rs.emaildatasink.service.emaildatasink.configs.DatasinkEmailConfig2; import net.datenwerke.rs.emaildatasink.service.emaildatasink.definitions.EmailDatasink; +import net.datenwerke.rs.scheduler.service.scheduler.annotations.SchedulerModuleProperties; import net.datenwerke.rs.scheduler.service.scheduler.jobs.report.ReportExecuteJob; import net.datenwerke.rs.utils.entitycloner.annotation.EnclosedEntity; import net.datenwerke.rs.utils.juel.SimpleJuel; +import net.datenwerke.rs.utils.localization.LocalizationServiceImpl; import net.datenwerke.scheduler.service.scheduler.SchedulerHelperService; import net.datenwerke.scheduler.service.scheduler.entities.AbstractAction; import net.datenwerke.scheduler.service.scheduler.entities.AbstractJob; @@ -43,6 +52,15 @@ public class ScheduleAsEmailFileAction extends AbstractAction { @Transient @Inject private DatasinkService datasinkService; + + @Transient + @Inject + private RemoteMessageService remoteMessageService; + + @Transient + @Inject + @SchedulerModuleProperties + private Configuration config; @EnclosedEntity @OneToOne(fetch = FetchType.LAZY) @@ -92,9 +110,11 @@ public void execute(AbstractJob job) throws ActionExecutionException { SimpleJuel juel = schedulerHelperService.getConfiguredJuel(rJob); juel.addReplacement(PROPERTY_SUBJECT, getSubject()); juel.addReplacement(PROPERTY_MESSAGE, getMessage()); + /* enable msgs replacement */ + String currentLanguage = LocalizationServiceImpl.getLocale().getLanguage(); + juel.addReplacement("msgs", remoteMessageService.getMessages(currentLanguage)); filename = null == name ? "" : juel.parse(name); - sendViaEmailDatasink(rJob, juel, filename); if (null == name || name.trim().isEmpty()) @@ -106,12 +126,34 @@ public void execute(AbstractJob job) throws ActionExecutionException { } private void sendViaEmailDatasink(final ReportExecuteJob rJob, final SimpleJuel juel, final String filename) - throws ActionExecutionException { - datasinkService.exportIntoDatasink(rJob, compressed, emailDatasink, new DatasinkEmailConfig() { - + throws ActionExecutionException { + datasinkService.exportIntoDatasink(rJob, compressed, emailDatasink, new DatasinkEmailConfig2() { + + /* default values */ + boolean isHtml = false; + String sSubject = subject; + String sMessage = message; + String sFilename = filename; + + boolean isInit = false; + + private void init() { + /* only init once */ + if (isInit) + return; + /* values from config */ + isHtml = config.getBoolean(PROPERTY_EMAIL_HTML, isHtml); + sSubject = config.getString(PROPERTY_EMAIL_SUBJECT, sSubject); + sMessage = config.getString(PROPERTY_EMAIL_TEXT, sMessage); + sFilename = config.getString(PROPERTY_EMAIL_ATTACHEMENT_NAME, sFilename); + isInit = true; + } + + @Override public String getFilename() { - return datasinkService.getFilenameForDatasink(rJob, compressed, filename); + init(); + return datasinkService.getFilenameForDatasink(rJob, compressed, juel.parse(sFilename)); } @Override @@ -121,7 +163,8 @@ public boolean isSendSyncEmail() { @Override public String getSubject() { - return juel.parse(subject); + init(); + return juel.parse(sSubject); } @Override @@ -131,7 +174,13 @@ public List getRecipients() { @Override public String getBody() { - return juel.parse(message); + init(); + return juel.parse(sMessage); + } + + @Override + public boolean isHtml() { + return isHtml; } }); } diff --git a/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/configs/DatasinkEmailConfig2.java b/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/configs/DatasinkEmailConfig2.java new file mode 100644 index 000000000..c880d83e7 --- /dev/null +++ b/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/configs/DatasinkEmailConfig2.java @@ -0,0 +1,6 @@ +package net.datenwerke.rs.emaildatasink.service.emaildatasink.configs; + +public interface DatasinkEmailConfig2 extends DatasinkEmailConfig { + + boolean isHtml(); +} diff --git a/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/hooker/ScheduleAsEmailDatasinkEmailNotificationHooker.java b/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/hooker/ScheduleAsEmailDatasinkEmailNotificationHooker.java index 127d1e643..6c2f2c574 100755 --- a/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/hooker/ScheduleAsEmailDatasinkEmailNotificationHooker.java +++ b/src/net/datenwerke/rs/emaildatasink/service/emaildatasink/hooker/ScheduleAsEmailDatasinkEmailNotificationHooker.java @@ -34,7 +34,6 @@ public class ScheduleAsEmailDatasinkEmailNotificationHooker extends SchedulerExe { put(DatasinkModule.PROPERTY_SUBJECT, "scheduler.fileactionEmailDatasink.subject"); put(DatasinkModule.PROPERTY_TEXT, "scheduler.fileactionEmailDatasink.text"); - put(DatasinkModule.PROPERTY_DISABLED, "scheduler.fileactionEmailDatasink[@disabled]"); put(DatasinkModule.PROPERTY_HTML, "scheduler.fileactionEmailDatasink[@html]"); put(DatasinkModule.PROPERTY_TRANSLATIONS_SUBJECT, "fileactionEmailDatasinkMsgSubject"); put(DatasinkModule.PROPERTY_TRANSLATIONS_TEXT, "fileactionEmailDatasinkMsgText"); diff --git a/src/net/datenwerke/rs/scheduler/service/scheduler/RsSchedulerModule.java b/src/net/datenwerke/rs/scheduler/service/scheduler/RsSchedulerModule.java index 34535bcf9..ba0850904 100755 --- a/src/net/datenwerke/rs/scheduler/service/scheduler/RsSchedulerModule.java +++ b/src/net/datenwerke/rs/scheduler/service/scheduler/RsSchedulerModule.java @@ -25,6 +25,8 @@ public class RsSchedulerModule extends AbstractReportServerModule { public static final String CONFIG_FILE = "scheduler/scheduler.cf"; //$NON-NLS-1$ + public static final String PROPERTY_EMAIL_DISABLED = "scheduler.mailaction[@disabled]"; + public static final String PROPERTY_EMAIL_HTML = "scheduler.mailaction[@html]"; public static final String PROPERTY_EMAIL_SUBJECT = "scheduler.mailaction.subject"; public static final String PROPERTY_EMAIL_TEXT = "scheduler.mailaction.text"; public static final String PROPERTY_EMAIL_ATTACHEMENT_NAME = "scheduler.mailaction.attachment.name"; diff --git a/src/net/datenwerke/rs/utils/reflection/DynaBeanUtilService.java b/src/net/datenwerke/rs/utils/reflection/DynaBeanUtilService.java deleted file mode 100644 index 78d1481e0..000000000 --- a/src/net/datenwerke/rs/utils/reflection/DynaBeanUtilService.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.datenwerke.rs.utils.reflection; - -import java.util.List; -import java.util.Map; - -import org.apache.commons.beanutils.DynaBean; - -import com.google.inject.ImplementedBy; - -@ImplementedBy(DynaBeanUtilServiceImpl.class) -public interface DynaBeanUtilService { - - Map convertDynaBeanToMap(DynaBean dynaBean); - - List> convertDynaBeansToMap(List dynaBeans); - -} diff --git a/src/net/datenwerke/rs/utils/reflection/DynaBeanUtilServiceImpl.java b/src/net/datenwerke/rs/utils/reflection/DynaBeanUtilServiceImpl.java deleted file mode 100644 index c2c933ea9..000000000 --- a/src/net/datenwerke/rs/utils/reflection/DynaBeanUtilServiceImpl.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.datenwerke.rs.utils.reflection; - -import static java.util.stream.Collectors.toList; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.beanutils.DynaBean; -import org.apache.commons.beanutils.DynaProperty; -import org.apache.commons.beanutils.PropertyUtils; - -public class DynaBeanUtilServiceImpl implements DynaBeanUtilService { - - @Override - public Map convertDynaBeanToMap(DynaBean dynaBean) { - Map resultMap = new HashMap<>(); - DynaProperty[] dynaProperties = dynaBean.getDynaClass().getDynaProperties(); - - try { - for (DynaProperty dynaProperty : dynaProperties) { - String propertyName = dynaProperty.getName(); - Object propertyValue = PropertyUtils.getProperty(dynaBean, propertyName); - resultMap.put(propertyName, propertyValue); - } - } catch (Exception e) { - throw new IllegalStateException("Could not convert DynaBean into a map", e); - } - - return resultMap; - } - - @Override - public List> convertDynaBeansToMap(List dynaBeans) { - return dynaBeans - .stream() - .map(this::convertDynaBeanToMap) - .collect(toList()); - } - -}