001/* 002* Copyright 2016 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.workspaces.repository.maintenance; 017 018import java.util.Map; 019 020import javax.jcr.RepositoryException; 021 022import org.apache.commons.lang.StringUtils; 023import org.apache.jackrabbit.core.config.RepositoryConfig; 024import org.joda.time.Duration; 025import org.joda.time.format.PeriodFormatter; 026import org.joda.time.format.PeriodFormatterBuilder; 027import org.slf4j.Logger; 028 029import org.ametys.plugins.repositoryapp.RepositoryProvider; 030import org.ametys.runtime.plugin.component.LogEnabled; 031 032/** 033 * Jackrabbit maintenance tasks implementations should extends this class. 034 */ 035public abstract class AbstractMaintenanceTask implements LogEnabled 036{ 037 /** TaskProgress */ 038 protected TaskProgress _progress; 039 040 /** The repository config */ 041 protected RepositoryConfig _repositoryConfig; 042 043 /** The repository provider. */ 044 protected RepositoryProvider _repositoryProvider; 045 046 /** Logger for traces */ 047 protected Logger _logger; 048 049 private boolean _isFinished; 050 051 /** 052 * Execute the task 053 * @param repositoryConfig The RepositoryConfig object, used to create new Repository instance. 054 * @throws RepositoryException If an error with the repository occurs while the task is executed. 055 */ 056 public void execute(RepositoryConfig repositoryConfig) throws RepositoryException 057 { 058 _repositoryConfig = repositoryConfig; 059 060 long startTime = System.currentTimeMillis(); 061 062 setLogger(); 063 064 _logger.info("Executing task."); 065 066 try 067 { 068 // task specific initialization. 069 initialize(); 070 071 // Mark the task as running. 072 setRunning(); 073 074 // Perform the task. 075 apply(); 076 077 // Mark the task as finished. 078 setFinished(); 079 } 080 catch (Exception e) 081 { 082 setInErrorState(e); 083 throw e; 084 } 085 finally 086 { 087 close(); 088 089 _logger.info("End of the task."); 090 091 long elapsedTime = System.currentTimeMillis() - startTime; 092 _logger.info("Done in " + _getFormattedDuration(elapsedTime)); 093 } 094 } 095 096 /** 097 * Initialize the tasks. 098 * This method can also create the {@link TaskProgress} object bounded to the task. 099 * @throws RepositoryException If a repository exception 100 */ 101 protected void initialize() throws RepositoryException 102 { 103 return; 104 } 105 106 /** 107 * Set the tasks logger. 108 */ 109 protected abstract void setLogger(); 110 111 @Override 112 public void setLogger(Logger logger) 113 { 114 _logger = logger; 115 } 116 117 /** 118 * Apply the tasks (within the execute method()). 119 * @throws RepositoryException If a repository exception 120 */ 121 protected abstract void apply() throws RepositoryException; 122 123 /** 124 * Close the tasks 125 * @throws RepositoryException If a repository exception 126 */ 127 protected void close() throws RepositoryException 128 { 129 return; 130 } 131 132 /** 133 * Get progress information. 134 * @return a map containing information on the progress status. 135 */ 136 public Map<String, Object> getProgressInfo() 137 { 138 if (_progress != null) 139 { 140 return _progress.getProgressInfo(); 141 } 142 else 143 { 144 return null; 145 } 146 } 147 148 /** 149 * Is the execution of the task finished? 150 * @return true if finished 151 */ 152 public boolean isFinished() 153 { 154 return _isFinished; 155 } 156 157 private synchronized void setRunning() 158 { 159 if (_progress != null) 160 { 161 _progress.setRunning(); 162 } 163 } 164 165 private synchronized void setFinished() 166 { 167 if (_progress != null) 168 { 169 _progress.setFinished(); 170 } 171 172 _isFinished = true; 173 } 174 175 private synchronized void setInErrorState(Exception e) 176 { 177 _logger.error(e.getLocalizedMessage(), e); 178 179 if (_progress != null) 180 { 181 _progress.setInErrorState(e); 182 } 183 184 _isFinished = true; 185 } 186 187 /** 188 * Transforms millisecond to a formatted string representing a duration. 189 * @param elapsedTime milleseconds corresponding to the duration. 190 * @return Pretty formatted string. 191 */ 192 protected String _getFormattedDuration(long elapsedTime) 193 { 194 Duration duration = new Duration(elapsedTime); 195 PeriodFormatter formatter = new PeriodFormatterBuilder() 196 .appendHours() 197 .appendSuffix("h") 198 .appendMinutes() 199 .appendSuffix("m") 200 .appendSeconds() 201 .appendSuffix("s") 202 .toFormatter(); 203 String formatted = formatter.print(duration.toPeriod()); 204 return StringUtils.defaultIfEmpty(formatted, "0s"); 205 } 206}