1 | /* |
2 | * Copyright (c) 2001-2009, Jean Tessier |
3 | * All rights reserved. |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
8 | * |
9 | * * Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * |
12 | * * Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. |
15 | * |
16 | * * Neither the name of Jean Tessier nor the names of his contributors |
17 | * may be used to endorse or promote products derived from this software |
18 | * without specific prior written permission. |
19 | * |
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR |
24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | */ |
32 | |
33 | package com.jeantessier.classreader; |
34 | |
35 | import java.io.*; |
36 | import java.util.*; |
37 | import java.util.zip.*; |
38 | |
39 | import org.apache.log4j.*; |
40 | |
41 | public class ZipClassfileLoader extends ClassfileLoaderDecorator { |
42 | private static final int BUFFER_SIZE = 16 * 1024; |
43 | |
44 | public ZipClassfileLoader(ClassfileLoader loader) { |
45 | super(loader); |
46 | } |
47 | |
48 | protected void load(String filename) { |
49 | Logger.getLogger(getClass()).debug("Starting group in file " + filename); |
50 | |
51 | ZipFile zipfile = null; |
52 | try { |
53 | zipfile = new ZipFile(filename); |
54 | |
55 | fireBeginGroup(filename, zipfile.size()); |
56 | |
57 | Logger.getLogger(getClass()).debug("Loading ZipFile " + filename); |
58 | load(zipfile); |
59 | Logger.getLogger(getClass()).debug("Loaded ZipFile " + filename); |
60 | |
61 | fireEndGroup(filename); |
62 | } catch (IOException ex) { |
63 | Logger.getLogger(getClass()).error("Cannot load Zip file \"" + filename + "\"", ex); |
64 | } finally { |
65 | if (zipfile != null) { |
66 | try { |
67 | zipfile.close(); |
68 | } catch (IOException ex) { |
69 | // Ignore |
70 | } |
71 | } |
72 | } |
73 | } |
74 | |
75 | protected void load(String filename, InputStream in) { |
76 | Logger.getLogger(getClass()).debug("Starting group in stream " + filename); |
77 | |
78 | ZipInputStream zipfile = null; |
79 | try { |
80 | zipfile = new ZipInputStream(in); |
81 | |
82 | fireBeginGroup(filename, -1); |
83 | |
84 | Logger.getLogger(getClass()).debug("Loading ZipInputStream " + filename); |
85 | load(zipfile); |
86 | Logger.getLogger(getClass()).debug("Loaded ZipInputStream " + filename); |
87 | |
88 | fireEndGroup(filename); |
89 | } catch (IOException ex) { |
90 | Logger.getLogger(getClass()).error("Cannot load Zip file \"" + filename + "\"", ex); |
91 | } finally { |
92 | if (zipfile != null) { |
93 | try { |
94 | zipfile.close(); |
95 | } catch (IOException ex) { |
96 | // Ignore |
97 | } |
98 | } |
99 | } |
100 | } |
101 | |
102 | protected void load(ZipFile zipfile) throws IOException { |
103 | Enumeration entries = zipfile.entries(); |
104 | while(entries.hasMoreElements()) { |
105 | ZipEntry entry = (ZipEntry) entries.nextElement(); |
106 | |
107 | fireBeginFile(entry.getName()); |
108 | |
109 | Logger.getLogger(getClass()).debug("Starting file " + entry.getName() + " (" + entry.getSize() + " bytes)"); |
110 | |
111 | byte[] bytes = null; |
112 | InputStream in = null; |
113 | try { |
114 | in = zipfile.getInputStream(entry); |
115 | bytes = readBytes(in); |
116 | } finally { |
117 | if (in != null) { |
118 | try { |
119 | in.close(); |
120 | } catch (IOException ex) { |
121 | // Ignore |
122 | } |
123 | } |
124 | } |
125 | |
126 | Logger.getLogger(getClass()).debug("Passing up file " + entry.getName() + " (" + bytes.length + " bytes)"); |
127 | getLoader().load(entry.getName(), new ByteArrayInputStream(bytes)); |
128 | |
129 | fireEndFile(entry.getName()); |
130 | } |
131 | } |
132 | |
133 | protected void load(ZipInputStream in) throws IOException { |
134 | ZipEntry entry; |
135 | while ((entry = in.getNextEntry()) != null) { |
136 | fireBeginFile(entry.getName()); |
137 | |
138 | Logger.getLogger(getClass()).debug("Starting file " + entry.getName() + " (" + entry.getSize() + " bytes)"); |
139 | byte[] bytes = readBytes(in); |
140 | |
141 | Logger.getLogger(getClass()).debug("Passing up file " + entry.getName() + " (" + bytes.length + " bytes)"); |
142 | getLoader().load(entry.getName(), new ByteArrayInputStream(bytes)); |
143 | |
144 | fireEndFile(entry.getName()); |
145 | } |
146 | } |
147 | |
148 | private byte[] readBytes(InputStream in) { |
149 | byte[] result = null; |
150 | |
151 | try { |
152 | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
153 | byte[] buffer = new byte[BUFFER_SIZE]; |
154 | int bytesRead = 0; |
155 | while ((bytesRead = in.read(buffer, 0, BUFFER_SIZE)) != -1) { |
156 | out.write(buffer, 0, bytesRead); |
157 | } |
158 | out.close(); |
159 | |
160 | result = out.toByteArray(); |
161 | } catch (IOException ex) { |
162 | Logger.getLogger(getClass()).debug("Error loading Zip entry", ex); |
163 | } |
164 | |
165 | return(result); |
166 | } |
167 | } |