KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > ant > jaxb > GreedyClassLoader


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Emil Ong
28  */

29
30 package com.caucho.ant.jaxb;
31
32 import java.io.*;
33
34 import java.util.*;
35
36 import java.net.URL JavaDoc;
37
38 import com.caucho.util.*;
39 import com.caucho.vfs.*;
40
41
42 /**
43  * Class loader which loads all the classes in a directory tree.
44  *
45  * The JAXB TCK has tests with package access classes. This loader
46  * deals with this irregularity.
47  */

48 public class GreedyClassLoader extends java.net.URLClassLoader JavaDoc
49 {
50   private final static URL JavaDoc[] NULL_URL_ARRAY = new URL JavaDoc[0];
51
52   private ClassLoader JavaDoc _parent;
53   private Hashtable<String JavaDoc,Class JavaDoc> _classes = new Hashtable<String JavaDoc,Class JavaDoc>();
54   private ByteBuffer _buffer = new ByteBuffer();
55   private HashMap<File,String JavaDoc> _problemFiles = new HashMap<File,String JavaDoc>();
56
57   public GreedyClassLoader(ClassLoader JavaDoc parent)
58   {
59     super(NULL_URL_ARRAY);
60     _parent = parent;
61   }
62
63   public Class JavaDoc<?> loadClass(String JavaDoc name)
64     throws ClassNotFoundException JavaDoc
65   {
66     if (_classes.containsKey(name))
67       return _classes.get(name);
68
69     return _parent.loadClass(name);
70   }
71
72   public Class JavaDoc<?> loadClassFile(File file, String JavaDoc packagePrefix)
73     throws IOException
74   {
75     String JavaDoc name = file.getName();
76     String JavaDoc className = name.substring(0, name.length() - ".class".length());
77
78     _buffer.clear();
79     _buffer.ensureCapacity((int) file.length());
80
81     Path path = Vfs.lookup(file.getPath());
82     ReadStream rs = path.openRead();
83
84     try {
85       rs.readAll(_buffer.getBuffer(), 0, (int) file.length());
86
87       Class JavaDoc cl = defineClass(packagePrefix + "." + className,
88                              _buffer.getBuffer(), 0, (int) file.length());
89
90       if (packagePrefix == null)
91         _classes.put(className, cl);
92       else
93         _classes.put(packagePrefix + "." + className, cl);
94
95       return cl;
96     }
97     finally {
98       rs.close();
99     }
100   }
101
102   public void loadClassFiles(File root)
103     throws IOException
104   {
105     loadClassFiles(root, null);
106
107     int startSize;
108
109     // XXX
110
// Very crude method to deal with dependencies
111
do {
112       startSize = _problemFiles.size();
113
114       Iterator<Map.Entry<File,String JavaDoc>> i = _problemFiles.entrySet().iterator();
115
116       while (i.hasNext()) {
117         try {
118           Map.Entry<File,String JavaDoc> problem = i.next();
119
120           loadClassFile(problem.getKey(), problem.getValue());
121
122           i.remove();
123         }
124         catch (NoClassDefFoundError JavaDoc e) {
125         }
126       }
127     }
128     while (_problemFiles.size() < startSize);
129   }
130
131   public void loadClassFiles(File root, String JavaDoc packagePrefix)
132     throws IOException
133   {
134     if (root.isDirectory()) {
135       for (File child : root.listFiles()) {
136         // if we have a root like /x/y/z with a class /x/y/z/a/b.class
137
// then we need to produce a.b. When packagePrefix == null, we
138
// are at /x/y/z, so we don't want to pick up z. When
139
// packagePrefix == "", that means the current root is a
140
// subpackage, so we can append their name to the packagePrefix.
141
// Basically, this is an off-by-one fix.
142

143         if (packagePrefix == null)
144           loadClassFiles(child, "");
145         else if ("".equals(packagePrefix))
146           loadClassFiles(child, root.getName());
147         else
148           loadClassFiles(child, packagePrefix + "." + root.getName());
149       }
150     }
151     else {
152       if (root.getPath().endsWith(".class")) {
153         try {
154           loadClassFile(root, packagePrefix);
155         }
156         catch (NoClassDefFoundError JavaDoc e) {
157           _problemFiles.put(root, packagePrefix);
158         }
159       }
160     }
161   }
162
163   public Class JavaDoc[] getLoadedClasses()
164   {
165     return _classes.values().toArray(new Class JavaDoc[0]);
166   }
167 }
168
Popular Tags