fixed encoding bug
[pnews.git] / war / src / main / java / pnews / servlet / Pnews.java
1 package pnews.servlet;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.io.InputStreamReader;
6 import java.io.Reader;
7 import java.io.UnsupportedEncodingException;
8 import java.io.Writer;
9 import java.net.URLDecoder;
10 import java.util.ArrayList;
11 import java.util.List;
12 import java.util.Locale;
13 import java.util.logging.Level;
14 import java.util.logging.Logger;
15
16 import javax.servlet.ServletConfig;
17 import javax.servlet.ServletException;
18 import javax.servlet.http.HttpServlet;
19 import javax.servlet.http.HttpServletRequest;
20 import javax.servlet.http.HttpServletResponse;
21
22 import com.rometools.rome.io.FeedException;
23
24 import pnews.Article;
25 import pnews.Category;
26 import pnews.HTML;
27
28 public class Pnews extends HttpServlet {
29         private static final Logger LOG = Logger.getLogger(Pnews.class.getName());
30         private static final long serialVersionUID = 1L;
31         private static final ArticleProvider provider = ArticleProvider.singleton;
32
33         private static String getQueryParameter(HttpServletRequest rq, String key)
34                         throws UnsupportedEncodingException {
35                 String[] params;
36                 int idx;
37                 String q;
38
39                 q = rq.getQueryString();
40
41                 if (q == null)
42                         return null;
43
44                 params = URLDecoder.decode(q, "UTF-8").split("&");
45
46                 for (String p: params) {
47                         idx = p.indexOf('=');
48
49                         if (idx > 1 && p.substring(0, idx).equals(key))
50                                 return p.substring(idx + 1);
51                 }
52
53                 return null;
54         }
55
56         private static void redirect(HttpServletRequest rq, HttpServletResponse rp) {
57                 String redirectURL;
58
59                 LOG.entering(Pnews.class.getName(), "redirect");
60
61                 try {
62                         redirectURL = getQueryParameter(rq, "url");
63
64                         LOG.info("Request redirection to " + redirectURL);
65
66                         if (redirectURL != null) {
67                                 rp.setHeader("Location", redirectURL);
68                                 rp.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
69                         } else {
70                                 LOG.severe("No redirection URL");
71                                 rp.setStatus(HttpServletResponse.SC_NOT_FOUND);
72                         }
73
74                 } catch (UnsupportedEncodingException e) {
75                         e.printStackTrace();
76                         LOG.log(Level.SEVERE, "redirect failure", e);
77                         rp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
78                 }
79
80                 LOG.exiting(Pnews.class.getName(), "redirect");
81         }
82
83         private void writeArticles(Category cat, HttpServletResponse rp) {
84                 String html;
85                 List<Article> articles;
86
87                 try {
88                         articles = provider.getArticles(cat);
89                         if (articles != null) {
90                                 html = HTML.toHTML(articles, cat);
91                                 rp.setContentType("text/html;charset=utf-8");
92                                 rp.getWriter().write(html);
93                                 rp.setCharacterEncoding("utf8-8");
94                         } else {
95                                 LOG.severe("writeArticles cannot retrieve any articles");
96                                 html = HTML.toHTML(new ArrayList<Article>(), cat);
97                                 rp.setContentType("text/html");
98                                 rp.getWriter().write(html);
99                         }
100                 } catch (IOException | IllegalArgumentException | FeedException e) {
101                         LOG.log(Level.SEVERE, "writeArticles failure", e);
102                         rp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
103                 }
104         }
105
106         private void copy(InputStream in, Writer writer) throws IOException {
107                 Reader r;
108                 char[] buf;
109                 int n;
110
111                 buf = new char[1024];
112                 r = new InputStreamReader(in);
113                 while ( (n = r.read(buf, 0, buf.length)) != -1)
114                         writer.write(buf, 0, n);
115         }
116
117         @Override
118         protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
119                 String path;
120                 InputStream in;
121
122                 RequesterLog.singleton.writeRequest(req);
123               
124                 LOG.info("doGet " + req.getRemoteAddr().toString() + " " + req.getRequestURI() + " " + req.getQueryString());
125                                 
126                 path = req.getPathInfo();
127
128                 if (path.equals("/redirect")) {
129                         redirect(req, resp);
130                         return ;
131                 }
132
133                 if (path.equals("/style.css")) {
134                         try {
135                                 in = HTML.class.getClassLoader().getResourceAsStream("style.css");
136                                 copy(in, resp.getWriter());
137                                 resp.setContentType("text/css");
138
139                                 return ;
140                         } catch (IOException e) {
141                                 LOG.log(Level.SEVERE, "doGet failure", e);
142                                 resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
143
144                                 return ;
145                         }
146                 }
147
148                 if (path.equals("/")) {
149                         writeArticles(Category.TOP, resp);
150                         return ;
151                 }
152
153                 for (Category cat: Category.values()) {
154                         if (path.equals('/' + cat.getId())) {
155                                 writeArticles(cat, resp);
156                                 return ;
157                         }
158                 }
159
160                 try {
161                         resp.getWriter().write("Not found " + req.getPathInfo());
162                         resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
163                 } catch (IOException e) {
164                         LOG.log(Level.SEVERE, "doGet failure", e);
165                         resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
166                 }
167         }
168
169         @Override
170         public void init(ServletConfig config) throws ServletException {
171                 LOG.info("Pnews servlet init " + config.getServletContext().getContextPath());
172
173         }
174 }