KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hudson > remoting > RemoteClassLoader


1 package hudson.remoting;
2
3 import java.io.ByteArrayOutputStream JavaDoc;
4 import java.io.File JavaDoc;
5 import java.io.FileOutputStream JavaDoc;
6 import java.io.IOException JavaDoc;
7 import java.io.InputStream JavaDoc;
8 import java.net.URL JavaDoc;
9 import java.util.Enumeration JavaDoc;
10 import java.util.HashMap JavaDoc;
11 import java.util.Map JavaDoc;
12 import java.util.Vector JavaDoc;
13 import java.util.List JavaDoc;
14 import java.util.ArrayList JavaDoc;
15
16 /**
17  * Loads class files from the other peer through {@link Channel}.
18  *
19  * @author Kohsuke Kawaguchi
20  */

21 final class RemoteClassLoader extends ClassLoader JavaDoc {
22     private final IClassLoader proxy;
23
24     private final Map JavaDoc<String JavaDoc,URL JavaDoc> resourceMap = new HashMap JavaDoc<String JavaDoc,URL JavaDoc>();
25     private final Map JavaDoc<String JavaDoc,Vector JavaDoc<URL JavaDoc>> resourcesMap = new HashMap JavaDoc<String JavaDoc,Vector JavaDoc<URL JavaDoc>>();
26
27     public RemoteClassLoader(ClassLoader JavaDoc parent, IClassLoader proxy) {
28         super(parent);
29         this.proxy = proxy;
30     }
31
32     protected Class JavaDoc<?> findClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
33         byte[] bytes = proxy.fetch(name);
34         return defineClass(name, bytes, 0, bytes.length);
35     }
36
37     protected URL JavaDoc findResource(String JavaDoc name) {
38         if(resourceMap.containsKey(name))
39             return resourceMap.get(name);
40
41         try {
42             byte[] image = proxy.getResource(name);
43             if(image==null) {
44                 resourceMap.put(name,null);
45                 return null;
46             }
47     
48             URL JavaDoc url = makeResource(name, image);
49             resourceMap.put(name,url);
50             return url;
51         } catch (IOException JavaDoc e) {
52             throw new Error JavaDoc("Unable to load resource "+name,e);
53         }
54     }
55
56     protected Enumeration JavaDoc<URL JavaDoc> findResources(String JavaDoc name) throws IOException JavaDoc {
57         Vector JavaDoc<URL JavaDoc> urls = resourcesMap.get(name);
58         if(urls!=null)
59             return urls.elements();
60
61         byte[][] images = proxy.getResources(name);
62
63         urls = new Vector JavaDoc<URL JavaDoc>();
64         for( byte[] image: images )
65             urls.add(makeResource(name,image));
66         resourcesMap.put(name,urls);
67
68         return urls.elements();
69     }
70
71     private URL JavaDoc makeResource(String JavaDoc name, byte[] image) throws IOException JavaDoc {
72         int idx = name.lastIndexOf('/');
73         File JavaDoc f = File.createTempFile("hudson-remoting","."+name.substring(idx+1));
74         FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(f);
75         fos.write(image);
76         fos.close();
77         f.deleteOnExit();
78
79         return f.toURL();
80     }
81
82     /**
83      * Remoting interface.
84      */

85     /*package*/ static interface IClassLoader {
86         byte[] fetch(String JavaDoc className) throws ClassNotFoundException JavaDoc;
87         byte[] getResource(String JavaDoc name) throws IOException JavaDoc;
88         byte[][] getResources(String JavaDoc name) throws IOException JavaDoc;
89     }
90
91     public static IClassLoader export(ClassLoader JavaDoc cl, Channel local) {
92         return local.export(IClassLoader.class, new ClassLoaderProxy(cl), false);
93     }
94
95     /**
96      * Exports and just returns the object ID, instead of obtaining the proxy.
97      */

98     static int exportId(ClassLoader JavaDoc cl, Channel local) {
99         return local.export(new ClassLoaderProxy(cl));
100     }
101
102     /*package*/ static final class ClassLoaderProxy implements IClassLoader {
103         private final ClassLoader JavaDoc cl;
104
105         public ClassLoaderProxy(ClassLoader JavaDoc cl) {
106             this.cl = cl;
107         }
108
109         public byte[] fetch(String JavaDoc className) throws ClassNotFoundException JavaDoc {
110             InputStream JavaDoc in = cl.getResourceAsStream(className.replace('.', '/') + ".class");
111             if(in==null)
112                 throw new ClassNotFoundException JavaDoc(className);
113
114             try {
115                 return readFully(in);
116             } catch (IOException JavaDoc e) {
117                 throw new ClassNotFoundException JavaDoc();
118             }
119         }
120
121
122         public byte[] getResource(String JavaDoc name) throws IOException JavaDoc {
123             InputStream JavaDoc in = cl.getResourceAsStream(name);
124             if(in==null) return null;
125
126             return readFully(in);
127         }
128
129         public byte[][] getResources(String JavaDoc name) throws IOException JavaDoc {
130             List JavaDoc<byte[]> images = new ArrayList JavaDoc<byte[]>();
131
132             Enumeration JavaDoc<URL JavaDoc> e = cl.getResources(name);
133             while(e.hasMoreElements()) {
134                 images.add(readFully(e.nextElement().openStream()));
135             }
136
137             return images.toArray(new byte[images.size()][]);
138         }
139
140         private byte[] readFully(InputStream JavaDoc in) throws IOException JavaDoc {
141             ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
142
143             byte[] buf = new byte[8192];
144             int len;
145             while((len=in.read(buf))>0)
146                 baos.write(buf,0,len);
147             in.close();
148
149             return baos.toByteArray();
150         }
151
152         public boolean equals(Object JavaDoc that) {
153             if (this == that) return true;
154             if (that == null || getClass() != that.getClass()) return false;
155
156             return cl.equals(((ClassLoaderProxy) that).cl);
157         }
158
159         public int hashCode() {
160             return cl.hashCode();
161         }
162     }
163 }
164
Popular Tags