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 [UpdateLoader.java]

nameclass, %method, %block, %line, %
UpdateLoader.java100% (2/2)100% (17/17)88%  (491/560)90%  (123/137)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ClassLoaderLock100% (1/1)100% (2/2)100% (18/18)100% (7/7)
ClassLoaderLock (UpdateLoader): void 100% (1/1)100% (6/6)100% (3/3)
unlockEvent (Latch): void 100% (1/1)100% (12/12)100% (4/4)
     
class UpdateLoader100% (1/1)100% (15/15)87%  (473/542)89%  (116/130)
UpdateLoader (String, DatabaseClasses, boolean, boolean): void 100% (1/1)100% (34/34)100% (10/10)
checkLoaded (String, boolean): Class 100% (1/1)100% (23/23)100% (5/5)
close (): void 100% (1/1)100% (17/17)100% (3/3)
getClassLoaderVersion (): int 100% (1/1)100% (3/3)100% (1/1)
getClasspath (): String 100% (1/1)100% (17/17)100% (6/6)
getJarReader (): JarReader 100% (1/1)100% (14/14)100% (4/4)
getResourceAsStream (String): InputStream 100% (1/1)68%  (71/104)68%  (15.6/23)
initLoaders (): void 100% (1/1)95%  (21/22)83%  (5/6)
initializeFromClassPath (String): void 100% (1/1)100% (48/48)100% (10/10)
loadClass (String, boolean): Class 100% (1/1)81%  (104/128)88%  (22.1/25)
lockClassLoader (ShExQual): boolean 100% (1/1)84%  (31/37)79%  (7.9/10)
modifyClasspath (String): void 100% (1/1)100% (17/17)100% (5/5)
modifyJar (boolean): void 100% (1/1)91%  (49/54)96%  (13.4/14)
needReload (): void 100% (1/1)100% (10/10)100% (3/3)
reload (): void 100% (1/1)100% (14/14)100% (5/5)

