/* * Copyright 2017 Anton Tananaev (anton@traccar.org) * Copyright 2017 Andrey Kunitsyn (andrey@traccar.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.traccar.database; import java.sql.SQLException; import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.traccar.Context; import org.traccar.helper.Log; import org.traccar.model.Device; import org.traccar.model.DeviceDriver; import org.traccar.model.Driver; import org.traccar.model.DriverPermission; import org.traccar.model.GroupDriver; public class DriversManager { private final DataManager dataManager; private final Map drivers = new ConcurrentHashMap<>(); private final Map driversByUniqueId = new ConcurrentHashMap<>(); private final Map> deviceDrivers = new ConcurrentHashMap<>(); private final Map> deviceDriversWithGroups = new ConcurrentHashMap<>(); private final Map> groupDrivers = new ConcurrentHashMap<>(); private final Map> userDrivers = new ConcurrentHashMap<>(); public DriversManager(DataManager dataManager) { this.dataManager = dataManager; refreshDrivers(); } public Set getUserDrivers(long userId) { if (!userDrivers.containsKey(userId)) { userDrivers.put(userId, new HashSet()); } return userDrivers.get(userId); } public Set getGroupDrivers(long groupId) { if (!groupDrivers.containsKey(groupId)) { groupDrivers.put(groupId, new HashSet()); } return groupDrivers.get(groupId); } public Set getDeviceDrivers(long deviceId) { return getDeviceDrivers(deviceDrivers, deviceId); } public Set getAllDeviceDrivers(long deviceId) { return getDeviceDrivers(deviceDriversWithGroups, deviceId); } private Set getDeviceDrivers(Map> deviceDrivers, long deviceId) { if (!deviceDrivers.containsKey(deviceId)) { deviceDrivers.put(deviceId, new HashSet()); } return deviceDrivers.get(deviceId); } public final void refreshDrivers() { if (dataManager != null) { try { drivers.clear(); driversByUniqueId.clear(); for (Driver driver : dataManager.getDrivers()) { drivers.put(driver.getId(), driver); driversByUniqueId.put(driver.getUniqueId(), driver); } } catch (SQLException error) { Log.warning(error); } } refreshUserDrivers(); refresh(); } public final void refreshUserDrivers() { if (dataManager != null) { try { userDrivers.clear(); for (DriverPermission driverPermission : dataManager.getDriverPermissions()) { getUserDrivers(driverPermission.getUserId()).add(driverPermission.getDriverId()); } } catch (SQLException error) { Log.warning(error); } } } public final void refresh() { if (dataManager != null) { try { Collection databaseGroupDrivers = dataManager.getGroupDrivers(); groupDrivers.clear(); for (GroupDriver groupDriver : databaseGroupDrivers) { getGroupDrivers(groupDriver.getGroupId()).add(groupDriver.getDriverId()); } Collection databaseDeviceDrivers = dataManager.getDeviceDrivers(); Collection allDevices = Context.getDeviceManager().getAllDevices(); deviceDrivers.clear(); deviceDriversWithGroups.clear(); for (DeviceDriver deviceAttribute : databaseDeviceDrivers) { getDeviceDrivers(deviceAttribute.getDeviceId()) .add(deviceAttribute.getDriverId()); getAllDeviceDrivers(deviceAttribute.getDeviceId()) .add(deviceAttribute.getDriverId()); } for (Device device : allDevices) { long groupId = device.getGroupId(); while (groupId != 0) { getAllDeviceDrivers(device.getId()).addAll(getGroupDrivers(groupId)); if (Context.getDeviceManager().getGroupById(groupId) != null) { groupId = Context.getDeviceManager().getGroupById(groupId).getGroupId(); } else { groupId = 0; } } } } catch (SQLException error) { Log.warning(error); } } } public void addDriver(Driver driver) throws SQLException { dataManager.addDriver(driver); drivers.put(driver.getId(), driver); driversByUniqueId.put(driver.getUniqueId(), driver); } public void updateDriver(Driver driver) throws SQLException { dataManager.updateDriver(driver); Driver cachedDriver = drivers.get(driver.getId()); cachedDriver.setName(driver.getName()); if (!driver.getUniqueId().equals(cachedDriver.getUniqueId())) { driversByUniqueId.remove(cachedDriver.getUniqueId()); cachedDriver.setUniqueId(driver.getUniqueId()); driversByUniqueId.put(cachedDriver.getUniqueId(), cachedDriver); } cachedDriver.setAttributes(driver.getAttributes()); } public void removeDriver(long driverId) throws SQLException { dataManager.removeDriver(driverId); if (drivers.containsKey(driverId)) { String driverUniqueId = drivers.get(driverId).getUniqueId(); drivers.remove(driverId); driversByUniqueId.remove(driverUniqueId); } refreshUserDrivers(); refresh(); } public boolean checkDriver(long userId, long driverId) { return getUserDrivers(userId).contains(driverId); } public Driver getDriver(long id) { return drivers.get(id); } public Driver getDriverByUniqueId(String uniqueId) { return driversByUniqueId.get(uniqueId); } public final Collection getDrivers(Set driverIds) { Collection result = new LinkedList<>(); for (long driverId : driverIds) { result.add(getDriver(driverId)); } return result; } public final Set getAllDrivers() { return drivers.keySet(); } public final Set getManagedDrivers(long userId) { Set drivers = new HashSet<>(); drivers.addAll(getUserDrivers(userId)); for (long managedUserId : Context.getPermissionsManager().getUserPermissions(userId)) { drivers.addAll(getUserDrivers(managedUserId)); } return drivers; } public final boolean authorizeDriverByUniqueId(String driverUniqueId, long deviceId) { if (driversByUniqueId.containsKey(driverUniqueId)) { long chekingDriverId = getDriverByUniqueId(driverUniqueId).getId(); Set deviceDrivers = getAllDeviceDrivers(deviceId); if (deviceDrivers.isEmpty()) { return true; } for (long driverId : deviceDrivers) { if (chekingDriverId == driverId) { return true; } } } return false; } }