Mercurial Hosting > nabble
comparison src/cachingfilter/FileHandler.java @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:7ecd1a4ef557 |
---|---|
1 package cachingfilter; | |
2 | |
3 import java.io.File; | |
4 import java.io.InputStream; | |
5 import java.io.FileInputStream; | |
6 import java.io.BufferedInputStream; | |
7 import java.io.IOException; | |
8 import java.nio.MappedByteBuffer; | |
9 import java.nio.channels.FileChannel; | |
10 import javax.servlet.ServletOutputStream; | |
11 import org.slf4j.Logger; | |
12 import org.slf4j.LoggerFactory; | |
13 import org.eclipse.jetty.io.nio.DirectNIOBuffer; | |
14 import org.eclipse.jetty.server.AbstractHttpConnection; | |
15 | |
16 | |
17 public abstract class FileHandler { | |
18 abstract void close(); | |
19 abstract InputStream getInputStream(); | |
20 abstract void writeTo(ServletOutputStream out) throws IOException; | |
21 | |
22 public interface Factory { | |
23 public FileHandler newInstance(File file) throws IOException; | |
24 } | |
25 | |
26 private static final Logger logger = LoggerFactory.getLogger(FileHandler.class); | |
27 | |
28 private static abstract class BufferedFactory implements Factory { | |
29 abstract DirectNIOBuffer getDirectNIOBuffer(File file) throws IOException; | |
30 | |
31 public FileHandler newInstance(File file) throws IOException { | |
32 final DirectNIOBuffer fileBuffer = getDirectNIOBuffer(file); | |
33 | |
34 return new FileHandler() { | |
35 | |
36 void close() {} | |
37 | |
38 InputStream getInputStream() { | |
39 return new BufferInputStream(fileBuffer); | |
40 } | |
41 | |
42 void writeTo(ServletOutputStream out) throws IOException { | |
43 if (out instanceof AbstractHttpConnection.Output) { | |
44 logger.trace("sendFileContent using AbstractHttpConnection.Output"); | |
45 ((AbstractHttpConnection.Output)out).sendContent(fileBuffer); | |
46 } else { | |
47 fileBuffer.writeTo(out); | |
48 } | |
49 } | |
50 }; | |
51 } | |
52 } | |
53 | |
54 public static final Factory mappedFile = new BufferedFactory() { | |
55 | |
56 private MappedByteBuffer map(File file) throws IOException { | |
57 FileInputStream fis = new FileInputStream(file); | |
58 try { | |
59 return fis.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, file.length()); | |
60 } finally { | |
61 fis.close(); | |
62 } | |
63 } | |
64 | |
65 DirectNIOBuffer getDirectNIOBuffer(File file) throws IOException { | |
66 return new DirectNIOBuffer(map(file),true); | |
67 } | |
68 | |
69 }; | |
70 | |
71 public static final Factory memFile = new BufferedFactory() { | |
72 | |
73 DirectNIOBuffer getDirectNIOBuffer(File file) throws IOException { | |
74 int len = (int)file.length(); | |
75 DirectNIOBuffer buffer = new DirectNIOBuffer(len); | |
76 InputStream is = new FileInputStream(file); | |
77 buffer.readFrom(is,len); | |
78 is.close(); | |
79 return buffer; | |
80 } | |
81 | |
82 }; | |
83 | |
84 public static final Factory ioFile = new Factory() { | |
85 | |
86 public FileHandler newInstance(File file) throws IOException { | |
87 final InputStream in = new BufferedInputStream(new FileInputStream(file)); | |
88 | |
89 return new FileHandler() { | |
90 | |
91 void close() { | |
92 try { | |
93 in.close(); | |
94 } catch(IOException e) { | |
95 logger.error("",e); | |
96 } | |
97 } | |
98 | |
99 InputStream getInputStream() { | |
100 return in; | |
101 } | |
102 | |
103 void writeTo(ServletOutputStream out) throws IOException { | |
104 byte[] a = new byte[8192]; | |
105 while(true) { | |
106 int n; | |
107 try { | |
108 n = in.read(a); | |
109 } catch(IOException e) { | |
110 throw new RuntimeException(e); | |
111 } | |
112 if( n == -1 ) | |
113 break; | |
114 out.write(a,0,n); | |
115 } | |
116 } | |
117 }; | |
118 } | |
119 | |
120 }; | |
121 | |
122 public static final Factory mappedOrIoFile = new Factory() { | |
123 | |
124 public FileHandler newInstance(File file) throws IOException { | |
125 try { | |
126 return mappedFile.newInstance(file); | |
127 } catch(IOException e) { | |
128 if( !"Operation not permitted".equals(e.getMessage()) ) | |
129 throw e; | |
130 logger.warn("couldn't map "+file+" length="+file.length(),e); | |
131 return ioFile.newInstance(file); | |
132 } | |
133 } | |
134 | |
135 }; | |
136 | |
137 public static Factory factory = mappedFile; // change for other implementations | |
138 } |