/* * Copyright 2012 Axel Winkler, Daniel Dunér * * This file is part of Daxplore Presenter. * * Daxplore Presenter is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. * * Daxplore Presenter is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Daxplore Presenter. If not, see <http://www.gnu.org/licenses/>. */ package org.daxplore.presenter.server.servlets; import java.io.IOException; import java.io.PrintWriter; import java.io.StringReader; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import javax.jdo.PersistenceManager; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.daxplore.presenter.server.storage.LocaleStore; import org.daxplore.presenter.server.storage.PMF; import org.daxplore.presenter.server.storage.QuestionMetadataServerImpl; import org.daxplore.presenter.server.storage.StatDataItemStore; import org.daxplore.presenter.server.storage.TextFileStore; import org.daxplore.presenter.server.throwable.BadRequestException; import org.daxplore.presenter.server.throwable.InternalServerException; import org.daxplore.presenter.shared.QueryDefinition; import org.daxplore.presenter.shared.QuestionMetadata; import org.daxplore.shared.SharedResourceTools; /** * The {@linkplain GetStatsServlet} serves StatDataItem data. * * <p>The data is sent on requests made by Daxplore clients. The data is sent * as a json-serialized StatDataItem.</p> * * <p>The servlet takes the arguments: * <ul> * <li>q, which is a queryString that defines the query for which data * should be returned</li> * <li>prefix, which defines which prefix to read the data from</li> * </ul> * </p> */ @SuppressWarnings("serial") public class GetStatsServlet extends HttpServlet { private static Logger logger = Logger.getLogger(GetStatsServlet.class.getName()); private static Map<String, QuestionMetadata> metadataPrefixMap = new HashMap<>(); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) { PersistenceManager pm = null; try { pm = PMF.get().getPersistenceManager(); String prefix = request.getParameter("prefix"); if(!SharedResourceTools.isSyntacticallyValidPrefix(prefix)){ throw new BadRequestException("Request made with syntactically invalid prefix: '" + prefix + "'"); } if (!metadataPrefixMap.containsKey(prefix)) { LocaleStore localeStore = pm.getObjectById(LocaleStore.class, prefix); //it shouldn't matter what locale we use here, as we don't read any localized data String questionText = TextFileStore.getLocalizedFile(pm, prefix, "questions", localeStore.getDefaultLocale(), ".json"); metadataPrefixMap.put(prefix, new QuestionMetadataServerImpl(new StringReader(questionText))); } String queryString = request.getParameter("q"); QueryDefinition queryDefinition = new QueryDefinition(metadataPrefixMap.get(prefix), queryString); response.setContentType("text/html; charset=UTF-8"); try (PrintWriter respWriter = response.getWriter()) { respWriter.write(StatDataItemStore.getStats(pm, prefix, queryDefinition)); respWriter.close(); } catch (IOException e) { throw new InternalServerException("Failed to write response", e); } response.setStatus(HttpServletResponse.SC_OK); } catch (BadRequestException e) { logger.log(Level.WARNING, e.getMessage(), e); response.setStatus(HttpServletResponse.SC_BAD_REQUEST); } catch (InternalServerException e) { logger.log(Level.SEVERE, e.getMessage(), e); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } catch (Exception e) { logger.log(Level.SEVERE, "Unexpected exception: " + e.getMessage(), e); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); } finally { if (pm!=null) { pm.close(); } } } public static void clearServletCache(String prefix) { metadataPrefixMap.remove(prefix); } }