Home | History | Annotate | Download | only in servlet
      1 /*
      2  * Copyright (c) 2016 Google Inc. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you
      5  * may not use this file except in compliance with the License. You may
      6  * obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
     13  * implied. See the License for the specific language governing
     14  * permissions and limitations under the License.
     15  */
     16 
     17 package com.android.vts.servlet;
     18 
     19 import com.android.vts.entity.TestEntity;
     20 import com.android.vts.entity.TestStatusEntity;
     21 import com.android.vts.entity.UserFavoriteEntity;
     22 import com.google.appengine.api.datastore.DatastoreService;
     23 import com.google.appengine.api.datastore.DatastoreServiceFactory;
     24 import com.google.appengine.api.datastore.Entity;
     25 import com.google.appengine.api.datastore.Key;
     26 import com.google.appengine.api.datastore.KeyFactory;
     27 import com.google.appengine.api.datastore.PropertyProjection;
     28 import com.google.appengine.api.datastore.Query;
     29 import com.google.appengine.api.datastore.Query.Filter;
     30 import com.google.appengine.api.datastore.Query.FilterOperator;
     31 import com.google.appengine.api.datastore.Query.FilterPredicate;
     32 import com.google.appengine.api.users.User;
     33 import com.google.appengine.api.users.UserService;
     34 import com.google.appengine.api.users.UserServiceFactory;
     35 import com.google.gson.Gson;
     36 import java.io.IOException;
     37 import java.util.ArrayList;
     38 import java.util.Comparator;
     39 import java.util.HashMap;
     40 import java.util.List;
     41 import java.util.Map;
     42 import java.util.logging.Level;
     43 import javax.servlet.RequestDispatcher;
     44 import javax.servlet.ServletException;
     45 import javax.servlet.http.HttpServletRequest;
     46 import javax.servlet.http.HttpServletResponse;
     47 import javax.servlet.http.HttpSession;
     48 
     49 /** Represents the servlet that is invoked on loading the first page of dashboard. */
     50 public class DashboardMainServlet extends BaseServlet {
     51     private static final String DASHBOARD_MAIN_JSP = "WEB-INF/jsp/dashboard_main.jsp";
     52     private static final String NO_TESTS_ERROR = "No test results available.";
     53 
     54     @Override
     55     public PageType getNavParentType() {
     56         return PageType.TOT;
     57     }
     58 
     59     @Override
     60     public List<Page> getBreadcrumbLinks(HttpServletRequest request) {
     61         return null;
     62     }
     63 
     64     /** Helper class for displaying test entries on the main dashboard. */
     65     public class TestDisplay implements Comparable<TestDisplay> {
     66         private final Key testKey;
     67         private final int passCount;
     68         private final int failCount;
     69         private boolean muteNotifications;
     70         private boolean isFavorite;
     71 
     72         /**
     73          * Test display constructor.
     74          *
     75          * @param testKey The key of the test.
     76          * @param passCount The number of tests passing.
     77          * @param failCount The number of tests failing.
     78          * @param muteNotifications The flag for user notification in case of test failure.
     79          * @param isFavorite The flag for showing favorite mark on All Tests Tab page.
     80          */
     81         public TestDisplay(Key testKey, int passCount, int failCount, boolean muteNotifications,
     82             boolean isFavorite) {
     83             this.testKey = testKey;
     84             this.passCount = passCount;
     85             this.failCount = failCount;
     86             this.muteNotifications = muteNotifications;
     87             this.isFavorite = isFavorite;
     88         }
     89 
     90         /**
     91          * Get the key of the test.
     92          *
     93          * @return The key of the test.
     94          */
     95         public String getName() {
     96             return this.testKey.getName();
     97         }
     98 
     99         /**
    100          * Get the number of passing test cases.
    101          *
    102          * @return The number of passing test cases.
    103          */
    104         public int getPassCount() {
    105             return this.passCount;
    106         }
    107 
    108         /**
    109          * Get the number of failing test cases.
    110          *
    111          * @return The number of failing test cases.
    112          */
    113         public int getFailCount() {
    114             return this.failCount;
    115         }
    116 
    117         /**
    118          * Get the notification mute status.
    119          *
    120          * @return True if the subscriber has muted notifications, false otherwise.
    121          */
    122         public boolean getMuteNotifications() {
    123             return this.muteNotifications;
    124         }
    125 
    126         /** Set the notification mute status. */
    127         public void setMuteNotifications(boolean muteNotifications) {
    128             this.muteNotifications = muteNotifications;
    129         }
    130 
    131         /**
    132          * Get the favorate status.
    133          *
    134          * @return True if an user set favorate for the test, false otherwise.
    135          */
    136         public boolean getIsFavorite() {
    137             return this.isFavorite;
    138         }
    139 
    140         /** Set the favorite status. */
    141         public void setIsFavorite(boolean isFavorite) {
    142             this.isFavorite = isFavorite;
    143         }
    144 
    145         @Override
    146         public int compareTo(TestDisplay test) {
    147             return this.testKey.getName().compareTo(test.getName());
    148         }
    149     }
    150 
    151     @Override
    152     public void doGetHandler(HttpServletRequest request, HttpServletResponse response)
    153             throws IOException {
    154         UserService userService = UserServiceFactory.getUserService();
    155         User currentUser = userService.getCurrentUser();
    156         RequestDispatcher dispatcher = null;
    157         DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
    158         HttpSession session = request.getSession(true);
    159         PageType referTo = PageType.TREE;
    160         if (session.getAttribute("treeDefault") != null) {
    161             boolean treeDefault = (boolean) session.getAttribute("treeDefault");
    162             if (!treeDefault) {
    163                 referTo = PageType.TABLE;
    164             }
    165         }
    166 
    167         List<TestDisplay> displayedTests = new ArrayList<>();
    168         List<String> allTestNames = new ArrayList<>();
    169         List<Key> unprocessedTestKeys = new ArrayList<>();
    170 
    171         Map<Key, TestDisplay> testMap = new HashMap<>(); // map from table key to TestDisplay
    172         Map<String, String> subscriptionMap = new HashMap<>();
    173 
    174         boolean showAll = request.getParameter("showAll") != null;
    175         String error = null;
    176 
    177         Query query = new Query(TestEntity.KIND).setKeysOnly();
    178         for (Entity test : datastore.prepare(query).asIterable()) {
    179             allTestNames.add(test.getKey().getName());
    180         }
    181 
    182         List<Key> favoriteKeyList = new ArrayList<Key>();
    183         Filter userFilter =
    184                 new FilterPredicate(
    185                         UserFavoriteEntity.USER, FilterOperator.EQUAL, currentUser);
    186         Query filterQuery = new Query(UserFavoriteEntity.KIND).setFilter(userFilter);
    187         Iterable<Entity> favoriteIter = datastore.prepare(filterQuery).asIterable();
    188         favoriteIter.forEach(fe -> {
    189             Key testKey = UserFavoriteEntity.fromEntity(fe).testKey;
    190             favoriteKeyList.add(testKey);
    191             subscriptionMap.put(testKey.getName(), KeyFactory.keyToString(fe.getKey()));
    192         });
    193 
    194         query =
    195                 new Query(TestStatusEntity.KIND)
    196                         .addProjection(
    197                                 new PropertyProjection(TestStatusEntity.PASS_COUNT, Long.class))
    198                         .addProjection(
    199                                 new PropertyProjection(TestStatusEntity.FAIL_COUNT, Long.class));
    200         for (Entity status : datastore.prepare(query).asIterable()) {
    201             TestStatusEntity statusEntity = TestStatusEntity.fromEntity(status);
    202             if (statusEntity == null) continue;
    203             Key testKey = KeyFactory.createKey(TestEntity.KIND, statusEntity.testName);
    204             boolean isFavorite = favoriteKeyList.contains(testKey);
    205             TestDisplay display = new TestDisplay(testKey, -1, -1, false, isFavorite);
    206             if (!unprocessedTestKeys.contains(testKey)) {
    207                 display = new TestDisplay(testKey, statusEntity.passCount, statusEntity.failCount,
    208                     false, isFavorite);
    209             }
    210             testMap.put(testKey, display);
    211         }
    212 
    213         if (testMap.size() == 0) {
    214             error = NO_TESTS_ERROR;
    215         }
    216 
    217         if (showAll) {
    218             for (Key testKey : testMap.keySet()) {
    219                 displayedTests.add(testMap.get(testKey));
    220             }
    221         } else {
    222             if (testMap.size() > 0) {
    223                 for (Entity favoriteEntity : favoriteIter) {
    224                     UserFavoriteEntity favorite = UserFavoriteEntity.fromEntity(favoriteEntity);
    225                     Key testKey = favorite.testKey;
    226                     if (!testMap.containsKey(testKey)) {
    227                         continue;
    228                     }
    229                     TestDisplay display = testMap.get(testKey);
    230                     display.setMuteNotifications(favorite.muteNotifications);
    231                     displayedTests.add(display);
    232                 }
    233             }
    234         }
    235         displayedTests.sort(Comparator.naturalOrder());
    236 
    237         response.setStatus(HttpServletResponse.SC_OK);
    238         request.setAttribute("allTestsJson", new Gson().toJson(allTestNames));
    239         request.setAttribute("subscriptionMapJson", new Gson().toJson(subscriptionMap));
    240         request.setAttribute("testNames", displayedTests);
    241         request.setAttribute("showAll", showAll);
    242         request.setAttribute("error", error);
    243         request.setAttribute("resultsUrl", referTo.defaultUrl);
    244         dispatcher = request.getRequestDispatcher(DASHBOARD_MAIN_JSP);
    245         try {
    246             dispatcher.forward(request, response);
    247         } catch (ServletException e) {
    248             logger.log(Level.SEVERE, "Servlet Excpetion caught : ", e);
    249         }
    250     }
    251 }
    252