| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
| URLResourceReader |
|
| 2.2;2.2 |
| 1 | /* |
|
| 2 | * ==================================================================== |
|
| 3 | * |
|
| 4 | * The Apache Software License, Version 1.1 |
|
| 5 | * |
|
| 6 | * Copyright (c) 1999 The Apache Software Foundation. All rights |
|
| 7 | * reserved. |
|
| 8 | * |
|
| 9 | * Redistribution and use in source and binary forms, with or without |
|
| 10 | * modification, are permitted provided that the following conditions |
|
| 11 | * are met: |
|
| 12 | * |
|
| 13 | * 1. Redistributions of source code must retain the above copyright |
|
| 14 | * notice, this list of conditions and the following disclaimer. |
|
| 15 | * |
|
| 16 | * 2. Redistributions in binary form must reproduce the above copyright |
|
| 17 | * notice, this list of conditions and the following disclaimer in |
|
| 18 | * the documentation and/or other materials provided with the |
|
| 19 | * distribution. |
|
| 20 | * |
|
| 21 | * 3. The end-user documentation included with the redistribution, if |
|
| 22 | * any, must include the following acknowlegement: |
|
| 23 | * "This product includes software developed by the |
|
| 24 | * Apache Software Foundation (http://www.apache.org/)." |
|
| 25 | * Alternately, this acknowlegement may appear in the software itself, |
|
| 26 | * if and wherever such third-party acknowlegements normally appear. |
|
| 27 | * |
|
| 28 | * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software |
|
| 29 | * Foundation" must not be used to endorse or promote products derived |
|
| 30 | * from this software without prior written permission. For written |
|
| 31 | * permission, please contact apache@apache.org. |
|
| 32 | * |
|
| 33 | * 5. Products derived from this software may not be called "Apache" |
|
| 34 | * nor may "Apache" appear in their names without prior written |
|
| 35 | * permission of the Apache Group. |
|
| 36 | * |
|
| 37 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
|
| 38 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
| 39 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|
| 40 | * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
|
| 41 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
| 42 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
| 43 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
| 44 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
|
| 45 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
|
| 46 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
|
| 47 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
|
| 48 | * SUCH DAMAGE. |
|
| 49 | * ==================================================================== |
|
| 50 | */ |
|
| 51 | ||
| 52 | package net.wotonomy.foundation.internal; |
|
| 53 | ||
| 54 | import java.io.ByteArrayOutputStream; |
|
| 55 | import java.io.IOException; |
|
| 56 | import java.io.InputStream; |
|
| 57 | import java.net.URL; |
|
| 58 | import java.util.Enumeration; |
|
| 59 | import java.util.Hashtable; |
|
| 60 | import java.util.zip.ZipEntry; |
|
| 61 | import java.util.zip.ZipInputStream; |
|
| 62 | ||
| 63 | /** |
|
| 64 | * This implementation of URL Resource Reader assumes 2 types |
|
| 65 | * of base urls. A base url that ends with / is considered a |
|
| 66 | * resource folder, whereas a resource that does not end with |
|
| 67 | * / is considered a zip/jar resource folder. |
|
| 68 | * |
|
| 69 | * If the resource folder happens is a zip/jar archive, the |
|
| 70 | * entries are always cached. |
|
| 71 | * For non-zip base urls, one could specify whether or not it should |
|
| 72 | * be cached. |
|
| 73 | * |
|
| 74 | * @author Harish Prabandham |
|
| 75 | */ |
|
| 76 | public class URLResourceReader { |
|
| 77 | 0 | private Hashtable resourceCache = new Hashtable(); |
| 78 | 0 | private boolean iszip = true; |
| 79 | 0 | private URL url = null; |
| 80 | 0 | private boolean cache = true; |
| 81 | ||
| 82 | /** |
|
| 83 | * Creates a new URLResourceReader object. You can either give |
|
| 84 | * the URL of the zip/jar file or a base url where to |
|
| 85 | * look for additional resources. If the url ends with |
|
| 86 | * "/" then it is assumed to be a Base URL. |
|
| 87 | * @param The base url to look for the resources. |
|
| 88 | * @param If the base url is not a zip/jar, then true indicates |
|
| 89 | * that entries should be cached, false otherwise. |
|
| 90 | */ |
|
| 91 | 0 | public URLResourceReader(URL baseurl, boolean cache) throws IOException { |
| 92 | 0 | this.url = baseurl; |
| 93 | 0 | this.cache = cache; |
| 94 | 0 | this.iszip = !url.getFile().endsWith("/"); |
| 95 | 0 | if(this.iszip) |
| 96 | 0 | this.cache = true; |
| 97 | 0 | initialize(); |
| 98 | 0 | } |
| 99 | ||
| 100 | /** |
|
| 101 | * equivalent to URLResourceReader(baseurl, false) |
|
| 102 | */ |
|
| 103 | public URLResourceReader(URL baseurl) throws IOException { |
|
| 104 | 0 | this(baseurl, false); |
| 105 | 0 | } |
| 106 | ||
| 107 | /** |
|
| 108 | * Creates a new URLResourceReader object with the given |
|
| 109 | * input stream. The stream is assumed to be a zip/jar |
|
| 110 | * stream. |
|
| 111 | */ |
|
| 112 | 0 | public URLResourceReader(InputStream is) throws IOException { |
| 113 | 0 | init(is); |
| 114 | 0 | } |
| 115 | ||
| 116 | private void initialize() throws IOException { |
|
| 117 | 0 | if(iszip) { |
| 118 | 0 | InputStream is = url.openStream(); |
| 119 | 0 | init(is); |
| 120 | 0 | is.close(); |
| 121 | } |
|
| 122 | 0 | } |
| 123 | ||
| 124 | private byte[] readFully(InputStream is) throws IOException { |
|
| 125 | 0 | byte[] buf = new byte[1024]; |
| 126 | 0 | int num = 0; |
| 127 | 0 | ByteArrayOutputStream bout = new ByteArrayOutputStream(); |
| 128 | ||
| 129 | 0 | while( (num = is.read(buf)) != -1) { |
| 130 | 0 | bout.write(buf, 0, num); |
| 131 | 0 | } |
| 132 | ||
| 133 | 0 | return bout.toByteArray(); |
| 134 | } |
|
| 135 | ||
| 136 | private void init(InputStream is) throws IOException { |
|
| 137 | 0 | ZipInputStream zstream = new ZipInputStream(is); |
| 138 | ZipEntry entry; |
|
| 139 | ||
| 140 | 0 | while( (entry = zstream.getNextEntry()) != null) { |
| 141 | 0 | byte[] entryData = readFully(zstream); |
| 142 | 0 | if(cache) |
| 143 | 0 | resourceCache.put(entry.getName(), entryData); |
| 144 | 0 | zstream.closeEntry(); |
| 145 | 0 | } |
| 146 | ||
| 147 | 0 | zstream.close(); |
| 148 | 0 | } |
| 149 | ||
| 150 | /** |
|
| 151 | * Returns an Enumeration of all "known" resource names. |
|
| 152 | */ |
|
| 153 | public Enumeration getResourceNames() { |
|
| 154 | 0 | return resourceCache.keys(); |
| 155 | } |
|
| 156 | ||
| 157 | /** |
|
| 158 | * Returns an array of bytes read for this resource if the |
|
| 159 | * resource exists. This method blocks until the resource |
|
| 160 | * has been fully read. If the resource does not exist, |
|
| 161 | * this method returns null. |
|
| 162 | */ |
|
| 163 | public byte[] getResource(String resource) { |
|
| 164 | // lookup the data in the cache... |
|
| 165 | 0 | byte[] data = (byte[]) resourceCache.get(resource); |
| 166 | 0 | if(data != null) { |
| 167 | 0 | return data; |
| 168 | } |
|
| 169 | ||
| 170 | // if the data was to come from a zip file that we |
|
| 171 | // already read fully & cached , then it is probably |
|
| 172 | // not there. |
|
| 173 | 0 | if(iszip) { |
| 174 | 0 | return null; |
| 175 | } |
|
| 176 | ||
| 177 | // Now the only choice left is to make a url connection. |
|
| 178 | try { |
|
| 179 | 0 | URL realURL = new URL(url.getProtocol(), url.getHost(), |
| 180 | 0 | url.getFile() + resource); |
| 181 | 0 | data = readFully(realURL.openStream()); |
| 182 | // add it to cache if needed... |
|
| 183 | 0 | if(cache) |
| 184 | 0 | resourceCache.put(resource, data); |
| 185 | 0 | return data; |
| 186 | 0 | } catch(Exception e) { |
| 187 | 0 | return null; |
| 188 | } |
|
| 189 | } |
|
| 190 | ||
| 191 | public void close() { |
|
| 192 | 0 | resourceCache.clear(); |
| 193 | 0 | resourceCache = null; |
| 194 | 0 | } |
| 195 | ||
| 196 | public String toString() { |
|
| 197 | 0 | return url.toString(); |
| 198 | } |
|
| 199 | } |
|
| 200 | ||
| 201 | ||
| 202 | ||
| 203 | ||
| 204 | ||
| 205 | ||
| 206 | ||
| 207 |