001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.scheduler.jobs; 029 030import org.opencms.file.CmsObject; 031import org.opencms.loader.CmsLoaderException; 032import org.opencms.main.CmsLog; 033import org.opencms.main.OpenCms; 034import org.opencms.report.CmsLogReport; 035import org.opencms.scheduler.I_CmsScheduledJob; 036import org.opencms.util.CmsStringUtil; 037 038import java.util.ArrayList; 039import java.util.Calendar; 040import java.util.GregorianCalendar; 041import java.util.HashSet; 042import java.util.List; 043import java.util.Map; 044import java.util.Set; 045 046import org.apache.commons.logging.Log; 047 048/** 049 * A schedulable OpenCms job to clear the history.<p> 050 * 051 * The user to execute the process should have have access to the required "Workplace manager" role.<p> 052 * 053 * If there is an Uri set for the scheduled job, which should only be folders, it will be used 054 * for clearing the history only in there (and the subfolders).<p> 055 * 056 * Job parameters:<p> 057 * <dl> 058 * <dt><code>keepVersions={Number/Integer}</code></dt> 059 * <dd>Number/Integer to control how many versions will be kept. Use -1 if you only want to perform the 'clear deleted resources' part of the job.</dd> 060 * <dt><code>clearDeleted=true|false</code></dt> 061 * <dd>Boolean to configure if the versions of deleted resources should be cleared. 062 * The default is false.</dd> 063 * <dt><code>clearDeletedTypes=image,binary</code></dt> 064 * <dd>OPTIONAL. A comma-separated list of resource types to consider for clearing the deleted resources. If not configured, the resource type will not be restricted.</dd> 065 * <dt><code>clearDeletedPath=/sites/default</code></dt> 066 * <dd>OPTIONAL. A path below which resources will be considered when clearing the deleted resources. If not configured, the resource path will not be restricted.</dd> 067 * <dt><code>keepTimeRange</code></dt> 068 * <dd>Number/Integer to configure the number of days the versions of deleted resources will 069 * be kept. That means that all versions wich are older than the specified number will be deleted. 070 * This parameter is optional and only makes sense if the clearDeleted parameter is set to true.</dd> 071 * </dl> 072 * 073 * @since 7.0.0 074 */ 075public class CmsHistoryClearJob implements I_CmsScheduledJob { 076 077 /**Parameter for selecting the path of deleted resources to clear. */ 078 public static final String PARAM_CLEAR_DELETED_PATHS = "clearDeletedPaths"; 079 080 /** Parameter for selecting the types of deleted resources to clear. */ 081 public static final String PARAM_CLEAR_DELETED_TYPES = "clearDeletedTypes"; 082 083 /** Name of the parameter where to configure if versions of deleted resources are cleared. */ 084 public static final String PARAM_CLEARDELETED = "clearDeleted"; 085 086 /** Name of the parameter where to configure the number of days the versions will be kept. */ 087 public static final String PARAM_KEEPTIMERANGE = "keepTimeRange"; 088 089 /** Name of the parameter where to configure how many versions are kept. */ 090 public static final String PARAM_KEEPVERSIONS = "keepVersions"; 091 092 private static final Log LOG = CmsLog.getLog(CmsHistoryClearJob.class); 093 094 /** 095 * @see org.opencms.scheduler.I_CmsScheduledJob#launch(org.opencms.file.CmsObject, java.util.Map) 096 */ 097 public String launch(CmsObject cms, Map<String, String> parameters) throws Exception { 098 099 // read the parameter for the versions to keep 100 int keepVersions = Integer.parseInt(parameters.get(PARAM_KEEPVERSIONS)); 101 102 // read the parameter if to clear versions of deleted resources 103 boolean clearDeleted = Boolean.valueOf(parameters.get(PARAM_CLEARDELETED)).booleanValue(); 104 105 // read the optional parameter for the time range to keep versions 106 String keepTimeRangeStr = parameters.get(PARAM_KEEPTIMERANGE); 107 int keepTimeRange = -1; 108 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(keepTimeRangeStr)) { 109 keepTimeRange = Integer.parseInt(keepTimeRangeStr); 110 } 111 112 final String clearDeletedTypesStr = parameters.get(PARAM_CLEAR_DELETED_TYPES); 113 final Set<Integer> clearDeletedTypes = new HashSet<>(); 114 if (clearDeletedTypesStr != null) { 115 for (String token : clearDeletedTypesStr.split(",")) { 116 String typeName = token.trim(); 117 if (OpenCms.getResourceManager().hasResourceType(typeName)) { 118 try { 119 clearDeletedTypes.add( 120 Integer.valueOf(OpenCms.getResourceManager().getResourceType(typeName).getTypeId())); 121 } catch (CmsLoaderException e) { 122 LOG.error(e.getLocalizedMessage(), e); 123 } 124 } 125 } 126 } 127 128 final String clearDeletedPathsStr = parameters.get(PARAM_CLEAR_DELETED_PATHS); 129 final List<String> clearDeletedPaths = new ArrayList<>(); 130 if (clearDeletedPathsStr != null) { 131 for (String token : clearDeletedPathsStr.split(",")) { 132 token = token.trim(); 133 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(token)) { 134 clearDeletedPaths.add(token); 135 } 136 } 137 } 138 // calculate the date from where to clear deleted versions 139 long timeDeleted = -1; 140 int keepDeletedVersions; 141 if (clearDeleted) { 142 keepDeletedVersions = 1; 143 GregorianCalendar cal = new GregorianCalendar(); 144 cal.add(Calendar.DAY_OF_YEAR, (keepTimeRange) * -1); 145 timeDeleted = cal.getTimeInMillis(); 146 } else { 147 keepDeletedVersions = -1; 148 } 149 150 // create a new report 151 CmsLogReport report = new CmsLogReport(cms.getRequestContext().getLocale(), CmsHistoryClearJob.class); 152 153 // delete the versions 154 cms.deleteHistoricalVersions(keepVersions, keepDeletedVersions, timeDeleted, res -> { 155 boolean delete = true; 156 if (clearDeletedTypesStr != null) { 157 delete &= clearDeletedTypes.contains(res.getTypeId()); 158 } 159 if (clearDeletedPathsStr != null) { 160 delete &= clearDeletedPaths.stream().anyMatch( 161 prefix -> CmsStringUtil.isPrefixPath(prefix, res.getRootPath())); 162 } 163 return delete; 164 }, report); 165 166 return null; 167 } 168 169}