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.HashMap;
020import java.util.Map;
021
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024import org.apache.commons.lang3.StringUtils;
025import org.apache.commons.lang3.exception.ExceptionUtils;
026import org.quartz.JobDataMap;
027import org.quartz.JobExecutionContext;
028import org.quartz.JobExecutionException;
029
030import org.ametys.cms.schedule.AbstractSendingMailSchedulable;
031import org.ametys.core.schedule.progression.ContainerProgressionTracker;
032import org.ametys.core.ui.mail.StandardMailBodyHelper;
033import org.ametys.odf.catalog.Catalog;
034import org.ametys.odf.catalog.CatalogsManager;
035import org.ametys.plugins.core.schedule.Scheduler;
036import org.ametys.runtime.i18n.I18nizableText;
037import org.ametys.runtime.i18n.I18nizableTextParameter;
038
039/**
040 * Schedulable to delete a catalog
041 */
042public class DeleteCatalogSchedulable extends AbstractSendingMailSchedulable
043{
044    /** Schedulable ID */
045    public static final String SCHEDULABLE_ID = DeleteCatalogSchedulable.class.getName();
046    
047    /** The job data map key for the catalog Id to delete*/
048    public static final String JOBDATAMAP_CATALOG_NAME_KEY = "catalog";
049    
050    private CatalogsManager _catalogsManager;
051
052    @Override
053    public void service(ServiceManager manager) throws ServiceException
054    {
055        super.service(manager);
056        _catalogsManager = (CatalogsManager) manager.lookup(CatalogsManager.ROLE);
057    }
058    
059    @Override
060    protected void _doExecute(JobExecutionContext context, ContainerProgressionTracker progressionTracker) throws Exception
061    {
062        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
063        
064        String catalogName = jobDataMap.getString(Scheduler.PARAM_VALUES_PREFIX + JOBDATAMAP_CATALOG_NAME_KEY);
065        if (StringUtils.isEmpty(catalogName))
066        {
067            throw new JobExecutionException("The catalog name cannot be empty.");
068        }
069        Catalog catalog = _catalogsManager.getCatalog(catalogName);
070        if (catalog == null)
071        {
072            throw new JobExecutionException("The catalog " + catalogName + " can't be retrieved.");
073        }
074        
075        Map<String, Object> deleteCatalogResult = _catalogsManager.deleteCatalog(catalog);
076        if (deleteCatalogResult.containsKey("error"))
077        {
078            switch ((String) deleteCatalogResult.get("error"))
079            {
080                case "unknown-catalog":
081                    throw new JobExecutionException("The catalog with id " + catalogName + " can not be resolved.");
082                case "referencing-contents":
083                    throw new JobExecutionException("Impossible to delete catalog with id " + catalogName + ". There are contents outside of the catalog referencing the contents in the catalog to delete. See previous log for more info.");
084                default:
085                    throw new JobExecutionException("Something bad happened while trying to delete the catalog " + catalogName);
086            }
087        }
088    }
089
090    @Override
091    protected I18nizableText _getSuccessMailSubject(JobExecutionContext context) throws Exception
092    {
093        return new I18nizableText("plugin.odf", "PLUGINS_ODF_SCHEDULABLE_DELETE_CATALOG_SUCCESS_MAIL_SUBJECT", _getI18nParams(context));
094    }
095    
096    @Override
097    protected boolean _isMailBodyInHTML(JobExecutionContext context) throws Exception
098    {
099        return true;
100    }
101
102    @Override
103    protected String _getSuccessMailBody(JobExecutionContext context, String language) throws Exception
104    {
105        try
106        {
107            return StandardMailBodyHelper.newHTMLBody()
108                    .withTitle(_getSuccessMailSubject(context))
109                    .withMessage(new I18nizableText("plugin.odf", "PLUGINS_ODF_SCHEDULABLE_DELETE_CATALOG_SUCCESS_MAIL_BODY", _getI18nParams(context)))
110                    .withLanguage(language)
111                    .build();
112        }
113        catch (IOException e)
114        {
115            getLogger().warn("Failed to build HTML email body for catalog deletion result. Fallback to no wrapped email", e);
116            return _i18nUtils.translate(new I18nizableText("plugin.odf", "PLUGINS_ODF_SCHEDULABLE_DELETE_CATALOG_SUCCESS_MAIL_BODY", _getI18nParams(context)), language);
117        }
118    }
119
120    @Override
121    protected I18nizableText _getErrorMailSubject(JobExecutionContext context) throws Exception
122    {
123        return new I18nizableText("plugin.odf", "PLUGINS_ODF_SCHEDULABLE_DELETE_CATALOG_ERROR_MAIL_SUBJECT", _getI18nParams(context));
124    }
125
126    @Override
127    protected String _getErrorMailBody(JobExecutionContext context, String language, Throwable throwable) throws Exception
128    {
129        String error = ExceptionUtils.getStackTrace(throwable);
130        
131        try
132        {
133            return StandardMailBodyHelper.newHTMLBody()
134                    .withTitle(_getErrorMailSubject(context))
135                    .withMessage(new I18nizableText("plugin.odf", "PLUGINS_ODF_SCHEDULABLE_DELETE_CATALOG_ERROR_MAIL_BODY", _getI18nParams(context)))
136                    .withDetails(null, error, true)
137                    .withLanguage(language)
138                    .build();
139        }
140        catch (IOException e)
141        {
142            getLogger().warn("Failed to build HTML email body for catalog deletion result. Fallback to no wrapped email", e);
143            return _i18nUtils.translate(new I18nizableText("plugin.odf", "PLUGINS_ODF_SCHEDULABLE_DELETE_CATALOG_ERROR_MAIL_BODY", _getI18nParams(context)), language);
144        }
145    }
146
147    private Map<String, I18nizableTextParameter> _getI18nParams(JobExecutionContext context)
148    {
149        Map<String, I18nizableTextParameter> i18nParams = new HashMap<>();
150        
151        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
152        String catalogName = jobDataMap.getString(Scheduler.PARAM_VALUES_PREFIX + JOBDATAMAP_CATALOG_NAME_KEY);
153        i18nParams.put("catalogName", new I18nizableText(catalogName));
154        return i18nParams;
155    }
156}
157