/* * This file is part of the Wayback archival access software * (http://archive-access.sourceforge.net/projects/wayback/). * * Licensed to the Internet Archive (IA) by one or more individual * contributors. * * The IA licenses this file to You 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.archive.wayback.resourcestore; import java.io.IOException; import java.util.List; import java.util.logging.Logger; import javax.servlet.http.HttpServletResponse; import org.archive.wayback.ResourceStore; import org.archive.wayback.core.CaptureSearchResult; import org.archive.wayback.core.Resource; import org.archive.wayback.exception.ResourceNotAvailableException; import org.archive.wayback.resourcestore.resourcefile.ArcWarcFilenameFilter; /** * A ResourceStore which contains one or more other resource stores. * This container simply searches each one in turn for a requested * resource, returning the first one found. */ public class MultipleResourceStore implements ResourceStore { private final static Logger LOGGER = Logger.getLogger(MultipleResourceStore.class.getName()); private List<ResourceStore> stores; // If true, subsequent resource stores are skipped if the first private boolean failOnFirstUnavailable = false; public boolean isFailOnFirstUnavailable() { return failOnFirstUnavailable; } public void setFailOnFirstUnavailable(boolean failOnFirstUnavailable) { this.failOnFirstUnavailable = failOnFirstUnavailable; } public Resource retrieveResource(CaptureSearchResult result) throws ResourceNotAvailableException { String fileName = result.getFile(); if(fileName == null || fileName.length() < 1) { throw new ResourceNotAvailableException("No ARC/WARC name in search result...", fileName); } if(!fileName.endsWith(ArcWarcFilenameFilter.ARC_SUFFIX) && !fileName.endsWith(ArcWarcFilenameFilter.ARC_GZ_SUFFIX) && !fileName.endsWith(ArcWarcFilenameFilter.WARC_SUFFIX) && !fileName.endsWith(ArcWarcFilenameFilter.WARC_GZ_SUFFIX)) { fileName = fileName + ArcWarcFilenameFilter.ARC_GZ_SUFFIX; } String errMsg = ""; Exception origException = null; for ( ResourceStore store : stores ) { try { Resource r = store.retrieveResource(result); if ( r != null ) { return r; } } catch (ResourceNotAvailableException e) { LOGGER.info(e.toString()); if (!errMsg.isEmpty()) { errMsg += " "; } origException = e; errMsg += e.getMessage(); // if skipOnUnavailable, then don't try any more resource stores if the current one is unavailable if (failOnFirstUnavailable && (e.getStatus() == HttpServletResponse.SC_SERVICE_UNAVAILABLE)) { break; } } } throw new ResourceNotAvailableException(errMsg.isEmpty() ? "Unable to retrieve: "+fileName : errMsg, fileName, origException); } public void setStores(List<ResourceStore> stores) { this.stores = stores; } public List<ResourceStore> getStores( ) { return this.stores; } public void shutdown() throws IOException { // no-op } }