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 */
022 package org.biojava3.core.sequence.io.util;
023
024 import static org.biojava3.core.sequence.io.util.IOUtils.close;
025 import static org.biojava3.core.sequence.io.util.IOUtils.copy;
026
027 import java.io.BufferedReader;
028 import java.io.ByteArrayInputStream;
029 import java.io.ByteArrayOutputStream;
030 import java.io.IOException;
031 import java.io.InputStream;
032 import java.io.InputStreamReader;
033 import java.util.List;
034 import java.util.zip.GZIPInputStream;
035
036 import org.biojava3.core.exceptions.ParserException;
037
038 /**
039 * This object represents a classpath resource on the local system. It allows
040 * you to specify a location and then extract the inputstream, reader or
041 * lines of the resource. We also support GZiped files (so long as the resource
042 * ends with a .gz) and pre-caching of the data so we read only once from
043 * the classpath and close that link down. This is useful if you want to keep
044 * IO handles down but not very useful if the file is very large.
045 *
046 * @author ayates
047 *
048 */
049 public class ClasspathResource {
050
051 private final String location;
052 private final boolean preCache;
053 private final Boolean isGzip;
054
055 /**
056 * Basic constructor only allowing you to specify where to find the file.
057 *
058 * @param location Specified as <i>my/classpath/loc.txt</i>
059 */
060 public ClasspathResource(String location) {
061 this(location, false);
062 }
063
064 /**
065 * Advanced constructor which allows you to optionally pre-cache the
066 * data
067 *
068 * @param location Specified as <i>my/classpath/loc.txt</i>
069 * @param preCache If set to true will cause the data to be copied
070 * to an in memory byte array and then an InputStream will be wrapped around
071 * that.
072 */
073 public ClasspathResource(String location, boolean preCache) {
074 this.location = location;
075 this.preCache = preCache;
076 this.isGzip = null;
077 }
078
079 /**
080 * Advanced constructor which lets you set the preCache variable and to
081 * force the type of file we are decompressing. If this constructor is
082 * used we trust your call as to the file's compression status.
083 *
084 * @param location Specified as <i>my/classpath/loc.txt</i>
085 * @param preCache If set to true will cause the data to be copied
086 * to an in memory byte array and then an InputStream will be wrapped around
087 * that.
088 * @param isGzip Set to true or false if the file is gziped.
089 */
090 public ClasspathResource(String location, boolean preCache, boolean isGzip) {
091 this.location = location;
092 this.preCache = preCache;
093 this.isGzip = isGzip;
094 }
095
096 /**
097 * Returns the InputStream instance of this classpath resource
098 */
099 public InputStream getInputStream() {
100 return createClasspathInputStream();
101 }
102
103 /**
104 * Returns the reader representation of this classpath resource
105 */
106 public BufferedReader getBufferedReader() {
107 return new BufferedReader(new InputStreamReader(getInputStream()));
108 }
109
110 /**
111 * Returns this resource as a list of Strings
112 */
113 public List<String> getList() {
114 return IOUtils.getList(getBufferedReader());
115 }
116
117 private InputStream createClasspathInputStream() {
118 final InputStream is;
119 final InputStream classpathIs = getClass().getClassLoader().getResourceAsStream(location);
120 if(classpathIs == null) {
121 throw new IllegalArgumentException("Location "+
122 location+" resulted in a null InputStream");
123 }
124 if(preCache) {
125 ByteArrayOutputStream os = new ByteArrayOutputStream();
126 try {
127 copy(classpathIs, os);
128 } catch (IOException e) {
129 throw new ParserException("Cannot copy classpath InputStream", e);
130 }
131 finally {
132 close(classpathIs);
133 }
134 is = new ByteArrayInputStream(os.toByteArray());
135 }
136 else {
137 is = classpathIs;
138 }
139
140 if(isGzip()) {
141 try {
142 return new GZIPInputStream(is);
143 }
144 catch (IOException e) {
145 throw new ParserException("Cannot open stream as a GZIP stream", e);
146 }
147 }
148
149 return is;
150 }
151
152 /**
153 * Returns true if the location given ends with a .gz extension. No magic
154 * number investigation is done.
155 */
156 private boolean isGzip() {
157 if(isGzip != null) {
158 return isGzip;
159 }
160 else {
161 return this.location.endsWith(".gz");
162 }
163 }
164 }