001/* 002 * Copyright 2022 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.odf.schedulable; 017 018import java.io.IOException; 019import java.util.List; 020import java.util.Objects; 021import java.util.stream.Collectors; 022 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025import org.apache.commons.lang3.StringUtils; 026import org.apache.commons.lang3.exception.ExceptionUtils; 027import org.quartz.JobDataMap; 028import org.quartz.JobExecutionContext; 029 030import org.ametys.cms.contenttype.ContentType; 031import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 032import org.ametys.cms.schedule.AbstractSendingMailSchedulable; 033import org.ametys.core.schedule.progression.ContainerProgressionTracker; 034import org.ametys.core.ui.mail.StandardMailBodyHelper; 035import org.ametys.odf.init.OdfRefTableDataExtensionPoint; 036import org.ametys.odf.init.OdfRefTableDataHelper; 037import org.ametys.odf.init.OdfRefTableDataHelper.OdfRefTableDataResult; 038import org.ametys.plugins.contentio.csv.SynchronizeModeEnumerator.ImportMode; 039import org.ametys.plugins.core.schedule.Scheduler; 040import org.ametys.runtime.i18n.I18nizableText; 041 042/** 043 * Import reference table data described by {@link OdfRefTableDataExtensionPoint}. 044 */ 045public class OdfRefTableDataSynchronizationSchedulable extends AbstractSendingMailSchedulable 046{ 047 private static final String __CONTEXT_KEY_SYNC_REPORT = OdfRefTableDataSynchronizationSchedulable.class.getName() + "$syncReport"; 048 private static final String __IMPORT_MODE = "importMode"; 049 050 private OdfRefTableDataHelper _odfRefTableDataHelper; 051 private ContentTypeExtensionPoint _contentTypeEP; 052 053 @Override 054 public void service(ServiceManager manager) throws ServiceException 055 { 056 super.service(manager); 057 _odfRefTableDataHelper = (OdfRefTableDataHelper) manager.lookup(OdfRefTableDataHelper.ROLE); 058 _contentTypeEP = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE); 059 } 060 061 @Override 062 protected void _doExecute(JobExecutionContext context, ContainerProgressionTracker progressionTracker) throws Exception 063 { 064 JobDataMap jobDataMap = context.getJobDetail().getJobDataMap(); 065 ImportMode importMode = ImportMode.valueOf((String) jobDataMap.get(Scheduler.PARAM_VALUES_PREFIX + __IMPORT_MODE)); 066 067 OdfRefTableDataResult result = _odfRefTableDataHelper.processRefTableData(importMode); 068 context.put(__CONTEXT_KEY_SYNC_REPORT, result); 069 } 070 071 @Override 072 protected boolean _isMailBodyInHTML(JobExecutionContext context) throws Exception 073 { 074 return true; 075 } 076 077 @Override 078 protected I18nizableText _getSuccessMailSubject(JobExecutionContext context) throws Exception 079 { 080 String subjectKey = "PLUGINS_ODF_TABLEREF_SYNC_MAIL_SUCCESS_SUBJECT"; 081 OdfRefTableDataResult result = (OdfRefTableDataResult) context.get(__CONTEXT_KEY_SYNC_REPORT); 082 if (!result.getPartial().isEmpty() || !result.getFail().isEmpty()) 083 { 084 subjectKey += "_WITH_ERRORS"; 085 } 086 return new I18nizableText("plugin.odf", subjectKey); 087 } 088 089 @Override 090 protected String _getSuccessMailBody(JobExecutionContext context, String language) throws Exception 091 { 092 try 093 { 094 OdfRefTableDataResult result = (OdfRefTableDataResult) context.get(__CONTEXT_KEY_SYNC_REPORT); 095 096 StringBuilder sb = new StringBuilder(); 097 098 // Duration 099 sb.append(_i18nUtils.translate(new I18nizableText("plugin.odf", "PLUGINS_ODF_TABLEREF_SYNC_MAIL_SUCCESS_BODY_RESUME_DURATION", List.of(result.duration())), language)); 100 101 // Imported count 102 sb.append(_i18nUtils.translate(new I18nizableText("plugin.odf", "PLUGINS_ODF_TABLEREF_SYNC_MAIL_SUCCESS_BODY_RESUME_COUNT", List.of(result.getImported().toString())), language)); 103 104 // Success 105 if (!result.getSuccess().isEmpty()) 106 { 107 sb.append(_i18nUtils.translate(new I18nizableText("plugin.odf", "PLUGINS_ODF_TABLEREF_SYNC_MAIL_SUCCESS_BODY_RESUME_SUCCESS", List.of(String.valueOf(result.getSuccess().size()))), language)); 108 } 109 110 // Partial 111 if (!result.getPartial().isEmpty()) 112 { 113 List<String> partialCTypes = result.getPartial(); 114 List<String> partialCTypeLabels = partialCTypes.stream() 115 .map(id -> _contentTypeEP.getExtension(id)) 116 .filter(Objects::nonNull) 117 .map(ContentType::getLabel) 118 .map(label -> _i18nUtils.translate(label, language)) 119 .collect(Collectors.toList()); 120 121 sb.append(_i18nUtils.translate(new I18nizableText("plugin.odf", "PLUGINS_ODF_TABLEREF_SYNC_MAIL_SUCCESS_BODY_RESUME_PARTIAL", List.of(String.valueOf(partialCTypes.size()), StringUtils.join(partialCTypeLabels, ", "))), language)); 122 } 123 124 // Fail 125 if (!result.getFail().isEmpty()) 126 { 127 List<String> failCTypes = result.getFail(); 128 List<String> failCTypesLabels = failCTypes.stream() 129 .map(id -> _contentTypeEP.getExtension(id)) 130 .filter(Objects::nonNull) 131 .map(ContentType::getLabel) 132 .map(label -> _i18nUtils.translate(label, language)) 133 .collect(Collectors.toList()); 134 135 sb.append(_i18nUtils.translate(new I18nizableText("plugin.odf", "PLUGINS_ODF_TABLEREF_SYNC_MAIL_SUCCESS_BODY_RESUME_FAIL", List.of(String.valueOf(failCTypes.size()), StringUtils.join(failCTypesLabels, ", "))), language)); 136 } 137 138 String details = sb.toString(); 139 140 return StandardMailBodyHelper.newHTMLBody() 141 .withTitle(new I18nizableText("plugin.odf", "PLUGINS_ODF_TABLEREF_SYNC_MAIL_SUCCESS_SUBJECT")) 142 .addMessage(new I18nizableText("plugin.odf", "PLUGINS_ODF_TABLEREF_SYNC_MAIL_SUCCESS_BODY_RESUME")) 143 .addMessage(new I18nizableText("plugin.odf", "PLUGINS_ODF_TABLEREF_SYNC_MAIL_SUCCESS_BODY_RESUME_ASK_DETAILS")) 144 .withDetails(new I18nizableText("plugin.odf", "PLUGINS_ODF_TABLEREF_SYNC_MAIL_SUCCESS_BODY_REPORT"), details, false) 145 .withLanguage(language) 146 .build(); 147 } 148 catch (IOException e) 149 { 150 getLogger().error("Failed to build HTML email body for reference table synchronization report", e); 151 return null; 152 } 153 } 154 155 @Override 156 protected I18nizableText _getErrorMailSubject(JobExecutionContext context) throws Exception 157 { 158 return new I18nizableText("plugin.odf", "PLUGINS_ODF_TABLEREF_SYNC_MAIL_ERROR_SUBJECT"); 159 } 160 161 @Override 162 protected String _getErrorMailBody(JobExecutionContext context, String language, Throwable throwable) throws Exception 163 { 164 String error = StringUtils.join(ExceptionUtils.getStackFrames(throwable), "<br/>"); 165 166 return StandardMailBodyHelper.newHTMLBody() 167 .withTitle(new I18nizableText("plugin.odf", "PLUGINS_ODF_TABLEREF_SYNC_MAIL_ERROR_SUBJECT")) 168 .addMessage(new I18nizableText("plugin.odf", "PLUGINS_ODF_TABLEREF_SYNC_MAIL_ERROR_BODY")) 169 .withDetails(null, error, false) 170 .withLanguage(language) 171 .build(); 172 } 173}