/* * Copyright 2005 Joe Walker * * 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.directwebremoting.impl; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.directwebremoting.extend.DownloadManager; import org.directwebremoting.io.FileTransfer; /** * A {@link DownloadManager} that simply stores the links in-memory. * This implementation has the advantage that it is simple - no disk storage is * required, however in anything but a lightly used system it could cause * significant memory usage. * @author Joe Walker [joe at getahead dot ltd dot uk] */ public class InMemoryDownloadManager extends PurgingDownloadManager implements DownloadManager { /* (non-Javadoc) * @see org.directwebremoting.impl.PurgingDownloadManager#putFileTransfer(java.lang.String, org.directwebremoting.extend.DownloadManager.FileTransfer) */ @Override protected void putFileTransfer(String id, FileTransfer transfer) { synchronized (contentsLock) { contents.put(id, new TimedFileTransfer(transfer)); } } /* (non-Javadoc) * @see org.directwebremoting.impl.PurgingDownloadManager#getFileTransfer(java.lang.String) */ public FileTransfer getFileTransfer(String id) { synchronized (contentsLock) { TimedFileTransfer transfer = contents.get(id); if (transfer == null) { return null; } transfer.downloadRequests++; if (transfer.downloadRequests >= this.downloadRequestsBeforeRemove) { contents.remove(id); } return transfer.fileTransfer; } } /* (non-Javadoc) * @see org.directwebremoting.impl.PurgingDownloadManager#purge() */ @Override protected void purge() { long now = System.currentTimeMillis(); synchronized (contentsLock) { for (Iterator<Map.Entry<String, TimedFileTransfer>> it = contents.entrySet().iterator(); it.hasNext();) { Map.Entry<String, TimedFileTransfer> entry = it.next(); try { if (now > entry.getValue().timeInserted + purgeDownloadsAfter) { it.remove(); } } catch (Exception ex) { log.warn("Deletion queue processing error: " + ex.getMessage()); } } } } /** * A union of a FileTransfer and the time it was inserted into this manager */ protected static class TimedFileTransfer { protected TimedFileTransfer(FileTransfer fileTransfer) { this.fileTransfer = fileTransfer; this.timeInserted = System.currentTimeMillis(); } protected final FileTransfer fileTransfer; protected final long timeInserted; protected int downloadRequests = 0; } /** * Some download managers cause multiple downloads, so we count the number * of downloads before the delete is done. */ public void setDownloadRequestsBeforeRemove(int downloadRequestsBeforeRemove) { this.downloadRequestsBeforeRemove = downloadRequestsBeforeRemove; } /** * @see #setDownloadRequestsBeforeRemove(int) */ protected int downloadRequestsBeforeRemove = 1; /** * The lock which you must hold to read or write from the list of * {@link FileTransfer}s. */ protected final Object contentsLock = new Object(); /** * The list of files in the system */ protected final Map<String, TimedFileTransfer> contents = Collections.synchronizedMap(new HashMap<String, TimedFileTransfer>()); /** * The log stream */ private static final Log log = LogFactory.getLog(InMemoryDownloadManager.class); }