KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > system > url > file > FileURLConnection


1 /**
2  *
3  * Copyright 2004 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.geronimo.system.url.file;
19
20 import java.io.BufferedInputStream JavaDoc;
21 import java.io.BufferedOutputStream JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.FileDescriptor JavaDoc;
24 import java.io.FileInputStream JavaDoc;
25 import java.io.FileNotFoundException JavaDoc;
26 import java.io.FileOutputStream JavaDoc;
27 import java.io.FilePermission JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.InputStream JavaDoc;
30 import java.io.OutputStream JavaDoc;
31 import java.io.SyncFailedException JavaDoc;
32 import java.net.MalformedURLException JavaDoc;
33 import java.net.URL JavaDoc;
34 import java.net.URLConnection JavaDoc;
35 import java.security.Permission JavaDoc;
36 import java.util.ArrayList JavaDoc;
37 import java.util.Collections JavaDoc;
38 import java.util.HashMap JavaDoc;
39 import java.util.List JavaDoc;
40 import java.util.Map JavaDoc;
41
42 import sun.net.www.ParseUtil;
43
44 /**
45  * A URLConnection for the 'file' protocol.
46  *
47  * <p>Correctly returns headers.
48  *
49  * @version $Rev: 46019 $ $Date: 2004-09-14 02:56:06 -0700 (Tue, 14 Sep 2004) $
50  */

51 public class FileURLConnection extends URLConnection JavaDoc {
52     private static final boolean IS_OS_WINDOWS = System.getProperty("os.name").startsWith("Windows");
53     private File JavaDoc file;
54     private FileDescriptor JavaDoc fd;
55
56     public FileURLConnection(final URL JavaDoc url, final File JavaDoc file) throws MalformedURLException JavaDoc, IOException JavaDoc {
57         super(url);
58
59         if (file == null) {
60             throw new IllegalArgumentException JavaDoc("file is null");
61         }
62
63         this.file = file;
64     }
65
66     public File JavaDoc getFile() {
67         return file;
68     }
69
70     public void connect() throws IOException JavaDoc {
71         if (connected) {
72             return;
73         }
74
75         if (!file.exists()) {
76             throw new FileNotFoundException JavaDoc(file.toString());
77         }
78
79         connected = true;
80     }
81
82     /**
83      * Return the input stream for the file.
84      *
85      * <p>Sun's URL connections use buffered streams, so we do too.
86      *
87      * <p>This impl will return a new stream for each call.
88      */

89     public InputStream JavaDoc getInputStream() throws IOException JavaDoc {
90         if (!connected) {
91             connect();
92         }
93
94         FileInputStream JavaDoc fis = new FileInputStream JavaDoc(file);
95         fd = fis.getFD();
96
97         return new BufferedInputStream JavaDoc(fis);
98     }
99
100     /**
101      * Return the output stream for the file.
102      *
103      * <p>Sun's URL connections use buffered streams, so we do too.
104      *
105      * <p>This impl will return a new stream for each call.
106      */

107     public OutputStream JavaDoc getOutputStream() throws IOException JavaDoc {
108         if (!connected) {
109             connect();
110         }
111
112         FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(file);
113         fd = fos.getFD();
114
115         return new BufferedOutputStream JavaDoc(fos);
116     }
117
118     /**
119      * Return the permission for the file.
120      *
121      * <p>Sun's impl always returns "read", but no reason why we can
122      * not also write to a file URL, so we do.
123      */

124     public Permission JavaDoc getPermission() throws IOException JavaDoc {
125         // Detect if we have read/write perms
126
String JavaDoc perms = null;
127
128         if (file.canRead()) {
129             perms = "read";
130         }
131         if (file.canWrite()) {
132             if (perms != null) {
133                 perms += ",write";
134             } else {
135                 perms = "write";
136             }
137         }
138
139         // File perms need filename to be in system format
140
String JavaDoc filename = ParseUtil.decode(url.getPath());
141         if (File.separatorChar != '/') {
142             filename.replace('/', File.separatorChar);
143         }
144
145         return new FilePermission JavaDoc(filename, perms);
146     }
147
148     /**
149      * Conditionaly sync the underlying file descriptor if we are running
150      * on windows, so that the file details update.
151      */

152     private void maybeSync() {
153         if (fd != null && fd.valid()) {
154             if (IS_OS_WINDOWS) {
155                 try {
156                     fd.sync();
157                 } catch (SyncFailedException JavaDoc e) {
158                     // ignore... data may be a bit out of sync but who cares?
159
}
160             }
161         }
162     }
163
164     /**
165      * Always return the last-modified from the file.
166      *
167      * <p>NOTE: Sun's impl caches this value, so it will appear to never change
168      * even if the underlying file's last-modified has changed.
169      */

170     public long getLastModified() {
171         maybeSync();
172         return file.lastModified();
173     }
174
175     /**
176      * Returns the last modified time of the file.
177      */

178     public long getDate() {
179         return getLastModified();
180     }
181
182     /**
183      * Returns the length of the file.
184      *
185      */

186     public int getContentLength() {
187         maybeSync();
188
189         final long value = file.length();
190         if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE) {
191             throw new IllegalStateException JavaDoc("Can not safly convert to int: " + value);
192         }
193
194         return (int) value;
195     }
196
197     /**
198      * Returns the content type of the file as mapped by the filename map.
199      */

