EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.impl.services.reflect]

COVERAGE SUMMARY FOR SOURCE FILE [JarLoader.java]

nameclass, %method, %block, %line, %
JarLoader.java100% (1/1)88%  (14/16)55%  (229/420)51%  (59.6/118)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class JarLoader100% (1/1)88%  (14/16)55%  (229/420)51%  (59.6/118)
<static initializer> 100% (1/1)100% (5/5)100% (2/2)
JarLoader (UpdateLoader, String [], HeaderPrintWriter): void 100% (1/1)100% (14/14)100% (5/5)
checkLoaded (String, boolean): Class 100% (1/1)89%  (16/18)83%  (5/6)
getJarName (): String 100% (1/1)100% (4/4)100% (1/1)
getRawStream (InputStream, String): InputStream 0%   (0/1)0%   (0/43)0%   (0/15)
getRawStream (ZipFile, String): InputStream 100% (1/1)80%  (12/15)67%  (4/6)
getResourceAsStream (String): InputStream 100% (1/1)80%  (8/10)67%  (2/3)
getStream (String): InputStream 100% (1/1)48%  (14/29)43%  (3/7)
initialize (): void 100% (1/1)28%  (12/43)25%  (4/16)
load (): Object 100% (1/1)56%  (19/34)50%  (4/8)
loadClass (String, boolean): Class 100% (1/1)65%  (17/26)75%  (6/8)
loadClassData (InputStream, String, String, boolean): Class 0%   (0/1)0%   (0/33)0%   (0/9)
loadClassData (String, String, boolean): Class 100% (1/1)29%  (13/45)27%  (3/11)
loadClassData (ZipEntry, InputStream, String, boolean): Class 100% (1/1)100% (54/54)100% (12/12)
loadClassDataFromJar (String, String, boolean): Class 100% (1/1)100% (31/31)100% (6/6)
setInvalid (boolean): JarFile 100% (1/1)62%  (10/16)87%  (2.6/3)

