Commits

Vadim Ne. committed b5c5fcb

Task 3. General code improvements, errors, exceptions and empty lists handling.

Comments (0)

Files changed (22)

database-services-api/pom.xml

     <artifactId>database-services-api</artifactId>
     <packaging>jar</packaging>
     <version>1.0</version>
-    <name>Database services API.</name>
+    <name>Database Services API</name>
 
     <dependencies>
         <dependency>
             <artifactId>libngram</artifactId>
             <version>2.2</version>
         </dependency>
+
         <dependency>
             <groupId>gd-internship</groupId>
             <artifactId>libngram-database</artifactId>

database-services-impl/pom.xml

     <artifactId>database-services-impl</artifactId>
     <packaging>jar</packaging>
     <version>1.0</version>
-    <name>Database services implementation.</name>
+    <name>Database Services Implementation</name>
 
     <dependencies>
         <dependency>
             <artifactId>database-services-api</artifactId>
             <version>1.0</version>
         </dependency>
+
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>1.3.2</version>
+        </dependency>
     </dependencies>
 
     <build>

database-services-impl/src/main/java/services/NgramsJdbcReader.java

 import dao.entities.dbTables.Ngram;
 import dao.jdbcDao.JdbcNgramsDao;
 import jdbcUtilities.JdbcH2DataSource;
+import org.apache.commons.lang3.StringUtils;
 import services.enums.DBEnumUtils;
 