200     public String JavaDoc getContentType() {
201         return getFileNameMap().getContentTypeFor(file.getName());
202     }
203
204
205     /////////////////////////////////////////////////////////////////////////
206
// Headers //
207
/////////////////////////////////////////////////////////////////////////
208

209     /**
210      * Get a header field by name.
211      *
212      * <p>Supported headers:
213      * <ul>
214      * <li>last-modified
215      * <li>content-length
216      * <li>content-type
217      * <li>date
218      * </ul>
219      *
220      * <p>Hook into our local methods to get headers. URLConnection
221      * normally goes the other way around. ie. URLConnection.getDate()
222      * calls getHeaderField('date'), but for file usage this is wasteful
223      * string creation as normally the getHeaderField() will not be called.
224      */

225     public String JavaDoc getHeaderField(final String JavaDoc name) {
226         if (name == null) {
227             throw new IllegalArgumentException JavaDoc("name is null");
228         }
229
230         String JavaDoc headerName = name.toLowerCase();
231
232         if (headerName.equals("last-modified")) {
233             return String.valueOf(getLastModified());
234         } else if (headerName.equals("content-length")) {
235             return String.valueOf(getContentLength());
236         } else if (headerName.equals("content-type")) {
237             return getContentType();
238         } else if (headerName.equals("date")) {
239             return String.valueOf(getDate());
240         }
241
242         return super.getHeaderField(name);
243     }
244
245     /**
246      * Returns supported headers.
247      *
248      * @see #getHeaderField(java.lang.String)
249      */

250     public Map JavaDoc getHeaderFields() {
251         Map JavaDoc headers = new HashMap JavaDoc();
252         String JavaDoc[] headerNames = {
253             "last-modified",
254             "content-length",
255             "content-type",
256             "date"
257         };
258
259         for (int i = 0; i < headerNames.length; i++) {
260             List JavaDoc list = new ArrayList JavaDoc(1);
261             list.add(getHeaderField(headerNames[i]));
262             headers.put(headerNames[i], Collections.unmodifiableList(list));
263         }
264
265         return Collections.unmodifiableMap(headers);
266     }
267
268     //
269
// TODO: implement these... no one uses these so who cares?
270
//
271

272     public String JavaDoc getHeaderFieldKey(final int n) {
273         return getHeaderFieldKey(n);
274     }
275
276     public String JavaDoc getHeaderField(final int n) {
277         return getHeaderField(n);
278     }
279 }
280
Popular Tags