/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache license, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.internna.iwebmvc.core.jobs.impl;
import org.internna.iwebmvc.core.jobs.*;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.internna.iwebmvc.core.dao.DAO;
import org.internna.iwebmvc.model.core.TemporalFile;
import org.internna.iwebmvc.repository.DocumentRepository;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* Quartz task to delete uploaded files that do not match a Document
*
* @author Jose Noheda
* @since 1.0
*/
@Component("temporalFileSweeper")
public class TemporalFileSweeperImpl implements TemporalFileSweeper, InitializingBean {
protected final int TIMEOUT = -31;
protected Calendar cal;
private Set<String> docUris = Collections.synchronizedSet(new HashSet<String>());
private Map<String, String> updatedUris = Collections.synchronizedMap(new HashMap<String, String>());
private Set<String> actualUpdatedUris = Collections.synchronizedSet(new HashSet<String>());
private static Log log = LogFactory.getLog(TemporalFileSweeperImpl.class);
@Autowired protected DocumentRepository documentRepository;
@Autowired @Qualifier("baseDAO") protected DAO dao;
@Override
public void afterPropertiesSet() throws Exception {
cal = Calendar.getInstance();
cal.roll(Calendar.YEAR, -1);
}
protected void processDocumentsUpdates() {
Set<String> removed = new HashSet<String>();
synchronized(actualUpdatedUris) {
for (String uri : actualUpdatedUris) {
dao.create(new TemporalFile(uri, cal.getTime()));
if (log.isDebugEnabled()) log.debug("Temporal file URI [" + uri + "] added to outdated repository file list");
}
dao.flush();
actualUpdatedUris.clear();
}
}
protected void processDocuments() {
Map<String, Object> parameters = new HashMap<String, Object>(1);
Set<String> removed = new HashSet<String>();
synchronized(docUris) {
if (docUris.size() > 0) {
for (String uri : docUris) {
parameters.put("uri", uri);
List<TemporalFile> tf = dao.findByNamedQuery(TemporalFile.FIND_BY_URI, 0, 1, parameters);
if ((tf != null) && (tf.size() > 0)) {
dao.remove(tf.get(0));
if (log.isDebugEnabled()) log.debug("Temporal file URI [" + uri + "] removed from outdated repository file list");
}
removed.add(uri);
}
dao.flush();
docUris.removeAll(removed);
}
}
}
protected void processDeletions() {
Map<String, Object> parameters = new HashMap<String, Object>(1);
Calendar cal = Calendar.getInstance();
cal.roll(Calendar.MINUTE, TIMEOUT);
parameters.put("creation", cal.getTime());
List<TemporalFile> outdated = dao.findByNamedQuery(TemporalFile.FIND_TIMED_OUT, 0, 50, parameters);
if (log.isInfoEnabled()) log.info("Found [" + outdated.size() + "] outdated temporal files to remove");
for (TemporalFile tempFile : outdated) {
String uri = tempFile.getUri();
if (log.isInfoEnabled()) log.info("Deleting uploaded file [" + uri + "]");
dao.remove(tempFile);
documentRepository.delete(uri);
}
}
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void sweep() {
if (log.isDebugEnabled()) log.debug("Cron job TemporalFileSweeper started");
processDocumentsUpdates();
processDocuments();
processDeletions();
if (log.isDebugEnabled()) log.debug("Cron job TemporalFileSweeper finished");
}
@Override
public void addDocumentUri(String uri) {
synchronized (docUris) {
docUris.add(uri);
}
}
@Override
public synchronized void preaddOverrideUri(String oldUri, String uri) {
synchronized(updatedUris) {
updatedUris.put(uri, oldUri);
}
}
@Override
public synchronized void confirmOverrideUri(String uri) {
synchronized (updatedUris) {
if (updatedUris.containsKey(uri)) {
addDocumentUri(uri);
synchronized(actualUpdatedUris) {
actualUpdatedUris.add(updatedUris.get(uri));
}
updatedUris.remove(uri);
}
}
}
}