KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > clif > supervisor > lib > CodeServer


1 /*
2 * CLIF is a Load Injection Framework
3 * Copyright (C) 2004 France Telecom R&D
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * CLIF $Name: $
20 *
21 * Contact: clif@objectweb.org
22 */

23
24 package org.objectweb.clif.supervisor.lib;
25
26 import java.util.Map JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Enumeration JavaDoc;
29 import java.util.StringTokenizer JavaDoc;
30 import java.util.zip.ZipEntry JavaDoc;
31 import java.util.jar.JarFile JavaDoc;
32 import java.io.File JavaDoc;
33 import java.io.IOException JavaDoc;
34 import java.io.InputStream JavaDoc;
35 import java.io.FileInputStream JavaDoc;
36 import java.io.DataOutputStream JavaDoc;
37 import java.io.DataInputStream JavaDoc;
38 import java.net.ServerSocket JavaDoc;
39 import java.net.Socket JavaDoc;
40 import java.net.SocketException JavaDoc;
41
42
43 /**
44  * This class implements a resource or class server.
45  * The requested resource or class is first looked for in jar files in CLIF's lib/ext/ directory.
46  * Then, current directory and directories set by property clif.codeserver.path are visited, in
47  * this order. The property, when set, should contain a ';' separated list of directory paths.
48  * <p>
49  * In detail, the codeserver listens on a given port, and upon any connection request:
50  * <ul>
51  * <li>reads from the socket an UTF String representing the class or resource name
52  * <li>writes a positive int stating the resource or class file length or a negative int providing
53  * an error code (resource/class not found or resource/class too big).
54  * <li>if the class/resource file has been found and can be transfered, all of its bytes are written
55  * in the socket.
56  * <li>the socket is not closed by the code server, except when an exception occurs while handling
57  * the socket.
58  * </ul>
59  * As of current implementation, class/resource files bigger than 2GB can't be transfered.
60  * @author Bruno Dillenseger
61  */

