/** * Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.onebusaway.users.impl; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.onebusaway.users.client.model.BookmarkBean; import org.onebusaway.users.client.model.RouteFilterBean; import org.onebusaway.users.client.model.UserBean; import org.onebusaway.users.model.User; import org.onebusaway.users.model.UserProperties; import org.onebusaway.users.model.properties.Bookmark; import org.onebusaway.users.model.properties.RouteFilter; import org.onebusaway.users.model.properties.UserPropertiesV2; import org.onebusaway.users.services.UserDao; import org.onebusaway.users.services.UserPropertiesMigration; import org.onebusaway.users.services.UserPropertiesService; import org.onebusaway.users.services.internal.LastSelectedStopService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; public class UserPropertiesServiceV2Impl implements UserPropertiesService { private static Logger _log = LoggerFactory.getLogger(UserPropertiesServiceV2Impl.class); private UserDao _userDao; private UserPropertiesMigration _userPropertiesMigration; private LastSelectedStopService _lastSelectedStopService; @Autowired public void setUserDao(UserDao dao) { _userDao = dao; } @Autowired public void setUserPropertiesMigration( UserPropertiesMigration userPropertiesMigration) { _userPropertiesMigration = userPropertiesMigration; } @Autowired public void setLastSelectedStopService( LastSelectedStopService lastSelectedStopService) { _lastSelectedStopService = lastSelectedStopService; } @Override public Class<? extends UserProperties> getUserPropertiesType() { return UserPropertiesV2.class; } @Override public UserBean getUserAsBean(User user, UserBean bean) { UserPropertiesV2 properties = getProperties(user); bean.setRememberPreferencesEnabled(properties.isRememberPreferencesEnabled()); bean.setHasDefaultLocation(properties.hasDefaultLocationLat() && properties.hasDefaultLocationLon()); bean.setDefaultLocationName(properties.getDefaultLocationName()); bean.setDefaultLocationLat(properties.getDefaultLocationLat()); bean.setDefaultLocationLon(properties.getDefaultLocationLon()); List<String> stopIds = _lastSelectedStopService.getLastSelectedStopsForUser(user.getId()); bean.setLastSelectedStopIds(stopIds); for (Bookmark bookmark : properties.getBookmarks()) { BookmarkBean bookmarkBean = new BookmarkBean(); bookmarkBean.setId(bookmark.getId()); bookmarkBean.setName(bookmark.getName()); bookmarkBean.setStopIds(bookmark.getStopIds()); bookmarkBean.setRouteFilter(getRouteFilterAsBean(bookmark.getRouteFilter())); bean.addBookmark(bookmarkBean); } bean.setMinApiRequestInterval(properties.getMinApiRequestInterval()); Map<String, Long> readServiceAlerts = properties.getReadSituationIdsWithReadTime(); if( readServiceAlerts == null) readServiceAlerts = Collections.emptyMap(); bean.setReadServiceAlerts(readServiceAlerts); return bean; } @Override public UserBean getAnonymousUserAsBean(UserBean bean) { bean.setRememberPreferencesEnabled(true); return bean; } @Override public void setRememberUserPreferencesEnabled(User user, boolean rememberPreferencesEnabled) { UserPropertiesV2 properties = getProperties(user); properties.setRememberPreferencesEnabled(rememberPreferencesEnabled); if (!rememberPreferencesEnabled) properties.clear(); _userDao.saveOrUpdateUser(user); } @Override public void setDefaultLocation(User user, String locationName, double lat, double lon) { UserPropertiesV2 properties = getProperties(user); if (!properties.isRememberPreferencesEnabled()) return; properties.setDefaultLocationName(locationName); properties.setDefaultLocationLat(lat); properties.setDefaultLocationLon(lon); _userDao.saveOrUpdateUser(user); } @Override public void clearDefaultLocation(User user) { setDefaultLocation(user, null, Double.NaN, Double.NaN); } @Override public int addStopBookmark(User user, String name, List<String> stopIds, RouteFilter filter) { UserPropertiesV2 properties = getProperties(user); if (!properties.isRememberPreferencesEnabled()) return -1; int maxId = 0; for (Bookmark bookmark : properties.getBookmarks()) maxId = Math.max(maxId, bookmark.getId() + 1); Bookmark bookmark = new Bookmark(maxId, name, stopIds, filter); properties.getBookmarks().add(bookmark); _userDao.saveOrUpdateUser(user); return bookmark.getId(); } @Override public void updateStopBookmark(User user, int id, String name, List<String> stopIds, RouteFilter routeFilter) { UserPropertiesV2 properties = getProperties(user); if (!properties.isRememberPreferencesEnabled()) return; List<Bookmark> bookmarks = properties.getBookmarks(); for (int index = 0; index < bookmarks.size(); index++) { Bookmark bookmark = bookmarks.get(index); if (bookmark.getId() == id) { bookmark = new Bookmark(id, name, stopIds, routeFilter); bookmarks.set(index, bookmark); _userDao.saveOrUpdateUser(user); return; } } } @Override public void resetUser(User user) { user.setProperties(new UserPropertiesV2()); _userDao.saveOrUpdateUser(user); _lastSelectedStopService.clearLastSelectedStopForUser(user.getId()); } @Override public void deleteStopBookmarks(User user, int id) { UserPropertiesV2 properties = getProperties(user); // Why don't we have a check for stateless user here? If the user wants to // remove information, that's ok. Still not sure why this would be called // either way. if (!properties.isRememberPreferencesEnabled()) _log.warn("Attempt to delete bookmark for stateless user. They shouldn't have bookmarks in the first place. User=" + user.getId()); boolean modified = false; for (Iterator<Bookmark> it = properties.getBookmarks().iterator(); it.hasNext();) { Bookmark bookmark = it.next(); if (bookmark.getId() == id) { it.remove(); modified = true; } } if (modified) _userDao.saveOrUpdateUser(user); } @Override public void setLastSelectedStopIds(User user, List<String> stopIds) { _lastSelectedStopService.setLastSelectedStopsForUser(user.getId(), stopIds); } @Override public void authorizeApi(User user, long minApiRequestInterval) { UserPropertiesV2 properties = getProperties(user); properties.setMinApiRequestInterval(minApiRequestInterval); _userDao.saveOrUpdateUser(user); } @Override public void markServiceAlertAsRead(User user, String situationId, long time, boolean isRead) { UserPropertiesV2 properties = getProperties(user); Map<String, Long> readSituationIdsWithReadTime = properties.getReadSituationIdsWithReadTime(); if (isRead) { if (readSituationIdsWithReadTime == null) { readSituationIdsWithReadTime = new HashMap<String, Long>(); properties.setReadSituationIdsWithReadTime(readSituationIdsWithReadTime); } readSituationIdsWithReadTime.put(situationId, time); _userDao.saveOrUpdateUser(user); } else { if (readSituationIdsWithReadTime == null) return; if (readSituationIdsWithReadTime.remove(situationId) != null) _userDao.saveOrUpdateUser(user); } } @Override public void mergeProperties(User sourceUser, User targetUser) { mergeProperties(getProperties(sourceUser), getProperties(targetUser)); } /**** * Private Methods ****/ private UserPropertiesV2 getProperties(User user) { UserProperties props = user.getProperties(); UserPropertiesV2 v2 = _userPropertiesMigration.migrate(props, UserPropertiesV2.class); if (props != v2) user.setProperties(v2); return v2; } private void mergeProperties(UserPropertiesV2 sourceProps, UserPropertiesV2 destProps) { if (!destProps.isRememberPreferencesEnabled()) return; if (!sourceProps.isRememberPreferencesEnabled()) { destProps.setRememberPreferencesEnabled(false); destProps.clear(); return; } if (!destProps.hasDefaultLocationLat()) { destProps.setDefaultLocationLat(sourceProps.getDefaultLocationLat()); destProps.setDefaultLocationLon(sourceProps.getDefaultLocationLon()); destProps.setDefaultLocationName(sourceProps.getDefaultLocationName()); } List<Bookmark> bookmarks = new ArrayList<Bookmark>(); bookmarks.addAll(destProps.getBookmarks()); bookmarks.addAll(sourceProps.getBookmarks()); destProps.setBookmarks(bookmarks); } private RouteFilterBean getRouteFilterAsBean(RouteFilter routeFilter) { return new RouteFilterBean(routeFilter.getRouteIds()); } }