001: /*
002: * Copyright 1995-2004 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: /**
027: * Open an file input stream given a URL.
028: * @author James Gosling
029: * @author Steven B. Byrne
030: * @version 1.65, 05/05/07
031: */package sun.net.www.protocol.file;
032:
033: import java.net.URL;
034: import java.net.FileNameMap;
035: import java.io.*;
036: import java.text.Collator;
037: import java.security.Permission;
038: import sun.net.*;
039: import sun.net.www.*;
040: import java.util.*;
041: import java.text.SimpleDateFormat;
042:
043: import sun.security.action.GetPropertyAction;
044: import sun.security.action.GetIntegerAction;
045: import sun.security.action.GetBooleanAction;
046:
047: public class FileURLConnection extends URLConnection {
048:
049: static String CONTENT_LENGTH = "content-length";
050: static String CONTENT_TYPE = "content-type";
051: static String TEXT_PLAIN = "text/plain";
052: static String LAST_MODIFIED = "last-modified";
053:
054: String contentType;
055: InputStream is;
056:
057: File file;
058: String filename;
059: boolean isDirectory = false;
060: boolean exists = false;
061: List files;
062:
063: long length = -1;
064: long lastModified = 0;
065:
066: protected FileURLConnection(URL u, File file) {
067: super (u);
068: this .file = file;
069: }
070:
071: /*
072: * Note: the semantics of FileURLConnection object is that the
073: * results of the various URLConnection calls, such as
074: * getContentType, getInputStream or getContentLength reflect
075: * whatever was true when connect was called.
076: */
077: public void connect() throws IOException {
078: if (!connected) {
079: try {
080: filename = file.toString();
081: isDirectory = file.isDirectory();
082: if (isDirectory) {
083: files = (List) Arrays.asList(file.list());
084: } else {
085:
086: is = new BufferedInputStream(new FileInputStream(
087: filename));
088:
089: // Check if URL should be metered
090: boolean meteredInput = ProgressMonitor.getDefault()
091: .shouldMeterInput(url, "GET");
092: if (meteredInput) {
093: ProgressSource pi = new ProgressSource(url,
094: "GET", (int) file.length());
095: is = new MeteredStream(is, pi, (int) file
096: .length());
097: }
098: }
099: } catch (IOException e) {
100: throw e;
101: }
102: connected = true;
103: }
104: }
105:
106: private boolean initializedHeaders = false;
107:
108: private void initializeHeaders() {
109: try {
110: connect();
111: exists = file.exists();
112: } catch (IOException e) {
113: }
114: if (!initializedHeaders || !exists) {
115: length = file.length();
116: lastModified = file.lastModified();
117:
118: if (!isDirectory) {
119: FileNameMap map = java.net.URLConnection
120: .getFileNameMap();
121: contentType = map.getContentTypeFor(filename);
122: if (contentType != null) {
123: properties.add(CONTENT_TYPE, contentType);
124: }
125: properties.add(CONTENT_LENGTH, String.valueOf(length));
126:
127: /*
128: * Format the last-modified field into the preferred
129: * Internet standard - ie: fixed-length subset of that
130: * defined by RFC 1123
131: */
132: if (lastModified != 0) {
133: Date date = new Date(lastModified);
134: SimpleDateFormat fo = new SimpleDateFormat(
135: "EEE, dd MMM yyyy HH:mm:ss 'GMT'",
136: Locale.US);
137: fo.setTimeZone(TimeZone.getTimeZone("GMT"));
138: properties.add(LAST_MODIFIED, fo.format(date));
139: }
140: } else {
141: properties.add(CONTENT_TYPE, TEXT_PLAIN);
142: }
143: initializedHeaders = true;
144: }
145: }
146:
147: public String getHeaderField(String name) {
148: initializeHeaders();
149: return super .getHeaderField(name);
150: }
151:
152: public String getHeaderField(int n) {
153: initializeHeaders();
154: return super .getHeaderField(n);
155: }
156:
157: public int getContentLength() {
158: initializeHeaders();
159: return (int) length;
160: }
161:
162: public String getHeaderFieldKey(int n) {
163: initializeHeaders();
164: return super .getHeaderFieldKey(n);
165: }
166:
167: public MessageHeader getProperties() {
168: initializeHeaders();
169: return super .getProperties();
170: }
171:
172: public long getLastModified() {
173: initializeHeaders();
174: return lastModified;
175: }
176:
177: public synchronized InputStream getInputStream() throws IOException {
178:
179: int iconHeight;
180: int iconWidth;
181:
182: connect();
183:
184: if (is == null) {
185: if (isDirectory) {
186: FileNameMap map = java.net.URLConnection
187: .getFileNameMap();
188:
189: StringBuffer buf = new StringBuffer();
190:
191: if (files == null) {
192: throw new FileNotFoundException(filename);
193: }
194:
195: Collections.sort(files, Collator.getInstance());
196:
197: for (int i = 0; i < files.size(); i++) {
198: String fileName = (String) files.get(i);
199: buf.append(fileName);
200: buf.append("\n");
201: }
202: // Put it into a (default) locale-specific byte-stream.
203: is = new ByteArrayInputStream(buf.toString().getBytes());
204: } else {
205: throw new FileNotFoundException(filename);
206: }
207: }
208: return is;
209: }
210:
211: Permission permission;
212:
213: /* since getOutputStream isn't supported, only read permission is
214: * relevant
215: */
216: public Permission getPermission() throws IOException {
217: if (permission == null) {
218: String decodedPath = ParseUtil.decode(url.getPath());
219: if (File.separatorChar == '/') {
220: permission = new FilePermission(decodedPath, "read");
221: } else {
222: permission = new FilePermission(decodedPath.replace(
223: '/', File.separatorChar), "read");
224: }
225: }
226: return permission;
227: }
228: }
|