Added a "directory multiplexer" responder.
[jsvc.git] / src / dolda / jsvc / util / Multiplexer.java
1 package dolda.jsvc.util;
2
3 import dolda.jsvc.*;
4 import java.util.*;
5
6 public class Multiplexer implements Responder {
7     private Responder def;
8     private Collection<Sub> subs = new LinkedList<Sub>();
9
10     private static interface Sub {
11         boolean match(Request req);
12     }
13     
14     public Multiplexer(Responder def) {
15         this.def = def;
16     }
17     
18     public Multiplexer() {
19         this(new SimpleWriter("html") {
20                 public void respond(Request req, java.io.PrintWriter out) {
21                     req.status(404);
22                     out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
23                     out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">");
24                     out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en-US\">");
25                     out.println("<head><title>Resource not found</title></head>");
26                     out.println("<body>");
27                     out.println("<h1>Resource not found</h1>");
28                     out.println("The resource you requested could not be found on this server.");
29                     out.println("</body>");
30                     out.println("</html>");
31                 }
32             });
33     }
34     
35     public void file(final String path, final Responder responder) {
36         subs.add(new Sub() {
37                 public boolean match(Request req) {
38                     if(req.path().equals(path)) {
39                         responder.respond(req);
40                         return(true);
41                     }
42                     return(false);
43                 }
44             });
45     }
46
47     public void dir(String path, final Responder responder) {
48         final String fp = Misc.stripslashes(path, true, true);
49         subs.add(new Sub() {
50                 public boolean match(Request req) {
51                     if(req.path().equals(fp)) {
52                         throw(Restarts.redirect(fp + "/"));
53                     } else if(req.path().startsWith(fp + "/")) {
54                         responder.respond(RequestWrap.chpath(req, req.path().substring(fp.length() + 1)));
55                         return(true);
56                     }
57                     return(false);
58                 }
59             });
60     }
61     
62     public void respond(Request req) {
63         for(Sub s : subs) {
64             if(s.match(req))
65                 return;
66         }
67         def.respond(req);
68     }
69 }