multi languages support
[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.logging.Level;
13 import java.util.logging.Logger;
14
15 import javax.servlet.ServletConfig;
16 import javax.servlet.ServletException;
17 import javax.servlet.http.HttpServlet;
18 import javax.servlet.http.HttpServletRequest;
19 import javax.servlet.http.HttpServletResponse;
20
21 import com.rometools.rome.io.FeedException;
22
23 import pnews.Article;
24 import pnews.Category;
25
26 public class Pnews extends HttpServlet {
27         private static final String CLASS_NAME = Pnews.class.getName();
28         private static final Logger LOG = Logger.getLogger(Pnews.class.getName());
29         private static final long serialVersionUID = 1L;
30         private ArticleProvider provider;
31         private Config config;
32
33         private static String getQueryParameter(HttpServletRequest rq, String key)
34                         throws UnsupportedEncodingException {
35                 final String METHOD_NAME="getQueryParameter";                
36                 String[] params;
37                 int idx;
38                 String q;
39                 
40                 
41                 LOG.entering(CLASS_NAME, METHOD_NAME, new Object[] { rq, key} );
42
43                 q = rq.getQueryString();
44
45                 if (q == null)
46                         return null;
47
48                 params = q.split("&");
49
50                 for (String p: params) {
51                         idx = p.indexOf('=');
52
53                         if (idx > 1 && p.substring(0, idx).equals(key))
54                                 return URLDecoder.decode(p.substring(idx + 1), "UTF-8");
55                 }
56
57                 return null;
58         }
59
60         private static void redirect(HttpServletRequest rq, HttpServletResponse rp) {
61                 String redirectURL;
62                 Article a;
63
64                 LOG.entering(Pnews.class.getName(), "redirect", new Object[] { rq, rp });
65
66                 try {
67                         redirectURL = getQueryParameter(rq, "url");
68
69                         LOG.info("Request redirection to " + redirectURL);
70
71                         if (redirectURL != null) {
72                                 a = ArticleStore.singleton.get(redirectURL);
73                                 if (a != null)
74                                         a.readCount.incrementAndGet();
75                                 else
76                                         LOG.severe("Cannot find the article " + redirectURL);
77                                 
78                                 rp.setHeader("Location", redirectURL);
79                                 rp.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
80                         } else {
81                                 LOG.severe("No redirection URL");
82                                 rp.setStatus(HttpServletResponse.SC_NOT_FOUND);
83                         }
84
85                 } catch (UnsupportedEncodingException e) {
86                         e.printStackTrace();
87                         LOG.log(Level.SEVERE, "redirect failure", e);
88                         rp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
89                 }
90
91                 LOG.exiting(Pnews.class.getName(), "redirect");
92         }
93         
94         private static void doTemporaryRedirect(String newURL, HttpServletResponse rp) {
95                 rp.setHeader("Location", newURL);
96                 rp.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);             
97         }
98
99         private void writeStats(HttpServletResponse rp) throws IOException {
100                 rp.setContentType("application/json;charset=utf-8");
101                 rp.setCharacterEncoding("utf-8");
102
103                 rp.getWriter().write(JSON.getStats(config.getCategories()));
104         }
105
106         
107         private void writeArticles(Category cat, HttpServletResponse rp) {
108                 String html;
109                 List<Article> articles;
110
111                 try {
112                         articles = provider.getArticles(cat);
113                         if (articles != null) {
114                                 html = HTML.toHTML(articles, cat, config.getCategories());
115                                 rp.setContentType("text/html;charset=utf-8");
116                                 rp.getWriter().write(html);
117                                 rp.setCharacterEncoding("utf-8");
118                         } else {
119                                 LOG.severe("writeArticles cannot retrieve any articles");
120                                 html = HTML.toHTML(new ArrayList<Article>(), cat, config.getCategories());
121                                 rp.setContentType("text/html");
122                                 rp.getWriter().write(html);
123                         }
124                 } catch (IOException | IllegalArgumentException | FeedException e) {
125                         LOG.log(Level.SEVERE, "writeArticles failure", e);
126                         rp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
127                 }
128         }
129
130         private void copy(InputStream in, Writer writer) throws IOException {
131                 Reader r;
132                 char[] buf;
133                 int n;
134
135                 buf = new char[1024];
136                 r = new InputStreamReader(in);
137                 while ( (n = r.read(buf, 0, buf.length)) != -1)
138                         writer.write(buf, 0, n);
139         }
140
141         @Override
142         protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
143                 final String METHOD_NAME = "doGet";
144                 String path;
145                 InputStream in;
146
147                 RequesterLog.singleton.writeRequest(req);
148               
149                 LOG.info("doGet " + req.getRemoteAddr().toString() + " " + req.getRequestURI() + " " + req.getQueryString());
150                                 
151                 LOG.info(METHOD_NAME + " queryString=" + req.getQueryString());
152                 
153                 path = req.getPathInfo();
154
155                 if (path.equals("/redirect")) {
156                         redirect(req, resp);
157                         return ;
158                 }
159
160                 if (path.equals("/style.css")) {
161                         try {
162                                 in = HTML.class.getClassLoader().getResourceAsStream("style.css");
163                                 copy(in, resp.getWriter());
164                                 resp.setContentType("text/css");
165
166                                 return ;
167                         } catch (IOException e) {
168                                 LOG.log(Level.SEVERE, "doGet failure", e);
169                                 resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
170
171                                 return ;
172                         }
173                 }
174
175                 if (path.equals("/")) {
176                         writeArticles(config.getDefaultCategory(), resp);
177                         return ;
178                 }
179
180                 try {
181                         if (path.equals("/stats")) {
182                                 writeStats(resp);
183                                 return ;
184                         }
185                 
186                         for (Category cat: config.getCategories()) {
187                                 if (path.equals(cat.getURL())) {
188                                         writeArticles(cat, resp);
189                                         return ;
190                                 }
191                         }
192                         
193                         for (String l: config.getLanguages()) {
194                                 if (path.equals("/" + l) || path.equals("/" + l + "/")) {
195                                         doTemporaryRedirect(config.getDefaultCategory().getURL(), resp);
196                                         return ;
197                                 }
198                         }
199                 
200                         resp.getWriter().write("Not found " + req.getPathInfo());
201                         resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
202                 } catch (IOException e) {
203                         LOG.log(Level.SEVERE, "doGet failure", e);
204                         resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
205                 }
206         }
207
208         @Override
209         public void init(ServletConfig cfg) throws ServletException {
210                 LOG.info("Pnews servlet init " + cfg.getServletContext().getContextPath());
211                 
212                 config = new Config();
213                 try {
214                         config.loadConfig();
215                 } catch (UnsupportedEncodingException e) {
216                         throw new ServletException(e);
217                 }
218                 
219                 provider = new ArticleProvider(config);
220         }
221 }