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.UserFavoriteEntity; 21 import com.google.appengine.api.datastore.DatastoreService; 22 import com.google.appengine.api.datastore.DatastoreServiceFactory; 23 import com.google.appengine.api.datastore.Entity; 24 import com.google.appengine.api.datastore.Key; 25 import com.google.appengine.api.datastore.KeyFactory; 26 import com.google.appengine.api.datastore.Query; 27 import com.google.appengine.api.datastore.Query.Filter; 28 import com.google.appengine.api.datastore.Query.FilterOperator; 29 import com.google.appengine.api.datastore.Query.FilterPredicate; 30 import com.google.appengine.api.users.User; 31 import com.google.appengine.api.users.UserService; 32 import com.google.appengine.api.users.UserServiceFactory; 33 import com.google.gson.Gson; 34 import java.io.IOException; 35 import java.util.ArrayList; 36 import java.util.HashMap; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.logging.Level; 40 import javax.servlet.RequestDispatcher; 41 import javax.servlet.ServletException; 42 import javax.servlet.http.HttpServletRequest; 43 import javax.servlet.http.HttpServletResponse; 44 import org.apache.commons.lang.StringUtils; 45 46 /** Represents the servlet that is invoked on loading the preferences page to manage favorites. */ 47 public class ShowPreferencesServlet extends BaseServlet { 48 private static final String PREFERENCES_JSP = "WEB-INF/jsp/show_preferences.jsp"; 49 private static final String DASHBOARD_MAIN_LINK = "/"; 50 51 /** Helper class for displaying test subscriptions. */ 52 public class Subscription { 53 private final String testName; 54 private final String key; 55 56 /** 57 * Test display constructor. 58 * 59 * @param testName The name of the test. 60 * @param key The websafe string serialization of the subscription key. 61 */ Subscription(String testName, String key)62 public Subscription(String testName, String key) { 63 this.testName = testName; 64 this.key = key; 65 } 66 67 /** 68 * Get the name of the test. 69 * 70 * @return The name of the test. 71 */ getTestName()72 public String getTestName() { 73 return this.testName; 74 } 75 76 /** 77 * Get the subscription key. 78 * 79 * @return The subscription key. 80 */ getKey()81 public String getKey() { 82 return this.key; 83 } 84 } 85 86 @Override getNavbarLinks(HttpServletRequest request)87 public List<String[]> getNavbarLinks(HttpServletRequest request) { 88 List<String[]> links = new ArrayList<>(); 89 Page root = Page.HOME; 90 String[] rootEntry = new String[] {root.getUrl(), root.getName()}; 91 links.add(rootEntry); 92 93 Page prefs = Page.PREFERENCES; 94 String[] prefsEntry = new String[] {CURRENT_PAGE, prefs.getName()}; 95 links.add(prefsEntry); 96 return links; 97 } 98 99 @Override doGetHandler(HttpServletRequest request, HttpServletResponse response)100 public void doGetHandler(HttpServletRequest request, HttpServletResponse response) 101 throws IOException { 102 // Get the user's information 103 UserService userService = UserServiceFactory.getUserService(); 104 User currentUser = userService.getCurrentUser(); 105 RequestDispatcher dispatcher = null; 106 DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); 107 108 List<Subscription> subscriptions = new ArrayList<>(); 109 110 // Map from TestEntity key to the UserFavoriteEntity object 111 Map<Key, Entity> subscriptionEntityMap = new HashMap<>(); 112 113 // Map from test name to the subscription object 114 Map<String, Subscription> subscriptionMap = new HashMap<>(); 115 116 // Query for the favorites entities matching the current user 117 Filter propertyFilter = 118 new FilterPredicate(UserFavoriteEntity.USER, FilterOperator.EQUAL, currentUser); 119 Query q = new Query(UserFavoriteEntity.KIND).setFilter(propertyFilter); 120 for (Entity favorite : datastore.prepare(q).asIterable()) { 121 UserFavoriteEntity favoriteEntity = UserFavoriteEntity.fromEntity(favorite); 122 if (favoriteEntity == null) { 123 continue; 124 } 125 subscriptionEntityMap.put(favoriteEntity.testKey, favorite); 126 } 127 if (subscriptionEntityMap.size() > 0) { 128 // Query for the tests specified by the user favorite entities 129 propertyFilter = new FilterPredicate(Entity.KEY_RESERVED_PROPERTY, FilterOperator.IN, 130 subscriptionEntityMap.keySet()); 131 q = new Query(TestEntity.KIND).setFilter(propertyFilter).setKeysOnly(); 132 for (Entity test : datastore.prepare(q).asIterable()) { 133 String testName = test.getKey().getName(); 134 Entity subscriptionEntity = subscriptionEntityMap.get(test.getKey()); 135 Subscription sub = new Subscription( 136 testName, KeyFactory.keyToString(subscriptionEntity.getKey())); 137 subscriptions.add(sub); 138 subscriptionMap.put(testName, sub); 139 } 140 } 141 List<String> allTests = new ArrayList<>(); 142 for (Entity result : datastore.prepare(new Query(TestEntity.KIND)).asIterable()) { 143 allTests.add(result.getKey().getName()); 144 } 145 146 request.setAttribute("allTestsJson", new Gson().toJson(allTests)); 147 request.setAttribute("subscriptions", subscriptions); 148 request.setAttribute("subscriptionMapJson", new Gson().toJson(subscriptionMap)); 149 request.setAttribute("subscriptionsJson", new Gson().toJson(subscriptions)); 150 151 dispatcher = request.getRequestDispatcher(PREFERENCES_JSP); 152 try { 153 dispatcher.forward(request, response); 154 } catch (ServletException e) { 155 logger.log(Level.SEVERE, "Servlet Exception caught : ", e); 156 } 157 } 158 159 @Override doPost(HttpServletRequest request, HttpServletResponse response)160 public void doPost(HttpServletRequest request, HttpServletResponse response) 161 throws IOException { 162 UserService userService = UserServiceFactory.getUserService(); 163 User currentUser = userService.getCurrentUser(); 164 DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); 165 166 // Retrieve the added tests from the request. 167 String addedTestsString = request.getParameter("addedTests"); 168 List<Key> addedTests = new ArrayList<>(); 169 if (!StringUtils.isBlank(addedTestsString)) { 170 for (String test : addedTestsString.trim().split(",")) { 171 addedTests.add(KeyFactory.createKey(TestEntity.KIND, test)); 172 } 173 } 174 if (addedTests.size() > 0) { 175 // Filter the tests that exist from the set of tests to add 176 Filter propertyFilter = new FilterPredicate( 177 Entity.KEY_RESERVED_PROPERTY, FilterOperator.IN, addedTests); 178 Query q = new Query(TestEntity.KIND).setFilter(propertyFilter).setKeysOnly(); 179 List<Entity> newSubscriptions = new ArrayList<>(); 180 181 // Create subscription entities 182 for (Entity test : datastore.prepare(q).asIterable()) { 183 UserFavoriteEntity favorite = new UserFavoriteEntity(currentUser, test.getKey()); 184 newSubscriptions.add(favorite.toEntity()); 185 } 186 datastore.put(newSubscriptions); 187 } 188 189 // Retrieve the removed tests from the request. 190 String removedSubscriptionString = request.getParameter("removedKeys"); 191 if (!StringUtils.isBlank(removedSubscriptionString)) { 192 for (String stringKey : removedSubscriptionString.trim().split(",")) { 193 try { 194 datastore.delete(KeyFactory.stringToKey(stringKey)); 195 } catch (IllegalArgumentException e) { 196 continue; 197 } 198 } 199 } 200 response.sendRedirect(DASHBOARD_MAIN_LINK); 201 } 202 } 203