1/*
2 
3   Derby - Class org.apache.derby.impl.services.reflect.JarLoader
4 
5   Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 */
20 
21package org.apache.derby.impl.services.reflect;
22 
23import org.apache.derby.impl.sql.execute.JarUtil;
24import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
25import org.apache.derby.iapi.error.StandardException;
26 
27import java.io.File;
28import java.io.InputStream;
29import java.io.IOException;
30 
31import java.util.zip.ZipFile;
32import java.util.zip.ZipInputStream;
33import java.util.zip.ZipEntry;
34 
35 
36import org.apache.derby.iapi.services.io.LimitInputStream;
37import org.apache.derby.iapi.util.IdUtil;
38 
39import org.apache.derby.iapi.reference.MessageId;
40import org.apache.derby.iapi.services.i18n.MessageService;
41 
42 
43public class JarLoader extends ClassLoader {
44 
45        private static final JarFile jarFileFactory;
46 
47        static {
48 
49                // 
50                jarFileFactory = new JarFileJava2();
51        }
52 
53        private UpdateLoader updateLoader;
54        private JarFile jf;
55        private HeaderPrintWriter vs;
56 
57        JarLoader(UpdateLoader updateLoader, String[] name, HeaderPrintWriter vs) {
58 
59                this.updateLoader = updateLoader;
60                this.jf = jarFileFactory.newJarFile(name);
61                this.vs = vs;
62        }
63 
64        // Initialize the class loader so it knows if it
65        // is loading from a ZipFile or an InputStream
66        void initialize() {
67 
68                Object zipData = load();
69 
70                try {
71 
72                        if (zipData instanceof File) {
73                                jf.initialize((File) zipData);
74                                return;
75                        }
76 
77                        if (zipData instanceof InputStream) {
78                                jf.isStream = true;
79                                try {
80                                        ((InputStream) zipData).close();
81                                } catch (IOException ioe) {
82                                }
83                                return;
84                        }
85                } catch (IOException ioe) {
86                        if (vs != null)
87                                vs.println(MessageService.getTextMessage(MessageId.CM_LOAD_JAR_EXCEPTION, getJarName(), ioe));
88                }
89 
90                // No such zip.
91                setInvalid(false);        
92        }
93 
94        /**
95                Handle all requests to the top-level loader.
96 
97                @exception ClassNotFoundException Class can not be found
98        */
99        public Class loadClass(String className, boolean resolve) 
100                throws ClassNotFoundException {
101 
102                // we attempt the system class load even if we
103                // are stale because otherwise we will fail
104                // to load java.* classes which confuses some VMs
105                try {
106                        return Class.forName(className);
107                } catch (ClassNotFoundException cnfe) {
108 
109                        if (updateLoader == null)
110                                throw new ClassNotFoundException(MessageService.getTextMessage(MessageId.CM_STALE_LOADER, className));
111 
112                        Class c = updateLoader.loadClass(className, resolve);
113                        if (c == null)
114                                throw cnfe;
115                        return c;
116                }
117        }
118 
119        /**
120                
121        */
122        public InputStream getResourceAsStream(String name) {
123                if (updateLoader == null)
124                        return null;
125                return updateLoader.getResourceAsStream(name);
126        }
127 
128        /*
129        ** Package level api
130        */
131        final String getJarName() {
132                return jf.getJarName();
133        }
134 
135        Class loadClassData(String className, String jvmClassName, boolean resolve) {
136 
137                if (updateLoader == null)
138                        return null;
139 
140                try {
141                        if (jf.isZip())
142                                return loadClassDataFromJar(className, jvmClassName, resolve);
143 
144                        if (jf.isStream) {
145                                // have to use a new stream each time
146                                return loadClassData((InputStream) load(),
147                                                className, jvmClassName, resolve);
148                        }
149 
150                        return null;
151                } catch (IOException ioe) {
152                        if (vs != null)
153                                vs.println(MessageService.getTextMessage(MessageId.CM_CLASS_LOAD_EXCEPTION, className, getJarName(), ioe));
154                        return null;
155                }        
156        }
157 
158        /**
159                Get an InputStream for the given resource.
160        */
161        InputStream getStream(String name) {
162 
163                if (updateLoader == null)
164                        return null;
165 
166                if (jf.isZip())
167                        return getRawStream(jf.getZip(), name);
168 
169                if (jf.isStream) {
170                        return getRawStream((InputStream) load(), name);
171                }
172                return null;
173        }
174 
175 
176        /*
177        ** Private api
178        */
179 
180 
181        private Class loadClassDataFromJar(String className, String jvmClassName, boolean resolve) 
182                throws IOException {
183 
184                ZipEntry ze = jf.getEntry(jvmClassName);
185                if (ze == null)
186                        return null;
187 
188                InputStream in = jf.getZip().getInputStream(ze);
189 
190                try {
191                        return loadClassData(ze, in, className, resolve);
192                } finally {
193                        in.close();
194                }
195        }
196 
197        private Class loadClassData(
198                InputStream in, String className, String jvmClassName, boolean resolve) 
199                throws IOException {
200 
201                ZipInputStream zipIn = jf.getZipOnStream(in);
202 
203                for (;;) {
204 
205                        ZipEntry ze = jf.getNextEntry(zipIn);
206                        if (ze == null) {
207                                zipIn.close();
208                                return null;
209                        }
210 
211                        if (ze.getName().equals(jvmClassName)) {
212                                Class c = loadClassData(ze, zipIn, className, resolve);
213                                zipIn.close();
214                                return c;
215                        }
216                }
217                
218        }
219 
220        private Class loadClassData(ZipEntry ze, InputStream in,
221                String className, boolean resolve) throws IOException {
222 
223                byte[] data = jf.readData(ze, in, className);
224 
225                Object[] signers = jf.getSigners(className, ze);
226 
227                synchronized (updateLoader) {
228                        // see if someone else loaded it while we
229                        // were getting the bytes ...
230                        Class c = updateLoader.checkLoaded(className, resolve);
231                        if (c == null) {
232                                c = defineClass(className, data, 0, data.length);
233                                if (signers != null) {
234                                        setSigners(c, signers);
235                                }
236                                if (resolve)
237                                        resolveClass(c);
238                        }
239                        return c;
240 
241                }
242        }
243 
244        Class checkLoaded(String className, boolean resolve) {
245                if (updateLoader == null)
246                        return null;
247 
248                Class c = findLoadedClass(className);
249                if ((c != null) && resolve)
250                        resolveClass(c);
251                return c;
252        }
253 
254        private Object load() {
255 
256                String[] dbJarName = jf.name;
257 
258                String schemaName = dbJarName[IdUtil.DBCP_SCHEMA_NAME];
259                String sqlName = dbJarName[IdUtil.DBCP_SQL_JAR_NAME];
260 
261                // don't need a connection, just call the code directly
262                try {
263                        return updateLoader.getJarReader().readJarFile(schemaName, sqlName);
264                } catch (StandardException se) {
265                        if (vs != null)
266                                vs.println(MessageService.getTextMessage(MessageId.CM_LOAD_JAR_EXCEPTION, jf.getJarName(), se));
267                        return null;
268                }
269 
270        }
271 
272        JarFile setInvalid(boolean newJarFile) {
273 
274                jf.setInvalid();
275                updateLoader = null;
276                return newJarFile ? jarFileFactory.newJarFile(jf.name) : null;
277        }
278 
279        /*
280        ** Routines to get an InputStream for a namedResource
281        */
282 
283        /**
284                Get a stream directly from a ZipFile.
285                In this case we can safely return the stream directly.
286                It's a new stream set up by the zip code to read just
287                the contents of this entry.
288        */
289        private InputStream getRawStream(ZipFile zip, String name) {
290 
291                try {
292                        ZipEntry ze = zip.getEntry(name);
293                        if (ze == null)
294                                return null;
295 
296                        return zip.getInputStream(ze);
297                } catch (IOException ioe) {
298                        return null;
299                }
300        }
301 
302        /**
303                Get a stream from a zip file that is itself a stream.
304                Here we need to get the size of the zip entry and
305                put a limiting stream around it. Otherwise the
306                caller would end up reading the entire zip file!
307        */
308        private InputStream getRawStream(InputStream in, String name) { 
309 
310                ZipInputStream zipIn = null;
311                try {
312                        zipIn = new ZipInputStream(in);
313 
314                        ZipEntry ze;
315                        while ((ze = jf.getNextEntry(zipIn)) != null) {
316 
317                                if (ze.getName().equals(name)) {
318                                        LimitInputStream lis = new LimitInputStream(zipIn);
319                                        lis.setLimit((int) ze.getSize());
320                                        return lis;
321                                }
322                        }
323 
324                        zipIn.close();
325 
326                } catch (IOException ioe) {
327                        if (zipIn != null) {
328                                try {
329                                        zipIn.close();
330                                } catch (IOException ioe2) {
331                                }
332                        }
333                }
334                return null;
335        }
336}

[all classes][org.apache.derby.impl.services.reflect]
EMMA 2.0.5312 (C) Vladimir Roubtsov