00001
package com.quadcap.http.servlets.file;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
import java.io.File;
00042
import java.io.FileInputStream;
00043
import java.io.FileNotFoundException;
00044
import java.io.InputStream;
00045
import java.io.IOException;
00046
import java.io.OutputStream;
00047
00048
import java.net.URL;
00049
import java.net.URLConnection;
00050
00051
import javax.servlet.ServletContext;
00052
00053
import javax.servlet.http.HttpServletRequest;
00054
import javax.servlet.http.HttpServletResponse;
00055
00056
import com.quadcap.util.collections.Cacheable;
00057
00058
import com.quadcap.io.IO;
00059
00060
import com.quadcap.io.dir.Directory;
00061
import com.quadcap.io.dir.Entry;
00062
00063
import com.quadcap.util.Debug;
00064
import com.quadcap.util.Util;
00065
00066
00067
00068
00069
00070
00071 public class HttpFile extends Cacheable {
00072 ServletContext
context;
00073 String
contentType =
"text/plain";
00074 File
file;
00075 URL
url;
00076 long lastMod;
00077 long lastCheck = -1;
00078 byte[]
buf = null;
00079
00080 static int MAX_CACHED = 16 * 1024;
00081
00082
00083
00084
00085 public HttpFile() {}
00086
00087 public void init(Object store, Object key)
throws IOException {
00088 super.init(store, key);
00089
FileServlet fs = (
FileServlet)store;
00090
this.context = fs.getServletContext();
00091 String path = key.toString();
00092
this.contentType =
context.getMimeType(path);
00093
this.file =
new File(path);
00094
if (!
file.exists()) {
00095
this.file = null;
00096
this.url = fs.
getURL(path);
00097
if (
url == null) {
00098
throw new FileNotFoundException(
"Not found: " + path);
00099 }
00100 }
00101
compile();
00102 }
00103
00104 public synchronized void compile() throws IOException {
00105
if (
file != null) {
00106
if (!
file.exists()) {
00107
throw new FileNotFoundException(
"Not found: " +
file);
00108 }
00109
if (
file.isDirectory()) {
00110 File g =
new File(
file,
"index.html");
00111
if (g.canRead()) {
00112
file = g;
00113
contentType =
"text/html";
00114 }
else {
00115
throw new FileNotFoundException(
"Not found: " +
file);
00116 }
00117 }
00118
if (
file.canRead() &&
file.length() <
MAX_CACHED) {
00119
buf =
new byte[(
int)
file.length()];
00120 FileInputStream is =
new FileInputStream(
file);
00121
try {
00122
IO.readFully(is,
buf);
00123 } finally {
00124 is.close();
00125 }
00126
this.lastMod =
file.lastModified();
00127 }
else {
00128
buf = null;
00129 }
00130 }
else {
00131 URLConnection conn =
url.openConnection();
00132
long len = conn.getContentLength();
00133
if (len <
MAX_CACHED) {
00134
buf =
new byte[(
int)len];
00135
try {
00136
this.lastMod = conn.getLastModified();
00137 InputStream is = conn.getInputStream();
00138
try {
00139
IO.readFully(is,
buf);
00140 } finally {
00141 is.close();
00142 }
00143 }
catch (IOException e) {
00144
buf = null;
00145
throw e;
00146 }
00147 }
else {
00148
buf = null;
00149 }
00150 }
00151 }
00152
00153 public synchronized void service(HttpServletRequest req,
00154 HttpServletResponse res)
00155
throws IOException
00156 {
00157
00158 res.setContentType(
contentType);
00159
00160 OutputStream os = res.getOutputStream();
00161
00162
if (
buf != null) {
00163 res.setContentLength(
buf.length);
00164
00165 os.write(
buf);
00166
00167 }
else if (
file != null) {
00168 res.setContentLength((
int)
file.length());
00169
try {
00170 FileInputStream is =
new FileInputStream(
file);
00171
try {
00172
IO.copyStream(is, os);
00173 } finally {
00174 is.close();
00175 }
00176 }
catch (FileNotFoundException fe) {
00177 res.sendError(res.SC_NOT_FOUND,
"Not found: " +
00178
file.getName());
00179 }
00180 }
else {
00181 URLConnection conn =
url.openConnection();
00182 res.setContentLength(conn.getContentLength());
00183 InputStream is = conn.getInputStream();
00184
try {
00185
IO.copyStream(is, os);
00186 } finally {
00187 is.close();
00188 }
00189 }
00190
00191 }
00192
00193 public synchronized void checkModified() throws Exception {
00194
long now = System.currentTimeMillis();
00195
if (now -
lastCheck > 2000) {
00196
lastCheck = now;
00197
if (
file != null) {
00198
if (
file.lastModified() >
lastMod) {
00199
compile();
00200 }
00201 }
else {
00202 URLConnection conn =
url.openConnection();
00203
if (conn.getLastModified() >
lastMod) {
00204
compile();
00205 }
00206 }
00207 }
00208 }
00209
00210 public Object
getData() {
00211
return this;
00212 }
00213
00214 public void setData(Object obj) {
00215
throw new RuntimeException(
"not implemented");
00216 }
00217 }