2 * DemosceneMusic - TemplateServlet.java - Copyright © 2012 David Roden
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.
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.
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/>.
18 package net.pterodactylus.demoscenemusic.core;
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;
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;
40 import net.pterodactylus.demoscenemusic.data.Artist;
41 import net.pterodactylus.demoscenemusic.data.DefaultGroup;
42 import net.pterodactylus.demoscenemusic.data.DefaultParty;
43 import net.pterodactylus.demoscenemusic.data.Group;
44 import net.pterodactylus.demoscenemusic.data.Party;
45 import net.pterodactylus.demoscenemusic.data.Properties;
46 import net.pterodactylus.demoscenemusic.data.Style;
47 import net.pterodactylus.demoscenemusic.data.Track;
48 import net.pterodactylus.demoscenemusic.data.TrackDerivative;
49 import net.pterodactylus.demoscenemusic.data.User;
50 import net.pterodactylus.demoscenemusic.page.ServletRequest;
51 import net.pterodactylus.demoscenemusic.template.ConciseNumberFilter;
52 import net.pterodactylus.demoscenemusic.template.DurationFilter;
53 import net.pterodactylus.demoscenemusic.template.PropertiesAccessor;
54 import net.pterodactylus.demoscenemusic.template.TrackDerivativeAccessor;
55 import net.pterodactylus.demoscenemusic.template.UserAccessor;
56 import net.pterodactylus.util.io.Closer;
57 import net.pterodactylus.util.io.StreamCopier;
58 import net.pterodactylus.util.template.ClassPathTemplateProvider;
59 import net.pterodactylus.util.template.CollectionSortFilter;
60 import net.pterodactylus.util.template.HtmlFilter;
61 import net.pterodactylus.util.template.MatchFilter;
62 import net.pterodactylus.util.template.ReflectionAccessor;
63 import net.pterodactylus.util.template.RemoveFilter;
64 import net.pterodactylus.util.template.Template;
65 import net.pterodactylus.util.template.TemplateContextFactory;
66 import net.pterodactylus.util.template.TemplateParser;
67 import net.pterodactylus.util.web.Header;
68 import net.pterodactylus.util.web.Page;
69 import net.pterodactylus.util.web.Response;
74 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
76 public class TemplateServlet extends HttpServlet {
80 private final TemplateContextFactory templateContextFactory = new TemplateContextFactory();
82 private final Map<String, Page<ServletRequest>> pages = new HashMap<String, Page<ServletRequest>>();
92 public void init(ServletConfig config) throws ServletException {
94 core = (Core) config.getServletContext().getAttribute("core");
96 templateContextFactory.addAccessor(Object.class, new ReflectionAccessor());
97 templateContextFactory.addAccessor(User.class, new UserAccessor());
98 templateContextFactory.addAccessor(Properties.class, new PropertiesAccessor());
99 templateContextFactory.addAccessor(TrackDerivative.class, new TrackDerivativeAccessor());
101 templateContextFactory.addFilter("html", new HtmlFilter());
102 CollectionSortFilter sortFilter = new CollectionSortFilter();
103 sortFilter.addComparator(Artist.class, new Comparator<Artist>() {
106 public int compare(Artist leftArtist, Artist rightArtist) {
107 return leftArtist.getName().compareToIgnoreCase(rightArtist.getName());
111 sortFilter.addComparator(Track.class, new Comparator<Track>() {
114 public int compare(Track leftTrack, Track rightTrack) {
115 return leftTrack.getName().compareToIgnoreCase(rightTrack.getName());
119 sortFilter.addComparator(Style.class, new Comparator<Style>() {
122 public int compare(Style leftStyle, Style rightStyle) {
123 return leftStyle.getName().compareToIgnoreCase(rightStyle.getName());
127 sortFilter.addComparator(Party.class, DefaultParty.NAME_YEAR_COMPARATOR);
128 sortFilter.addComparator(Group.class, DefaultGroup.NAME_COMPARATOR);
129 templateContextFactory.addFilter("sort", sortFilter);
130 templateContextFactory.addFilter("matches", new MatchFilter());
131 templateContextFactory.addFilter("time", new DurationFilter());
132 templateContextFactory.addFilter("concise", new ConciseNumberFilter());
133 templateContextFactory.addFilter("remove", new RemoveFilter());
135 templateContextFactory.addTemplateObject("core", core);
136 templateContextFactory.addTemplateObject("dataManager", core.getDataManager());
138 templateContextFactory.addProvider(new ClassPathTemplateProvider(getClass(), "/templates/"));
140 for (@SuppressWarnings("rawtypes")
141 Enumeration parameterNames = config.getInitParameterNames(); parameterNames.hasMoreElements();) {
142 String pageName = (String) parameterNames.nextElement();
143 Template template = getTemplate(pageName);
144 String pageClassName = config.getInitParameter(pageName);
146 Class<?> pageClass = Class.forName(pageClassName);
147 @SuppressWarnings("unchecked")
148 Page<ServletRequest> page = (Page<ServletRequest>) pageClass.getConstructor(Core.class, TemplateContextFactory.class, Template.class).newInstance(core, templateContextFactory, template);
149 pages.put(pageName, page);
150 } catch (ClassNotFoundException cnfe1) {
151 cnfe1.printStackTrace();
152 } catch (IllegalArgumentException iae1) {
153 iae1.printStackTrace();
154 } catch (SecurityException se1) {
155 se1.printStackTrace();
156 } catch (InstantiationException ie1) {
157 ie1.printStackTrace();
158 } catch (IllegalAccessException iae1) {
159 iae1.printStackTrace();
160 } catch (InvocationTargetException ite1) {
161 ite1.printStackTrace();
162 } catch (NoSuchMethodException nsme1) {
163 nsme1.printStackTrace();
172 protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException {
173 request.setCharacterEncoding("UTF-8");
174 String path = request.getPathInfo();
175 if (path.startsWith("/")) {
176 path = path.substring(1);
178 if ((path.length() == 0) || (path.endsWith("/"))) {
181 Page<ServletRequest> page = pages.get(path);
183 ServletRequest servletRequest;
185 servletRequest = new ServletRequest(request, this);
186 } catch (URISyntaxException use1) {
187 throw new IOException("Could not create URI from " + request.getRequestURI(), use1);
189 ByteArrayOutputStream responseOutputBuffer = new ByteArrayOutputStream();
190 Response response = new Response(responseOutputBuffer);
191 response = page.handleRequest(servletRequest, response);
192 for (Header header : response.getHeaders()) {
193 for (String value : header) {
194 httpServletResponse.addHeader(header.getName(), value);
197 httpServletResponse.setContentType(response.getContentType());
198 httpServletResponse.setStatus(response.getStatusCode());
199 StreamCopier.copy(new ByteArrayInputStream(responseOutputBuffer.toByteArray()), httpServletResponse.getOutputStream());
208 protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
209 doGet(httpServletRequest, httpServletResponse);
216 private Template getTemplate(String pageName) {
217 InputStream templateInputStream = getClass().getResourceAsStream("/templates/" + pageName);
218 if (templateInputStream == null) {
221 Reader templateReader = null;
223 templateReader = new InputStreamReader(templateInputStream, "UTF-8");
224 return TemplateParser.parse(templateReader);
225 } catch (UnsupportedEncodingException uee1) {
226 /* can not happen. */
227 throw new RuntimeException("Could not parse templates!", uee1);
229 Closer.close(templateReader);
230 Closer.close(templateInputStream);