KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jac > core > dist > DistdClassLoader


1 /*
2   Copyright (C) 2001 Renaud Pawlak <renaud@aopsys.com>
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as
6   published by the Free Software Foundation; either version 2 of the
7   License, or (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12   GNU Lesser General Public License for more details.
13
14   You should have received a copy of the GNU Lesser Generaly Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */

17
18 package org.objectweb.jac.core.dist;
19
20 import java.io.FileInputStream JavaDoc;
21 import java.util.Hashtable JavaDoc;
22 import org.apache.log4j.Logger;
23
24 /**
25  * DistdClassLoader is a class loader that load classes from a remote
26  * JAC container (the class repository site).
27  *
28  * @see RemoteContainer#getByteCodeFor(String)
29  *
30  * @author <a HREF="http://cedric.cnam.fr/~pawlak/index-english.html">Renaud Pawlak</a> */

31
32 public class DistdClassLoader extends ClassLoader JavaDoc {
33     static Logger logger = Logger.getLogger("dist.classloader");
34
35    /** loadedClasses is a hashtable of classes that have been
36        loaded. */

37     protected transient Hashtable JavaDoc loadedClasses = new Hashtable JavaDoc();
38
39     /** loadedByteCodes is a hashtable of byte codes that have been
40        remotely load (so that this site may be used as an intermediate
41        class repository. */

42     protected Hashtable JavaDoc loadedByteCodes = new Hashtable JavaDoc();
43
44     /** Bootstrapping flag (do not load classes while true). */
45     public boolean bootstrapping = true;
46
47     /** The class repository site. */
48     public static String JavaDoc classRepositoryName = null;
49    
50     /**
51     * Overrides the default mechanism to load classes (only for
52     * non-java classes). The behavior is the following :<p>
53     *
54     * <ul>
55     * <li>check whether the class is already loaded</li>
56     * <li>try to load it from the class repository site</li>
57     * <li>if success, store its bytecode (see getByteCode)</li>
58     * <li>try to load it from the local filesystem</li>
59     * <li>if all these failed, delegate to the parent</li>
60     * </ul>
61     *
62     * @param name the name for the class to load
63     * @return the loaded class
64     */

65
66     public Class JavaDoc loadClass(String JavaDoc name)
67         throws ClassNotFoundException JavaDoc {
68
69         /** Do not reload the same class */
70         if (name.equals(getClass().getName())) {
71             logger.debug("Do not reload "+getClass().getName());
72             return getClass();
73         }
74
75         Class JavaDoc cl;
76         if (name.startsWith("java.")) {
77             logger.debug("Get system class "+name+" from parent classloader");
78             cl = getParent().loadClass(name);
79             loadedClasses.put(name, cl);
80             return cl;
81         }
82       
83         /** Check whether already loaded */
84         cl = (Class JavaDoc)loadedClasses.get(name);
85
86         if (cl == null) {
87
88             byte[] bc = null;
89
90             /** Check if we know a class repository to download the bytecode */
91
92             if ( (!bootstrapping) && classRepositoryName != null ) {
93
94                 /** Download the bytecode */
95                 logger.debug("Downloading "+name+" from "+classRepositoryName);
96                 RemoteContainer rc = RemoteContainer.resolve(classRepositoryName);
97                 try {
98                     bc = rc.getByteCodeFor(name);
99                 } catch(Exception JavaDoc e) {
100                     logger.debug("Failed to get bytecode for "+name+
101                               " from "+classRepositoryName+": "+e);
102                 }
103                 if (bc != null) {
104                     loadedByteCodes.put(name, bc);
105                 }
106             }
107          
108             /** Check if download was successfully performed */
109
110             if (bc == null) {
111
112                 /** Try to load it from the local filesystem */
113                 logger.debug("Loading "+name+" from local FS");
114                 try {
115                     FileInputStream JavaDoc in = new FileInputStream JavaDoc(
116                         getParent().getResource(name.replace('.','/')+".class").getFile());
117                     bc = new byte[in.available()];
118                     in.read(bc);
119                 } catch (Exception JavaDoc e) {
120                     /** If failed, delegate to the parent classloader */
121                     cl = getParent().loadClass(name);
122                     loadedClasses.put(name, cl);
123                     return cl;
124                 }
125             
126             }
127
128             if (bc != null) {
129                 /** Define the class from the bytecode */
130                 try {
131                     cl = defineClass(name, bc, 0, bc.length);
132                     loadedClasses.put(name, cl);
133                 } catch (Exception JavaDoc e) {
134                     /** Bytecode was corrupted or some error occured */
135                     logger.error("Cannot load class "+name,e);
136                 }
137             }
138       
139         } else {
140             logger.debug("Already loaded "+name);
141         }
142
143         return cl;
144     }
145
146     /**
147     * Gets the bytecode for a given remotely loaded class name.
148     *
149     * @param className the name of the class
150     * @return the corresponding bytecode */

151
152     public byte[] getByteCode (String JavaDoc className) {
153         byte[] bc = (byte[])loadedByteCodes.get (className);
154         if (bc == null) {
155         }
156         return bc;
157     }
158       
159 }
160
Popular Tags