001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 * Created on 01-21-2010 021 */ 022package org.biojava.nbio.core.sequence.io.util; 023 024import org.biojava.nbio.core.exceptions.ParserException; 025 026import java.io.*; 027import java.util.List; 028import java.util.zip.GZIPInputStream; 029 030import static org.biojava.nbio.core.sequence.io.util.IOUtils.close; 031import static org.biojava.nbio.core.sequence.io.util.IOUtils.copy; 032 033/** 034 * This object represents a classpath resource on the local system. It allows 035 * you to specify a location and then extract the inputstream, reader or 036 * lines of the resource. We also support GZiped files (so long as the resource 037 * ends with a .gz) and pre-caching of the data so we read only once from 038 * the classpath and close that link down. This is useful if you want to keep 039 * IO handles down but not very useful if the file is very large. 040 * 041 * @author ayates 042 * 043 */ 044public class ClasspathResource { 045 046 private final String location; 047 private final boolean preCache; 048 private final Boolean isGzip; 049 050 /** 051 * Basic constructor only allowing you to specify where to find the file. 052 * 053 * @param location Specified as <i>my/classpath/loc.txt</i> 054 */ 055 public ClasspathResource(String location) { 056 this(location, false); 057 } 058 059 /** 060 * Advanced constructor which allows you to optionally pre-cache the 061 * data 062 * 063 * @param location Specified as <i>my/classpath/loc.txt</i> 064 * @param preCache If set to true will cause the data to be copied 065 * to an in memory byte array and then an InputStream will be wrapped around 066 * that. 067 */ 068 public ClasspathResource(String location, boolean preCache) { 069 this.location = location; 070 this.preCache = preCache; 071 this.isGzip = null; 072 } 073 074 /** 075 * Advanced constructor which lets you set the preCache variable and to 076 * force the type of file we are decompressing. If this constructor is 077 * used we trust your call as to the file's compression status. 078 * 079 * @param location Specified as <i>my/classpath/loc.txt</i> 080 * @param preCache If set to true will cause the data to be copied 081 * to an in memory byte array and then an InputStream will be wrapped around 082 * that. 083 * @param isGzip Set to true or false if the file is gziped. 084 */ 085 public ClasspathResource(String location, boolean preCache, boolean isGzip) { 086 this.location = location; 087 this.preCache = preCache; 088 this.isGzip = isGzip; 089 } 090 091 /** 092 * Returns the InputStream instance of this classpath resource 093 */ 094 public InputStream getInputStream() { 095 return createClasspathInputStream(); 096 } 097 098 /** 099 * Returns the reader representation of this classpath resource 100 */ 101 public BufferedReader getBufferedReader() { 102 return new BufferedReader(new InputStreamReader(getInputStream())); 103 } 104 105 /** 106 * Returns this resource as a list of Strings 107 */ 108 public List<String> getList() { 109 return IOUtils.getList(getBufferedReader()); 110 } 111 112 private InputStream createClasspathInputStream() { 113 final InputStream is; 114 final InputStream classpathIs = getClass().getClassLoader().getResourceAsStream(location); 115 if(classpathIs == null) { 116 throw new IllegalArgumentException("Location "+ 117 location+" resulted in a null InputStream"); 118 } 119 if(preCache) { 120 ByteArrayOutputStream os = new ByteArrayOutputStream(); 121 try { 122 copy(classpathIs, os); 123 } catch (IOException e) { 124 throw new ParserException("Cannot copy classpath InputStream", e); 125 } 126 finally { 127 close(classpathIs); 128 } 129 is = new ByteArrayInputStream(os.toByteArray()); 130 } 131 else { 132 is = classpathIs; 133 } 134 135 if(isGzip()) { 136 try { 137 return new GZIPInputStream(is); 138 } 139 catch (IOException e) { 140 throw new ParserException("Cannot open stream as a GZIP stream", e); 141 } 142 } 143 144 return is; 145 } 146 147 /** 148 * Returns true if the location given ends with a .gz extension. No magic 149 * number investigation is done. 150 */ 151 private boolean isGzip() { 152 if(isGzip != null) { 153 return isGzip; 154 } 155 else { 156 return this.location.endsWith(".gz"); 157 } 158 } 159}