Add servlet that forwards all requests to pages and templates.
[demoscenemusic.git] / src / main / java / net / pterodactylus / demoscenemusic / core / TemplateServlet.java
1 /*
2  * DemosceneMusic - TemplateServlet.java - Copyright © 2012 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package net.pterodactylus.demoscenemusic.core;
19
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.InputStreamReader;
23 import java.io.Reader;
24 import java.io.UnsupportedEncodingException;
25 import java.lang.reflect.InvocationTargetException;
26 import java.net.URISyntaxException;
27 import java.util.Enumeration;
28 import java.util.HashMap;
29 import java.util.Map;
30
31 import javax.servlet.ServletConfig;
32 import javax.servlet.ServletException;
33 import javax.servlet.http.HttpServlet;
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpServletResponse;
36
37 import net.pterodactylus.demoscenemusic.page.ServletRequest;
38 import net.pterodactylus.util.io.Closer;
39 import net.pterodactylus.util.template.Template;
40 import net.pterodactylus.util.template.TemplateContextFactory;
41 import net.pterodactylus.util.template.TemplateParser;
42 import net.pterodactylus.util.web.Header;
43 import net.pterodactylus.util.web.Page;
44 import net.pterodactylus.util.web.Response;
45
46 /**
47  * TODO
48  *
49  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
50  */
51 public class TemplateServlet extends HttpServlet {
52
53         private Core core;
54         private final TemplateContextFactory templateContextFactory = new TemplateContextFactory();
55
56         private final Map<String, Page<ServletRequest>> pages = new HashMap<String, Page<ServletRequest>>();
57
58         //
59         // SERVLET METHODS
60         //
61
62         /**
63          * {@inheritDoc}
64          */
65         @Override
66         public void init(ServletConfig config) throws ServletException {
67                 super.init(config);
68                 core = (Core) config.getServletContext().getAttribute("core");
69
70                 templateContextFactory.addTemplateObject("core", core);
71                 templateContextFactory.addTemplateObject("dataManager", core.getDataManager());
72
73                 for (@SuppressWarnings("rawtypes")
74                 Enumeration parameterNames = config.getInitParameterNames(); parameterNames.hasMoreElements();) {
75                         String pageName = (String) parameterNames.nextElement();
76                         Template template = getTemplate(pageName);
77                         String pageClassName = config.getInitParameter(pageName);
78                         try {
79                                 Class<?> pageClass = Class.forName(pageClassName);
80                                 @SuppressWarnings("unchecked")
81                                 Page<ServletRequest> page = (Page<ServletRequest>) pageClass.getConstructor(Core.class, TemplateContextFactory.class, Template.class).newInstance(core, templateContextFactory, template);
82                                 pages.put(pageName, page);
83                         } catch (ClassNotFoundException cnfe1) {
84                                 cnfe1.printStackTrace();
85                         } catch (IllegalArgumentException iae1) {
86                                 iae1.printStackTrace();
87                         } catch (SecurityException se1) {
88                                 se1.printStackTrace();
89                         } catch (InstantiationException ie1) {
90                                 ie1.printStackTrace();
91                         } catch (IllegalAccessException iae1) {
92                                 iae1.printStackTrace();
93                         } catch (InvocationTargetException ite1) {
94                                 ite1.printStackTrace();
95                         } catch (NoSuchMethodException nsme1) {
96                                 nsme1.printStackTrace();
97                         }
98                 }
99         }
100
101         /**
102          * {@inheritDoc}
103          */
104         @Override
105         protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException {
106                 String path = request.getPathInfo();
107                 if (path.startsWith("/")) {
108                         path = path.substring(1);
109                 }
110                 Page<ServletRequest> page = pages.get(path);
111                 if (page != null) {
112                         ServletRequest servletRequest;
113                         try {
114                                 servletRequest = new ServletRequest(request);
115                         } catch (URISyntaxException use1) {
116                                 throw new IOException("Could not create URI from " + request.getRequestURI(), use1);
117                         }
118                         Response response = new Response(httpServletResponse.getOutputStream());
119                         response = page.handleRequest(servletRequest, response);
120                         for (Header header : response.getHeaders()) {
121                                 for (String value : header) {
122                                         httpServletResponse.addHeader(header.getName(), value);
123                                 }
124                         }
125                         httpServletResponse.setContentType(response.getContentType());
126                         httpServletResponse.setStatus(response.getStatusCode());
127                         return;
128                 }
129         }
130
131         //
132         // PRIVATE METHODS
133         //
134
135         private Template getTemplate(String pageName) {
136                 InputStream templateInputStream = getClass().getResourceAsStream("/templates/" + pageName);
137                 if (templateInputStream == null) {
138                         return null;
139                 }
140                 Reader templateReader = null;
141                 try {
142                         templateReader = new InputStreamReader(templateInputStream, "UTF-8");
143                         return TemplateParser.parse(templateReader);
144                 } catch (UnsupportedEncodingException uee1) {
145                         /* can not happen. */
146                         throw new RuntimeException("Could not parse templates!", uee1);
147                 } finally {
148                         Closer.close(templateReader);
149                         Closer.close(templateInputStream);
150                 }
151         }
152
153 }