KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javassist > web > Viewer


1 /*
2  * Javassist, a Java-bytecode translator toolkit.
3  * Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. Alternatively, the contents of this file may be used under
8  * the terms of the GNU Lesser General Public License Version 2.1 or later.
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  */

15
16 package javassist.web;
17
18 import java.io.*;
19 import java.net.*;
20
21 /**
22  * An applet viewer.
23  *
24  * <p>This is a sort of applet viewer that can run any program even if
25  * the main class is not a subclass of <code>Applet</code>.
26  * This viewwer first calls <code>main()</code> in the main class.
27  *
28  * <p>To run, you should type:
29  *
30  * <ul><code>% java javassist.web.Viewer <i>host port</i> Main arg1, ...</code></ul>
31  *
32  * <p>This command calls <code>Main.main()</code> with <code>arg1,...</code>
33  * All classes including <code>Main</code> are fetched from
34  * a server http://<i>host</i>:<i>port</i>.
35  * Only the class file for <code>Viewer</code> must exist
36  * on a local file system at the client side; even other
37  * <code>javassist.*</code> classes are not needed at the client side.
38  * <code>Viewer</code> uses only Java core API classes.
39  *
40  * <p>Note: since a <code>Viewer</code> object is a class loader,
41  * a program loaded by this object can call a method in <code>Viewer</code>.
42  * For example, you can write something like this:
43  *
44  * <ul><pre>
45  * Viewer v = (Viewer)this.getClass().getClassLoader();
46  * String port = v.getPort();
47  * </pre></ul>
48  *
49  */

50 public class Viewer extends ClassLoader JavaDoc {
51     private String JavaDoc server;
52     private int port;
53
54     /**
55      * Starts a program.
56      */

57     public static void main(String JavaDoc[] args) throws Throwable JavaDoc {
58         if (args.length >= 3) {
59             Viewer cl = new Viewer(args[0], Integer.parseInt(args[1]));
60             String JavaDoc[] args2 = new String JavaDoc[args.length - 3];
61             System.arraycopy(args, 3, args2, 0, args.length - 3);
62             cl.run(args[2], args2);
63         }
64         else
65             System.err.println(
66         "Usage: java javassist.web.Viewer <host> <port> class [args ...]");
67     }
68
69     /**
70      * Constructs a viewer.
71      *
72      * @param host server name
73      * @param p port number
74      */

75     public Viewer(String JavaDoc host, int p) {
76         server = host;
77         port = p;
78     }
79
80     /**
81      * Returns the server name.
82      */

83     public String JavaDoc getServer() { return server; }
84
85     /**
86      * Returns the port number.
87      */

88     public int getPort() { return port; }
89
90     /**
91      * Invokes main() in the class specified by <code>classname</code>.
92      *
93      * @param classname executed class
94      * @param args the arguments passed to <code>main()</code>.
95      */

96     public void run(String JavaDoc classname, String JavaDoc[] args)
97         throws Throwable JavaDoc
98     {
99         Class JavaDoc c = loadClass(classname);
100         try {
101             c.getDeclaredMethod("main", new Class JavaDoc[] { String JavaDoc[].class })
102                 .invoke(null, new Object JavaDoc[] { args });
103         }
104         catch (java.lang.reflect.InvocationTargetException JavaDoc e) {
105             throw e.getTargetException();
106         }
107     }
108
109     /**
110      * Requests the class loader to load a class.
111      */

112     protected synchronized Class JavaDoc loadClass(String JavaDoc name, boolean resolve)
113         throws ClassNotFoundException JavaDoc
114     {
115         Class JavaDoc c = findLoadedClass(name);
116         if (c == null)
117             c = findClass(name);
118
119         if (c == null)
120             throw new ClassNotFoundException JavaDoc(name);
121
122         if (resolve)
123             resolveClass(c);
124
125         return c;
126     }
127
128     /**
129      * Finds the specified class. The implementation in this class
130      * fetches the class from the http server. If the class is
131      * either <code>java.*</code>, <code>javax.*</code>, or
132      * <code>Viewer</code>, then it is loaded by the parent class
133      * loader.
134      *
135      * <p>This method can be overridden by a subclass of
136      * <code>Viewer</code>.
137      */

138     protected Class JavaDoc findClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
139         Class JavaDoc c = null;
140         if (name.startsWith("java.") || name.startsWith("javax.")
141             || name.equals("javassist.web.Viewer"))
142             c = findSystemClass(name);
143
144         if (c == null)
145             try {
146                 byte[] b = fetchClass(name);
147                 if (b != null)
148                     c = defineClass(name, b, 0, b.length);
149             }
150         catch (Exception JavaDoc e) {
151         }
152
153         return c;
154     }
155
156     /**
157      * Fetches the class file of the specified class from the http
158      * server.
159      */

160     protected byte[] fetchClass(String JavaDoc classname) throws Exception JavaDoc
161     {
162         byte[] b;
163         URL url = new URL("http", server, port,
164                           "/" + classname.replace('.', '/') + ".class");
165         URLConnection con = url.openConnection();
166         con.connect();
167         int size = con.getContentLength();
168         InputStream s = con.getInputStream();
169         if (size <= 0)
170             b = readStream(s);
171         else {
172             b = new byte[size];
173             int len = 0;
174             do {
175                 int n = s.read(b, len, size - len);
176                 if (n < 0) {
177                     s.close();
178                     throw new IOException("the stream was closed: "
179                                           + classname);
180                 }
181                 len += n;
182             } while (len < size);
183         }
184
185         s.close();
186         return b;
187     }
188
189     private byte[] readStream(InputStream fin) throws IOException {
190         byte[] buf = new byte[4096];
191         int size = 0;
192         int len = 0;
193         do {
194             size += len;
195             if (buf.length - size <= 0) {
196                 byte[] newbuf = new byte[buf.length * 2];
197                 System.arraycopy(buf, 0, newbuf, 0, size);
198                 buf = newbuf;
199             }
200
201             len = fin.read(buf, size, buf.length - size);
202         } while (len >= 0);
203
204         byte[] result = new byte[size];
205         System.arraycopy(buf, 0, result, 0, size);
206         return result;
207     }
208 }
209
Popular Tags