-import java.sql.SQLException;
 import java.util.List;
 
 public class NgramsJdbcReader implements NgramsDatabaseReaderInterface {
 
     private final NgramsDao ngramsDao;
 
-    public NgramsJdbcReader() throws SQLException {
+    public NgramsJdbcReader() {
         ngramsDao = new JdbcNgramsDao(JdbcH2DataSource.getDBConnection());
     }
 
 
     @Override
     public List<Ngram> getListOfTenNgrams(int offsetPage, String fieldName) {
-        if (fieldName == null || !DBEnumUtils.isInEnum(fieldName, FieldName.class))
+        if (StringUtils.isEmpty(fieldName) || !DBEnumUtils.isInEnum(fieldName, FieldName.class))
             return null;
 
         if (fieldName.equals(FieldName.name.toString())) {
 
     @Override
     public List<Ngram> getListOfTenNgrams(int offsetPage, String fieldName, String order) {
-        if (fieldName == null || !DBEnumUtils.isInEnum(fieldName, FieldName.class))
+        if (StringUtils.isEmpty(fieldName) || !DBEnumUtils.isInEnum(fieldName, FieldName.class))
             return null;
-        if (order == null || !DBEnumUtils.isInEnum(order, Order.class))
+        if (StringUtils.isEmpty(order) || !DBEnumUtils.isInEnum(order, Order.class))
             return null;
 
         if (fieldName.equals(FieldName.name.toString())) {

database-services-impl/src/main/java/services/WordsJdbcReader.java

 import dao.jdbcDao.JdbcNgramsDao;
 import dao.jdbcDao.JdbcWordsDao;
 import jdbcUtilities.JdbcH2DataSource;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import services.enums.DBEnumUtils;
 
 import java.sql.Connection;
-import java.sql.SQLException;
 import java.util.List;
 
 public class WordsJdbcReader implements WordsDatabaseReaderInterface {
     private final NgramsDao ngramsDao;
     private final Logger logger = LoggerFactory.getLogger(WordsJdbcReader.class);
 
-    public WordsJdbcReader() throws SQLException {
+    public WordsJdbcReader() {
         Connection connection = JdbcH2DataSource.getDBConnection();
 
         wordsDao = new JdbcWordsDao(connection);
 
     @Override
     public List<WordForNgramWithCount> getListOfTenWordsWithCounters(int offsetPage, String ngramData, String partOfWord) {
-        if (offsetPage < 0 || ngramData == null || partOfWord == null) {
+        if (offsetPage < 0 || StringUtils.isEmpty(ngramData) || StringUtils.isEmpty(partOfWord)) {
             return null;
         }
         int ngramId = ngramsDao.getIdForNgram(ngramData);
 
     @Override
     public List<WordForNgramWithCount> getListOfTenWordsWithCounters(int offsetPage, String ngramData, String partOfWord, String fieldName) {
-        if (offsetPage < 0 || ngramData == null || partOfWord == null || fieldName == null || !DBEnumUtils.isInEnum(fieldName, FieldName.class))
+        if (offsetPage < 0 || StringUtils.isEmpty(ngramData) || StringUtils.isEmpty(partOfWord) || StringUtils.isEmpty(fieldName) || !DBEnumUtils.isInEnum(fieldName, FieldName.class))
             return null;
 
         int ngramId = ngramsDao.getIdForNgram(ngramData);
 
     @Override
     public List<WordForNgramWithCount> getListOfTenWordsWithCounters(int offsetPage, String ngramData, String partOfWord, String fieldName, String order) {
-        if (offsetPage < 0 || ngramData == null || partOfWord == null || fieldName == null || !DBEnumUtils.isInEnum(fieldName, FieldName.class))
+        if (offsetPage < 0 || StringUtils.isEmpty(ngramData) || StringUtils.isEmpty(partOfWord) || StringUtils.isEmpty(fieldName) || !DBEnumUtils.isInEnum(fieldName, FieldName.class))
             return null;
-        if (order == null || !DBEnumUtils.isInEnum(order, Order.class))
+        if (StringUtils.isEmpty(order) || !DBEnumUtils.isInEnum(order, Order.class))
             return null;
 
         int ngramId = ngramsDao.getIdForNgram(ngramData);
 
     @Override
     public int getAmountOfWordsWithCountersInDatabase(String ngramData, String partOfWord) {
-        if (ngramData == null || partOfWord == null)
+        if (StringUtils.isEmpty(ngramData) || StringUtils.isEmpty(partOfWord))
             return 0;
 
         int ngramId = ngramsDao.getIdForNgram(ngramData);

ngram-stats-web-view/src/main/java/exceptions/WrongURIException.java

+package exceptions;
+
+public class WrongURIException extends Exception {
+    public WrongURIException(String wrongURI) {
+    }
+}

ngram-stats-web-view/src/main/java/servlets/ngram/ViewNgram.java

 import services.WordsDatabaseReaderInterface;
 import services.WordsJdbcReader;
 import servlets.rest.ViewNgramRest;
+import exceptions.WrongURIException;
 
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
-import java.sql.SQLException;
 import java.util.HashMap;
 import java.util.List;
 
 public class ViewNgram extends HttpServlet {
     private static final String JSP_VIEW_NGRAM_URL = "/WEB-INF/pages/ngram/view.jsp";
     private static final String JSP_VIEW_SEARCH_RESULT = "/WEB-INF/pages/ngram/search-result.jsp";
+    private static final String COLLECTION_URL_SERVLET_IS_MAPPED = "/ngram";
+    private static final String REGEX_PATTERN_TO_EXTRACT_ALL_WORDS = ".";
     private final Logger logger = LoggerFactory.getLogger(ViewNgram.class);
 
-    private final String REGEX_PATTERN_TO_EXTRACT_ALL_WORDS = ".";
-
-
-    private void MakeASearch(final HttpServletRequest request, final String patternToFilter, final ViewNgramRest restParser, final boolean isSearch) throws SQLException {
+    private void MakeASearch(final HttpServletRequest request, final String patternToFilter, final ViewNgramRest restParser, final boolean isSearch) {
         int pageId;
         WordsDatabaseReaderInterface dbreader = new WordsJdbcReader();
-        List<WordForNgramWithCount> listOfWordsForNgram = null;
+        List<WordForNgramWithCount> listOfWordsForNgram;
         String pathPostConditions = "";
 
         final String ngramData = restParser.getNgramData();
 
         int amountOfPages = (int) Math.ceil(dbreader.getAmountOfWordsWithCountersInDatabase(ngramData, patternToFilter) * 1.0 / 10);
 
-        if(pageId > amountOfPages) {
-            pageId = amountOfPages; //TODO question -- what to do with overheaded page id (currently if greater than amount, -- shows last available page)
+        if (pageId > amountOfPages) {
+            pageId = amountOfPages; //TODO question -- what to do with overheaded page id (currently if greater than amount, -- currently shows last available page)
         }
 
         try {
-            if (orderFieldName != null) {
-                if (order != null) {
+            if (StringUtils.isNotEmpty(orderFieldName)) {
+                if (StringUtils.isNotEmpty(order)) {
                     listOfWordsForNgram = dbreader.getListOfTenWordsWithCounters(pageId - 1, ngramData, patternToFilter, orderFieldName, order);
                     pathPostConditions = orderFieldName + "/" + order;
                 } else {
                 listOfWordsForNgram = dbreader.getListOfTenWordsWithCounters(pageId - 1, ngramData, patternToFilter);
             }
 
-            final int finalPageId = pageId;
-            request.setAttribute("sortInfo", new HashMap<String, String>() {{
-                put("currentDirectoryPath", "/ngram/" + restParser.getNgramData());
-                put("page", String.valueOf(finalPageId));
-                put("sortByField", restParser.getOrderByFieldName());
-                put("order", restParser.getOrder());
-                if (isSearch) {
-                    put("additionalParameters", "?query=" + patternToFilter);
-                }
-            }});
         } catch (IllegalArgumentException e) {
             listOfWordsForNgram = dbreader.getListOfTenWordsWithCounters(0, ngramData, REGEX_PATTERN_TO_EXTRACT_ALL_WORDS);
-        } catch (Exception e) {
-            e.printStackTrace();
         }
 
-        request.setAttribute("listOfWordsForNgram", listOfWordsForNgram);
-        request.setAttribute("ngramDataString", ngramData);
+        final int finalPageId = pageId;
+        request.setAttribute("sortInfo", new HashMap<String, String>() {{
+            put("URISortMoulderCurrentCollectionPath", COLLECTION_URL_SERVLET_IS_MAPPED + "/" + restParser.getNgramData());
+            put("URISortMoulderCurrentPageNumber", String.valueOf(finalPageId));
+            put("URISortMoulderFieldToSort", restParser.getOrderByFieldName());
+            put("URISortMoulderOrder", restParser.getOrder());
+            if (isSearch) {
+                put("URISortMoulderAdditionalParameters", "?query=" + patternToFilter);
+            }
+        }});
 
         request.setAttribute("paginatorAmountOfPages", amountOfPages);
         request.setAttribute("paginatorCurrentPage", pageId);
-        request.setAttribute("restCollectionPath", "/ngram/" + ngramData);
+        request.setAttribute("paginatorRestCollectionPath", COLLECTION_URL_SERVLET_IS_MAPPED + "/" + ngramData);
         if (isSearch) {
-            request.setAttribute("restQueryParameters", pathPostConditions + "?query=" + patternToFilter);
+            request.setAttribute("paginatorRestQueryParameters", pathPostConditions + "?query=" + patternToFilter);
         } else {
-            request.setAttribute("restQueryParameters", pathPostConditions);
+            request.setAttribute("paginatorRestQueryParameters", pathPostConditions);
         }
+
+
+        final List<WordForNgramWithCount> finalListOfWordsForNgram = listOfWordsForNgram;
+        request.setAttribute("listResult", new HashMap<String, List>() {{
+            put("listOfWordsForNgram", finalListOfWordsForNgram);
+        }});
+        request.setAttribute("ngramDataString", ngramData);
     }
 
-    private RequestDispatcher returnSearchOfWordsForThisNgramResultPage(HttpServletRequest request, final String wordSearchData, final ViewNgramRest restParser) throws SQLException {
+    private RequestDispatcher returnSearchOfWordsForThisNgramResultPage(HttpServletRequest request, final String wordSearchData, final ViewNgramRest restParser) {
         logger.info("Showing a search result page.");
         MakeASearch(request, wordSearchData, restParser, true);
 
         return request.getRequestDispatcher(JSP_VIEW_SEARCH_RESULT);
     }
 
-    private RequestDispatcher returnListOfWordsForThisNgramPage(HttpServletRequest request, final String patternToFilter, final ViewNgramRest restParser) throws SQLException {
+    private RequestDispatcher returnListOfWordsForThisNgramPage(HttpServletRequest request, final String patternToFilter, final ViewNgramRest restParser) {
         logger.info("Showing an an ngram page (words for ngram and their amount).");
         MakeASearch(request, patternToFilter, restParser, false);
 
             if (view != null) {
                 view.forward(request, response);
             }
-        } catch (SQLException e) {
-            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+        } catch (WrongURIException e) {
+            logger.info("WrongURIException catched");
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
         } catch (Exception e) {
-            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+            logger.info("Exception catched");
+            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
         }
     }
 }

ngram-stats-web-view/src/main/java/servlets/ngrams/ViewNgrams.java

 package servlets.ngrams;
 
 import dao.entities.dbTables.Ngram;
+import exceptions.WrongURIException;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import services.NgramsJdbcReader;
 import services.NgramsDatabaseReaderInterface;
+import services.NgramsJdbcReader;
 import servlets.rest.NgramsViewRest;
 
 import javax.servlet.RequestDispatcher;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
-import java.sql.SQLException;
 import java.util.HashMap;
 import java.util.List;
 
 public class ViewNgrams extends HttpServlet {
     private static final String JSP_VIEW_TABLE_OF_NGRAMS_URL = "/WEB-INF/pages/ngrams/view.jsp";
     private static final String JSP_VIEW_SEARCH_RESULT = "/WEB-INF/pages/ngrams/search-result.jsp";
+    private static final String COLLECTION_URL_SERVLET_IS_MAPPED = "/ngrams/view";
     private final Logger logger = LoggerFactory.getLogger(ViewNgrams.class);
 
-    private RequestDispatcher returnSearchResultPage(HttpServletRequest request, String searchNgramData) throws ServletException, IOException, SQLException {
+    private RequestDispatcher returnSearchResultPage(HttpServletRequest request, String searchNgramData) {
         logger.info("User input is search query " + searchNgramData);
         NgramsDatabaseReaderInterface dbreader = new NgramsJdbcReader();
         final Ngram ngram = dbreader.searchNgramByDataFullMatch(searchNgramData);
         return request.getRequestDispatcher(JSP_VIEW_SEARCH_RESULT);
     }
 
-    private RequestDispatcher returnListOfNgramsPage(HttpServletRequest request) throws ServletException, IOException, SQLException {
+    private RequestDispatcher returnListOfNgramsPage(HttpServletRequest request) throws WrongURIException {
         logger.info("Show a list of ngrams page.");
         NgramsDatabaseReaderInterface dbreader = new NgramsJdbcReader();
-        int pageId = 1;
-        List<Ngram> listOfNgrams = null;
+        int pageId; // = 1
+        List<Ngram> listOfNgrams;
 
         String pathConditionsPart = "";
 
-        try {
-            final NgramsViewRest restParser = new NgramsViewRest(request.getRequestURI());
-            pageId = restParser.getPageId();
+        final NgramsViewRest restParser = new NgramsViewRest(request.getRequestURI());
+        pageId = restParser.getPageId();
+        String orderFieldName = restParser.getOrderByFieldName();
+        String order = restParser.getOrder();
 
-            if (restParser.getOrderByFieldName() != null) {
-                if (restParser.getOrder() != null) {
-                    listOfNgrams = dbreader.getListOfTenNgrams(pageId - 1, restParser.getOrderByFieldName(), restParser.getOrder());
-                    pathConditionsPart = restParser.getOrderByFieldName() + "/" + restParser.getOrder();
+        try {
+            if (StringUtils.isNotEmpty(orderFieldName)) {
+                if (StringUtils.isNotEmpty(order)) {
+                    listOfNgrams = dbreader.getListOfTenNgrams(pageId - 1, orderFieldName, order);
+                    pathConditionsPart = orderFieldName + "/" + order;
                 } else {
-                    listOfNgrams = dbreader.getListOfTenNgrams(pageId - 1, restParser.getOrderByFieldName());
-                    pathConditionsPart = restParser.getOrderByFieldName();
+                    listOfNgrams = dbreader.getListOfTenNgrams(pageId - 1, orderFieldName);
+                    pathConditionsPart = orderFieldName;
                 }
             } else {
                 listOfNgrams = dbreader.getListOfTenNgrams(pageId - 1);
             }
-
-            final int finalPageId = pageId;
-            request.setAttribute("sortInfo", new HashMap<String, String>() {{
-                put("currentDirectoryPath", "/ngrams/view");
-                put("page", String.valueOf(finalPageId));
-                put("sortByField", restParser.getOrderByFieldName());
-                put("order", restParser.getOrder());
-            }});
         } catch (IllegalArgumentException e) {
             listOfNgrams = dbreader.getListOfTenNgrams(0);
-        } catch (Exception e) {
-            e.printStackTrace();
         }
 
-        request.setAttribute("listOfNgrams", listOfNgrams);
+        final int finalPageId = pageId;
+        request.setAttribute("sortInfo", new HashMap<String, String>() {{
+            put("URISortMoulderCurrentCollectionPath", COLLECTION_URL_SERVLET_IS_MAPPED);
+            put("URISortMoulderCurrentPageNumber", String.valueOf(finalPageId));
+            put("URISortMoulderFieldToSort", restParser.getOrderByFieldName());
+            put("URISortMoulderOrder", restParser.getOrder());
+        }});
 
         request.setAttribute("paginatorAmountOfPages", (int) Math.ceil(dbreader.getAmountOfNgramsInDatabase() * 1.0 / 10));
         request.setAttribute("paginatorCurrentPage", pageId);
-        request.setAttribute("restCollectionPath", "/ngrams/view");
-        request.setAttribute("restQueryParameters", pathConditionsPart);
+        request.setAttribute("paginatorRestCollectionPath", COLLECTION_URL_SERVLET_IS_MAPPED);
+        request.setAttribute("paginatorRestQueryParameters", pathConditionsPart);
+
+        final List<Ngram> finalListOfNgrams = listOfNgrams;
+        request.setAttribute("listResult", new HashMap<String, List>() {{
+            put("listOfNgrams", finalListOfNgrams);
+        }});
 
         return request.getRequestDispatcher(JSP_VIEW_TABLE_OF_NGRAMS_URL);
     }
             if (view != null) {
                 view.forward(request, response);
             }
-        } catch (SQLException e) {
-            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+        } catch (WrongURIException e) {
+            response.sendError(HttpServletResponse.SC_NOT_FOUND);
         }
     }
 }

ngram-stats-web-view/src/main/java/servlets/rest/NgramsViewRest.java

 package servlets.rest;
 
+import exceptions.WrongURIException;
+
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
     private String orderByFieldName;
     private String order;
 
-    public NgramsViewRest(String requestURI) throws Exception {
+    public NgramsViewRest(String requestURI) throws WrongURIException {
         if (requestURI == null)
             throw new IllegalArgumentException("Path Info is null.");
 
                 }
                 orderByFieldName = matcher.group(2);
                 order = matcher.group(3);
+            } else {
+                throw new WrongURIException("Wrong URI.");
             }
         } else {
-            throw new Exception("WrongURI");
+            throw new WrongURIException("Wrong URI.");
         }
     }
 

ngram-stats-web-view/src/main/java/servlets/rest/ViewNgramRest.java

 package servlets.rest;
 
+import exceptions.WrongURIException;
+
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
     private String orderByFieldName; // 'word' or 'count'
     private String order;
 
-    public ViewNgramRest(String requestURI) throws Exception {
+    public ViewNgramRest(String requestURI) throws WrongURIException {
         if (requestURI == null)
             throw new IllegalArgumentException("Path Info is null.");
 
             matcher = REGEX_ORDER_PATTERN.matcher(requestURI);
             if (matcher.find()) {
                 ngramData = matcher.group(1);
+                if (ngramData == null) {
+                    throw new WrongURIException("Wrong URI. Ngram not specified.");
+                }
+
                 try {
                     pageId = Integer.parseInt(matcher.group(2));
                     if (pageId == 0) {
                 }
                 orderByFieldName = matcher.group(3);
                 order = matcher.group(4);
+            } else {
+                throw new WrongURIException("Wrong URI.");
             }
         } else {
-            throw new Exception("WrongURI");
+            throw new WrongURIException("Wrong URI.");
         }
     }
 

ngram-stats-web-view/src/main/webapp/WEB-INF/pages/about.jsp

 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="buttons" uri="/WEB-INF/tags/anchors-buttons.tld" %>
 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <%@page trimDirectiveWhitespaces="true" %>
+
 <!DOCTYPE html>
 <html lang="en">
 <head>
             <h1>N-grams statistic web viewer</h1>
             <p>By Vadim Ne. as a task of internship project for Grid Dynamics.</p>
             <p>Kharkiv, autumn-winter 2013</p>
+            <br />
+            <br />
+            <br />
+            <buttons:back-to-main-page-button/>
         </div>
     </div>
 </div>

ngram-stats-web-view/src/main/webapp/WEB-INF/pages/error-pages/404.jsp

+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="buttons" uri="/WEB-INF/tags/anchors-buttons.tld" %>
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ page trimDirectiveWhitespaces="true" %>
+
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <%@ include file="/WEB-INF/pages/includes/common-head.jspf" %>
+    <title>404 -- Not Found</title>
+</head>
+<body style="background-color: #2067B2">
+
+<%@ include file="/WEB-INF/pages/includes/common-navbar.jspf" %>
+
+<div class="container" id="container">
+    <!-- This page has a lot of css code and is harmful for brain -->
+    <h1 style="width: 500px; color: #FFFFFF;">404 -- Not Found</h1>
+
+    <p style="font-family:serif; color: #FFFFFF; font-size: 235pt;
+        display: block; float: right; margin-top: 50px; margin-bottom: 150px;">:(</p>
+    <br/>
+    <br/>
+    <br/>
+
+    <h2 style="width: 500px; font-family: Comic Sans MS,serif; color: #FFFFFF;">The requested URL not found.</h2>
+    <br/>
+    <br/>
+
+    <buttons:back-to-main-page-button/>
+</div>
+
+<%@ include file="/WEB-INF/pages/includes/common-tail.jspf" %>
+</body>
+</html>

ngram-stats-web-view/src/main/webapp/WEB-INF/pages/error-pages/500.jsp

+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="buttons" uri="/WEB-INF/tags/anchors-buttons.tld" %>
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ page trimDirectiveWhitespaces="true" %>
+
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <%@ include file="/WEB-INF/pages/includes/common-head.jspf" %>
+    <title>500 -- Internal Server Error</title>
+</head>
+<body style="background-color: #2067B2">
+
+<%@ include file="/WEB-INF/pages/includes/common-navbar.jspf" %>
+
+<div class="container" id="container">
+    <div class="span6 center-element">
+
+        <div class="text-center">
+            <h1>500 -- Internal Server Error</h1>
+            <p>Something went wrong.</p>
+        </div>
+        <br/>
+        <br/>
+        <buttons:back-to-main-page-button/>
+    </div>
+</div>
+
+<%@ include file="/WEB-INF/pages/includes/common-tail.jspf" %>
+</body>
+</html>

ngram-stats-web-view/src/main/webapp/WEB-INF/pages/includes/pagination.jspf

 
 <jsp:useBean id="paginatorCurrentPage" scope="request" type="java.lang.Integer"/>
 <jsp:useBean id="paginatorAmountOfPages" scope="request" type="java.lang.Integer"/>
-<jsp:useBean id="restCollectionPath" scope="request" type="java.lang.String"/>
-<jsp:useBean id="restQueryParameters" scope="request" type="java.lang.String"/>
+<jsp:useBean id="paginatorRestCollectionPath" scope="request" type="java.lang.String"/>
+<jsp:useBean id="paginatorRestQueryParameters" scope="request" type="java.lang.String"/>
 
 <c:if test="${paginatorAmountOfPages > 1}">
     <div class="pagination pagination-mini pagination-centered">
                 </c:when>
                 <c:otherwise>
                     <li>
-                        <a href="<c:url value="${restCollectionPath}/1/${restQueryParameters}"/>"> First </a>
+                        <a href="<c:url value="${paginatorRestCollectionPath}/1/${paginatorRestQueryParameters}"/>"> First </a>
                     </li>
                 </c:otherwise>
             </c:choose>
                 <%-- Display Previous link except for the 1st page --%>
             <c:if test="${paginatorCurrentPage != 1}">
                 <li>
-                    <a href="<c:url value="${restCollectionPath}/${paginatorCurrentPage - 1}/${restQueryParameters}"/>">
+                    <a href="<c:url value="${paginatorRestCollectionPath}/${paginatorCurrentPage - 1}/${paginatorRestQueryParameters}"/>">
                         Previous
                     </a>
                 </li>
                                         <pagination:active-page current="${p}" total="${paginatorAmountOfPages}"/>
                                     </c:when>
                                     <c:otherwise>
-                                        <pagination:non-active-page paginatorPathPrePart="${restCollectionPath}"
-                                                                    paginatorPathPostPart="${restQueryParameters}"
+                                        <pagination:non-active-page paginatorPathPrePart="${paginatorRestCollectionPath}"
+                                                                    paginatorPathPostPart="${paginatorRestQueryParameters}"
                                                                     p="${p}"/>
                                     </c:otherwise>
                                 </c:choose>
                                         <pagination:active-page current="${p}" total="${paginatorAmountOfPages}"/>
                                     </c:when>
                                     <c:otherwise>
-                                        <pagination:non-active-page paginatorPathPrePart="${restCollectionPath}"
-                                                                    paginatorPathPostPart="${restQueryParameters}"
+                                        <pagination:non-active-page paginatorPathPrePart="${paginatorRestCollectionPath}"
+                                                                    paginatorPathPostPart="${paginatorRestQueryParameters}"
                                                                     p="${p}"/>
                                     </c:otherwise>
                                 </c:choose>
                             </c:when>
                             <c:otherwise>
                                 <li>
-                                    <pagination:non-active-page paginatorPathPrePart="${restCollectionPath}"
-                                                                paginatorPathPostPart="${restQueryParameters}"
+                                    <pagination:non-active-page paginatorPathPrePart="${paginatorRestCollectionPath}"
+                                                                paginatorPathPostPart="${paginatorRestQueryParameters}"
                                                                 p="${p}"/>
                                 </li>
                             </c:otherwise>
                                 <pagination:active-page current="${p}" total="${paginatorAmountOfPages}"/>
                             </c:when>
                             <c:otherwise>
-                                <pagination:non-active-page paginatorPathPrePart="${restCollectionPath}"
-                                                            paginatorPathPostPart="${restQueryParameters}"
+                                <pagination:non-active-page paginatorPathPrePart="${paginatorRestCollectionPath}"
+                                                            paginatorPathPostPart="${paginatorRestQueryParameters}"
                                                             p="${p}"/>
                             </c:otherwise>
                         </c:choose>
                 <%-- Display Next link --%>
             <c:if test="${paginatorCurrentPage != paginatorAmountOfPages}">
                 <li>
-                    <a href="<c:url value="${restCollectionPath}/${paginatorCurrentPage + 1}/${restQueryParameters}"/>">
+                    <a href="<c:url value="${paginatorRestCollectionPath}/${paginatorCurrentPage + 1}/${paginatorRestQueryParameters}"/>">
                         Next </a>
                 </li>
             </c:if>
                 </c:when>
                 <c:otherwise>
                     <li>
-                        <a href="<c:url value="${restCollectionPath}/${paginatorAmountOfPages}/${restQueryParameters}"/>">
+                        <a href="<c:url value="${paginatorRestCollectionPath}/${paginatorAmountOfPages}/${paginatorRestQueryParameters}"/>">
                             Last </a>
                     </li>
                 </c:otherwise>

ngram-stats-web-view/src/main/webapp/WEB-INF/pages/ngram/search-result.jsp

 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <%@ page trimDirectiveWhitespaces="true" %>
 
-<%@ taglib prefix="buttons" uri="/WEB-INF/tags/anchor-buttons.tld" %>
+<%@ taglib prefix="buttons" uri="/WEB-INF/tags/anchors-buttons.tld" %>
 
 <jsp:useBean id="sortInfo" scope="request" type="java.util.Map"/>
-<jsp:useBean id="listOfWordsForNgram" scope="request" type="java.util.List<dao.entities.logical.WordForNgramWithCount>"/> <%-- TODO check on empty!!--%>
+
+<%--<jsp:useBean id="listOfWordsForNgram" scope="request" type="java.util.List<dao.entities.logical.WordForNgramWithCount>"/>--%>
+
 <jsp:useBean id="ngramDataString" scope="request" type="java.lang.String"/>
 <jsp:useBean id="searchWordPatternDataString" scope="request" type="java.lang.String"/>
 
+<%-- have listOfWordsForNgram inside: --%>
+<jsp:useBean id="listResult" scope="request" type="java.util.Map<java.lang.String,java.util.List>"/>
+
 <!DOCTYPE html>
 <html lang="en">
 <head>
 
 <div class="container" id="container">
     <div class="span6 center-element">
-        <h1>Search result for n-gram: '${ngramDataString}'</h1> <h1>Word pattern: '${searchWordPatternDataString}'</h1>
+        <h1>Search result for n-gram: '${ngramDataString}'</h1>
+
+        <h1>Word pattern: '${searchWordPatternDataString}'</h1>
         <br/>
         <%@ include file="/WEB-INF/pages/includes/search.jspf" %>
         <br/>
 
         <c:choose>
-            <c:when test="${listOfWordsForNgram != null}">
+            <c:when test="${listResult.listOfWordsForNgram != null}">
                 <table id="content-table" class="table table-bordered table-striped data-table sort display">
                     <thead>
                     <tr>
-                        <th class="sorting">Words <buttons:table-sort-icon-generator sortInfo="${sortInfo}" currentFieldName="word"/></th>
-                        <th class="sorting">N-Grams count <buttons:table-sort-icon-generator sortInfo="${sortInfo}" currentFieldName="count"/></th>
+                        <th class="sorting">Words <buttons:table-sort-icon-generator sortInfo="${sortInfo}"
+                                                                                     currentFieldName="word"/></th>
+                        <th class="sorting">N-Grams count <buttons:table-sort-icon-generator sortInfo="${sortInfo}"
+                                                                                             currentFieldName="count"/></th>
                     </tr>
                     </thead>
                     <tbody>
-                    <c:forEach items="${listOfWordsForNgram}" var="word">
+                    <c:forEach items="${listResult.listOfWordsForNgram}" var="word">
                         <tr>
                             <td>
                                 <c:out value="${word.word}"/>
                 <%@ include file="/WEB-INF/pages/includes/pagination.jspf" %>
             </c:when>
             <c:otherwise>
-                <h1>Nothing found. You can retry search</h1>
+                <h1>Nothing found</h1>
+
+                <p>Seems, that we have no results for this query. Retry your search, please.</p>
+                <br/>
+                <br/>
+                <buttons:back-to-main-page-button/>
             </c:otherwise>
         </c:choose>
     </div>

ngram-stats-web-view/src/main/webapp/WEB-INF/pages/ngram/view.jsp

 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <%@ page trimDirectiveWhitespaces="true" %>
 
-<%@ taglib prefix="buttons" uri="/WEB-INF/tags/anchor-buttons.tld" %>
+<%@ taglib prefix="buttons" uri="/WEB-INF/tags/anchors-buttons.tld" %>
 
 <jsp:useBean id="sortInfo" scope="request" type="java.util.Map"/>
-<jsp:useBean id="listOfWordsForNgram" scope="request" type="java.util.List<dao.entities.logical.WordForNgramWithCount>"/>
 <jsp:useBean id="ngramDataString" scope="request" type="java.lang.String"/>
+<%-- have listOfWordsForNgram inside: --%>
+<jsp:useBean id="listResult" scope="request" type="java.util.Map<java.lang.String,java.util.List>"/>
+<%--<jsp:useBean id="listOfWordsForNgram" scope="request" type="java.util.List<dao.entities.logical.WordForNgramWithCount>"/>--%>
 
 <!DOCTYPE html>
 <html lang="en">
         <%@ include file="/WEB-INF/pages/includes/search.jspf" %>
         <br/>
 
-        <table id="content-table" class="table table-bordered table-striped data-table sort display">
-            <thead>
-            <tr>
-                <th class="sorting">Words <buttons:table-sort-icon-generator sortInfo="${sortInfo}" currentFieldName="word"/></th>
-                <th class="sorting">N-Grams count <buttons:table-sort-icon-generator sortInfo="${sortInfo}" currentFieldName="count"/></th>
-            </tr>
-            </thead>
-            <tbody>
-
-            <c:forEach items="${listOfWordsForNgram}" var="word"> <%--TODO check for empty--%>
-                <tr>
-                    <td><c:out value="${word.word}"/></td>
-                    <td><c:out value="${word.count}"/></td>
-                </tr>
-            </c:forEach>
-
-            </tbody>
-        </table>
-        <br/>
-        <%@ include file="/WEB-INF/pages/includes/pagination.jspf" %>
-    </div>
+        <c:choose>
+            <c:when test="${listResult.listOfWordsForNgram != null}">
+                <table id="content-table" class="table table-bordered table-striped data-table sort display">
+                    <thead>
+                    <tr>
+                        <th class="sorting">Words <buttons:table-sort-icon-generator sortInfo="${sortInfo}"
+                                                                                     currentFieldName="word"/></th>
+                        <th class="sorting">N-Grams count <buttons:table-sort-icon-generator sortInfo="${sortInfo}"
+                                                                                             currentFieldName="count"/></th>
+                    </tr>
+                    </thead>
+                    <tbody>
+
+                    <c:forEach items="${listResult.listOfWordsForNgram}" var="word">
+                        <tr>
+                            <td><c:out value="${word.word}"/></td>
+                            <td><c:out value="${word.count}"/></td>
+                        </tr>
+                    </c:forEach>
+                    </tbody>
+                </table>
 
+                <br/>
+                <%@ include file="/WEB-INF/pages/includes/pagination.jspf" %>
+
+            </c:when>
+            <c:otherwise>
+                <h1>Nothing found</h1>
+
+                <p>Seems, that we have no ngram '${ngramDataString}' in our database. Try to find another one.</p>
+                <br/>
+                <br/>
+                <buttons:back-to-main-page-button/>
+            </c:otherwise>
+        </c:choose>
+    </div>
 </div>
 
 <%@ include file="/WEB-INF/pages/includes/common-tail.jspf" %>

ngram-stats-web-view/src/main/webapp/WEB-INF/pages/ngrams/view.jsp

 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <%@ page trimDirectiveWhitespaces="true" %>
 
-<%@ taglib prefix="buttons" uri="/WEB-INF/tags/anchor-buttons.tld" %>
+<%@ taglib prefix="buttons" uri="/WEB-INF/tags/anchors-buttons.tld" %>
 
 <jsp:useBean id="sortInfo" scope="request" type="java.util.Map"/>
-<jsp:useBean id="listOfNgrams" scope="request" type="java.util.List<dao.entities.dbTables.Ngram>"/>
+<%-- have listOfNgrams inside: --%>
+<jsp:useBean id="listResult" scope="request" type="java.util.Map<java.lang.String,java.util.List>"/>
+<%--<jsp:useBean id="listOfNgrams" scope="request" type="java.util.List<dao.entities.dbTables.Ngram>"/>--%>
 
 <!DOCTYPE html>
 <html lang="en">
         <%@ include file="/WEB-INF/pages/includes/search.jspf" %>
         <br/>
 
-        <table id="content-table" class="table table-bordered table-striped data-table sort display">
-            <thead>
-            <tr>
-                <th class="sorting">N-Gram <buttons:table-sort-icon-generator sortInfo="${sortInfo}" currentFieldName="name"/></th>
-                <th class="sorting">Count <buttons:table-sort-icon-generator sortInfo="${sortInfo}" currentFieldName="count"/></th>
-            </tr>
-            </thead>
-            <tbody>
-
-            <c:forEach items="${listOfNgrams}" var="ngramItem"> <%--TODO check for empty--%>
-                <tr>
-                    <td><a href="<c:url value="/ngram/${ngramItem.data}"/>"><c:out value="${ngramItem.data}"/></a></td>
-                    <td><c:out value="${ngramItem.count}"/></td>
-                </tr>
-            </c:forEach>
-
-            </tbody>
-        </table>
-        <br/>
-        <%@ include file="/WEB-INF/pages/includes/pagination.jspf" %>
+        <c:choose>
+            <c:when test="${listResult.listOfNgrams != null}">   <%-- TODO page over limit --%>
+                <table id="content-table" class="table table-bordered table-striped data-table sort display">
+                    <thead>
+                    <tr>
+                        <th class="sorting">N-Gram <buttons:table-sort-icon-generator sortInfo="${sortInfo}"
+                                                                                      currentFieldName="name"/></th>
+                        <th class="sorting">Count <buttons:table-sort-icon-generator sortInfo="${sortInfo}"
+                                                                                     currentFieldName="count"/></th>
+                    </tr>
+                    </thead>
+                    <tbody>
+
+                    <c:forEach items="${listResult.listOfNgrams}" var="ngramItem"> <%--TODO check for empty--%>
+                        <tr>
+                            <td><a href="<c:url value="/ngram/${ngramItem.data}"/>"><c:out
+                                    value="${ngramItem.data}"/></a>
+                            </td>
+                            <td><c:out value="${ngramItem.count}"/></td>
+                        </tr>
+                    </c:forEach>
+
+                    </tbody>
+                </table>
+                <br/>
+                <%@ include file="/WEB-INF/pages/includes/pagination.jspf" %>
+
+            </c:when>
+            <c:otherwise>
+                <h1>Nothing found</h1>
+
+                <p>Seems, that this list is empty. Fill database, please.</p>
+                <br/>
+                <br/>
+                <buttons:back-to-main-page-button/>
+            </c:otherwise>
+        </c:choose>
     </div>
 
 </div>

ngram-stats-web-view/src/main/webapp/WEB-INF/tags/anchor-buttons.tld

-<?xml version="1.0" encoding="ISO-8859-1"?>
-
-<taglib xmlns="http://java.sun.com/xml/ns/javaee"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
-        version="2.1">
-
-    <tlib-version>1.0</tlib-version>
-    <short-name>anchor-buttons</short-name>
-
-    <tag-file>
-        <name>table-sort-icon-generator</name>
-        <path>/WEB-INF/tags/anchor-buttons/table-sort-icon-generator.tag</path>
-    </tag-file>
-</taglib>

ngram-stats-web-view/src/main/webapp/WEB-INF/tags/anchor-buttons/table-sort-icon-generator.tag

-<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-<%@ tag trimDirectiveWhitespaces="true" %>
-
-<%--This tag generates anchor (link) and an icon to refer to appropriate tabe sorting url.
-    -- sortInfo bean refers to Map<String, String> which contains
-        ---- currentDirectoryPath -- contain current path info without last slash (e.g. for http://example.com/one/two/, this value may be "/one/two")
-        ---- page -- page to get after the sort will be applied
-        ---- sortByField -- name of the field to sort by
-        ---- order -- order of sort [asc|desc]
-        ---- additionalParameters -- parameters that will be added to the end of generated URL
-    -- currentFieldName String that names the field where this tag inserted.
---%>
-
-<%@ attribute name="sortInfo" required="true" type="java.util.Map" %>
-<%@ attribute name="currentFieldName" required="true" type="java.lang.String" %>
-
-<c:choose>
-    <c:when test="${sortInfo.sortByField == currentFieldName}">
-        <c:if test="${sortInfo.order == 'asc'}"> <%--From asc switch to default sort method.--%>
-            <a href="<c:out value="${sortInfo.currentDirectoryPath}/${sortInfo.page}/${sortInfo.additionalParameters}"/>">
-                <i class="icon-chevron-up element-glow"></i>
-            </a>
-        </c:if>
-        <c:if test="${sortInfo.order == 'desc'}"> <%--From desc switch to asc sort method.--%>
-            <a href="<c:out value="${sortInfo.currentDirectoryPath}/${sortInfo.page}/${currentFieldName}/asc/${sortInfo.additionalParameters}"/>">
-                <i class="icon-chevron-down element-glow"></i>
-            </a>
-        </c:if>
-    </c:when>
-    <c:otherwise> <%--From default switch to desc sort method.--%>
-        <a href="<c:out value="${sortInfo.currentDirectoryPath}/${sortInfo.page}/${currentFieldName}/desc/${sortInfo.additionalParameters}"/>">
-            <i class="icon-list element-glow"></i>
-        </a>
-    </c:otherwise>
-</c:choose>

ngram-stats-web-view/src/main/webapp/WEB-INF/tags/anchors-buttons.tld

+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<taglib xmlns="http://java.sun.com/xml/ns/javaee"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
+        version="2.1">
+
+    <tlib-version>1.0</tlib-version>
+    <short-name>anchor-buttons</short-name>
+
+    <tag-file>
+        <name>back-to-main-page-button</name>
+        <path>/WEB-INF/tags/anchors-buttons/back-to-main-page-button.tag</path>
+    </tag-file>
+
+    <tag-file>
+        <name>table-sort-icon-generator</name>
+        <path>/WEB-INF/tags/anchors-buttons/table-sort-icon-generator.tag</path>
+    </tag-file>
+</taglib>

ngram-stats-web-view/src/main/webapp/WEB-INF/tags/anchors-buttons/back-to-main-page-button.tag

+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ tag trimDirectiveWhitespaces="true" %>
+
+<p class="text-center">
+    <a href="<c:url value="/"/>" class="btn btn-primary btn-large">
+    <i class="icon-white icon-align-justify"></i> Go to main page</a>
+</p>

ngram-stats-web-view/src/main/webapp/WEB-INF/tags/anchors-buttons/table-sort-icon-generator.tag

+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ tag trimDirectiveWhitespaces="true" %>
+
+<%--This tag generates anchor (link) and an icon to refer to appropriate tabe sorting url.
+    -- sortInfo bean refers to Map<String, String> which contains
+        ---- URISortMoulderCurrentCollectionPath -- contain current path info without last slash (e.g. for http://example.com/one/two/, this value may be "/one/two")
+        ---- URISortMoulderCurrentPageNumber -- page to get after the sort will be applied
+        ---- URISortMoulderFieldToSort -- name of the field to sort by
+        ---- URISortMoulderOrder -- order of sort [asc|desc]
+        ---- URISortMoulderAdditionalParameters -- parameters that will be added to the end of generated URL
+    -- currentFieldName String that names the field where this tag inserted.
+--%>
+
+<%@ attribute name="sortInfo" required="true" type="java.util.Map" %>
+<%@ attribute name="currentFieldName" required="true" type="java.lang.String" %>
+
+<c:choose>
+    <c:when test="${sortInfo.URISortMoulderFieldToSort == currentFieldName}">
+        <c:if test="${sortInfo.URISortMoulderOrder == 'asc'}"> <%--From asc switch to default sort method.--%>
+            <a href="<c:out value="${sortInfo.URISortMoulderCurrentCollectionPath}/${sortInfo.URISortMoulderCurrentPageNumber}/${sortInfo.URISortMoulderAdditionalParameters}"/>">
+                <i class="icon-chevron-up element-glow"></i>
+            </a>
+        </c:if>
+        <c:if test="${sortInfo.URISortMoulderOrder == 'desc'}"> <%--From desc switch to asc sort method.--%>
+            <a href="<c:out value="${sortInfo.URISortMoulderCurrentCollectionPath}/${sortInfo.URISortMoulderCurrentPageNumber}/${currentFieldName}/asc/${sortInfo.URISortMoulderAdditionalParameters}"/>">
+                <i class="icon-chevron-down element-glow"></i>
+            </a>
+        </c:if>
+    </c:when>
+    <c:otherwise> <%--From default switch to desc sort method.--%>
+        <a href="<c:out value="${sortInfo.URISortMoulderCurrentCollectionPath}/${sortInfo.URISortMoulderCurrentPageNumber}/${currentFieldName}/desc/${sortInfo.additionalPaURISortMoulderAdditionalParametersrameters}"/>">
+            <i class="icon-list element-glow"></i>
+        </a>
+    </c:otherwise>
+</c:choose>

ngram-stats-web-view/src/main/webapp/WEB-INF/web.xml

 
     <display-name>N-grams stats web viewer</display-name>
     <servlet>
-        <servlet-name>Homepage Servlet</servlet-name>
-        <servlet-class>servlets.HomepageServlet</servlet-class>
-        <load-on-startup>1</load-on-startup>
-    </servlet>
-    <servlet-mapping>
-        <servlet-name>Homepage Servlet</servlet-name>
-        <url-pattern>/</url-pattern>
-    </servlet-mapping>
-
-    <servlet>
         <servlet-name>N-grams View Servlet</servlet-name>
         <servlet-class>servlets.ngrams.ViewNgrams</servlet-class>
-        <load-on-startup>1</load-on-startup>
     </servlet>
     <servlet-mapping>
         <servlet-name>N-grams View Servlet</servlet-name>
     <servlet>
         <servlet-name>Single N-gram View Servlet</servlet-name>
         <servlet-class>servlets.ngram.ViewNgram</servlet-class>
-        <load-on-startup>1</load-on-startup>
     </servlet>
     <servlet-mapping>
         <servlet-name>Single N-gram View Servlet</servlet-name>
         <url-pattern>/static/*</url-pattern>
     </servlet-mapping>
 
+    <servlet>
+        <servlet-name>Homepage Servlet</servlet-name>
+        <servlet-class>servlets.HomepageServlet</servlet-class>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>Homepage Servlet</servlet-name>
+        <url-pattern>/</url-pattern>
+    </servlet-mapping>
+
     <listener>
         <listener-class>listeners.Log4jConfigListener</listener-class>
     </listener>
+
+    <error-page>
+        <error-code>500</error-code>
+        <location>/WEB-INF/pages/error-pages/500.jsp</location>
+    </error-page>
+
+    <error-page>
+        <error-code>404</error-code>
+        <location>/WEB-INF/pages/error-pages/404.jsp</location>
+    </error-page>
 </web-app>