1/*
2 
3   Derby - Class org.apache.derby.impl.services.reflect.UpdateLoader
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.iapi.services.context.ContextService;
24import org.apache.derby.iapi.services.monitor.Monitor;
25import org.apache.derby.iapi.services.monitor.Monitor;
26import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
27import org.apache.derby.iapi.util.IdUtil;
28import org.apache.derby.iapi.error.StandardException;
29import org.apache.derby.iapi.services.locks.ShExLockable;
30import org.apache.derby.iapi.services.locks.ShExQual;
31import org.apache.derby.iapi.services.locks.LockFactory;
32import org.apache.derby.iapi.services.locks.Latch;
33import org.apache.derby.iapi.services.locks.C_LockFactory;
34import org.apache.derby.iapi.services.loader.ClassFactoryContext;
35import org.apache.derby.iapi.services.loader.JarReader;
36import org.apache.derby.iapi.services.property.PersistentSet;
37 
38import org.apache.derby.iapi.services.property.PropertyUtil;
39import org.apache.derby.iapi.reference.Property;
40 
41import java.io.InputStream;
42 
43import org.apache.derby.iapi.reference.MessageId;
44import org.apache.derby.iapi.reference.Module;
45import org.apache.derby.iapi.services.i18n.MessageService;
46 
47public class UpdateLoader {
48 
49        private JarLoader[] jarList;
50        private HeaderPrintWriter vs;
51        private final ClassLoader myLoader;
52        private boolean initDone;
53        private String thisClasspath;
54        private final LockFactory lf;
55        private final ShExLockable classLoaderLock;
56        private int version;
57    private boolean normalizeToUpper;
58        private DatabaseClasses parent;
59 
60        private boolean needReload;
61        private JarReader jarReader;
62 
63        public UpdateLoader(String classpath, DatabaseClasses parent, boolean verbose, boolean normalizeToUpper) 
64                throws StandardException {
65 
66        this.normalizeToUpper = normalizeToUpper;
67                this.parent = parent;
68                lf = (LockFactory) Monitor.getServiceModule(parent, Module.LockFactory);
69 
70                if (verbose) {
71                        vs = Monitor.getStream();
72                }
73                
74                myLoader = getClass().getClassLoader();
75 
76                this.classLoaderLock = new ClassLoaderLock(this);
77 
78                initializeFromClassPath(classpath);
79        }
80 
81        private void initializeFromClassPath(String classpath) throws StandardException {
82 
83                String[][] elements = IdUtil.parseDbClassPath(classpath, normalizeToUpper);
84                
85                int jarCount = elements.length;
86                jarList = new JarLoader[jarCount];
87                        
88                for (int i = 0; i < jarCount; i++) {
89                        jarList[i] = new JarLoader(this, elements[i], vs);
90                }
91 
92                if (vs != null) {
93                        vs.println(MessageService.getTextMessage(MessageId.CM_CLASS_LOADER_START, classpath));
94                }
95                
96                thisClasspath = classpath;
97                initDone = false;
98        }
99 
100        /**
101                Load the class from the class path.
102 
103                @exception ClassNotFoundException Class can not be found
104        */
105        public Class loadClass(String className, boolean resolve) 
106                throws ClassNotFoundException {
107 
108 
109                JarLoader jl = null;
110 
111                boolean unlockLoader = false;
112                try {
113                        unlockLoader = lockClassLoader(ShExQual.SH);
114 
115                        synchronized (this) {
116 
117                                if (needReload) {
118                                        reload();
119                                }
120                        
121                                Class clazz = checkLoaded(className, resolve);
122                                if (clazz != null)
123                                        return clazz;
124 
125                                String jvmClassName = className.replace('.', '/').concat(".class");
126 
127                                if (!initDone)
128                                        initLoaders();
129 
130                                for (int i = 0; i < jarList.length; i++) {
131 
132                                        jl = jarList[i];
133 
134                                        Class c = jl.loadClassData(className, jvmClassName, resolve);
135                                        if (c != null) {
136                                                if (vs != null)
137                                                        vs.println(MessageService.getTextMessage(MessageId.CM_CLASS_LOAD, className, jl.getJarName()));
138 
139                                                return c;
140                                        }
141                                }
142                        }
143 
144                        return null;
145 
146 
147                } catch (StandardException se) {
148                        throw new ClassNotFoundException(MessageService.getTextMessage(MessageId.CM_CLASS_LOAD_EXCEPTION, className, jl == null ? null : jl.getJarName(), se));
149                } finally {
150                        if (unlockLoader) {
151                                lf.unlock(this, this, classLoaderLock, ShExQual.SH);
152                        }
153                }
154        }
155 
156        public InputStream getResourceAsStream(String name) {
157 
158                InputStream is = (myLoader == null) ?
159                        ClassLoader.getSystemResourceAsStream(name) :
160                        myLoader.getResourceAsStream(name);
161 
162                if (is != null)
163                        return is;
164 
165                // match behaviour of standard class loaders. 
166                if (name.endsWith(".class"))
167                        return null;
168 
169                boolean unlockLoader = false;
170                try {
171                        unlockLoader = lockClassLoader(ShExQual.SH);
172 
173                        synchronized (this) {
174 
175                                if (needReload) {
176                                        reload();                
177                                }
178 
179                                if (!initDone)
180                                        initLoaders();
181 
182                                for (int i = 0; i < jarList.length; i++) {
183 
184                                        JarLoader jl = jarList[i];
185 
186                                        is = jl.getStream(name);
187                                        if (is != null) {
188                                                return is;
189                                        }
190                                }
191                        }
192                        return null;
193 
194                } catch (StandardException se) {
195                        return null;
196                } finally {
197                        if (unlockLoader) {
198                                lf.unlock(this, this, classLoaderLock, ShExQual.SH);
199                        }
200                }
201        }
202 
203        public synchronized void modifyClasspath(String classpath)
204                throws StandardException {
205 
206                // lock transaction classloader exclusively
207                lockClassLoader(ShExQual.EX);
208                version++;
209 
210 
211                modifyJar(false);
212                initializeFromClassPath(classpath);
213        }
214 
215 
216        public synchronized void modifyJar(boolean reload) throws StandardException {
217 
218                // lock transaction classloader exclusively
219                lockClassLoader(ShExQual.EX);
220                version++;
221 
222                if (!initDone)
223                        return;
224 
225                if (reload) {
226                        //first close the existing jar file opens
227                        close();
228                        initializeFromClassPath(thisClasspath);
229                        return;
230                }
231 
232                // first thing to do is to remove all Class entries
233                // and then get a complete set of loaders ...
234                synchronized (this) {
235 
236                        for (int i = 0; i < jarList.length; i++) {
237 
238                                JarLoader jl = jarList[i];
239 
240                                JarFile newJarFile = jl.setInvalid(reload);
241                        }
242                }
243        }
244 
245        private boolean lockClassLoader(ShExQual qualifier)
246                throws StandardException {
247 
248                if (lf == null)
249                        return false;
250 
251                ClassFactoryContext cfc = (ClassFactoryContext) ContextService.getContextOrNull(ClassFactoryContext.CONTEXT_ID);
252 
253                // This method can be called from outside of the database
254                // engine, in which case tc will be null. In that case
255                // we lock the class loader only for the duration of
256                // the loadClass().
257                Object lockSpace = null;
258                
259                if (cfc != null) {
260                        lockSpace = cfc.getLockSpace();
261                }
262                if (lockSpace == null)
263                        lockSpace = this;
264 
265                lf.lockObject(lockSpace, lockSpace, classLoaderLock, qualifier, C_LockFactory.TIMED_WAIT);
266 
267                return (lockSpace == this);
268        }
269 
270        Class checkLoaded(String className, boolean resolve) {
271 
272                for (int i = 0; i < jarList.length; i++) {
273                        Class c = jarList[i].checkLoaded(className, resolve);
274                        if (c != null)
275                                return c;
276                }
277                return null;
278        }
279 
280        public void close() {
281 
282                for (int i = 0; i < jarList.length; i++) {
283                        jarList[i].setInvalid(false);
284                }
285 
286        }
287 
288        private void initLoaders() {
289 
290                if (initDone)
291                        return;
292 
293                for (int i = 0; i < jarList.length; i++) {
294                        jarList[i].initialize();
295                }
296                initDone = true;
297        }
298 
299        public int getClassLoaderVersion() {
300                return version;
301        }
302 
303        synchronized void needReload() {
304                version++;
305                needReload = true;
306        }
307 
308        private void reload() throws StandardException {
309                thisClasspath = getClasspath();
310                // first close the existing jar file opens
311                close();
312                initializeFromClassPath(thisClasspath);
313                needReload = false;
314        }
315 
316 
317        private String getClasspath()
318                throws StandardException {
319 
320                ClassFactoryContext cfc = (ClassFactoryContext) ContextService.getContextOrNull(ClassFactoryContext.CONTEXT_ID);
321 
322                PersistentSet ps = cfc.getPersistentSet();
323                
324                String classpath = PropertyUtil.getServiceProperty(ps, Property.DATABASE_CLASSPATH);
325 
326                //
327                //In per database mode we must always have a classpath. If we do not
328                //yet have one we make one up.
329                if (classpath==null)
330                        classpath="";
331 
332 
333                return classpath;
334        }
335 
336        JarReader getJarReader() {
337                if (jarReader == null) {
338 
339                        ClassFactoryContext cfc = (ClassFactoryContext) ContextService.getContextOrNull(ClassFactoryContext.CONTEXT_ID);
340 
341                        jarReader = cfc.getJarReader(); 
342                }
343                return jarReader;
344        }
345}
346 
347 
348class ClassLoaderLock extends ShExLockable {
349 
350        private UpdateLoader myLoader;
351 
352        ClassLoaderLock(UpdateLoader myLoader) {
353                this.myLoader = myLoader;
354        }
355 
356        public void unlockEvent(Latch lockInfo)
357        {
358                super.unlockEvent(lockInfo);
359 
360                if (lockInfo.getQualifier().equals(ShExQual.EX)) {
361                        // how do we tell if we are reverting or not
362                        myLoader.needReload();
363                }
364        }
365}

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