62 public class CodeServer extends ServerSocket JavaDoc implements Runnable JavaDoc
63 {
64     static public final int NO_SUCH_RESOURCE = -1;
65     static public final int RESOURCE_TOO_BIG = -2;
66     static public final String JavaDoc PATH_PROPERTY = "clif.codeserver.path";
67     static public final String JavaDoc DEFAULT_PATH = "";
68     static public final String JavaDoc PATH_SEPARATOR = ";";
69     static public final String JavaDoc EXTENSION_DIR = "./lib/ext/";
70     static private Map JavaDoc libExtMap = new HashMap JavaDoc();
71     static private File JavaDoc[] paths;
72
73     static
74     {
75         // index content of jar files in Clif's lib/ext directory
76
try
77         {
78             File JavaDoc dir = new File JavaDoc(EXTENSION_DIR);
79             if (dir.canRead())
80             {
81                 String JavaDoc[] list = dir.list();
82                 for (int i=0 ; i<list.length ; ++i)
83                 {
84                     if (list[i].endsWith(".jar"))
85                     {
86                         JarFile JavaDoc jar = new JarFile JavaDoc(EXTENSION_DIR + list[i]);
87                         Enumeration JavaDoc entries = jar.entries();
88                         while (entries.hasMoreElements())
89                         {
90                             libExtMap.put(
91                                 ((ZipEntry JavaDoc)entries.nextElement()).getName(),
92                                 jar);
93                         }
94                     }
95                 }
96             }
97         }
98         catch (IOException JavaDoc ex)
99         {
100             System.err.println(
101                 "Warning - problem while indexing " + EXTENSION_DIR + " Jar files.\n" + ex);
102             ex.printStackTrace(System.err);
103         }
104         // parses the path property
105
StringTokenizer JavaDoc parser = new StringTokenizer JavaDoc(
106             System.getProperty(PATH_PROPERTY, DEFAULT_PATH),
107             PATH_SEPARATOR);
108         paths = new File JavaDoc[parser.countTokens()];
109         for (int i=0 ; i<paths.length ; ++i)
110         {
111             paths[i] = new File JavaDoc(parser.nextToken());
112         }
113     }
114
115
116     /**
117      * Creates a new HTTP-based code server.
118      * @param port the port the code server must listen to
119      */

120     public CodeServer(int port)
121         throws IOException JavaDoc
122     {
123         super(port);
124         setReuseAddress(true);
125         new Thread JavaDoc(this, "code server").start();
126     }
127
128
129     public void run()
130     {
131         while (true)
132         {
133             try
134             {
135                 new ClassServerRequest(accept());
136             }
137             catch (IOException JavaDoc ex)
138             {
139                 ex.printStackTrace(System.err);
140             }
141         }
142     }
143
144
145     class ClassServerRequest extends Thread JavaDoc
146     {
147         Socket JavaDoc sock;
148
149
150         public ClassServerRequest(Socket JavaDoc sock)
151         {
152             super("code server request handler " + sock);
153             this.sock = sock;
154             try
155             {
156                 sock.setReuseAddress(true);
157                 sock.setSoLinger(false, -1);
158             }
159             catch (SocketException JavaDoc ex)
160             {
161                 ex.printStackTrace(System.err);
162             }
163             start();
164         }
165
166
167         public void run()
168         {
169             DataOutputStream JavaDoc douts;
170             DataInputStream JavaDoc dins;
171             try
172             {
173                 douts = new DataOutputStream JavaDoc(sock.getOutputStream());
174                 dins = new DataInputStream JavaDoc(sock.getInputStream());
175             }
176             catch (IOException JavaDoc ex)
177             {
178                 throw new Error JavaDoc("can't properly handle incoming connection to codeserver", ex);
179             }
180             while (sock != null)
181             {
182                 try
183                 {
184                     String JavaDoc filename = dins.readUTF();
185 //System.out.println(filename);
186
File JavaDoc inputFile = new File JavaDoc(filename);
187                     JarFile JavaDoc jar = (JarFile JavaDoc)libExtMap.get(filename);
188                     if (jar == null)
189                     {
190                         for (int i=0 ; i<paths.length && !inputFile.canRead() ; ++i)
191                         {
192                             inputFile = new File JavaDoc(paths[i], filename);
193                         }
194                     }
195                     if (jar == null && ! inputFile.canRead())
196                     {
197                         douts.writeInt(NO_SUCH_RESOURCE);
198                         douts.flush();
199                     }
200                     else
201                     {
202                         long file_length = 0;
203                         ZipEntry JavaDoc entry = null;
204                         if (jar == null)
205                         {
206                             file_length = inputFile.length();
207                         }
208                         else
209                         {
210                             entry = jar.getEntry(filename);
211                             file_length = entry.getSize();
212                         }
213                         InputStream JavaDoc is;
214                         if (jar != null)
215                         {
216                             is = jar.getInputStream(entry);
217                         }
218                         else
219                         {
220                             is = new FileInputStream JavaDoc(inputFile);
221                         }
222                         if (file_length > Integer.MAX_VALUE)
223                         {
224                             douts.writeInt(RESOURCE_TOO_BIG);
225                             douts.flush();
226                         }
227                         else
228                         {
229                             douts.writeInt((int)file_length);
230                             byte[] buffer = new byte[(int)file_length];
231                             while (file_length > 0)
232                             {
233                                 int n = is.read(buffer, 0, (int)file_length);
234                                 douts.write(buffer, 0, n);
235                                 file_length -= n;
236                             }
237                             douts.flush();
238                         }
239                     }
240                 }
241                 catch (IOException JavaDoc ex)
242                 {
243                     try
244                     {
245                         sock.close();
246                     }
247                     catch (IOException JavaDoc exc)
248                     {
249                         System.err.println("Exception in codeserver while closing connection");
250                         ex.printStackTrace(System.err);
251                     }
252                     System.err.println("Exception in code server while serving classes");
253                     ex.printStackTrace(System.err);
254                     sock = null;
255                 }
256             }
257         }
258     }
259 }
260
Popular Tags