Add sort filter to template context factory.
[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.ByteArrayInputStream;
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.InputStreamReader;
25 import java.io.Reader;
26 import java.io.UnsupportedEncodingException;
27 import java.lang.reflect.InvocationTargetException;
28 import java.net.URISyntaxException;
29 import java.util.Comparator;
30 import java.util.Enumeration;
31 import java.util.HashMap;
32 import java.util.Map;
33
34 import javax.servlet.ServletConfig;
35 import javax.servlet.ServletException;
36 import javax.servlet.http.HttpServlet;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.servlet.http.HttpServletResponse;
39
40 import net.pterodactylus.demoscenemusic.data.Artist;
41 import net.pterodactylus.demoscenemusic.page.ServletRequest;
42 import net.pterodactylus.util.io.Closer;
43 import net.pterodactylus.util.io.StreamCopier;
44 import net.pterodactylus.util.template.CollectionSortFilter;
45 import net.pterodactylus.util.template.HtmlFilter;
46 import net.pterodactylus.util.template.ReflectionAccessor;
47 import net.pterodactylus.util.template.Template;
48 import net.pterodactylus.util.template.TemplateContextFactory;
49 import net.pterodactylus.util.template.TemplateParser;
50 import net.pterodactylus.util.web.Header;
51 import net.pterodactylus.util.web.Page;
52 import net.pterodactylus.util.web.Response;
53
54 /**
55  * TODO
56  *
57  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
58  */
59 public class TemplateServlet extends HttpServlet {
60
61         private Core core;
62         private final TemplateContextFactory templateContextFactory = new TemplateContextFactory();
63
64         private final Map<String, Page<ServletRequest>> pages = new HashMap<String, Page<ServletRequest>>();
65
66         //
67         // SERVLET METHODS
68         //
69
70         /**
71          * {@inheritDoc}
72          */
73         @Override
74         public void init(ServletConfig config) throws ServletException {
75                 super.init(config);
76                 core = (Core) config.getServletContext().getAttribute("core");
77
78                 templateContextFactory.addAccessor(Object.class, new ReflectionAccessor());
79
80                 templateContextFactory.addFilter("html", new HtmlFilter());
81                 CollectionSortFilter sortFilter = new CollectionSortFilter();
82                 sortFilter.addComparator(Artist.class, new Comparator<Artist>() {
83
84                         @Override
85                         public int compare(Artist leftArtist, Artist rightArtist) {
86                                 return leftArtist.name().compareToIgnoreCase(rightArtist.name());
87                         }
88
89                 });
90                 templateContextFactory.addFilter("sort", sortFilter);
91
92                 templateContextFactory.addTemplateObject("core", core);
93                 templateContextFactory.addTemplateObject("dataManager", core.getDataManager());
94
95                 for (@SuppressWarnings("rawtypes")
96                 Enumeration parameterNames = config.getInitParameterNames(); parameterNames.hasMoreElements();) {
97                         String pageName = (String) parameterNames.nextElement();
98                         Template template = getTemplate(pageName);
99                         String pageClassName = config.getInitParameter(pageName);
100                         try {
101                                 Class<?> pageClass = Class.forName(pageClassName);
102                                 @SuppressWarnings("unchecked")
103                                 Page<ServletRequest> page = (Page<ServletRequest>) pageClass.getConstructor(Core.class, TemplateContextFactory.class, Template.class).newInstance(core, templateContextFactory, template);
104                                 pages.put(pageName, page);
105                         } catch (ClassNotFoundException cnfe1) {
106                                 cnfe1.printStackTrace();
107                         } catch (IllegalArgumentException iae1) {
108                                 iae1.printStackTrace();
109                         } catch (SecurityException se1) {
110                                 se1.printStackTrace();
111                         } catch (InstantiationException ie1) {
112                                 ie1.printStackTrace();
113                         } catch (IllegalAccessException iae1) {
114                                 iae1.printStackTrace();
115                         } catch (InvocationTargetException ite1) {
116                                 ite1.printStackTrace();
117                         } catch (NoSuchMethodException nsme1) {
118                                 nsme1.printStackTrace();
119                         }
120                 }
121         }
122
123         /**
124          * {@inheritDoc}
125          */
126         @Override
127         protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException {
128                 String path = request.getPathInfo();
129                 if (path.startsWith("/")) {
130                         path = path.substring(1);
131                 }
132                 Page<ServletRequest> page = pages.get(path);
133                 if (page != null) {
134                         ServletRequest servletRequest;
135                         try {
136                                 servletRequest = new ServletRequest(request);
137                         } catch (URISyntaxException use1) {
138                                 throw new IOException("Could not create URI from " + request.getRequestURI(), use1);
139                         }
140                         ByteArrayOutputStream responseOutputBuffer = new ByteArrayOutputStream();
141                         Response response = new Response(responseOutputBuffer);
142                         response = page.handleRequest(servletRequest, response);
143                         for (Header header : response.getHeaders()) {
144                                 for (String value : header) {
145                                         httpServletResponse.addHeader(header.getName(), value);
146                                 }
147                         }
148                         httpServletResponse.setContentType(response.getContentType());
149                         httpServletResponse.setStatus(response.getStatusCode());
150                         StreamCopier.copy(new ByteArrayInputStream(responseOutputBuffer.toByteArray()), httpServletResponse.getOutputStream());
151                         return;
152                 }
153         }
154
155         //
156         // PRIVATE METHODS
157         //
158
159         private Template getTemplate(String pageName) {
160                 InputStream templateInputStream = getClass().getResourceAsStream("/templates/" + pageName);
161                 if (templateInputStream == null) {
162                         return null;
163                 }
164                 Reader templateReader = null;
165                 try {
166                         templateReader = new InputStreamReader(templateInputStream, "UTF-8");
167                         return TemplateParser.parse(templateReader);
168                 } catch (UnsupportedEncodingException uee1) {
169                         /* can not happen. */
170                         throw new RuntimeException("Could not parse templates!", uee1);
171                 } finally {
172                         Closer.close(templateReader);
173                         Closer.close(templateInputStream);
174                 }
175         }
176
177 }