1:
37:
38: package ;
39:
40: import ;
41:
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63:
64:
72: public class Connection extends URLConnection
73: {
74:
77: private static final String DEFAULT_PERMISSION = "read";
78:
79: private static class StaticData
80: {
81:
84: static SimpleDateFormat dateFormat
85: = new SimpleDateFormat("EEE, dd MMM yyyy hh:mm:ss 'GMT'",
86: new Locale ("En", "Us", "Unix"));
87:
88: static String lineSeparator =
89: SystemProperties.getProperty("line.separator");
90: }
91:
92:
93:
96: private File file;
97:
98:
101: private byte[] directoryListing;
102:
103:
106: private InputStream inputStream;
107:
108:
111: private OutputStream outputStream;
112:
113:
116: private FilePermission permission;
117:
118:
121: public Connection(URL url)
122: {
123: super (url);
124:
125: permission = new FilePermission(getURL().getFile(), DEFAULT_PERMISSION);
126: }
127:
128:
139: public static String unquote(String str) throws MalformedURLException
140: {
141: if (str == null)
142: return null;
143:
144: final int MAX_BYTES_PER_UTF_8_CHAR = 3;
145: byte[] buf = new byte[str.length()*MAX_BYTES_PER_UTF_8_CHAR];
146: int pos = 0;
147: for (int i = 0; i < str.length(); i++)
148: {
149: char c = str.charAt(i);
150: if (c == '%')
151: {
152: if (i + 2 >= str.length())
153: throw new MalformedURLException(str + " : Invalid quoted character");
154: int hi = Character.digit(str.charAt(++i), 16);
155: int lo = Character.digit(str.charAt(++i), 16);
156: if (lo < 0 || hi < 0)
157: throw new MalformedURLException(str + " : Invalid quoted character");
158: buf[pos++] = (byte) (hi * 16 + lo);
159: }
160: else if (c > 127) {
161: try {
162: byte [] c_as_bytes = Character.toString(c).getBytes("utf-8");
163: final int c_length = c_as_bytes.length;
164: System.arraycopy(c_as_bytes, 0, buf, pos, c_length);
165: pos += c_length;
166: }
167: catch (java.io.UnsupportedEncodingException x2) {
168: throw (Error) new InternalError().initCause(x2);
169: }
170: }
171: else
172: buf[pos++] = (byte) c;
173: }
174: try
175: {
176: return new String(buf, 0, pos, "utf-8");
177: }
178: catch (java.io.UnsupportedEncodingException x2)
179: {
180: throw (Error) new InternalError().initCause(x2);
181: }
182: }
183:
184:
187: public void connect() throws IOException
188: {
189:
190: if (connected)
191: return;
192:
193:
194: file = new File (unquote(getURL().getFile()));
195:
196: if (! file.isDirectory())
197: {
198: if (doInput)
199: inputStream = new BufferedInputStream(new FileInputStream(file));
200:
201: if (doOutput)
202: outputStream = new BufferedOutputStream(new FileOutputStream(file));
203: }
204: else
205: {
206: if (doInput)
207: {
208: inputStream = new ByteArrayInputStream(getDirectoryListing());
209: }
210:
211: if (doOutput)
212: throw new ProtocolException
213: ("file: protocol does not support output on directories");
214: }
215:
216: connected = true;
217: }
218:
219:
223: byte[] getDirectoryListing()
224: throws IOException
225: {
226: if (directoryListing == null)
227: {
228: ByteArrayOutputStream sink = new ByteArrayOutputStream();
229:
230: Writer writer = new OutputStreamWriter(sink);
231:
232: String[] files = file.list();
233:
234: for (int i = 0; i < files.length; i++)
235: {
236: writer.write(files[i]);
237: writer.write(StaticData.lineSeparator);
238: }
239:
240: directoryListing = sink.toByteArray();
241: }
242: return directoryListing;
243: }
244:
245:
252: public InputStream getInputStream()
253: throws IOException
254: {
255: if (!doInput)
256: throw new ProtocolException("Can't open InputStream if doInput is false");
257:
258: if (!connected)
259: connect();
260:
261: return inputStream;
262: }
263:
264:
271: public OutputStream getOutputStream()
272: throws IOException
273: {
274: if (!doOutput)
275: throw new
276: ProtocolException("Can't open OutputStream if doOutput is false");
277:
278: if (!connected)
279: connect();
280:
281: return outputStream;
282: }
283:
284:
289: public long getLastModified()
290: {
291: try
292: {
293: if (!connected)
294: connect();
295:
296: return file.lastModified();
297: }
298: catch (IOException e)
299: {
300: return -1;
301: }
302: }
303:
304:
307: public String getHeaderField(String field)
308: {
309: try
310: {
311: if (!connected)
312: connect();
313:
314: if (field.equals("content-type"))
315: return guessContentTypeFromName(file.getName());
316: else if (field.equals("content-length"))
317: {
318: if (file.isDirectory())
319: {
320: return Integer.toString(getContentLength());
321: }
322: return Long.toString(file.length());
323: }
324: else if (field.equals("last-modified"))
325: {
326: synchronized (StaticData.dateFormat)
327: {
328: return StaticData.dateFormat.format(
329: new Date(file.lastModified()));
330: }
331: }
332: }
333: catch (IOException e)
334: {
335:
336: }
337: return null;
338: }
339:
340:
345: public int getContentLength()
346: {
347: try
348: {
349: if (!connected)
350: connect();
351:
352: if (file.isDirectory())
353: {
354: return getDirectoryListing().length;
355: }
356: return (int) file.length();
357: }
358: catch (IOException e)
359: {
360: return -1;
361: }
362: }
363:
364:
372: public Permission getPermission() throws IOException
373: {
374: return permission;
375: }
376: }