001/* 002 * #%L 003 * Netarchivesuite - wayback 004 * %% 005 * Copyright (C) 2005 - 2014 The Royal Danish Library, the Danish State and University Library, 006 * the National Library of France and the Austrian National Library. 007 * %% 008 * This program is free software: you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation, either version 2.1 of the 011 * License, or (at your option) any later version. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Lesser Public License for more details. 017 * 018 * You should have received a copy of the GNU General Lesser Public 019 * License along with this program. If not, see 020 * <http://www.gnu.org/licenses/lgpl-2.1.html>. 021 * #L% 022 */ 023package dk.netarkivet.wayback; 024 025import java.io.File; 026import java.io.IOException; 027 028import org.apache.commons.logging.Log; 029import org.apache.commons.logging.LogFactory; 030import org.archive.wayback.ResourceStore; 031import org.archive.wayback.core.CaptureSearchResult; 032import org.archive.wayback.core.Resource; 033import org.archive.wayback.exception.ResourceNotAvailableException; 034import org.archive.wayback.resourcestore.resourcefile.ResourceFactory; 035 036import dk.netarkivet.common.CommonSettings; 037import dk.netarkivet.common.distribute.arcrepository.ArcRepositoryClientFactory; 038import dk.netarkivet.common.distribute.arcrepository.Replica; 039import dk.netarkivet.common.distribute.arcrepository.ViewerArcRepositoryClient; 040import dk.netarkivet.common.utils.Settings; 041 042/** 043 * This is the connector between netarchivesuite and wayback. And is based on the NetarchiveResourceStore, and the 044 * implementations of ResourceStore distributed with wayback-1.4.2. 045 */ 046public class NetarchiveCacheResourceStore implements ResourceStore { 047 048 /** JMS ArcRepositoryClient. */ 049 private ViewerArcRepositoryClient client; 050 051 /** Logger. */ 052 private Log logger = LogFactory.getLog(getClass().getName()); 053 /** The filecache being used by this class. */ 054 private LRUCache fileCache; 055 /** The replica being used by this class. */ 056 private Replica replicaUsed; 057 058 /** 059 * Constructor. Initiates the caching mechanism. 060 */ 061 public NetarchiveCacheResourceStore() { 062 fileCache = LRUCache.getInstance(); 063 client = ArcRepositoryClientFactory.getViewerInstance(); 064 replicaUsed = Replica.getReplicaFromId(Settings.get(CommonSettings.USE_REPLICA_ID)); 065 } 066 067 /** 068 * Transforms search result into a resource, according to the ResourceStore interface. 069 * 070 * @param captureSearchResult the search result. 071 * @return a valid resource containing metadata and a link to the ARC or warc-record 072 * @throws ResourceNotAvailableException if something went wrong fetching the record. 073 */ 074 public Resource retrieveResource(CaptureSearchResult captureSearchResult) throws ResourceNotAvailableException { 075 long offset; 076 077 String arcfile = captureSearchResult.getFile(); 078 offset = captureSearchResult.getOffset(); 079 080 logger.info("Received request for resource from file '" + arcfile + "' at offset '" + offset + "'"); 081 082 // Try to lookup the file in the cache 083 // make synchronized to disallow more than one using 084 // the cache at any one time 085 synchronized (fileCache) { 086 File wantedFile = fileCache.get(arcfile); 087 try { 088 if (wantedFile != null && wantedFile.exists()) { 089 logger.debug("Found the file '" + arcfile + "' in the cache. "); 090 return ResourceFactory.getResource(wantedFile, offset); 091 } else { 092 logger.debug("The file '" + arcfile + "' was not found in the cache. "); 093 // Get file from bitarchive, and place it in the cachedir 094 // directory 095 File fileFromBitarchive = new File(fileCache.getCacheDir(), arcfile); 096 client.getFile(arcfile, replicaUsed, fileFromBitarchive); 097 // put into the cache 098 fileCache.put(arcfile, fileFromBitarchive); 099 logger.info("File '" + arcfile + "' downloaded from archive and put into the cache '" 100 + fileCache.getCacheDir().getAbsolutePath() + "'."); 101 return ResourceFactory.getResource(fileFromBitarchive, offset); 102 } 103 } catch (IOException e) { 104 logger.error("Error looking for non existing resource", e); 105 throw new ResourceNotAvailableException(this.getClass().getName() + "Throws Exception when accessing " 106 + "CaptureResult given from Wayback."); 107 } 108 } 109 } 110 111 /** 112 * Shuts down this resource store, closing the arcrepository client. 113 * 114 * @throws IOException if an exception ocurred while closing the client. 115 */ 116 public void shutdown() throws IOException { 117 // Close JMS connection. 118 client.close(); 119 } 120}