From afb9a199f57824ec06c993b6028c35b616f64885 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 20 Jul 2017 08:56:29 +0500 Subject: Combine permission resources and reuse common database functions --- src/org/traccar/database/DeviceManager.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/org/traccar/database/DeviceManager.java') diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index f2a2dd565..ba360f165 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -85,7 +85,7 @@ public class DeviceManager implements IdentityManager { if ((force || System.currentTimeMillis() - lastUpdate > dataRefreshDelay) && devicesLastUpdate.compareAndSet(lastUpdate, System.currentTimeMillis())) { GeofenceManager geofenceManager = Context.getGeofenceManager(); - Collection databaseDevices = dataManager.getAllDevices(); + Collection databaseDevices = dataManager.getObjects(Device.class); if (devicesById == null) { devicesById = new ConcurrentHashMap<>(databaseDevices.size()); } @@ -199,7 +199,7 @@ public class DeviceManager implements IdentityManager { } public void addDevice(Device device) throws SQLException { - dataManager.addDevice(device); + dataManager.addObject(device); devicesById.put(device.getId(), device); devicesByUniqueId.put(device.getUniqueId(), device); @@ -209,7 +209,7 @@ public class DeviceManager implements IdentityManager { } public void updateDevice(Device device) throws SQLException { - dataManager.updateDevice(device); + dataManager.updateObject(device); devicesById.put(device.getId(), device); devicesByUniqueId.put(device.getUniqueId(), device); @@ -227,7 +227,7 @@ public class DeviceManager implements IdentityManager { } public void removeDevice(long deviceId) throws SQLException { - dataManager.removeDevice(deviceId); + dataManager.removeObject(Device.class, deviceId); if (devicesById.containsKey(deviceId)) { String deviceUniqueId = devicesById.get(deviceId).getUniqueId(); @@ -289,7 +289,7 @@ public class DeviceManager implements IdentityManager { long lastUpdate = groupsLastUpdate.get(); if ((force || System.currentTimeMillis() - lastUpdate > dataRefreshDelay) && groupsLastUpdate.compareAndSet(lastUpdate, System.currentTimeMillis())) { - Collection databaseGroups = dataManager.getAllGroups(); + Collection databaseGroups = dataManager.getObjects(Group.class); if (groupsById == null) { groupsById = new ConcurrentHashMap<>(databaseGroups.size()); } @@ -359,18 +359,18 @@ public class DeviceManager implements IdentityManager { public void addGroup(Group group) throws SQLException { checkGroupCycles(group); - dataManager.addGroup(group); + dataManager.addObject(group); groupsById.put(group.getId(), group); } public void updateGroup(Group group) throws SQLException { checkGroupCycles(group); - dataManager.updateGroup(group); + dataManager.updateObject(group); groupsById.put(group.getId(), group); } public void removeGroup(long groupId) throws SQLException { - dataManager.removeGroup(groupId); + dataManager.removeObject(Group.class, groupId); groupsById.remove(groupId); } -- cgit v1.2.3 From 6e08953f5a482b6cecc439bd79b94c03638f77cf Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Mon, 24 Jul 2017 17:03:54 +0500 Subject: Fix group cache update --- src/org/traccar/database/DeviceManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/org/traccar/database/DeviceManager.java') diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index ba360f165..6637df91c 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -306,7 +306,7 @@ public class DeviceManager implements IdentityManager { } for (Long cachedGroupId : groupsById.keySet()) { if (!databaseGroupsIds.contains(cachedGroupId)) { - devicesById.remove(cachedGroupId); + groupsById.remove(cachedGroupId); } } databaseGroupsIds.clear(); -- cgit v1.2.3 From 68af658ea2ff9593e5be7a2b2cfcb75c744fd749 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 25 Jul 2017 10:53:08 +0500 Subject: Move users management to separate manager --- src/org/traccar/Context.java | 13 +- src/org/traccar/api/resource/SessionResource.java | 2 +- src/org/traccar/api/resource/UserResource.java | 20 ++- src/org/traccar/database/DeviceManager.java | 4 +- src/org/traccar/database/PermissionsManager.java | 149 ++++++---------------- src/org/traccar/database/SimpleObjectManager.java | 4 +- src/org/traccar/database/UsersManager.java | 83 ++++++++++++ 7 files changed, 149 insertions(+), 126 deletions(-) create mode 100644 src/org/traccar/database/UsersManager.java (limited to 'src/org/traccar/database/DeviceManager.java') diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index a4fc5b679..47472b1d4 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -38,6 +38,7 @@ import org.traccar.database.NotificationManager; import org.traccar.database.PermissionsManager; import org.traccar.database.GeofenceManager; import org.traccar.database.StatisticsManager; +import org.traccar.database.UsersManager; import org.traccar.geocoder.BingMapsGeocoder; import org.traccar.geocoder.FactualGeocoder; import org.traccar.geocoder.GeocodeFarmGeocoder; @@ -98,6 +99,12 @@ public final class Context { return mediaManager; } + private static UsersManager usersManager; + + public static UsersManager getUsersManager() { + return usersManager; + } + private static DeviceManager deviceManager; public static DeviceManager getDeviceManager() { @@ -232,6 +239,10 @@ public final class Context { mediaManager = new MediaManager(config); } + if (dataManager != null) { + usersManager = new UsersManager(dataManager); + } + if (dataManager != null) { deviceManager = new DeviceManager(dataManager); } @@ -298,7 +309,7 @@ public final class Context { webServer = new WebServer(config, dataManager.getDataSource()); } - permissionsManager = new PermissionsManager(dataManager); + permissionsManager = new PermissionsManager(dataManager, usersManager); connectionManager = new ConnectionManager(); diff --git a/src/org/traccar/api/resource/SessionResource.java b/src/org/traccar/api/resource/SessionResource.java index acdbb7c87..fa2a14c6f 100644 --- a/src/org/traccar/api/resource/SessionResource.java +++ b/src/org/traccar/api/resource/SessionResource.java @@ -80,7 +80,7 @@ public class SessionResource extends BaseResource { request.getSession().setAttribute(USER_ID_KEY, userId); } } else if (token != null) { - User user = Context.getPermissionsManager().getUserByToken(token); + User user = Context.getUsersManager().getUserByToken(token); if (user != null) { userId = user.getId(); request.getSession().setAttribute(USER_ID_KEY, userId); diff --git a/src/org/traccar/api/resource/UserResource.java b/src/org/traccar/api/resource/UserResource.java index 98395e3cc..d3d82f99d 100644 --- a/src/org/traccar/api/resource/UserResource.java +++ b/src/org/traccar/api/resource/UserResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.database.UsersManager; import org.traccar.model.ManagedUser; import org.traccar.model.User; @@ -35,6 +36,7 @@ import javax.ws.rs.core.Response; import java.sql.SQLException; import java.util.Collection; import java.util.Date; +import java.util.Set; @Path("users") @Produces(MediaType.APPLICATION_JSON) @@ -43,17 +45,21 @@ public class UserResource extends BaseResource { @GET public Collection get(@QueryParam("userId") long userId) throws SQLException { + UsersManager usersManager = Context.getUsersManager(); + Set result = null; if (Context.getPermissionsManager().isAdmin(getUserId())) { if (userId != 0) { - return Context.getPermissionsManager().getUsers(userId); + result = usersManager.getManagedItems(userId); } else { - return Context.getPermissionsManager().getAllUsers(); + result = usersManager.getAllItems(); } } else if (Context.getPermissionsManager().isManager(getUserId())) { - return Context.getPermissionsManager().getManagedUsers(getUserId()); + result = usersManager.getManagedItems(getUserId()); + result.add(getUserId()); } else { throw new SecurityException("Admin or manager access required"); } + return usersManager.getItems(User.class, result); } @PermitAll @@ -73,11 +79,11 @@ public class UserResource extends BaseResource { } } } - Context.getPermissionsManager().addUser(entity); + Context.getUsersManager().addItem(entity); if (Context.getPermissionsManager().isManager(getUserId())) { Context.getDataManager().linkObject(User.class, getUserId(), ManagedUser.class, entity.getId(), true); } - Context.getPermissionsManager().refreshUserPermissions(); + Context.getUsersManager().refreshUserItems(); if (Context.getNotificationManager() != null) { Context.getNotificationManager().refresh(); } @@ -91,7 +97,7 @@ public class UserResource extends BaseResource { User before = Context.getPermissionsManager().getUser(entity.getId()); Context.getPermissionsManager().checkUser(getUserId(), entity.getId()); Context.getPermissionsManager().checkUserUpdate(getUserId(), before, entity); - Context.getPermissionsManager().updateUser(entity); + Context.getUsersManager().updateItem(entity); if (Context.getNotificationManager() != null) { Context.getNotificationManager().refresh(); } @@ -103,7 +109,7 @@ public class UserResource extends BaseResource { public Response remove(@PathParam("id") long id) throws SQLException { Context.getPermissionsManager().checkReadonly(getUserId()); Context.getPermissionsManager().checkUser(getUserId(), id); - Context.getPermissionsManager().removeUser(id); + Context.getUsersManager().removeItem(id); if (Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshUserItems(); } diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 6637df91c..995aa8ac3 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -192,7 +192,7 @@ public class DeviceManager implements IdentityManager { public Collection getManagedDevices(long userId) throws SQLException { Collection devices = new HashSet<>(); devices.addAll(getDevices(userId)); - for (long managedUserId : Context.getPermissionsManager().getUserPermissions(userId)) { + for (long managedUserId : Context.getUsersManager().getManagedItems(userId)) { devices.addAll(getDevices(managedUserId)); } return devices; @@ -340,7 +340,7 @@ public class DeviceManager implements IdentityManager { public Collection getManagedGroups(long userId) throws SQLException { Collection groups = new ArrayList<>(); groups.addAll(getGroups(userId)); - for (long managedUserId : Context.getPermissionsManager().getUserPermissions(userId)) { + for (long managedUserId : Context.getUsersManager().getManagedItems(userId)) { groups.addAll(getGroups(managedUserId)); } return groups; diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 70969d749..b38ecf9bf 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -30,29 +30,33 @@ import org.traccar.model.User; import java.lang.reflect.Method; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; public class PermissionsManager { private final DataManager dataManager; + private final UsersManager usersManager; private volatile Server server; - private final Map users = new ConcurrentHashMap<>(); - private final Map usersTokens = new HashMap<>(); - private final Map> groupPermissions = new HashMap<>(); private final Map> devicePermissions = new HashMap<>(); private final Map> deviceUsers = new HashMap<>(); private final Map> groupDevices = new HashMap<>(); - private final Map> userPermissions = new HashMap<>(); + public PermissionsManager(DataManager dataManager, UsersManager usersManager) { + this.dataManager = dataManager; + this.usersManager = usersManager; + refreshServer(); + refreshPermissions(); + } + + public User getUser(long userId) { + return (User) usersManager.getById(userId); + } public Set getGroupPermissions(long userId) { if (!groupPermissions.containsKey(userId)) { @@ -82,47 +86,14 @@ public class PermissionsManager { return groupDevices.get(groupId); } - public Set getUserPermissions(long userId) { - if (!userPermissions.containsKey(userId)) { - userPermissions.put(userId, new HashSet()); - } - return userPermissions.get(userId); - } - - public PermissionsManager(DataManager dataManager) { - this.dataManager = dataManager; - refreshUsers(); - refreshPermissions(); - refreshUserPermissions(); - } - - public final void refreshUsers() { - users.clear(); - usersTokens.clear(); + public void refreshServer() { try { server = dataManager.getServer(); - for (User user : dataManager.getObjects(User.class)) { - users.put(user.getId(), user); - if (user.getToken() != null) { - usersTokens.put(user.getToken(), user.getId()); - } - } } catch (SQLException error) { Log.warning(error); } } - public final void refreshUserPermissions() { - userPermissions.clear(); - try { - for (Permission permission : dataManager.getPermissions(User.class, User.class)) { - getUserPermissions(permission.getOwnerId()).add(permission.getPropertyId()); - } - } catch (SQLException | ClassNotFoundException error) { - Log.warning(error); - } - } - public final void refreshPermissions() { groupPermissions.clear(); devicePermissions.clear(); @@ -165,7 +136,8 @@ public class PermissionsManager { } public boolean isAdmin(long userId) { - return users.containsKey(userId) && users.get(userId).getAdmin(); + User user = getUser(userId); + return user != null && user.getAdmin(); } public void checkAdmin(long userId) throws SecurityException { @@ -175,7 +147,8 @@ public class PermissionsManager { } public boolean isManager(long userId) { - return users.containsKey(userId) && users.get(userId).getUserLimit() != 0; + User user = getUser(userId); + return user != null && user.getUserLimit() != 0; } public void checkManager(long userId) throws SecurityException { @@ -186,20 +159,20 @@ public class PermissionsManager { public void checkManager(long userId, long managedUserId) throws SecurityException { checkManager(userId); - if (!getUserPermissions(userId).contains(managedUserId)) { + if (!usersManager.getManagedItems(userId).contains(managedUserId)) { throw new SecurityException("User access denied"); } } public void checkUserLimit(long userId) throws SecurityException { - int userLimit = users.get(userId).getUserLimit(); - if (userLimit != -1 && getUserPermissions(userId).size() >= userLimit) { + int userLimit = getUser(userId).getUserLimit(); + if (userLimit != -1 && usersManager.getManagedItems(userId).size() >= userLimit) { throw new SecurityException("Manager user limit reached"); } } public void checkDeviceLimit(long userId) throws SecurityException, SQLException { - int deviceLimit = users.get(userId).getDeviceLimit(); + int deviceLimit = getUser(userId).getDeviceLimit(); if (deviceLimit != -1) { int deviceCount = 0; if (isManager(userId)) { @@ -214,11 +187,13 @@ public class PermissionsManager { } public boolean isReadonly(long userId) { - return users.containsKey(userId) && users.get(userId).getReadonly(); + User user = getUser(userId); + return user != null && user.getReadonly(); } public boolean isDeviceReadonly(long userId) { - return users.containsKey(userId) && users.get(userId).getDeviceReadonly(); + User user = getUser(userId); + return user != null && user.getDeviceReadonly(); } public void checkReadonly(long userId) throws SecurityException { @@ -235,6 +210,9 @@ public class PermissionsManager { public void checkUserEnabled(long userId) throws SecurityException { User user = getUser(userId); + if (user == null) { + throw new SecurityException("Unknown account"); + } if (user.getDisabled()) { throw new SecurityException("Account is disabled"); } @@ -249,9 +227,10 @@ public class PermissionsManager { || before.getUserLimit() != after.getUserLimit()) { checkAdmin(userId); } - if (users.containsKey(userId) && users.get(userId).getExpirationTime() != null + User user = getUser(userId); + if (user != null && user.getExpirationTime() != null && (after.getExpirationTime() == null - || users.get(userId).getExpirationTime().compareTo(after.getExpirationTime()) < 0)) { + || user.getExpirationTime().compareTo(after.getExpirationTime()) < 0)) { checkAdmin(userId); } if (before.getReadonly() != after.getReadonly() @@ -275,7 +254,7 @@ public class PermissionsManager { public void checkGroup(long userId, long groupId) throws SecurityException { if (!getGroupPermissions(userId).contains(groupId) && !isAdmin(userId)) { checkManager(userId); - for (long managedUserId : getUserPermissions(userId)) { + for (long managedUserId : usersManager.getManagedItems(userId)) { if (getGroupPermissions(managedUserId).contains(groupId)) { return; } @@ -287,7 +266,7 @@ public class PermissionsManager { public void checkDevice(long userId, long deviceId) throws SecurityException { if (!getDevicePermissions(userId).contains(deviceId) && !isAdmin(userId)) { checkManager(userId); - for (long managedUserId : getUserPermissions(userId)) { + for (long managedUserId : usersManager.getManagedItems(userId)) { if (getDevicePermissions(managedUserId).contains(deviceId)) { return; } @@ -326,7 +305,7 @@ public class PermissionsManager { if (manager != null && !manager.checkItemPermission(userId, objectId) && !isAdmin(userId)) { checkManager(userId); - for (long managedUserId : getUserPermissions(userId)) { + for (long managedUserId : usersManager.getManagedItems(userId)) { if (manager.checkItemPermission(managedUserId, objectId)) { return; } @@ -350,7 +329,7 @@ public class PermissionsManager { refreshPermissions(); refreshAllExtendedPermissions(); } else if (permission.getPropertyClass().equals(ManagedUser.class)) { - refreshUserPermissions(); + usersManager.refreshUserItems(); } else if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Driver.class)) { @@ -380,71 +359,15 @@ public class PermissionsManager { this.server = server; } - public Collection getAllUsers() { - return users.values(); - } - - public Collection getUsers(long userId) { - Collection result = new ArrayList<>(); - for (long managedUserId : getUserPermissions(userId)) { - result.add(users.get(managedUserId)); - } - return result; - } - - public Collection getManagedUsers(long userId) { - Collection result = getUsers(userId); - result.add(users.get(userId)); - return result; - } - - public User getUser(long userId) { - return users.get(userId); - } - - public void addUser(User user) throws SQLException { - dataManager.addObject(user); - users.put(user.getId(), user); - if (user.getToken() != null) { - usersTokens.put(user.getToken(), user.getId()); - } - refreshPermissions(); - } - - public void updateUser(User user) throws SQLException { - dataManager.updateUser(user); - User old = users.get(user.getId()); - users.put(user.getId(), user); - if (user.getToken() != null) { - usersTokens.put(user.getToken(), user.getId()); - } - if (old.getToken() != null && !old.getToken().equals(user.getToken())) { - usersTokens.remove(old.getToken()); - } - refreshPermissions(); - } - - public void removeUser(long userId) throws SQLException { - dataManager.removeObject(User.class, userId); - usersTokens.remove(users.get(userId).getToken()); - users.remove(userId); - refreshPermissions(); - refreshUserPermissions(); - } - public User login(String email, String password) throws SQLException { User user = dataManager.login(email, password); if (user != null) { checkUserEnabled(user.getId()); - return users.get(user.getId()); + return getUser(user.getId()); } return null; } - public User getUserByToken(String token) { - return users.get(usersTokens.get(token)); - } - public Object lookupPreference(long userId, String key, Object defaultValue) { String methodName = "get" + key.substring(0, 1).toUpperCase() + key.substring(1); Object preference; @@ -454,7 +377,7 @@ public class PermissionsManager { Method method = null; method = User.class.getMethod(methodName, (Class[]) null); if (method != null) { - userPreference = method.invoke(users.get(userId), (Object[]) null); + userPreference = method.invoke(getUser(userId), (Object[]) null); } method = null; method = Server.class.getMethod(methodName, (Class[]) null); diff --git a/src/org/traccar/database/SimpleObjectManager.java b/src/org/traccar/database/SimpleObjectManager.java index 282dea46e..124178a05 100644 --- a/src/org/traccar/database/SimpleObjectManager.java +++ b/src/org/traccar/database/SimpleObjectManager.java @@ -166,10 +166,10 @@ public abstract class SimpleObjectManager { return items.keySet(); } - public final Set getManagedItems(long userId) { + public Set getManagedItems(long userId) { Set result = new HashSet<>(); result.addAll(getUserItems(userId)); - for (long managedUserId : Context.getPermissionsManager().getUserPermissions(userId)) { + for (long managedUserId : Context.getUsersManager().getManagedItems(userId)) { result.addAll(getUserItems(managedUserId)); } return result; diff --git a/src/org/traccar/database/UsersManager.java b/src/org/traccar/database/UsersManager.java new file mode 100644 index 000000000..3c9c8b280 --- /dev/null +++ b/src/org/traccar/database/UsersManager.java @@ -0,0 +1,83 @@ +/* + * 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.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.traccar.model.BaseModel; +import org.traccar.model.User; + +public class UsersManager extends SimpleObjectManager { + + private Map usersTokens; + + public UsersManager(DataManager dataManager) { + super(dataManager, User.class); + } + + private void putToken(User user) { + if (usersTokens == null) { + usersTokens = new ConcurrentHashMap<>(); + } + if (user.getToken() != null) { + usersTokens.put(user.getToken(), user.getId()); + } + } + + @Override + protected void addNewItem(BaseModel item) { + super.addNewItem(item); + putToken((User) item); + } + + @Override + protected void updateCachedItem(BaseModel item) { + User user = (User) item; + User cachedUser = (User) getById(item.getId()); + super.updateCachedItem(item); + if (user.getToken() != null) { + usersTokens.put(user.getToken(), user.getId()); + } + if (cachedUser.getToken() != null && !cachedUser.getToken().equals(user.getToken())) { + usersTokens.remove(cachedUser.getToken()); + } + } + + @Override + protected void removeCachedItem(long userId) { + User cachedUser = (User) getById(userId); + if (cachedUser != null) { + String userToken = cachedUser.getToken(); + super.removeCachedItem(userId); + if (userToken != null) { + usersTokens.remove(userToken); + } + } + } + + @Override + public Set getManagedItems(long userId) { + return getUserItems(userId); + } + + public User getUserByToken(String token) { + return (User) getById(usersTokens.get(token)); + } + +} -- cgit v1.2.3 From bbcca3d65106069018e93a69b85290c075b128db Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 25 Jul 2017 17:33:00 +0500 Subject: Split Drivers and Groups management --- src/org/traccar/BaseProtocolDecoder.java | 2 +- src/org/traccar/Context.java | 11 +- src/org/traccar/api/resource/DeviceResource.java | 52 ++-- src/org/traccar/api/resource/GroupResource.java | 22 +- src/org/traccar/api/resource/UserResource.java | 11 +- src/org/traccar/database/BaseObjectManager.java | 124 ++++++++ src/org/traccar/database/DeviceManager.java | 342 +++++++-------------- .../traccar/database/ExtendedObjectManager.java | 20 +- src/org/traccar/database/GroupsManager.java | 104 +++++++ src/org/traccar/database/ManagableObjects.java | 27 ++ src/org/traccar/database/PermissionsManager.java | 43 ++- src/org/traccar/database/SimpleObjectManager.java | 134 ++------ src/org/traccar/database/UsersManager.java | 6 +- src/org/traccar/reports/Events.java | 2 +- src/org/traccar/reports/Route.java | 2 +- src/org/traccar/reports/Stops.java | 2 +- src/org/traccar/reports/Trips.java | 2 +- 17 files changed, 488 insertions(+), 418 deletions(-) create mode 100644 src/org/traccar/database/BaseObjectManager.java create mode 100644 src/org/traccar/database/GroupsManager.java create mode 100644 src/org/traccar/database/ManagableObjects.java (limited to 'src/org/traccar/database/DeviceManager.java') diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index 436ef9b02..1aff4564f 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -46,7 +46,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { } try { - Context.getDeviceManager().addDevice(device); + Context.getDeviceManager().addItem(device); Log.info("Automatically registered device " + uniqueId); diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index 47472b1d4..dfb8c5f47 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -37,6 +37,7 @@ import org.traccar.database.MediaManager; import org.traccar.database.NotificationManager; import org.traccar.database.PermissionsManager; import org.traccar.database.GeofenceManager; +import org.traccar.database.GroupsManager; import org.traccar.database.StatisticsManager; import org.traccar.database.UsersManager; import org.traccar.geocoder.BingMapsGeocoder; @@ -105,6 +106,12 @@ public final class Context { return usersManager; } + private static GroupsManager groupsManager; + + public static GroupsManager getGroupsManager() { + return groupsManager; + } + private static DeviceManager deviceManager; public static DeviceManager getDeviceManager() { @@ -241,9 +248,7 @@ public final class Context { if (dataManager != null) { usersManager = new UsersManager(dataManager); - } - - if (dataManager != null) { + groupsManager = new GroupsManager(dataManager); deviceManager = new DeviceManager(dataManager); } diff --git a/src/org/traccar/api/resource/DeviceResource.java b/src/org/traccar/api/resource/DeviceResource.java index 6cf7a6219..c621d4304 100644 --- a/src/org/traccar/api/resource/DeviceResource.java +++ b/src/org/traccar/api/resource/DeviceResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.database.DeviceManager; import org.traccar.model.Device; import org.traccar.model.DeviceTotalDistance; import org.traccar.model.User; @@ -34,9 +35,10 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.sql.SQLException; -import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; @Path("devices") @Produces(MediaType.APPLICATION_JSON) @@ -48,34 +50,34 @@ public class DeviceResource extends BaseResource { @QueryParam("all") boolean all, @QueryParam("userId") long userId, @QueryParam("uniqueId") List uniqueIds, @QueryParam("id") List deviceIds) throws SQLException { + DeviceManager deviceManager = Context.getDeviceManager(); + Set result = null; if (all) { if (Context.getPermissionsManager().isAdmin(getUserId())) { - return Context.getDeviceManager().getAllDevices(); + result = deviceManager.getAllItems(); } else { Context.getPermissionsManager().checkManager(getUserId()); - return Context.getDeviceManager().getManagedDevices(getUserId()); + result = deviceManager.getManagedItems(getUserId()); } - } - if (uniqueIds.isEmpty() && deviceIds.isEmpty()) { + } else if (uniqueIds.isEmpty() && deviceIds.isEmpty()) { if (userId == 0) { userId = getUserId(); } Context.getPermissionsManager().checkUser(getUserId(), userId); - return Context.getDeviceManager().getDevices(userId); - } - - ArrayList devices = new ArrayList<>(); - - for (String uniqueId : uniqueIds) { - Device device = Context.getDeviceManager().getDeviceByUniqueId(uniqueId); - Context.getPermissionsManager().checkDevice(getUserId(), device.getId()); - devices.add(device); - } - for (Long deviceId : deviceIds) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - devices.add(Context.getDeviceManager().getDeviceById(deviceId)); + result = deviceManager.getUserItems(userId); + } else { + result = new HashSet(); + for (String uniqueId : uniqueIds) { + Device device = deviceManager.getDeviceByUniqueId(uniqueId); + Context.getPermissionsManager().checkDevice(getUserId(), device.getId()); + result.add(device.getId()); + } + for (Long deviceId : deviceIds) { + Context.getPermissionsManager().checkDevice(getUserId(), deviceId); + result.add(deviceId); + } } - return devices; + return deviceManager.getItems(Device.class, result); } @POST @@ -83,9 +85,9 @@ public class DeviceResource extends BaseResource { Context.getPermissionsManager().checkReadonly(getUserId()); Context.getPermissionsManager().checkDeviceReadonly(getUserId()); Context.getPermissionsManager().checkDeviceLimit(getUserId()); - Context.getDeviceManager().addDevice(entity); + Context.getDeviceManager().addItem(entity); Context.getDataManager().linkObject(User.class, getUserId(), entity.getClass(), entity.getId(), true); - Context.getPermissionsManager().refreshPermissions(); + Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); Context.getPermissionsManager().refreshAllExtendedPermissions(); return Response.ok(entity).build(); } @@ -96,8 +98,8 @@ public class DeviceResource extends BaseResource { Context.getPermissionsManager().checkReadonly(getUserId()); Context.getPermissionsManager().checkDeviceReadonly(getUserId()); Context.getPermissionsManager().checkDevice(getUserId(), entity.getId()); - Context.getDeviceManager().updateDevice(entity); - Context.getPermissionsManager().refreshPermissions(); + Context.getDeviceManager().updateItem(entity); + Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); Context.getPermissionsManager().refreshAllExtendedPermissions(); return Response.ok(entity).build(); } @@ -108,8 +110,8 @@ public class DeviceResource extends BaseResource { Context.getPermissionsManager().checkReadonly(getUserId()); Context.getPermissionsManager().checkDeviceReadonly(getUserId()); Context.getPermissionsManager().checkDevice(getUserId(), id); - Context.getDeviceManager().removeDevice(id); - Context.getPermissionsManager().refreshPermissions(); + Context.getDeviceManager().removeItem(id); + Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); Context.getPermissionsManager().refreshAllExtendedPermissions(); Context.getAliasesManager().removeDevice(id); return Response.noContent().build(); diff --git a/src/org/traccar/api/resource/GroupResource.java b/src/org/traccar/api/resource/GroupResource.java index f20c95327..f832660b2 100644 --- a/src/org/traccar/api/resource/GroupResource.java +++ b/src/org/traccar/api/resource/GroupResource.java @@ -17,6 +17,7 @@ package org.traccar.api.resource; import org.traccar.Context; import org.traccar.api.BaseResource; +import org.traccar.database.GroupsManager; import org.traccar.model.Group; import org.traccar.model.User; @@ -33,6 +34,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.sql.SQLException; import java.util.Collection; +import java.util.Set; @Path("groups") @Produces(MediaType.APPLICATION_JSON) @@ -42,28 +44,31 @@ public class GroupResource extends BaseResource { @GET public Collection get( @QueryParam("all") boolean all, @QueryParam("userId") long userId) throws SQLException { + GroupsManager groupsManager = Context.getGroupsManager(); + Set result = null; if (all) { if (Context.getPermissionsManager().isAdmin(getUserId())) { - return Context.getDeviceManager().getAllGroups(); + result = groupsManager.getAllItems(); } else { Context.getPermissionsManager().checkManager(getUserId()); - return Context.getDeviceManager().getManagedGroups(getUserId()); + result = groupsManager.getManagedItems(getUserId()); } } else { if (userId == 0) { userId = getUserId(); } Context.getPermissionsManager().checkUser(getUserId(), userId); - return Context.getDeviceManager().getGroups(userId); + result = groupsManager.getUserItems(userId); } + return groupsManager.getItems(Group.class, result); } @POST public Response add(Group entity) throws SQLException { Context.getPermissionsManager().checkReadonly(getUserId()); - Context.getDeviceManager().addGroup(entity); + Context.getGroupsManager().addItem(entity); Context.getDataManager().linkObject(User.class, getUserId(), entity.getClass(), entity.getId(), true); - Context.getPermissionsManager().refreshPermissions(); + Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); Context.getPermissionsManager().refreshAllExtendedPermissions(); return Response.ok(entity).build(); } @@ -73,7 +78,8 @@ public class GroupResource extends BaseResource { public Response update(Group entity) throws SQLException { Context.getPermissionsManager().checkReadonly(getUserId()); Context.getPermissionsManager().checkGroup(getUserId(), entity.getId()); - Context.getDeviceManager().updateGroup(entity); + Context.getGroupsManager().updateItem(entity); + Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); Context.getPermissionsManager().refreshAllExtendedPermissions(); return Response.ok(entity).build(); } @@ -83,8 +89,8 @@ public class GroupResource extends BaseResource { public Response remove(@PathParam("id") long id) throws SQLException { Context.getPermissionsManager().checkReadonly(getUserId()); Context.getPermissionsManager().checkGroup(getUserId(), id); - Context.getDeviceManager().removeGroup(id); - Context.getPermissionsManager().refreshPermissions(); + Context.getGroupsManager().removeItem(id); + Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); Context.getPermissionsManager().refreshAllExtendedPermissions(); return Response.noContent().build(); } diff --git a/src/org/traccar/api/resource/UserResource.java b/src/org/traccar/api/resource/UserResource.java index d3d82f99d..9998ed346 100644 --- a/src/org/traccar/api/resource/UserResource.java +++ b/src/org/traccar/api/resource/UserResource.java @@ -49,13 +49,12 @@ public class UserResource extends BaseResource { Set result = null; if (Context.getPermissionsManager().isAdmin(getUserId())) { if (userId != 0) { - result = usersManager.getManagedItems(userId); + result = usersManager.getUserItems(userId); } else { result = usersManager.getAllItems(); } } else if (Context.getPermissionsManager().isManager(getUserId())) { result = usersManager.getManagedItems(getUserId()); - result.add(getUserId()); } else { throw new SecurityException("Admin or manager access required"); } @@ -110,12 +109,8 @@ public class UserResource extends BaseResource { Context.getPermissionsManager().checkReadonly(getUserId()); Context.getPermissionsManager().checkUser(getUserId(), id); Context.getUsersManager().removeItem(id); - if (Context.getGeofenceManager() != null) { - Context.getGeofenceManager().refreshUserItems(); - } - if (Context.getNotificationManager() != null) { - Context.getNotificationManager().refresh(); - } + Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); + Context.getPermissionsManager().refreshAllUsersPermissions(); return Response.noContent().build(); } diff --git a/src/org/traccar/database/BaseObjectManager.java b/src/org/traccar/database/BaseObjectManager.java new file mode 100644 index 000000000..d515fc2a9 --- /dev/null +++ b/src/org/traccar/database/BaseObjectManager.java @@ -0,0 +1,124 @@ +/* + * 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.helper.Log; +import org.traccar.model.BaseModel; + +public class BaseObjectManager { + + private final DataManager dataManager; + + private Map items; + private Class baseClass; + + protected BaseObjectManager(DataManager dataManager, Class baseClass) { + this.dataManager = dataManager; + this.baseClass = baseClass; + refreshItems(); + } + + protected final DataManager getDataManager() { + return dataManager; + } + + protected final Class getBaseClass() { + return baseClass; + } + + public final BaseModel getById(long itemId) { + return items.get(itemId); + } + + public void refreshItems() { + if (dataManager != null) { + try { + Collection databaseItems = dataManager.getObjects(baseClass); + if (items == null) { + items = new ConcurrentHashMap<>(databaseItems.size()); + } + Set databaseItemIds = new HashSet<>(); + for (BaseModel item : databaseItems) { + databaseItemIds.add(item.getId()); + if (items.containsKey(item.getId())) { + updateCachedItem(item); + } else { + addNewItem(item); + } + } + for (Long cachedItemId : items.keySet()) { + if (!databaseItemIds.contains(cachedItemId)) { + removeCachedItem(cachedItemId); + } + } + } catch (SQLException error) { + Log.warning(error); + } + } + } + + protected void addNewItem(BaseModel item) { + items.put(item.getId(), item); + } + + public void addItem(BaseModel item) throws SQLException { + dataManager.addObject(item); + addNewItem(item); + } + + protected void updateCachedItem(BaseModel item) { + items.put(item.getId(), item); + } + + public void updateItem(BaseModel item) throws SQLException { + dataManager.updateObject(item); + updateCachedItem(item); + } + + protected void removeCachedItem(long itemId) { + items.remove(itemId); + } + + public void removeItem(long itemId) throws SQLException { + BaseModel item = getById(itemId); + if (item != null) { + dataManager.removeObject(baseClass, itemId); + removeCachedItem(itemId); + } + } + + public final Collection getItems(Class clazz, Set itemIds) { + Collection result = new LinkedList<>(); + for (long itemId : itemIds) { + result.add((T) getById(itemId)); + } + return result; + } + + public Set getAllItems() { + return items.keySet(); + } + +} diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 995aa8ac3..ac66f1bb8 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -19,7 +19,6 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -31,6 +30,7 @@ import org.traccar.BaseProtocol; import org.traccar.Config; import org.traccar.Context; import org.traccar.helper.Log; +import org.traccar.model.BaseModel; import org.traccar.model.Command; import org.traccar.model.CommandType; import org.traccar.model.Device; @@ -39,121 +39,42 @@ import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Server; -public class DeviceManager implements IdentityManager { +public class DeviceManager extends BaseObjectManager implements IdentityManager, ManagableObjects { public static final long DEFAULT_REFRESH_DELAY = 300; private final Config config; - private final DataManager dataManager; private final long dataRefreshDelay; private boolean lookupGroupsAttribute; - private Map devicesById; private Map devicesByUniqueId; private Map devicesByPhone; private AtomicLong devicesLastUpdate = new AtomicLong(); - private Map groupsById; - private AtomicLong groupsLastUpdate = new AtomicLong(); - private final Map positions = new ConcurrentHashMap<>(); private boolean fallbackToText; public DeviceManager(DataManager dataManager) { - this.dataManager = dataManager; + super(dataManager, Device.class); this.config = Context.getConfig(); dataRefreshDelay = config.getLong("database.refreshDelay", DEFAULT_REFRESH_DELAY) * 1000; lookupGroupsAttribute = config.getBoolean("deviceManager.lookupGroupsAttribute"); fallbackToText = config.getBoolean("command.fallbackToSms"); - if (dataManager != null) { - try { - updateGroupCache(true); - updateDeviceCache(true); - for (Position position : dataManager.getLatestPositions()) { - positions.put(position.getDeviceId(), position); - } - } catch (SQLException error) { - Log.warning(error); - } - } + refreshLastPositions(); } private void updateDeviceCache(boolean force) throws SQLException { - long lastUpdate = devicesLastUpdate.get(); if ((force || System.currentTimeMillis() - lastUpdate > dataRefreshDelay) && devicesLastUpdate.compareAndSet(lastUpdate, System.currentTimeMillis())) { - GeofenceManager geofenceManager = Context.getGeofenceManager(); - Collection databaseDevices = dataManager.getObjects(Device.class); - if (devicesById == null) { - devicesById = new ConcurrentHashMap<>(databaseDevices.size()); - } - if (devicesByUniqueId == null) { - devicesByUniqueId = new ConcurrentHashMap<>(databaseDevices.size()); - } - if (devicesByPhone == null) { - devicesByPhone = new ConcurrentHashMap<>(databaseDevices.size()); - } - Set databaseDevicesIds = new HashSet<>(); - Set databaseDevicesUniqueIds = new HashSet<>(); - Set databaseDevicesPhones = new HashSet<>(); - for (Device device : databaseDevices) { - databaseDevicesIds.add(device.getId()); - databaseDevicesUniqueIds.add(device.getUniqueId()); - databaseDevicesPhones.add(device.getPhone()); - if (devicesById.containsKey(device.getId())) { - Device cachedDevice = devicesById.get(device.getId()); - cachedDevice.setName(device.getName()); - cachedDevice.setGroupId(device.getGroupId()); - cachedDevice.setCategory(device.getCategory()); - cachedDevice.setContact(device.getContact()); - cachedDevice.setModel(device.getModel()); - cachedDevice.setAttributes(device.getAttributes()); - if (!device.getUniqueId().equals(cachedDevice.getUniqueId())) { - devicesByUniqueId.put(device.getUniqueId(), cachedDevice); - } - cachedDevice.setUniqueId(device.getUniqueId()); - if (device.getPhone() != null && !device.getPhone().isEmpty() - && !device.getPhone().equals(cachedDevice.getPhone())) { - devicesByPhone.put(device.getPhone(), cachedDevice); - } - cachedDevice.setPhone(device.getPhone()); - } else { - devicesById.put(device.getId(), device); - devicesByUniqueId.put(device.getUniqueId(), device); - if (device.getPhone() != null && !device.getPhone().isEmpty()) { - devicesByPhone.put(device.getPhone(), device); - } - if (geofenceManager != null) { - Position lastPosition = getLastPosition(device.getId()); - if (lastPosition != null) { - device.setGeofenceIds(geofenceManager.getCurrentDeviceGeofences(lastPosition)); - } - } - } - } - for (Iterator iterator = devicesById.keySet().iterator(); iterator.hasNext();) { - if (!databaseDevicesIds.contains(iterator.next())) { - iterator.remove(); - } - } - for (Iterator iterator = devicesByUniqueId.keySet().iterator(); iterator.hasNext();) { - if (!databaseDevicesUniqueIds.contains(iterator.next())) { - iterator.remove(); - } - } - for (Iterator iterator = devicesByPhone.keySet().iterator(); iterator.hasNext();) { - if (!databaseDevicesPhones.contains(iterator.next())) { - iterator.remove(); - } - } + refreshItems(); } } @Override public Device getDeviceById(long id) { - return devicesById.get(id); + return (Device) getById(id); } @Override @@ -169,76 +90,129 @@ public class DeviceManager implements IdentityManager { return devicesByPhone.get(phone); } + @Override + public Set getAllItems() { + Set result = super.getAllItems(); + if (result.isEmpty()) { + try { + updateDeviceCache(true); + } catch (SQLException e) { + Log.warning(e); + } + result = super.getAllItems(); + } + return result; + } + public Collection getAllDevices() { - boolean forceUpdate = devicesById.isEmpty(); + return getItems(Device.class, getAllItems()); + } - try { - updateDeviceCache(forceUpdate); - } catch (SQLException e) { - Log.warning(e); + @Override + public Set getUserItems(long userId) { + if (Context.getPermissionsManager() != null) { + return Context.getPermissionsManager().getDevicePermissions(userId); + } else { + return new HashSet<>(); } - - return devicesById.values(); } - public Collection getDevices(long userId) throws SQLException { - Collection devices = new ArrayList<>(); - for (long id : Context.getPermissionsManager().getDevicePermissions(userId)) { - devices.add(devicesById.get(id)); + @Override + public Set getManagedItems(long userId) { + Set result = new HashSet<>(); + result.addAll(getUserItems(userId)); + for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { + result.addAll(getUserItems(managedUserId)); } - return devices; + return result; } - public Collection getManagedDevices(long userId) throws SQLException { - Collection devices = new HashSet<>(); - devices.addAll(getDevices(userId)); - for (long managedUserId : Context.getUsersManager().getManagedItems(userId)) { - devices.addAll(getDevices(managedUserId)); + private void putUniqueDeviceId(Device device) { + if (devicesByUniqueId == null) { + devicesByUniqueId = new ConcurrentHashMap<>(getAllItems().size()); } - return devices; + devicesByUniqueId.put(device.getUniqueId(), device); } - public void addDevice(Device device) throws SQLException { - dataManager.addObject(device); + private void putPhone(Device device) { + if (devicesByPhone == null) { + devicesByPhone = new ConcurrentHashMap<>(getAllItems().size()); + } + devicesByPhone.put(device.getPhone(), device); + } - devicesById.put(device.getId(), device); - devicesByUniqueId.put(device.getUniqueId(), device); + @Override + protected void addNewItem(BaseModel item) { + Device device = (Device) item; + super.addNewItem(item); + putUniqueDeviceId(device); if (device.getPhone() != null && !device.getPhone().isEmpty()) { - devicesByPhone.put(device.getPhone(), device); + putPhone(device); + } + if (Context.getGeofenceManager() != null) { + Position lastPosition = getLastPosition(device.getId()); + if (lastPosition != null) { + device.setGeofenceIds(Context.getGeofenceManager().getCurrentDeviceGeofences(lastPosition)); + } } } - public void updateDevice(Device device) throws SQLException { - dataManager.updateObject(device); + @Override + protected void updateCachedItem(BaseModel item) { + Device device = (Device) item; + Device cachedDevice = (Device) getById(device.getId()); + cachedDevice.setName(device.getName()); + cachedDevice.setGroupId(device.getGroupId()); + cachedDevice.setCategory(device.getCategory()); + cachedDevice.setContact(device.getContact()); + cachedDevice.setModel(device.getModel()); + cachedDevice.setAttributes(device.getAttributes()); + if (!device.getUniqueId().equals(cachedDevice.getUniqueId())) { + devicesByUniqueId.remove(cachedDevice.getUniqueId()); + cachedDevice.setUniqueId(device.getUniqueId()); + putUniqueDeviceId(cachedDevice); + } + if (device.getPhone() != null && !device.getPhone().isEmpty() + && !device.getPhone().equals(cachedDevice.getPhone())) { + devicesByPhone.remove(cachedDevice.getPhone()); + cachedDevice.setPhone(device.getPhone()); + putPhone(cachedDevice); + } + } - devicesById.put(device.getId(), device); - devicesByUniqueId.put(device.getUniqueId(), device); - if (device.getPhone() != null && !device.getPhone().isEmpty()) { - devicesByPhone.put(device.getPhone(), device); + @Override + protected void removeCachedItem(long deviceId) { + Device cachedDevice = (Device) getById(deviceId); + if (cachedDevice != null) { + String deviceUniqueId = cachedDevice.getUniqueId(); + String phone = cachedDevice.getPhone(); + super.removeCachedItem(deviceId); + devicesByUniqueId.remove(deviceUniqueId); + if (phone != null && !phone.isEmpty()) { + devicesByPhone.remove(phone); + } } + positions.remove(deviceId); } public void updateDeviceStatus(Device device) throws SQLException { - dataManager.updateDeviceStatus(device); - if (devicesById.containsKey(device.getId())) { - Device cachedDevice = devicesById.get(device.getId()); + getDataManager().updateDeviceStatus(device); + Device cachedDevice = (Device) getById(device.getId()); + if (cachedDevice != null) { cachedDevice.setStatus(device.getStatus()); } } - public void removeDevice(long deviceId) throws SQLException { - dataManager.removeObject(Device.class, deviceId); - - if (devicesById.containsKey(deviceId)) { - String deviceUniqueId = devicesById.get(deviceId).getUniqueId(); - String phone = devicesById.get(deviceId).getPhone(); - devicesById.remove(deviceId); - devicesByUniqueId.remove(deviceUniqueId); - if (phone != null && !phone.isEmpty()) { - devicesByPhone.remove(phone); + private void refreshLastPositions() { + if (getDataManager() != null) { + try { + for (Position position : getDataManager().getLatestPositions()) { + positions.put(position.getDeviceId(), position); + } + } catch (SQLException error) { + Log.warning(error); } } - positions.remove(deviceId); } public boolean isLatestPosition(Position position) { @@ -250,10 +224,11 @@ public class DeviceManager implements IdentityManager { if (isLatestPosition(position)) { - dataManager.updateLatestPosition(position); + getDataManager().updateLatestPosition(position); - if (devicesById.containsKey(position.getDeviceId())) { - devicesById.get(position.getDeviceId()).setPositionId(position.getId()); + Device device = (Device) getById(position.getDeviceId()); + if (device != null) { + device.setPositionId(position.getId()); } positions.put(position.getDeviceId(), position); @@ -274,7 +249,7 @@ public class DeviceManager implements IdentityManager { List result = new LinkedList<>(); if (Context.getPermissionsManager() != null) { - for (long deviceId : Context.getPermissionsManager().getDevicePermissions(userId)) { + for (long deviceId : getUserItems(userId)) { if (positions.containsKey(deviceId)) { result.add(positions.get(deviceId)); } @@ -284,96 +259,6 @@ public class DeviceManager implements IdentityManager { return result; } - private void updateGroupCache(boolean force) throws SQLException { - - long lastUpdate = groupsLastUpdate.get(); - if ((force || System.currentTimeMillis() - lastUpdate > dataRefreshDelay) - && groupsLastUpdate.compareAndSet(lastUpdate, System.currentTimeMillis())) { - Collection databaseGroups = dataManager.getObjects(Group.class); - if (groupsById == null) { - groupsById = new ConcurrentHashMap<>(databaseGroups.size()); - } - Set databaseGroupsIds = new HashSet<>(); - for (Group group : databaseGroups) { - databaseGroupsIds.add(group.getId()); - if (groupsById.containsKey(group.getId())) { - Group cachedGroup = groupsById.get(group.getId()); - cachedGroup.setName(group.getName()); - cachedGroup.setGroupId(group.getGroupId()); - } else { - groupsById.put(group.getId(), group); - } - } - for (Long cachedGroupId : groupsById.keySet()) { - if (!databaseGroupsIds.contains(cachedGroupId)) { - groupsById.remove(cachedGroupId); - } - } - databaseGroupsIds.clear(); - } - } - - public Group getGroupById(long id) { - return groupsById.get(id); - } - - public Collection getAllGroups() { - boolean forceUpdate = groupsById.isEmpty(); - - try { - updateGroupCache(forceUpdate); - } catch (SQLException e) { - Log.warning(e); - } - - return groupsById.values(); - } - - public Collection getGroups(long userId) throws SQLException { - Collection groups = new ArrayList<>(); - for (long id : Context.getPermissionsManager().getGroupPermissions(userId)) { - groups.add(getGroupById(id)); - } - return groups; - } - - public Collection getManagedGroups(long userId) throws SQLException { - Collection groups = new ArrayList<>(); - groups.addAll(getGroups(userId)); - for (long managedUserId : Context.getUsersManager().getManagedItems(userId)) { - groups.addAll(getGroups(managedUserId)); - } - return groups; - } - - private void checkGroupCycles(Group group) { - Set groups = new HashSet<>(); - while (group != null) { - if (groups.contains(group.getId())) { - throw new IllegalArgumentException("Cycle in group hierarchy"); - } - groups.add(group.getId()); - group = groupsById.get(group.getGroupId()); - } - } - - public void addGroup(Group group) throws SQLException { - checkGroupCycles(group); - dataManager.addObject(group); - groupsById.put(group.getId(), group); - } - - public void updateGroup(Group group) throws SQLException { - checkGroupCycles(group); - dataManager.updateObject(group); - groupsById.put(group.getId(), group); - } - - public void removeGroup(long groupId) throws SQLException { - dataManager.removeObject(Group.class, groupId); - groupsById.remove(groupId); - } - public boolean lookupAttributeBoolean( long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) { String result = lookupAttribute(deviceId, attributeName, lookupConfig); @@ -426,12 +311,13 @@ public class DeviceManager implements IdentityManager { if (result == null && lookupGroupsAttribute) { long groupId = device.getGroupId(); while (groupId != 0) { - if (getGroupById(groupId) != null) { - result = getGroupById(groupId).getString(attributeName); + Group group = (Group) Context.getGroupsManager().getById(groupId); + if (group != null) { + result = group.getString(attributeName); if (result != null) { break; } - groupId = getGroupById(groupId).getGroupId(); + groupId = group.getGroupId(); } else { groupId = 0; } @@ -453,7 +339,7 @@ public class DeviceManager implements IdentityManager { Position last = positions.get(deviceTotalDistance.getDeviceId()); if (last != null) { last.getAttributes().put(Position.KEY_TOTAL_DISTANCE, deviceTotalDistance.getTotalDistance()); - dataManager.addPosition(last); + getDataManager().addPosition(last); updateLatestPosition(last); } else { throw new IllegalArgumentException(); @@ -466,9 +352,9 @@ public class DeviceManager implements IdentityManager { Position lastPosition = getLastPosition(deviceId); if (lastPosition != null) { BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - protocol.sendTextCommand(devicesById.get(deviceId).getPhone(), command); + protocol.sendTextCommand(((Device) getById(deviceId)).getPhone(), command); } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - Context.getSmppManager().sendMessageSync(devicesById.get(deviceId).getPhone(), + Context.getSmppManager().sendMessageSync(((Device) getById(deviceId)).getPhone(), command.getString(Command.KEY_DATA), true); } else { throw new RuntimeException("Command " + command.getType() + " is not supported"); diff --git a/src/org/traccar/database/ExtendedObjectManager.java b/src/org/traccar/database/ExtendedObjectManager.java index 2833b3bae..19c9ca5b2 100644 --- a/src/org/traccar/database/ExtendedObjectManager.java +++ b/src/org/traccar/database/ExtendedObjectManager.java @@ -48,10 +48,6 @@ public abstract class ExtendedObjectManager extends SimpleObjectManager { return groupItems.get(groupId); } - protected final void clearGroupItems() { - groupItems.clear(); - } - public final Set getDeviceItems(long deviceId) { if (!deviceItems.containsKey(deviceId)) { deviceItems.put(deviceId, new HashSet()); @@ -59,10 +55,6 @@ public abstract class ExtendedObjectManager extends SimpleObjectManager { return deviceItems.get(deviceId); } - protected final void clearDeviceItems() { - deviceItems.clear(); - } - public Set getAllDeviceItems(long deviceId) { if (!deviceItemsWithGroups.containsKey(deviceId)) { deviceItemsWithGroups.put(deviceId, new HashSet()); @@ -83,16 +75,15 @@ public abstract class ExtendedObjectManager extends SimpleObjectManager { Collection databaseGroupPermissions = getDataManager().getPermissions(Group.class, getBaseClass()); - clearGroupItems(); + groupItems.clear(); for (Permission groupPermission : databaseGroupPermissions) { getGroupItems(groupPermission.getOwnerId()).add(groupPermission.getPropertyId()); } Collection databaseDevicePermissions = getDataManager().getPermissions(Device.class, getBaseClass()); - Collection allDevices = Context.getDeviceManager().getAllDevices(); - clearDeviceItems(); + deviceItems.clear(); deviceItemsWithGroups.clear(); for (Permission devicePermission : databaseDevicePermissions) { @@ -100,12 +91,13 @@ public abstract class ExtendedObjectManager extends SimpleObjectManager { getAllDeviceItems(devicePermission.getOwnerId()).add(devicePermission.getPropertyId()); } - for (Device device : allDevices) { + for (Device device : Context.getDeviceManager().getAllDevices()) { long groupId = device.getGroupId(); while (groupId != 0) { getAllDeviceItems(device.getId()).addAll(getGroupItems(groupId)); - if (Context.getDeviceManager().getGroupById(groupId) != null) { - groupId = Context.getDeviceManager().getGroupById(groupId).getGroupId(); + Group group = (Group) Context.getGroupsManager().getById(groupId); + if (group != null) { + groupId = group.getGroupId(); } else { groupId = 0; } diff --git a/src/org/traccar/database/GroupsManager.java b/src/org/traccar/database/GroupsManager.java new file mode 100644 index 000000000..e92158fd6 --- /dev/null +++ b/src/org/traccar/database/GroupsManager.java @@ -0,0 +1,104 @@ +/* + * 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.HashSet; +import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; + +import org.traccar.Context; +import org.traccar.helper.Log; +import org.traccar.model.BaseModel; +import org.traccar.model.Group; + +public class GroupsManager extends BaseObjectManager implements ManagableObjects { + + private AtomicLong groupsLastUpdate = new AtomicLong(); + private final long dataRefreshDelay; + + public GroupsManager(DataManager dataManager) { + super(dataManager, Group.class); + dataRefreshDelay = Context.getConfig().getLong("database.refreshDelay", + DeviceManager.DEFAULT_REFRESH_DELAY) * 1000; + } + + private void checkGroupCycles(BaseModel group) { + Set groups = new HashSet<>(); + while (group != null) { + if (groups.contains(group.getId())) { + throw new IllegalArgumentException("Cycle in group hierarchy"); + } + groups.add(group.getId()); + group = getById(((Group) group).getGroupId()); + } + } + + private void updateGroupCache(boolean force) throws SQLException { + long lastUpdate = groupsLastUpdate.get(); + if ((force || System.currentTimeMillis() - lastUpdate > dataRefreshDelay) + && groupsLastUpdate.compareAndSet(lastUpdate, System.currentTimeMillis())) { + refreshItems(); + } + } + + @Override + public Set getAllItems() { + Set result = super.getAllItems(); + if (result.isEmpty()) { + try { + updateGroupCache(true); + } catch (SQLException e) { + Log.warning(e); + } + result = super.getAllItems(); + } + return result; + } + + @Override + protected void addNewItem(BaseModel item) { + checkGroupCycles(item); + super.addNewItem(item); + } + + @Override + protected void updateCachedItem(BaseModel item) { + checkGroupCycles(item); + super.updateCachedItem(item); + } + + @Override + public Set getUserItems(long userId) { + if (Context.getPermissionsManager() != null) { + return Context.getPermissionsManager().getGroupPermissions(userId); + } else { + return new HashSet<>(); + } + } + + @Override + public Set getManagedItems(long userId) { + Set result = new HashSet<>(); + result.addAll(getUserItems(userId)); + for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { + result.addAll(getUserItems(managedUserId)); + } + return result; + } + +} diff --git a/src/org/traccar/database/ManagableObjects.java b/src/org/traccar/database/ManagableObjects.java new file mode 100644 index 000000000..ec9549493 --- /dev/null +++ b/src/org/traccar/database/ManagableObjects.java @@ -0,0 +1,27 @@ +/* + * 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.util.Set; + +public interface ManagableObjects { + + Set getUserItems(long userId); + + Set getManagedItems(long userId); + +} diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index b38ecf9bf..54e5ed979 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -51,7 +51,7 @@ public class PermissionsManager { this.dataManager = dataManager; this.usersManager = usersManager; refreshServer(); - refreshPermissions(); + refreshDeviceAndGroupPermissions(); } public User getUser(long userId) { @@ -94,11 +94,12 @@ public class PermissionsManager { } } - public final void refreshPermissions() { + public final void refreshDeviceAndGroupPermissions() { groupPermissions.clear(); devicePermissions.clear(); try { - GroupTree groupTree = new GroupTree(Context.getDeviceManager().getAllGroups(), + GroupTree groupTree = new GroupTree(Context.getGroupsManager().getItems( + Group.class, Context.getGroupsManager().getAllItems()), Context.getDeviceManager().getAllDevices()); for (Permission groupPermission : dataManager.getPermissions(User.class, Group.class)) { Set userGroupPermissions = getGroupPermissions(groupPermission.getOwnerId()); @@ -117,9 +118,9 @@ public class PermissionsManager { } groupDevices.clear(); - for (Group group : Context.getDeviceManager().getAllGroups()) { - for (Device device : groupTree.getDevices(group.getId())) { - getGroupDevices(group.getId()).add(device.getId()); + for (long groupId : Context.getGroupsManager().getAllItems()) { + for (Device device : groupTree.getDevices(groupId)) { + getGroupDevices(groupId).add(device.getId()); } } @@ -159,14 +160,14 @@ public class PermissionsManager { public void checkManager(long userId, long managedUserId) throws SecurityException { checkManager(userId); - if (!usersManager.getManagedItems(userId).contains(managedUserId)) { + if (!usersManager.getUserItems(userId).contains(managedUserId)) { throw new SecurityException("User access denied"); } } public void checkUserLimit(long userId) throws SecurityException { int userLimit = getUser(userId).getUserLimit(); - if (userLimit != -1 && usersManager.getManagedItems(userId).size() >= userLimit) { + if (userLimit != -1 && usersManager.getUserItems(userId).size() >= userLimit) { throw new SecurityException("Manager user limit reached"); } } @@ -176,9 +177,9 @@ public class PermissionsManager { if (deviceLimit != -1) { int deviceCount = 0; if (isManager(userId)) { - deviceCount = Context.getDeviceManager().getManagedDevices(userId).size(); + deviceCount = Context.getDeviceManager().getManagedItems(userId).size(); } else { - deviceCount = getDevicePermissions(userId).size(); + deviceCount = Context.getDeviceManager().getUserItems(userId).size(); } if (deviceCount >= deviceLimit) { throw new SecurityException("User device limit reached"); @@ -254,7 +255,7 @@ public class PermissionsManager { public void checkGroup(long userId, long groupId) throws SecurityException { if (!getGroupPermissions(userId).contains(groupId) && !isAdmin(userId)) { checkManager(userId); - for (long managedUserId : usersManager.getManagedItems(userId)) { + for (long managedUserId : usersManager.getUserItems(userId)) { if (getGroupPermissions(managedUserId).contains(groupId)) { return; } @@ -264,10 +265,10 @@ public class PermissionsManager { } public void checkDevice(long userId, long deviceId) throws SecurityException { - if (!getDevicePermissions(userId).contains(deviceId) && !isAdmin(userId)) { + if (!Context.getDeviceManager().getUserItems(userId).contains(deviceId) && !isAdmin(userId)) { checkManager(userId); - for (long managedUserId : usersManager.getManagedItems(userId)) { - if (getDevicePermissions(managedUserId).contains(deviceId)) { + for (long managedUserId : usersManager.getUserItems(userId)) { + if (Context.getDeviceManager().getUserItems(managedUserId).contains(deviceId)) { return; } } @@ -314,6 +315,18 @@ public class PermissionsManager { } } + public void refreshAllUsersPermissions() { + if (Context.getGeofenceManager() != null) { + Context.getGeofenceManager().refreshUserItems(); + } + Context.getCalendarManager().refreshUserItems(); + Context.getDriversManager().refreshUserItems(); + Context.getAttributesManager().refreshUserItems(); + if (Context.getNotificationManager() != null) { + Context.getNotificationManager().refresh(); + } + } + public void refreshAllExtendedPermissions() { if (Context.getGeofenceManager() != null) { Context.getGeofenceManager().refreshExtendedPermissions(); @@ -326,7 +339,7 @@ public class PermissionsManager { if (permission.getOwnerClass().equals(User.class)) { if (permission.getPropertyClass().equals(Device.class) || permission.getPropertyClass().equals(Group.class)) { - refreshPermissions(); + refreshDeviceAndGroupPermissions(); refreshAllExtendedPermissions(); } else if (permission.getPropertyClass().equals(ManagedUser.class)) { usersManager.refreshUserItems(); diff --git a/src/org/traccar/database/SimpleObjectManager.java b/src/org/traccar/database/SimpleObjectManager.java index 124178a05..fa41f30b6 100644 --- a/src/org/traccar/database/SimpleObjectManager.java +++ b/src/org/traccar/database/SimpleObjectManager.java @@ -17,9 +17,7 @@ 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; @@ -30,43 +28,15 @@ import org.traccar.model.BaseModel; import org.traccar.model.Permission; import org.traccar.model.User; -public abstract class SimpleObjectManager { +public abstract class SimpleObjectManager extends BaseObjectManager implements ManagableObjects { - private final DataManager dataManager; - - private Map items; - private final Map> userItems = new ConcurrentHashMap<>(); - - private Class baseClass; - private String baseClassIdName; + private Map> userItems; protected SimpleObjectManager(DataManager dataManager, Class baseClass) { - this.dataManager = dataManager; - this.baseClass = baseClass; - baseClassIdName = DataManager.makeNameId(baseClass); - refreshItems(); - } - - protected final DataManager getDataManager() { - return dataManager; - } - - protected final Class getBaseClass() { - return baseClass; - } - - protected final String getBaseClassIdName() { - return baseClassIdName; - } - - public final BaseModel getById(long itemId) { - return items.get(itemId); - } - - protected final void clearItems() { - items.clear(); + super(dataManager, baseClass); } + @Override public final Set getUserItems(long userId) { if (!userItems.containsKey(userId)) { userItems.put(userId, new HashSet()); @@ -74,47 +44,35 @@ public abstract class SimpleObjectManager { return userItems.get(userId); } - protected final void clearUserItems() { - userItems.clear(); + @Override + public Set getManagedItems(long userId) { + Set result = new HashSet<>(); + result.addAll(getUserItems(userId)); + for (long managedUserId : Context.getUsersManager().getUserItems(userId)) { + result.addAll(getUserItems(managedUserId)); + } + return result; } public final boolean checkItemPermission(long userId, long itemId) { return getUserItems(userId).contains(itemId); } + @Override public void refreshItems() { - if (dataManager != null) { - try { - Collection databaseItems = dataManager.getObjects(baseClass); - if (items == null) { - items = new ConcurrentHashMap<>(databaseItems.size()); - } - Set databaseItemIds = new HashSet<>(); - for (BaseModel item : databaseItems) { - databaseItemIds.add(item.getId()); - if (items.containsKey(item.getId())) { - updateCachedItem(item); - } else { - addNewItem(item); - } - } - for (Long cachedItemId : items.keySet()) { - if (!databaseItemIds.contains(cachedItemId)) { - removeCachedItem(cachedItemId); - } - } - } catch (SQLException error) { - Log.warning(error); - } - } + super.refreshItems(); refreshUserItems(); } public final void refreshUserItems() { - if (dataManager != null) { + if (getDataManager() != null) { try { - clearUserItems(); - for (Permission permission : dataManager.getPermissions(User.class, baseClass)) { + if (userItems != null) { + userItems.clear(); + } else { + userItems = new ConcurrentHashMap<>(); + } + for (Permission permission : getDataManager().getPermissions(User.class, getBaseClass())) { getUserItems(permission.getOwnerId()).add(permission.getPropertyId()); } } catch (SQLException | ClassNotFoundException error) { @@ -123,56 +81,10 @@ public abstract class SimpleObjectManager { } } - protected void addNewItem(BaseModel item) { - items.put(item.getId(), item); - } - - public void addItem(BaseModel item) throws SQLException { - dataManager.addObject(item); - addNewItem(item); - } - - protected void updateCachedItem(BaseModel item) { - items.put(item.getId(), item); - } - - public void updateItem(BaseModel item) throws SQLException { - dataManager.updateObject(item); - updateCachedItem(item); - } - - protected void removeCachedItem(long itemId) { - items.remove(itemId); - } - + @Override public void removeItem(long itemId) throws SQLException { - BaseModel item = getById(itemId); - if (item != null) { - dataManager.removeObject(baseClass, itemId); - removeCachedItem(itemId); - } + super.removeItem(itemId); refreshUserItems(); } - public final Collection getItems(Class clazz, Set itemIds) { - Collection result = new LinkedList<>(); - for (long itemId : itemIds) { - result.add((T) getById(itemId)); - } - return result; - } - - public final Set getAllItems() { - return items.keySet(); - } - - public Set getManagedItems(long userId) { - Set result = new HashSet<>(); - result.addAll(getUserItems(userId)); - for (long managedUserId : Context.getUsersManager().getManagedItems(userId)) { - result.addAll(getUserItems(managedUserId)); - } - return result; - } - } diff --git a/src/org/traccar/database/UsersManager.java b/src/org/traccar/database/UsersManager.java index 3c9c8b280..cb4ea623f 100644 --- a/src/org/traccar/database/UsersManager.java +++ b/src/org/traccar/database/UsersManager.java @@ -16,6 +16,7 @@ */ package org.traccar.database; +import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -73,7 +74,10 @@ public class UsersManager extends SimpleObjectManager { @Override public Set getManagedItems(long userId) { - return getUserItems(userId); + Set result = new HashSet<>(); + result.addAll(getUserItems(userId)); + result.add(userId); + return result; } public User getUserByToken(String token) { diff --git a/src/org/traccar/reports/Events.java b/src/org/traccar/reports/Events.java index 3a111944c..9d3acb250 100644 --- a/src/org/traccar/reports/Events.java +++ b/src/org/traccar/reports/Events.java @@ -92,7 +92,7 @@ public final class Events { deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); if (device.getGroupId() != 0) { - Group group = Context.getDeviceManager().getGroupById(device.getGroupId()); + Group group = (Group) Context.getGroupsManager().getById(device.getGroupId()); if (group != null) { deviceEvents.setGroupName(group.getName()); } diff --git a/src/org/traccar/reports/Route.java b/src/org/traccar/reports/Route.java index aa6b7105b..9f0696085 100644 --- a/src/org/traccar/reports/Route.java +++ b/src/org/traccar/reports/Route.java @@ -61,7 +61,7 @@ public final class Route { deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); if (device.getGroupId() != 0) { - Group group = Context.getDeviceManager().getGroupById(device.getGroupId()); + Group group = (Group) Context.getGroupsManager().getById(device.getGroupId()); if (group != null) { deviceRoutes.setGroupName(group.getName()); } diff --git a/src/org/traccar/reports/Stops.java b/src/org/traccar/reports/Stops.java index 64e589be1..1c631a0c2 100644 --- a/src/org/traccar/reports/Stops.java +++ b/src/org/traccar/reports/Stops.java @@ -78,7 +78,7 @@ public final class Stops { deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); if (device.getGroupId() != 0) { - Group group = Context.getDeviceManager().getGroupById(device.getGroupId()); + Group group = (Group) Context.getGroupsManager().getById(device.getGroupId()); if (group != null) { deviceStops.setGroupName(group.getName()); } diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java index 5c26bea54..51689bfd3 100644 --- a/src/org/traccar/reports/Trips.java +++ b/src/org/traccar/reports/Trips.java @@ -77,7 +77,7 @@ public final class Trips { deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); if (device.getGroupId() != 0) { - Group group = Context.getDeviceManager().getGroupById(device.getGroupId()); + Group group = (Group) Context.getGroupsManager().getById(device.getGroupId()); if (group != null) { deviceTrips.setGroupName(group.getName()); } -- cgit v1.2.3 From 82edf57e1b93d5a5ca34294dc62e3620889c2341 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 26 Jul 2017 15:20:22 +0500 Subject: Override getById in all managers --- src/org/traccar/BaseProtocolDecoder.java | 2 +- src/org/traccar/database/AttributesManager.java | 7 ++++++- src/org/traccar/database/BaseObjectManager.java | 2 +- src/org/traccar/database/CalendarManager.java | 5 +++++ src/org/traccar/database/DeviceManager.java | 14 +++++++------- src/org/traccar/database/DriversManager.java | 9 +++++++-- src/org/traccar/database/GeofenceManager.java | 7 ++++++- src/org/traccar/database/GroupsManager.java | 5 +++++ src/org/traccar/database/UsersManager.java | 11 ++++++++--- src/org/traccar/reports/Events.java | 2 +- src/org/traccar/reports/Route.java | 2 +- src/org/traccar/reports/Stops.java | 2 +- src/org/traccar/reports/Trips.java | 2 +- 13 files changed, 50 insertions(+), 20 deletions(-) (limited to 'src/org/traccar/database/DeviceManager.java') diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index 1aff4564f..b7ceabb5c 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -51,7 +51,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { Log.info("Automatically registered device " + uniqueId); if (defaultGroupId != 0) { - Context.getPermissionsManager().refreshPermissions(); + Context.getPermissionsManager().refreshDeviceAndGroupPermissions(); Context.getPermissionsManager().refreshAllExtendedPermissions(); } diff --git a/src/org/traccar/database/AttributesManager.java b/src/org/traccar/database/AttributesManager.java index 4dc70eeb7..e80d57c4e 100644 --- a/src/org/traccar/database/AttributesManager.java +++ b/src/org/traccar/database/AttributesManager.java @@ -25,10 +25,15 @@ public class AttributesManager extends ExtendedObjectManager { super(dataManager, Attribute.class); } + @Override + public Attribute getById(long calendarId) { + return (Attribute) super.getById(calendarId); + } + @Override public void updateCachedItem(BaseModel item) { Attribute attribute = (Attribute) item; - Attribute cachedAttribute = (Attribute) getById(item.getId()); + Attribute cachedAttribute = getById(item.getId()); cachedAttribute.setDescription(attribute.getDescription()); cachedAttribute.setAttribute(attribute.getAttribute()); cachedAttribute.setExpression(attribute.getExpression()); diff --git a/src/org/traccar/database/BaseObjectManager.java b/src/org/traccar/database/BaseObjectManager.java index d515fc2a9..92cfd9b6b 100644 --- a/src/org/traccar/database/BaseObjectManager.java +++ b/src/org/traccar/database/BaseObjectManager.java @@ -48,7 +48,7 @@ public class BaseObjectManager { return baseClass; } - public final BaseModel getById(long itemId) { + public BaseModel getById(long itemId) { return items.get(itemId); } diff --git a/src/org/traccar/database/CalendarManager.java b/src/org/traccar/database/CalendarManager.java index 6874020ec..b8d0914ee 100644 --- a/src/org/traccar/database/CalendarManager.java +++ b/src/org/traccar/database/CalendarManager.java @@ -24,4 +24,9 @@ public class CalendarManager extends SimpleObjectManager { super(dataManager, Calendar.class); } + @Override + public Calendar getById(long calendarId) { + return (Calendar) super.getById(calendarId); + } + } diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index ac66f1bb8..1fe7ddfa5 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -143,8 +143,8 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, @Override protected void addNewItem(BaseModel item) { - Device device = (Device) item; super.addNewItem(item); + Device device = (Device) item; putUniqueDeviceId(device); if (device.getPhone() != null && !device.getPhone().isEmpty()) { putPhone(device); @@ -160,7 +160,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, @Override protected void updateCachedItem(BaseModel item) { Device device = (Device) item; - Device cachedDevice = (Device) getById(device.getId()); + Device cachedDevice = getDeviceById(device.getId()); cachedDevice.setName(device.getName()); cachedDevice.setGroupId(device.getGroupId()); cachedDevice.setCategory(device.getCategory()); @@ -182,7 +182,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, @Override protected void removeCachedItem(long deviceId) { - Device cachedDevice = (Device) getById(deviceId); + Device cachedDevice = getDeviceById(deviceId); if (cachedDevice != null) { String deviceUniqueId = cachedDevice.getUniqueId(); String phone = cachedDevice.getPhone(); @@ -197,7 +197,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, public void updateDeviceStatus(Device device) throws SQLException { getDataManager().updateDeviceStatus(device); - Device cachedDevice = (Device) getById(device.getId()); + Device cachedDevice = getDeviceById(device.getId()); if (cachedDevice != null) { cachedDevice.setStatus(device.getStatus()); } @@ -226,7 +226,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, getDataManager().updateLatestPosition(position); - Device device = (Device) getById(position.getDeviceId()); + Device device = getDeviceById(position.getDeviceId()); if (device != null) { device.setPositionId(position.getId()); } @@ -311,7 +311,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, if (result == null && lookupGroupsAttribute) { long groupId = device.getGroupId(); while (groupId != 0) { - Group group = (Group) Context.getGroupsManager().getById(groupId); + Group group = Context.getGroupsManager().getById(groupId); if (group != null) { result = group.getString(attributeName); if (result != null) { @@ -352,7 +352,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, Position lastPosition = getLastPosition(deviceId); if (lastPosition != null) { BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - protocol.sendTextCommand(((Device) getById(deviceId)).getPhone(), command); + protocol.sendTextCommand(getDeviceById(deviceId).getPhone(), command); } else if (command.getType().equals(Command.TYPE_CUSTOM)) { Context.getSmppManager().sendMessageSync(((Device) getById(deviceId)).getPhone(), command.getString(Command.KEY_DATA), true); diff --git a/src/org/traccar/database/DriversManager.java b/src/org/traccar/database/DriversManager.java index 14b74bab1..420824dbb 100644 --- a/src/org/traccar/database/DriversManager.java +++ b/src/org/traccar/database/DriversManager.java @@ -30,6 +30,11 @@ public class DriversManager extends ExtendedObjectManager { super(dataManager, Driver.class); } + @Override + public Driver getById(long driverId) { + return (Driver) super.getById(driverId); + } + private void putUniqueDriverId(Driver driver) { if (driversByUniqueId == null) { driversByUniqueId = new ConcurrentHashMap<>(); @@ -46,7 +51,7 @@ public class DriversManager extends ExtendedObjectManager { @Override protected void updateCachedItem(BaseModel item) { Driver driver = (Driver) item; - Driver cachedDriver = (Driver) getById(driver.getId()); + Driver cachedDriver = getById(driver.getId()); cachedDriver.setName(driver.getName()); if (!driver.getUniqueId().equals(cachedDriver.getUniqueId())) { driversByUniqueId.remove(cachedDriver.getUniqueId()); @@ -58,7 +63,7 @@ public class DriversManager extends ExtendedObjectManager { @Override protected void removeCachedItem(long driverId) { - Driver cachedDriver = (Driver) getById(driverId); + Driver cachedDriver = getById(driverId); if (cachedDriver != null) { String driverUniqueId = cachedDriver.getUniqueId(); super.removeCachedItem(driverId); diff --git a/src/org/traccar/database/GeofenceManager.java b/src/org/traccar/database/GeofenceManager.java index 2c3c32c56..4bc3909cd 100644 --- a/src/org/traccar/database/GeofenceManager.java +++ b/src/org/traccar/database/GeofenceManager.java @@ -29,6 +29,11 @@ public class GeofenceManager extends ExtendedObjectManager { super(dataManager, Geofence.class); } + @Override + public Geofence getById(long geofenceId) { + return (Geofence) super.getById(geofenceId); + } + @Override public final void refreshExtendedPermissions() { super.refreshExtendedPermissions(); @@ -38,7 +43,7 @@ public class GeofenceManager extends ExtendedObjectManager { public List getCurrentDeviceGeofences(Position position) { List result = new ArrayList<>(); for (long geofenceId : getAllDeviceItems(position.getDeviceId())) { - Geofence geofence = (Geofence) getById(geofenceId); + Geofence geofence = getById(geofenceId); if (geofence != null && geofence.getGeometry() .containsPoint(position.getLatitude(), position.getLongitude())) { result.add(geofenceId); diff --git a/src/org/traccar/database/GroupsManager.java b/src/org/traccar/database/GroupsManager.java index e92158fd6..095e7a22c 100644 --- a/src/org/traccar/database/GroupsManager.java +++ b/src/org/traccar/database/GroupsManager.java @@ -37,6 +37,11 @@ public class GroupsManager extends BaseObjectManager implements ManagableObjects DeviceManager.DEFAULT_REFRESH_DELAY) * 1000; } + @Override + public Group getById(long groupId) { + return (Group) super.getById(groupId); + } + private void checkGroupCycles(BaseModel group) { Set groups = new HashSet<>(); while (group != null) { diff --git a/src/org/traccar/database/UsersManager.java b/src/org/traccar/database/UsersManager.java index cb4ea623f..e53409b4f 100644 --- a/src/org/traccar/database/UsersManager.java +++ b/src/org/traccar/database/UsersManager.java @@ -32,6 +32,11 @@ public class UsersManager extends SimpleObjectManager { super(dataManager, User.class); } + @Override + public User getById(long userId) { + return (User) super.getById(userId); + } + private void putToken(User user) { if (usersTokens == null) { usersTokens = new ConcurrentHashMap<>(); @@ -50,7 +55,7 @@ public class UsersManager extends SimpleObjectManager { @Override protected void updateCachedItem(BaseModel item) { User user = (User) item; - User cachedUser = (User) getById(item.getId()); + User cachedUser = getById(item.getId()); super.updateCachedItem(item); if (user.getToken() != null) { usersTokens.put(user.getToken(), user.getId()); @@ -62,7 +67,7 @@ public class UsersManager extends SimpleObjectManager { @Override protected void removeCachedItem(long userId) { - User cachedUser = (User) getById(userId); + User cachedUser = getById(userId); if (cachedUser != null) { String userToken = cachedUser.getToken(); super.removeCachedItem(userId); @@ -81,7 +86,7 @@ public class UsersManager extends SimpleObjectManager { } public User getUserByToken(String token) { - return (User) getById(usersTokens.get(token)); + return getById(usersTokens.get(token)); } } diff --git a/src/org/traccar/reports/Events.java b/src/org/traccar/reports/Events.java index 9d3acb250..348e6077f 100644 --- a/src/org/traccar/reports/Events.java +++ b/src/org/traccar/reports/Events.java @@ -92,7 +92,7 @@ public final class Events { deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); if (device.getGroupId() != 0) { - Group group = (Group) Context.getGroupsManager().getById(device.getGroupId()); + Group group = Context.getGroupsManager().getById(device.getGroupId()); if (group != null) { deviceEvents.setGroupName(group.getName()); } diff --git a/src/org/traccar/reports/Route.java b/src/org/traccar/reports/Route.java index 9f0696085..69be55155 100644 --- a/src/org/traccar/reports/Route.java +++ b/src/org/traccar/reports/Route.java @@ -61,7 +61,7 @@ public final class Route { deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); if (device.getGroupId() != 0) { - Group group = (Group) Context.getGroupsManager().getById(device.getGroupId()); + Group group = Context.getGroupsManager().getById(device.getGroupId()); if (group != null) { deviceRoutes.setGroupName(group.getName()); } diff --git a/src/org/traccar/reports/Stops.java b/src/org/traccar/reports/Stops.java index 1c631a0c2..20a6c1ce3 100644 --- a/src/org/traccar/reports/Stops.java +++ b/src/org/traccar/reports/Stops.java @@ -78,7 +78,7 @@ public final class Stops { deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); if (device.getGroupId() != 0) { - Group group = (Group) Context.getGroupsManager().getById(device.getGroupId()); + Group group = Context.getGroupsManager().getById(device.getGroupId()); if (group != null) { deviceStops.setGroupName(group.getName()); } diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java index 51689bfd3..7b5df0248 100644 --- a/src/org/traccar/reports/Trips.java +++ b/src/org/traccar/reports/Trips.java @@ -77,7 +77,7 @@ public final class Trips { deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); if (device.getGroupId() != 0) { - Group group = (Group) Context.getGroupsManager().getById(device.getGroupId()); + Group group = Context.getGroupsManager().getById(device.getGroupId()); if (group != null) { deviceTrips.setGroupName(group.getName()); } -- cgit v1.2.3 From d31f68d80a8e3ae75fa0c2f02b9ca258486a3cad Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 26 Jul 2017 17:52:27 +0500 Subject: - Implement base manager classes as generics - Remame getDeviceById and getDeviceByUniqueId functions --- src/org/traccar/BaseProtocolDecoder.java | 2 +- src/org/traccar/BaseProtocolEncoder.java | 4 +-- src/org/traccar/FilterHandler.java | 2 +- src/org/traccar/MainEventHandler.java | 2 +- src/org/traccar/WebDataHandler.java | 2 +- .../traccar/api/resource/AttributeResource.java | 2 +- src/org/traccar/api/resource/CalendarResource.java | 9 ++++-- src/org/traccar/api/resource/DeviceResource.java | 4 +-- src/org/traccar/api/resource/DriverResource.java | 2 +- src/org/traccar/api/resource/GeofenceResource.java | 2 +- src/org/traccar/api/resource/GroupResource.java | 2 +- src/org/traccar/api/resource/PositionResource.java | 2 +- src/org/traccar/api/resource/UserResource.java | 2 +- src/org/traccar/database/AttributesManager.java | 13 ++------- src/org/traccar/database/BaseObjectManager.java | 28 +++++++++--------- src/org/traccar/database/CalendarManager.java | 7 +---- src/org/traccar/database/ConnectionManager.java | 2 +- src/org/traccar/database/DeviceManager.java | 34 +++++++++------------- src/org/traccar/database/DriversManager.java | 25 ++++++---------- .../traccar/database/ExtendedObjectManager.java | 4 +-- src/org/traccar/database/GeofenceManager.java | 7 +---- src/org/traccar/database/GroupsManager.java | 19 +++++------- src/org/traccar/database/IdentityManager.java | 4 +-- src/org/traccar/database/PermissionsManager.java | 5 ++-- src/org/traccar/database/SimpleObjectManager.java | 5 ++-- src/org/traccar/database/UsersManager.java | 21 +++++-------- src/org/traccar/events/FuelDropEventHandler.java | 2 +- src/org/traccar/events/GeofenceEventHandler.java | 11 ++++--- src/org/traccar/events/IgnitionEventHandler.java | 2 +- .../traccar/events/MaintenanceEventHandler.java | 2 +- src/org/traccar/events/MotionEventHandler.java | 2 +- src/org/traccar/events/OverspeedEventHandler.java | 2 +- src/org/traccar/notification/EventForwarder.java | 2 +- .../notification/NotificationFormatter.java | 2 +- .../processing/ComputedAttributesHandler.java | 4 +-- src/org/traccar/protocol/Gt06ProtocolDecoder.java | 2 +- .../traccar/protocol/MeitrackProtocolDecoder.java | 4 +-- src/org/traccar/reports/Events.java | 2 +- src/org/traccar/reports/ReportUtils.java | 4 +-- src/org/traccar/reports/Route.java | 2 +- src/org/traccar/reports/Stops.java | 2 +- src/org/traccar/reports/Summary.java | 2 +- src/org/traccar/reports/Trips.java | 2 +- test/org/traccar/BaseTest.java | 4 +-- 44 files changed, 112 insertions(+), 152 deletions(-) (limited to 'src/org/traccar/database/DeviceManager.java') diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java index b7ceabb5c..cc16000f4 100644 --- a/src/org/traccar/BaseProtocolDecoder.java +++ b/src/org/traccar/BaseProtocolDecoder.java @@ -75,7 +75,7 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder { try { for (String uniqueId : uniqueIds) { if (uniqueId != null) { - Device device = Context.getIdentityManager().getDeviceByUniqueId(uniqueId); + Device device = Context.getIdentityManager().getByUniqueId(uniqueId); if (device != null) { deviceId = device.getId(); break; diff --git a/src/org/traccar/BaseProtocolEncoder.java b/src/org/traccar/BaseProtocolEncoder.java index 3c2d08471..2c8a81868 100644 --- a/src/org/traccar/BaseProtocolEncoder.java +++ b/src/org/traccar/BaseProtocolEncoder.java @@ -25,12 +25,12 @@ import org.traccar.model.Device; public abstract class BaseProtocolEncoder extends OneToOneEncoder { protected String getUniqueId(long deviceId) { - return Context.getIdentityManager().getDeviceById(deviceId).getUniqueId(); + return Context.getIdentityManager().getById(deviceId).getUniqueId(); } protected void initDevicePassword(Command command, String defaultPassword) { if (!command.getAttributes().containsKey(Command.KEY_DEVICE_PASSWORD)) { - Device device = Context.getIdentityManager().getDeviceById(command.getDeviceId()); + Device device = Context.getIdentityManager().getById(command.getDeviceId()); String password = device.getString(Command.KEY_DEVICE_PASSWORD); if (password != null) { command.set(Command.KEY_DEVICE_PASSWORD, password); diff --git a/src/org/traccar/FilterHandler.java b/src/org/traccar/FilterHandler.java index 71c0a1cf5..1f5fffc86 100644 --- a/src/org/traccar/FilterHandler.java +++ b/src/org/traccar/FilterHandler.java @@ -184,7 +184,7 @@ public class FilterHandler extends BaseDataHandler { message.append("Position filtered by "); message.append(filterType.toString()); message.append("filters from device: "); - message.append(Context.getIdentityManager().getDeviceById(position.getDeviceId()).getUniqueId()); + message.append(Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId()); message.append(" with id: "); message.append(position.getDeviceId()); diff --git a/src/org/traccar/MainEventHandler.java b/src/org/traccar/MainEventHandler.java index a005ee44b..8e88e15b9 100644 --- a/src/org/traccar/MainEventHandler.java +++ b/src/org/traccar/MainEventHandler.java @@ -55,7 +55,7 @@ public class MainEventHandler extends IdleStateAwareChannelHandler { Log.warning(error); } - String uniqueId = Context.getIdentityManager().getDeviceById(position.getDeviceId()).getUniqueId(); + String uniqueId = Context.getIdentityManager().getById(position.getDeviceId()).getUniqueId(); // Log position StringBuilder s = new StringBuilder(); diff --git a/src/org/traccar/WebDataHandler.java b/src/org/traccar/WebDataHandler.java index eaf0978ef..c64dcc81b 100644 --- a/src/org/traccar/WebDataHandler.java +++ b/src/org/traccar/WebDataHandler.java @@ -75,7 +75,7 @@ public class WebDataHandler extends BaseDataHandler { public String formatRequest(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); String request = url .replace("{name}", device.getName()) diff --git a/src/org/traccar/api/resource/AttributeResource.java b/src/org/traccar/api/resource/AttributeResource.java index 7b81d3ffb..c12fcd9e6 100644 --- a/src/org/traccar/api/resource/AttributeResource.java +++ b/src/org/traccar/api/resource/AttributeResource.java @@ -81,7 +81,7 @@ public class AttributeResource extends BaseResource { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); result.retainAll(attributesManager.getDeviceItems(deviceId)); } - return attributesManager.getItems(Attribute.class, result); + return attributesManager.getItems(result); } diff --git a/src/org/traccar/api/resource/CalendarResource.java b/src/org/traccar/api/resource/CalendarResource.java index a0f8656af..f8d78a847 100644 --- a/src/org/traccar/api/resource/CalendarResource.java +++ b/src/org/traccar/api/resource/CalendarResource.java @@ -18,6 +18,7 @@ package org.traccar.api.resource; import java.sql.SQLException; import java.util.Collection; +import java.util.Set; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -47,20 +48,22 @@ public class CalendarResource extends BaseResource { @QueryParam("all") boolean all, @QueryParam("userId") long userId) throws SQLException { CalendarManager calendarManager = Context.getCalendarManager(); + Set result = null; if (all) { if (Context.getPermissionsManager().isAdmin(getUserId())) { - return calendarManager.getItems(Calendar.class, calendarManager.getAllItems()); + result = calendarManager.getAllItems(); } else { Context.getPermissionsManager().checkManager(getUserId()); - return calendarManager.getItems(Calendar.class, calendarManager.getManagedItems(getUserId())); + result = calendarManager.getManagedItems(getUserId()); } } else { if (userId == 0) { userId = getUserId(); } Context.getPermissionsManager().checkUser(getUserId(), userId); - return calendarManager.getItems(Calendar.class, calendarManager.getUserItems(userId)); + result = calendarManager.getUserItems(userId); } + return calendarManager.getItems(result); } @POST diff --git a/src/org/traccar/api/resource/DeviceResource.java b/src/org/traccar/api/resource/DeviceResource.java index c621d4304..a473b7bde 100644 --- a/src/org/traccar/api/resource/DeviceResource.java +++ b/src/org/traccar/api/resource/DeviceResource.java @@ -68,7 +68,7 @@ public class DeviceResource extends BaseResource { } else { result = new HashSet(); for (String uniqueId : uniqueIds) { - Device device = deviceManager.getDeviceByUniqueId(uniqueId); + Device device = deviceManager.getByUniqueId(uniqueId); Context.getPermissionsManager().checkDevice(getUserId(), device.getId()); result.add(device.getId()); } @@ -77,7 +77,7 @@ public class DeviceResource extends BaseResource { result.add(deviceId); } } - return deviceManager.getItems(Device.class, result); + return deviceManager.getItems(result); } @POST diff --git a/src/org/traccar/api/resource/DriverResource.java b/src/org/traccar/api/resource/DriverResource.java index 72eadb711..d44979998 100644 --- a/src/org/traccar/api/resource/DriverResource.java +++ b/src/org/traccar/api/resource/DriverResource.java @@ -79,7 +79,7 @@ public class DriverResource extends BaseResource { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); result.retainAll(driversManager.getDeviceItems(deviceId)); } - return driversManager.getItems(Driver.class, result); + return driversManager.getItems(result); } diff --git a/src/org/traccar/api/resource/GeofenceResource.java b/src/org/traccar/api/resource/GeofenceResource.java index 47f889e9c..9a110fbcf 100644 --- a/src/org/traccar/api/resource/GeofenceResource.java +++ b/src/org/traccar/api/resource/GeofenceResource.java @@ -78,7 +78,7 @@ public class GeofenceResource extends BaseResource { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); result.retainAll(geofenceManager.getDeviceItems(deviceId)); } - return geofenceManager.getItems(Geofence.class, result); + return geofenceManager.getItems(result); } diff --git a/src/org/traccar/api/resource/GroupResource.java b/src/org/traccar/api/resource/GroupResource.java index f832660b2..4482f06c0 100644 --- a/src/org/traccar/api/resource/GroupResource.java +++ b/src/org/traccar/api/resource/GroupResource.java @@ -60,7 +60,7 @@ public class GroupResource extends BaseResource { Context.getPermissionsManager().checkUser(getUserId(), userId); result = groupsManager.getUserItems(userId); } - return groupsManager.getItems(Group.class, result); + return groupsManager.getItems(result); } @POST diff --git a/src/org/traccar/api/resource/PositionResource.java b/src/org/traccar/api/resource/PositionResource.java index 9d3cd9ae6..6dab51744 100644 --- a/src/org/traccar/api/resource/PositionResource.java +++ b/src/org/traccar/api/resource/PositionResource.java @@ -87,7 +87,7 @@ public class PositionResource extends BaseResource { @QueryParam("deviceId") long deviceId, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - GpxBuilder gpx = new GpxBuilder(Context.getIdentityManager().getDeviceById(deviceId).getName()); + GpxBuilder gpx = new GpxBuilder(Context.getIdentityManager().getById(deviceId).getName()); gpx.addPositions(Context.getDataManager().getPositions( deviceId, DateUtil.parseDate(from), DateUtil.parseDate(to))); return Response.ok(gpx.build()).header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_GPX).build(); diff --git a/src/org/traccar/api/resource/UserResource.java b/src/org/traccar/api/resource/UserResource.java index 9998ed346..deb2dd2b4 100644 --- a/src/org/traccar/api/resource/UserResource.java +++ b/src/org/traccar/api/resource/UserResource.java @@ -58,7 +58,7 @@ public class UserResource extends BaseResource { } else { throw new SecurityException("Admin or manager access required"); } - return usersManager.getItems(User.class, result); + return usersManager.getItems(result); } @PermitAll diff --git a/src/org/traccar/database/AttributesManager.java b/src/org/traccar/database/AttributesManager.java index e80d57c4e..28816645a 100644 --- a/src/org/traccar/database/AttributesManager.java +++ b/src/org/traccar/database/AttributesManager.java @@ -17,23 +17,16 @@ package org.traccar.database; import org.traccar.model.Attribute; -import org.traccar.model.BaseModel; -public class AttributesManager extends ExtendedObjectManager { +public class AttributesManager extends ExtendedObjectManager { public AttributesManager(DataManager dataManager) { super(dataManager, Attribute.class); } @Override - public Attribute getById(long calendarId) { - return (Attribute) super.getById(calendarId); - } - - @Override - public void updateCachedItem(BaseModel item) { - Attribute attribute = (Attribute) item; - Attribute cachedAttribute = getById(item.getId()); + public void updateCachedItem(Attribute attribute) { + Attribute cachedAttribute = getById(attribute.getId()); cachedAttribute.setDescription(attribute.getDescription()); cachedAttribute.setAttribute(attribute.getAttribute()); cachedAttribute.setExpression(attribute.getExpression()); diff --git a/src/org/traccar/database/BaseObjectManager.java b/src/org/traccar/database/BaseObjectManager.java index 92cfd9b6b..cc1dbde5f 100644 --- a/src/org/traccar/database/BaseObjectManager.java +++ b/src/org/traccar/database/BaseObjectManager.java @@ -27,14 +27,14 @@ import java.util.concurrent.ConcurrentHashMap; import org.traccar.helper.Log; import org.traccar.model.BaseModel; -public class BaseObjectManager { +public class BaseObjectManager { private final DataManager dataManager; - private Map items; - private Class baseClass; + private Map items; + private Class baseClass; - protected BaseObjectManager(DataManager dataManager, Class baseClass) { + protected BaseObjectManager(DataManager dataManager, Class baseClass) { this.dataManager = dataManager; this.baseClass = baseClass; refreshItems(); @@ -44,23 +44,23 @@ public class BaseObjectManager { return dataManager; } - protected final Class getBaseClass() { + protected final Class getBaseClass() { return baseClass; } - public BaseModel getById(long itemId) { + public T getById(long itemId) { return items.get(itemId); } public void refreshItems() { if (dataManager != null) { try { - Collection databaseItems = dataManager.getObjects(baseClass); + Collection databaseItems = dataManager.getObjects(baseClass); if (items == null) { items = new ConcurrentHashMap<>(databaseItems.size()); } Set databaseItemIds = new HashSet<>(); - for (BaseModel item : databaseItems) { + for (T item : databaseItems) { databaseItemIds.add(item.getId()); if (items.containsKey(item.getId())) { updateCachedItem(item); @@ -79,20 +79,20 @@ public class BaseObjectManager { } } - protected void addNewItem(BaseModel item) { + protected void addNewItem(T item) { items.put(item.getId(), item); } - public void addItem(BaseModel item) throws SQLException { + public void addItem(T item) throws SQLException { dataManager.addObject(item); addNewItem(item); } - protected void updateCachedItem(BaseModel item) { + protected void updateCachedItem(T item) { items.put(item.getId(), item); } - public void updateItem(BaseModel item) throws SQLException { + public void updateItem(T item) throws SQLException { dataManager.updateObject(item); updateCachedItem(item); } @@ -109,10 +109,10 @@ public class BaseObjectManager { } } - public final Collection getItems(Class clazz, Set itemIds) { + public final Collection getItems(Set itemIds) { Collection result = new LinkedList<>(); for (long itemId : itemIds) { - result.add((T) getById(itemId)); + result.add(getById(itemId)); } return result; } diff --git a/src/org/traccar/database/CalendarManager.java b/src/org/traccar/database/CalendarManager.java index b8d0914ee..44ced1082 100644 --- a/src/org/traccar/database/CalendarManager.java +++ b/src/org/traccar/database/CalendarManager.java @@ -18,15 +18,10 @@ package org.traccar.database; import org.traccar.model.Calendar; -public class CalendarManager extends SimpleObjectManager { +public class CalendarManager extends SimpleObjectManager { public CalendarManager(DataManager dataManager) { super(dataManager, Calendar.class); } - @Override - public Calendar getById(long calendarId) { - return (Calendar) super.getById(calendarId); - } - } diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index 0baafb578..1445fb785 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -70,7 +70,7 @@ public class ConnectionManager { } public void updateDevice(final long deviceId, String status, Date time) { - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); if (device == null) { return; } diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 1fe7ddfa5..4aafe6631 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -30,7 +30,6 @@ import org.traccar.BaseProtocol; import org.traccar.Config; import org.traccar.Context; import org.traccar.helper.Log; -import org.traccar.model.BaseModel; import org.traccar.model.Command; import org.traccar.model.CommandType; import org.traccar.model.Device; @@ -39,7 +38,7 @@ import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Server; -public class DeviceManager extends BaseObjectManager implements IdentityManager, ManagableObjects { +public class DeviceManager extends BaseObjectManager implements IdentityManager, ManagableObjects { public static final long DEFAULT_REFRESH_DELAY = 300; @@ -73,12 +72,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, } @Override - public Device getDeviceById(long id) { - return (Device) getById(id); - } - - @Override - public Device getDeviceByUniqueId(String uniqueId) throws SQLException { + public Device getByUniqueId(String uniqueId) throws SQLException { boolean forceUpdate = !devicesByUniqueId.containsKey(uniqueId) && !config.getBoolean("database.ignoreUnknown"); updateDeviceCache(forceUpdate); @@ -105,7 +99,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, } public Collection getAllDevices() { - return getItems(Device.class, getAllItems()); + return getItems(getAllItems()); } @Override @@ -142,9 +136,8 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, } @Override - protected void addNewItem(BaseModel item) { - super.addNewItem(item); - Device device = (Device) item; + protected void addNewItem(Device device) { + super.addNewItem(device); putUniqueDeviceId(device); if (device.getPhone() != null && !device.getPhone().isEmpty()) { putPhone(device); @@ -158,9 +151,8 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, } @Override - protected void updateCachedItem(BaseModel item) { - Device device = (Device) item; - Device cachedDevice = getDeviceById(device.getId()); + protected void updateCachedItem(Device device) { + Device cachedDevice = getById(device.getId()); cachedDevice.setName(device.getName()); cachedDevice.setGroupId(device.getGroupId()); cachedDevice.setCategory(device.getCategory()); @@ -182,7 +174,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, @Override protected void removeCachedItem(long deviceId) { - Device cachedDevice = getDeviceById(deviceId); + Device cachedDevice = getById(deviceId); if (cachedDevice != null) { String deviceUniqueId = cachedDevice.getUniqueId(); String phone = cachedDevice.getPhone(); @@ -197,7 +189,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, public void updateDeviceStatus(Device device) throws SQLException { getDataManager().updateDeviceStatus(device); - Device cachedDevice = getDeviceById(device.getId()); + Device cachedDevice = getById(device.getId()); if (cachedDevice != null) { cachedDevice.setStatus(device.getStatus()); } @@ -226,7 +218,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, getDataManager().updateLatestPosition(position); - Device device = getDeviceById(position.getDeviceId()); + Device device = getById(position.getDeviceId()); if (device != null) { device.setPositionId(position.getId()); } @@ -305,7 +297,7 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, private String lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) { String result = null; - Device device = getDeviceById(deviceId); + Device device = getById(deviceId); if (device != null) { result = device.getString(attributeName); if (result == null && lookupGroupsAttribute) { @@ -352,9 +344,9 @@ public class DeviceManager extends BaseObjectManager implements IdentityManager, Position lastPosition = getLastPosition(deviceId); if (lastPosition != null) { BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - protocol.sendTextCommand(getDeviceById(deviceId).getPhone(), command); + protocol.sendTextCommand(getById(deviceId).getPhone(), command); } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - Context.getSmppManager().sendMessageSync(((Device) getById(deviceId)).getPhone(), + Context.getSmppManager().sendMessageSync(getById(deviceId).getPhone(), command.getString(Command.KEY_DATA), true); } else { throw new RuntimeException("Command " + command.getType() + " is not supported"); diff --git a/src/org/traccar/database/DriversManager.java b/src/org/traccar/database/DriversManager.java index 420824dbb..d3866a5f0 100644 --- a/src/org/traccar/database/DriversManager.java +++ b/src/org/traccar/database/DriversManager.java @@ -20,37 +20,30 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.traccar.model.Driver; -import org.traccar.model.BaseModel; -public class DriversManager extends ExtendedObjectManager { +public class DriversManager extends ExtendedObjectManager { - private Map driversByUniqueId; + private Map driversByUniqueId; public DriversManager(DataManager dataManager) { super(dataManager, Driver.class); } - @Override - public Driver getById(long driverId) { - return (Driver) super.getById(driverId); - } - private void putUniqueDriverId(Driver driver) { if (driversByUniqueId == null) { - driversByUniqueId = new ConcurrentHashMap<>(); + driversByUniqueId = new ConcurrentHashMap<>(getAllItems().size()); } - driversByUniqueId.put(driver.getUniqueId(), driver); + driversByUniqueId.put(driver.getUniqueId(), driver.getId()); } @Override - protected void addNewItem(BaseModel item) { - super.addNewItem(item); - putUniqueDriverId((Driver) item); + protected void addNewItem(Driver driver) { + super.addNewItem(driver); + putUniqueDriverId(driver); } @Override - protected void updateCachedItem(BaseModel item) { - Driver driver = (Driver) item; + protected void updateCachedItem(Driver driver) { Driver cachedDriver = getById(driver.getId()); cachedDriver.setName(driver.getName()); if (!driver.getUniqueId().equals(cachedDriver.getUniqueId())) { @@ -72,6 +65,6 @@ public class DriversManager extends ExtendedObjectManager { } public Driver getDriverByUniqueId(String uniqueId) { - return driversByUniqueId.get(uniqueId); + return getById(driversByUniqueId.get(uniqueId)); } } diff --git a/src/org/traccar/database/ExtendedObjectManager.java b/src/org/traccar/database/ExtendedObjectManager.java index 19c9ca5b2..16785cb37 100644 --- a/src/org/traccar/database/ExtendedObjectManager.java +++ b/src/org/traccar/database/ExtendedObjectManager.java @@ -30,13 +30,13 @@ import org.traccar.model.Group; import org.traccar.model.Permission; import org.traccar.model.BaseModel; -public abstract class ExtendedObjectManager extends SimpleObjectManager { +public abstract class ExtendedObjectManager extends SimpleObjectManager { private final Map> deviceItems = new ConcurrentHashMap<>(); private final Map> deviceItemsWithGroups = new ConcurrentHashMap<>(); private final Map> groupItems = new ConcurrentHashMap<>(); - protected ExtendedObjectManager(DataManager dataManager, Class baseClass) { + protected ExtendedObjectManager(DataManager dataManager, Class baseClass) { super(dataManager, baseClass); refreshExtendedPermissions(); } diff --git a/src/org/traccar/database/GeofenceManager.java b/src/org/traccar/database/GeofenceManager.java index 4bc3909cd..a32847cf9 100644 --- a/src/org/traccar/database/GeofenceManager.java +++ b/src/org/traccar/database/GeofenceManager.java @@ -23,17 +23,12 @@ import org.traccar.model.Device; import org.traccar.model.Geofence; import org.traccar.model.Position; -public class GeofenceManager extends ExtendedObjectManager { +public class GeofenceManager extends ExtendedObjectManager { public GeofenceManager(DataManager dataManager) { super(dataManager, Geofence.class); } - @Override - public Geofence getById(long geofenceId) { - return (Geofence) super.getById(geofenceId); - } - @Override public final void refreshExtendedPermissions() { super.refreshExtendedPermissions(); diff --git a/src/org/traccar/database/GroupsManager.java b/src/org/traccar/database/GroupsManager.java index 095e7a22c..20b403d55 100644 --- a/src/org/traccar/database/GroupsManager.java +++ b/src/org/traccar/database/GroupsManager.java @@ -26,7 +26,7 @@ import org.traccar.helper.Log; import org.traccar.model.BaseModel; import org.traccar.model.Group; -public class GroupsManager extends BaseObjectManager implements ManagableObjects { +public class GroupsManager extends BaseObjectManager implements ManagableObjects { private AtomicLong groupsLastUpdate = new AtomicLong(); private final long dataRefreshDelay; @@ -37,11 +37,6 @@ public class GroupsManager extends BaseObjectManager implements ManagableObjects DeviceManager.DEFAULT_REFRESH_DELAY) * 1000; } - @Override - public Group getById(long groupId) { - return (Group) super.getById(groupId); - } - private void checkGroupCycles(BaseModel group) { Set groups = new HashSet<>(); while (group != null) { @@ -76,15 +71,15 @@ public class GroupsManager extends BaseObjectManager implements ManagableObjects } @Override - protected void addNewItem(BaseModel item) { - checkGroupCycles(item); - super.addNewItem(item); + protected void addNewItem(Group group) { + checkGroupCycles(group); + super.addNewItem(group); } @Override - protected void updateCachedItem(BaseModel item) { - checkGroupCycles(item); - super.updateCachedItem(item); + protected void updateCachedItem(Group group) { + checkGroupCycles(group); + super.updateCachedItem(group); } @Override diff --git a/src/org/traccar/database/IdentityManager.java b/src/org/traccar/database/IdentityManager.java index c8c593a54..82d905963 100644 --- a/src/org/traccar/database/IdentityManager.java +++ b/src/org/traccar/database/IdentityManager.java @@ -20,9 +20,9 @@ import org.traccar.model.Position; public interface IdentityManager { - Device getDeviceById(long id); + Device getById(long id); - Device getDeviceByUniqueId(String uniqueId) throws Exception; + Device getByUniqueId(String uniqueId) throws Exception; Position getLastPosition(long deviceId); diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 54e5ed979..3b03c1900 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -18,6 +18,7 @@ package org.traccar.database; import org.traccar.Context; import org.traccar.helper.Log; import org.traccar.model.Attribute; +import org.traccar.model.BaseModel; import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Driver; @@ -99,7 +100,7 @@ public class PermissionsManager { devicePermissions.clear(); try { GroupTree groupTree = new GroupTree(Context.getGroupsManager().getItems( - Group.class, Context.getGroupsManager().getAllItems()), + Context.getGroupsManager().getAllItems()), Context.getDeviceManager().getAllDevices()); for (Permission groupPermission : dataManager.getPermissions(User.class, Group.class)) { Set userGroupPermissions = getGroupPermissions(groupPermission.getOwnerId()); @@ -284,7 +285,7 @@ public class PermissionsManager { public void checkPermission(Class object, long userId, long objectId) throws SecurityException { - SimpleObjectManager manager = null; + SimpleObjectManager manager = null; if (object.equals(Device.class)) { checkDevice(userId, objectId); diff --git a/src/org/traccar/database/SimpleObjectManager.java b/src/org/traccar/database/SimpleObjectManager.java index fa41f30b6..0b4d11378 100644 --- a/src/org/traccar/database/SimpleObjectManager.java +++ b/src/org/traccar/database/SimpleObjectManager.java @@ -28,11 +28,12 @@ import org.traccar.model.BaseModel; import org.traccar.model.Permission; import org.traccar.model.User; -public abstract class SimpleObjectManager extends BaseObjectManager implements ManagableObjects { +public abstract class SimpleObjectManager extends BaseObjectManager + implements ManagableObjects { private Map> userItems; - protected SimpleObjectManager(DataManager dataManager, Class baseClass) { + protected SimpleObjectManager(DataManager dataManager, Class baseClass) { super(dataManager, baseClass); } diff --git a/src/org/traccar/database/UsersManager.java b/src/org/traccar/database/UsersManager.java index e53409b4f..28e6a31b2 100644 --- a/src/org/traccar/database/UsersManager.java +++ b/src/org/traccar/database/UsersManager.java @@ -21,10 +21,9 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import org.traccar.model.BaseModel; import org.traccar.model.User; -public class UsersManager extends SimpleObjectManager { +public class UsersManager extends SimpleObjectManager { private Map usersTokens; @@ -32,11 +31,6 @@ public class UsersManager extends SimpleObjectManager { super(dataManager, User.class); } - @Override - public User getById(long userId) { - return (User) super.getById(userId); - } - private void putToken(User user) { if (usersTokens == null) { usersTokens = new ConcurrentHashMap<>(); @@ -47,16 +41,15 @@ public class UsersManager extends SimpleObjectManager { } @Override - protected void addNewItem(BaseModel item) { - super.addNewItem(item); - putToken((User) item); + protected void addNewItem(User user) { + super.addNewItem(user); + putToken(user); } @Override - protected void updateCachedItem(BaseModel item) { - User user = (User) item; - User cachedUser = getById(item.getId()); - super.updateCachedItem(item); + protected void updateCachedItem(User user) { + User cachedUser = getById(user.getId()); + super.updateCachedItem(user); if (user.getToken() != null) { usersTokens.put(user.getToken(), user.getId()); } diff --git a/src/org/traccar/events/FuelDropEventHandler.java b/src/org/traccar/events/FuelDropEventHandler.java index e9a261aea..4e09bd4fa 100644 --- a/src/org/traccar/events/FuelDropEventHandler.java +++ b/src/org/traccar/events/FuelDropEventHandler.java @@ -31,7 +31,7 @@ public class FuelDropEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; } diff --git a/src/org/traccar/events/GeofenceEventHandler.java b/src/org/traccar/events/GeofenceEventHandler.java index 516df9d69..79e5d0f8e 100644 --- a/src/org/traccar/events/GeofenceEventHandler.java +++ b/src/org/traccar/events/GeofenceEventHandler.java @@ -25,7 +25,6 @@ import org.traccar.database.GeofenceManager; import org.traccar.model.Calendar; import org.traccar.model.Device; import org.traccar.model.Event; -import org.traccar.model.Geofence; import org.traccar.model.Position; public class GeofenceEventHandler extends BaseEventHandler { @@ -38,7 +37,7 @@ public class GeofenceEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; } @@ -59,8 +58,8 @@ public class GeofenceEventHandler extends BaseEventHandler { Collection events = new ArrayList<>(); for (long geofenceId : newGeofences) { - long calendarId = ((Geofence) geofenceManager.getById(geofenceId)).getCalendarId(); - Calendar calendar = calendarId != 0 ? (Calendar) Context.getCalendarManager().getById(calendarId) : null; + long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); + Calendar calendar = calendarId != 0 ? Context.getCalendarManager().getById(calendarId) : null; if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position.getDeviceId(), position.getId()); event.setGeofenceId(geofenceId); @@ -68,8 +67,8 @@ public class GeofenceEventHandler extends BaseEventHandler { } } for (long geofenceId : oldGeofences) { - long calendarId = ((Geofence) geofenceManager.getById(geofenceId)).getCalendarId(); - Calendar calendar = calendarId != 0 ? (Calendar) Context.getCalendarManager().getById(calendarId) : null; + long calendarId = geofenceManager.getById(geofenceId).getCalendarId(); + Calendar calendar = calendarId != 0 ? Context.getCalendarManager().getById(calendarId) : null; if (calendar == null || calendar.checkMoment(position.getFixTime())) { Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position.getDeviceId(), position.getId()); event.setGeofenceId(geofenceId); diff --git a/src/org/traccar/events/IgnitionEventHandler.java b/src/org/traccar/events/IgnitionEventHandler.java index c628cc107..5519135bf 100644 --- a/src/org/traccar/events/IgnitionEventHandler.java +++ b/src/org/traccar/events/IgnitionEventHandler.java @@ -29,7 +29,7 @@ public class IgnitionEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null || !Context.getIdentityManager().isLatestPosition(position)) { return null; } diff --git a/src/org/traccar/events/MaintenanceEventHandler.java b/src/org/traccar/events/MaintenanceEventHandler.java index 86836f6af..ffeefc8c5 100644 --- a/src/org/traccar/events/MaintenanceEventHandler.java +++ b/src/org/traccar/events/MaintenanceEventHandler.java @@ -32,7 +32,7 @@ public class MaintenanceEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null || !Context.getIdentityManager().isLatestPosition(position)) { return null; } diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index e6fd10f3e..ed81176a8 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -29,7 +29,7 @@ public class MotionEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; } diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java index 00c3845d2..795892f40 100644 --- a/src/org/traccar/events/OverspeedEventHandler.java +++ b/src/org/traccar/events/OverspeedEventHandler.java @@ -37,7 +37,7 @@ public class OverspeedEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device == null) { return null; } diff --git a/src/org/traccar/notification/EventForwarder.java b/src/org/traccar/notification/EventForwarder.java index 08f55df75..ac37f980c 100644 --- a/src/org/traccar/notification/EventForwarder.java +++ b/src/org/traccar/notification/EventForwarder.java @@ -69,7 +69,7 @@ public final class EventForwarder { data.put(KEY_POSITION, position); } if (event.getDeviceId() != 0) { - Device device = Context.getIdentityManager().getDeviceById(event.getDeviceId()); + Device device = Context.getIdentityManager().getById(event.getDeviceId()); if (device != null) { data.put(KEY_DEVICE, device); } diff --git a/src/org/traccar/notification/NotificationFormatter.java b/src/org/traccar/notification/NotificationFormatter.java index cd9959671..33fd2cdc7 100644 --- a/src/org/traccar/notification/NotificationFormatter.java +++ b/src/org/traccar/notification/NotificationFormatter.java @@ -40,7 +40,7 @@ public final class NotificationFormatter { public static VelocityContext prepareContext(long userId, Event event, Position position) { User user = Context.getPermissionsManager().getUser(userId); - Device device = Context.getIdentityManager().getDeviceById(event.getDeviceId()); + Device device = Context.getIdentityManager().getById(event.getDeviceId()); VelocityContext velocityContext = new VelocityContext(); velocityContext.put("user", user); diff --git a/src/org/traccar/processing/ComputedAttributesHandler.java b/src/org/traccar/processing/ComputedAttributesHandler.java index d6a762535..f1f371475 100644 --- a/src/org/traccar/processing/ComputedAttributesHandler.java +++ b/src/org/traccar/processing/ComputedAttributesHandler.java @@ -51,7 +51,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { private MapContext prepareContext(Position position) { MapContext result = new MapContext(); if (mapDeviceAttributes) { - Device device = Context.getIdentityManager().getDeviceById(position.getDeviceId()); + Device device = Context.getIdentityManager().getById(position.getDeviceId()); if (device != null) { for (Object key : device.getAttributes().keySet()) { result.set((String) key, device.getAttributes().get(key)); @@ -86,7 +86,7 @@ public class ComputedAttributesHandler extends BaseDataHandler { @Override protected Position handlePosition(Position position) { - Collection attributes = Context.getAttributesManager().getItems(Attribute.class, + Collection attributes = Context.getAttributesManager().getItems( Context.getAttributesManager().getAllDeviceItems(position.getDeviceId())); for (Attribute attribute : attributes) { if (attribute.getAttribute() != null) { diff --git a/src/org/traccar/protocol/Gt06ProtocolDecoder.java b/src/org/traccar/protocol/Gt06ProtocolDecoder.java index 36358b6e5..186867b9d 100644 --- a/src/org/traccar/protocol/Gt06ProtocolDecoder.java +++ b/src/org/traccar/protocol/Gt06ProtocolDecoder.java @@ -555,7 +555,7 @@ public class Gt06ProtocolDecoder extends BaseProtocolDecoder { if (photo.writableBytes() > 0) { sendPhotoRequest(channel, pictureId); } else { - Device device = Context.getDeviceManager().getDeviceById(deviceSession.getDeviceId()); + Device device = Context.getDeviceManager().getById(deviceSession.getDeviceId()); Context.getMediaManager().writeFile(device.getUniqueId(), photo, "jpg"); photos.remove(pictureId); } diff --git a/src/org/traccar/protocol/MeitrackProtocolDecoder.java b/src/org/traccar/protocol/MeitrackProtocolDecoder.java index 711697fc4..469ef3f76 100644 --- a/src/org/traccar/protocol/MeitrackProtocolDecoder.java +++ b/src/org/traccar/protocol/MeitrackProtocolDecoder.java @@ -160,7 +160,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { } } - String deviceModel = Context.getIdentityManager().getDeviceById(deviceSession.getDeviceId()).getModel(); + String deviceModel = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getModel(); if (deviceModel == null) { deviceModel = ""; } @@ -316,7 +316,7 @@ public class MeitrackProtocolDecoder extends BaseProtocolDecoder { case "D03": if (channel != null) { DeviceSession deviceSession = getDeviceSession(channel, remoteAddress); - String imei = Context.getIdentityManager().getDeviceById(deviceSession.getDeviceId()).getUniqueId(); + String imei = Context.getIdentityManager().getById(deviceSession.getDeviceId()).getUniqueId(); channel.write("@@O46," + imei + ",D00,camera_picture.jpg,0*00\r\n"); } return null; diff --git a/src/org/traccar/reports/Events.java b/src/org/traccar/reports/Events.java index 348e6077f..63077de32 100644 --- a/src/org/traccar/reports/Events.java +++ b/src/org/traccar/reports/Events.java @@ -88,7 +88,7 @@ public final class Events { } } DeviceReport deviceEvents = new DeviceReport(); - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); deviceEvents.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceEvents.getDeviceName())); if (device.getGroupId() != 0) { diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index bc58d28df..cf94030ab 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -176,7 +176,7 @@ public final class ReportUtils { long tripDuration = endTrip.getFixTime().getTime() - startTrip.getFixTime().getTime(); long deviceId = startTrip.getDeviceId(); trip.setDeviceId(deviceId); - trip.setDeviceName(Context.getIdentityManager().getDeviceById(deviceId).getName()); + trip.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); trip.setStartPositionId(startTrip.getId()); trip.setStartLat(startTrip.getLatitude()); @@ -210,7 +210,7 @@ public final class ReportUtils { long deviceId = startStop.getDeviceId(); stop.setDeviceId(deviceId); - stop.setDeviceName(Context.getIdentityManager().getDeviceById(deviceId).getName()); + stop.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); stop.setPositionId(startStop.getId()); stop.setLatitude(startStop.getLatitude()); diff --git a/src/org/traccar/reports/Route.java b/src/org/traccar/reports/Route.java index 69be55155..1c53a15cc 100644 --- a/src/org/traccar/reports/Route.java +++ b/src/org/traccar/reports/Route.java @@ -57,7 +57,7 @@ public final class Route { Collection positions = Context.getDataManager() .getPositions(deviceId, from, to); DeviceReport deviceRoutes = new DeviceReport(); - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); deviceRoutes.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceRoutes.getDeviceName())); if (device.getGroupId() != 0) { diff --git a/src/org/traccar/reports/Stops.java b/src/org/traccar/reports/Stops.java index 20a6c1ce3..886fd7915 100644 --- a/src/org/traccar/reports/Stops.java +++ b/src/org/traccar/reports/Stops.java @@ -74,7 +74,7 @@ public final class Stops { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection stops = detectStops(deviceId, from, to); DeviceReport deviceStops = new DeviceReport(); - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); deviceStops.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceStops.getDeviceName())); if (device.getGroupId() != 0) { diff --git a/src/org/traccar/reports/Summary.java b/src/org/traccar/reports/Summary.java index 5aaf33fae..dd9877cd7 100644 --- a/src/org/traccar/reports/Summary.java +++ b/src/org/traccar/reports/Summary.java @@ -38,7 +38,7 @@ public final class Summary { private static SummaryReport calculateSummaryResult(long deviceId, Date from, Date to) throws SQLException { SummaryReport result = new SummaryReport(); result.setDeviceId(deviceId); - result.setDeviceName(Context.getIdentityManager().getDeviceById(deviceId).getName()); + result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName()); Collection positions = Context.getDataManager().getPositions(deviceId, from, to); if (positions != null && !positions.isEmpty()) { Position firstPosition = null; diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java index 7b5df0248..68b03a819 100644 --- a/src/org/traccar/reports/Trips.java +++ b/src/org/traccar/reports/Trips.java @@ -73,7 +73,7 @@ public final class Trips { Context.getPermissionsManager().checkDevice(userId, deviceId); Collection trips = detectTrips(deviceId, from, to); DeviceReport deviceTrips = new DeviceReport(); - Device device = Context.getIdentityManager().getDeviceById(deviceId); + Device device = Context.getIdentityManager().getById(deviceId); deviceTrips.setDeviceName(device.getName()); sheetNames.add(WorkbookUtil.createSafeSheetName(deviceTrips.getDeviceName())); if (device.getGroupId() != 0) { diff --git a/test/org/traccar/BaseTest.java b/test/org/traccar/BaseTest.java index 6af8610cd..37956f11d 100644 --- a/test/org/traccar/BaseTest.java +++ b/test/org/traccar/BaseTest.java @@ -18,12 +18,12 @@ public class BaseTest { } @Override - public Device getDeviceById(long id) { + public Device getById(long id) { return createDevice(); } @Override - public Device getDeviceByUniqueId(String uniqueId) { + public Device getByUniqueId(String uniqueId) { return createDevice(); } -- cgit v1.2.3 From cabe5b5df2c1d31cd5fd3eeccbea32fa79cf404c Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 27 Jul 2017 14:57:22 +0500 Subject: Initialize some maps, because they might be accessed before initialized. --- src/org/traccar/database/DeviceManager.java | 6 ++++++ src/org/traccar/database/DriversManager.java | 3 +++ src/org/traccar/database/UsersManager.java | 3 +++ 3 files changed, 12 insertions(+) (limited to 'src/org/traccar/database/DeviceManager.java') diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 4aafe6631..5d123f9b8 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -57,6 +57,12 @@ public class DeviceManager extends BaseObjectManager implements Identity public DeviceManager(DataManager dataManager) { super(dataManager, Device.class); this.config = Context.getConfig(); + if (devicesByPhone == null) { + devicesByPhone = new ConcurrentHashMap<>(); + } + if (devicesByUniqueId == null) { + devicesByUniqueId = new ConcurrentHashMap<>(); + } dataRefreshDelay = config.getLong("database.refreshDelay", DEFAULT_REFRESH_DELAY) * 1000; lookupGroupsAttribute = config.getBoolean("deviceManager.lookupGroupsAttribute"); fallbackToText = config.getBoolean("command.fallbackToSms"); diff --git a/src/org/traccar/database/DriversManager.java b/src/org/traccar/database/DriversManager.java index d3866a5f0..9defa1931 100644 --- a/src/org/traccar/database/DriversManager.java +++ b/src/org/traccar/database/DriversManager.java @@ -27,6 +27,9 @@ public class DriversManager extends ExtendedObjectManager { public DriversManager(DataManager dataManager) { super(dataManager, Driver.class); + if (driversByUniqueId == null) { + driversByUniqueId = new ConcurrentHashMap<>(); + } } private void putUniqueDriverId(Driver driver) { diff --git a/src/org/traccar/database/UsersManager.java b/src/org/traccar/database/UsersManager.java index 28e6a31b2..ed39f6cfa 100644 --- a/src/org/traccar/database/UsersManager.java +++ b/src/org/traccar/database/UsersManager.java @@ -29,6 +29,9 @@ public class UsersManager extends SimpleObjectManager { public UsersManager(DataManager dataManager) { super(dataManager, User.class); + if (usersTokens == null) { + usersTokens = new ConcurrentHashMap<>(); + } } private void putToken(User user) { -- cgit v1.2.3 From 94a922eaf167a73a0188255398fb1c6799767e18 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 8 Aug 2017 09:53:31 +0500 Subject: Implement motion detection similar to trips detection --- src/org/traccar/database/ConnectionManager.java | 45 ++++++++++++- src/org/traccar/database/DeviceManager.java | 12 ++++ src/org/traccar/events/MotionEventHandler.java | 75 ++++++++++++++++++---- src/org/traccar/model/DeviceState.java | 41 ++++++++++++ src/org/traccar/reports/ReportUtils.java | 2 +- .../org/traccar/events/MotionEventHandlerTest.java | 56 +++++++++++++--- 6 files changed, 207 insertions(+), 24 deletions(-) create mode 100644 src/org/traccar/model/DeviceState.java (limited to 'src/org/traccar/database/DeviceManager.java') diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index 1445fb785..b3b00fefa 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -23,8 +23,11 @@ import org.traccar.GlobalTimer; import org.traccar.Protocol; import org.traccar.helper.Log; import org.traccar.model.Device; +import org.traccar.model.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.reports.ReportUtils; +import org.traccar.reports.model.TripsConfig; import java.net.SocketAddress; import java.sql.SQLException; @@ -41,6 +44,7 @@ public class ConnectionManager { private final long deviceTimeout; private final boolean enableStatusEvents; + private TripsConfig tripsConfig = null; private final Map activeDevices = new ConcurrentHashMap<>(); private final Map> listeners = new ConcurrentHashMap<>(); @@ -49,6 +53,9 @@ public class ConnectionManager { public ConnectionManager() { deviceTimeout = Context.getConfig().getLong("status.timeout", DEFAULT_TIMEOUT) * 1000; enableStatusEvents = Context.getConfig().getBoolean("event.enable"); + if (Context.getConfig().getBoolean("status.updateDeviceState")) { + tripsConfig = ReportUtils.initTripsConfig(); + } } public void addActiveDevice(long deviceId, Protocol protocol, Channel channel, SocketAddress remoteAddress) { @@ -80,21 +87,30 @@ public class ConnectionManager { if (enableStatusEvents && !status.equals(oldStatus)) { String eventType; + Event stateEvent = null; switch (status) { case Device.STATUS_ONLINE: eventType = Event.TYPE_DEVICE_ONLINE; break; case Device.STATUS_UNKNOWN: eventType = Event.TYPE_DEVICE_UNKNOWN; + if (tripsConfig != null) { + stateEvent = updateDeviceState(deviceId); + } break; default: eventType = Event.TYPE_DEVICE_OFFLINE; + if (tripsConfig != null) { + stateEvent = updateDeviceState(deviceId); + } break; } - Event event = new Event(eventType, deviceId); - if (Context.getNotificationManager() != null) { - Context.getNotificationManager().updateEvent(event, null); + Set events = new HashSet<>(); + if (stateEvent != null) { + events.add(stateEvent); } + events.add(new Event(eventType, deviceId)); + Context.getNotificationManager().updateEvents(events, null); } Timeout timeout = timeouts.remove(deviceId); @@ -126,6 +142,29 @@ public class ConnectionManager { updateDevice(device); } + public Event updateDeviceState(long deviceId) { + DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); + if (deviceState == null || deviceState.getMotionState() == null) { + return null; + } + Event result = null; + Boolean oldMotion = deviceState.getMotionState(); + long currentTime = new Date().getTime(); + boolean newMotion = !oldMotion; + Position potentialPosition = deviceState.getMotionPosition(); + if (potentialPosition != null) { + long potentialTime = potentialPosition.getFixTime().getTime() + + (newMotion ? tripsConfig.getMinimalTripDuration() : tripsConfig.getMinimalParkingDuration()); + if (potentialTime <= currentTime) { + String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; + result = new Event(eventType, potentialPosition.getDeviceId(), potentialPosition.getId()); + deviceState.setMotionState(newMotion); + deviceState.setMotionPosition(null); + } + } + return result; + } + public synchronized void updateDevice(Device device) { for (long userId : Context.getPermissionsManager().getDeviceUsers(device.getId())) { if (listeners.containsKey(userId)) { diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 5d123f9b8..3b7e5c617 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -33,6 +33,7 @@ import org.traccar.helper.Log; import org.traccar.model.Command; import org.traccar.model.CommandType; import org.traccar.model.Device; +import org.traccar.model.DeviceState; import org.traccar.model.DeviceTotalDistance; import org.traccar.model.Group; import org.traccar.model.Position; @@ -52,6 +53,8 @@ public class DeviceManager extends BaseObjectManager implements Identity private final Map positions = new ConcurrentHashMap<>(); + private final Map deviceStates = new ConcurrentHashMap<>(); + private boolean fallbackToText; public DeviceManager(DataManager dataManager) { @@ -387,4 +390,13 @@ public class DeviceManager extends BaseObjectManager implements Identity } return result; } + + public DeviceState getDeviceState(long deviceId) { + return deviceStates.get(deviceId); + } + + public void setDeviceState(long deviceId, DeviceState deviceState) { + deviceStates.put(deviceId, deviceState); + } + } diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index ed81176a8..9168d0fd8 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -21,11 +21,60 @@ import java.util.Collections; import org.traccar.BaseEventHandler; import org.traccar.Context; import org.traccar.model.Device; +import org.traccar.model.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.reports.ReportUtils; +import org.traccar.reports.model.TripsConfig; public class MotionEventHandler extends BaseEventHandler { + private TripsConfig tripsConfig; + + public MotionEventHandler() { + if (Context.getConfig() != null) { + tripsConfig = ReportUtils.initTripsConfig(); + } + } + + public static Event updateMotionState(DeviceState deviceState, Position position, TripsConfig tripsConfig) { + Event result = null; + Boolean oldMotion = deviceState.getMotionState(); + + long currentTime = position.getFixTime().getTime(); + boolean newMotion = position.getBoolean(Position.KEY_MOTION); + if (newMotion != oldMotion) { + if (deviceState.getMotionPosition() == null) { + deviceState.setMotionPosition(position); + } + } else { + deviceState.setMotionPosition(null); + } + + Position potentialPosition = deviceState.getMotionPosition(); + if (potentialPosition != null) { + long potentialTime = potentialPosition.getFixTime().getTime(); + double distance = ReportUtils.calculateDistance(potentialPosition, position, false); + if (newMotion) { + if (potentialTime + tripsConfig.getMinimalTripDuration() <= currentTime + || distance >= tripsConfig.getMinimalTripDistance()) { + result = new Event(Event.TYPE_DEVICE_MOVING, potentialPosition.getDeviceId(), + potentialPosition.getId()); + deviceState.setMotionState(true); + deviceState.setMotionPosition(null); + } + } else { + if (potentialTime + tripsConfig.getMinimalParkingDuration() <= currentTime) { + result = new Event(Event.TYPE_DEVICE_STOPPED, potentialPosition.getDeviceId(), + potentialPosition.getId()); + deviceState.setMotionState(false); + deviceState.setMotionPosition(null); + } + } + } + return result; + } + @Override protected Collection analyzePosition(Position position) { @@ -37,18 +86,22 @@ public class MotionEventHandler extends BaseEventHandler { return null; } - boolean motion = position.getBoolean(Position.KEY_MOTION); - boolean oldMotion = false; - Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId()); - if (lastPosition != null) { - oldMotion = lastPosition.getBoolean(Position.KEY_MOTION); + Event result = null; + + long deviceId = position.getDeviceId(); + DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); + + if (deviceState == null) { + deviceState = new DeviceState(); + deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); + } else if (deviceState.getMotionState() == null) { + deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); + } else { + result = updateMotionState(deviceState, position, tripsConfig); } - if (motion && !oldMotion) { - return Collections.singleton( - new Event(Event.TYPE_DEVICE_MOVING, position.getDeviceId(), position.getId())); - } else if (!motion && oldMotion) { - return Collections.singleton( - new Event(Event.TYPE_DEVICE_STOPPED, position.getDeviceId(), position.getId())); + Context.getDeviceManager().setDeviceState(deviceId, deviceState); + if (result != null) { + return Collections.singleton(result); } return null; } diff --git a/src/org/traccar/model/DeviceState.java b/src/org/traccar/model/DeviceState.java new file mode 100644 index 000000000..3626b9953 --- /dev/null +++ b/src/org/traccar/model/DeviceState.java @@ -0,0 +1,41 @@ +/* + * 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.model; + +public class DeviceState { + + private Boolean motionState; + + public void setMotionState(boolean motionState) { + this.motionState = motionState; + } + + public Boolean getMotionState() { + return motionState; + } + + private Position motionPosition; + + public void setMotionPosition(Position motionPosition) { + this.motionPosition = motionPosition; + } + + public Position getMotionPosition() { + return motionPosition; + } + +} diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java index 540feb6c6..e8db7e3b5 100644 --- a/src/org/traccar/reports/ReportUtils.java +++ b/src/org/traccar/reports/ReportUtils.java @@ -157,8 +157,8 @@ public final class ReportUtils { public static TripsConfig initTripsConfig() { return new TripsConfig( - Context.getConfig().getLong("report.trip.minimalTripDuration", 300) * 1000, Context.getConfig().getLong("report.trip.minimalTripDistance", 500), + Context.getConfig().getLong("report.trip.minimalTripDuration", 300) * 1000, Context.getConfig().getLong("report.trip.minimalParkingDuration", 300) * 1000, Context.getConfig().getBoolean("report.trip.greedyParking"), Context.getConfig().getLong("report.trip.minimalNoDataDuration", 3600) * 1000); diff --git a/test/org/traccar/events/MotionEventHandlerTest.java b/test/org/traccar/events/MotionEventHandlerTest.java index f05ef54d5..c44f3f4eb 100644 --- a/test/org/traccar/events/MotionEventHandlerTest.java +++ b/test/org/traccar/events/MotionEventHandlerTest.java @@ -2,28 +2,66 @@ package org.traccar.events; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; -import java.util.Collection; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; import org.junit.Test; import org.traccar.BaseTest; +import org.traccar.model.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; +import org.traccar.reports.model.TripsConfig; public class MotionEventHandlerTest extends BaseTest { - + + private Date date(String time) throws ParseException { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + return dateFormat.parse(time); + } + @Test public void testMotionEventHandler() throws Exception { - - MotionEventHandler motionEventHandler = new MotionEventHandler(); - + TripsConfig tripsConfig = new TripsConfig(500, 300 * 1000, 300 * 1000, false, 0); + Position position = new Position(); + position.setTime(date("2017-01-01 00:00:00")); position.set(Position.KEY_MOTION, true); - position.setValid(true); - Collection events = motionEventHandler.analyzePosition(position); - assertNotNull(events); - Event event = (Event) events.toArray()[0]; + position.set(Position.KEY_TOTAL_DISTANCE, 0); + DeviceState deviceState = new DeviceState(); + deviceState.setMotionState(false); + deviceState.setMotionPosition(position); + Position nextPosition = new Position(); + + nextPosition.setTime(date("2017-01-01 00:02:00")); + nextPosition.set(Position.KEY_MOTION, true); + nextPosition.set(Position.KEY_TOTAL_DISTANCE, 200); + + Event event = MotionEventHandler.updateMotionState(deviceState, nextPosition, tripsConfig); + assertNull(event); + + nextPosition.set(Position.KEY_TOTAL_DISTANCE, 600); + event = MotionEventHandler.updateMotionState(deviceState, nextPosition, tripsConfig); + assertNotNull(event); + assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); + assertTrue(deviceState.getMotionState()); + assertNull(deviceState.getMotionPosition()); + + deviceState.setMotionState(false); + deviceState.setMotionPosition(position); + nextPosition.setTime(date("2017-01-01 00:06:00")); + nextPosition.set(Position.KEY_TOTAL_DISTANCE, 200); + event = MotionEventHandler.updateMotionState(deviceState, nextPosition, tripsConfig); + assertNotNull(event); assertEquals(Event.TYPE_DEVICE_MOVING, event.getType()); + assertTrue(deviceState.getMotionState()); + assertNull(deviceState.getMotionPosition()); } } -- cgit v1.2.3 From 532e0a98d469573a575dc595554792cbbd4cd953 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 10 Aug 2017 13:31:18 +0500 Subject: Implement delayed overspeed events --- src/org/traccar/database/ConnectionManager.java | 58 ++++++++++----- src/org/traccar/database/DeviceManager.java | 7 +- src/org/traccar/events/MotionEventHandler.java | 10 +-- src/org/traccar/events/OverspeedEventHandler.java | 66 +++++++++++++---- src/org/traccar/model/DeviceState.java | 20 +++++ .../traccar/events/OverspeedEventHandlerTest.java | 85 ++++++++++++++++++++++ 6 files changed, 203 insertions(+), 43 deletions(-) create mode 100644 test/org/traccar/events/OverspeedEventHandlerTest.java (limited to 'src/org/traccar/database/DeviceManager.java') diff --git a/src/org/traccar/database/ConnectionManager.java b/src/org/traccar/database/ConnectionManager.java index 1c5d4428a..ee2a7bb47 100644 --- a/src/org/traccar/database/ConnectionManager.java +++ b/src/org/traccar/database/ConnectionManager.java @@ -21,6 +21,7 @@ import org.jboss.netty.util.TimerTask; import org.traccar.Context; import org.traccar.GlobalTimer; import org.traccar.Protocol; +import org.traccar.events.OverspeedEventHandler; import org.traccar.helper.Log; import org.traccar.model.Device; import org.traccar.model.DeviceState; @@ -44,7 +45,10 @@ public class ConnectionManager { private final long deviceTimeout; private final boolean enableStatusEvents; + private final boolean updateDeviceState; private TripsConfig tripsConfig = null; + private long minimalOverspeedDuration; + private boolean overspeedNotRepeat; private final Map activeDevices = new ConcurrentHashMap<>(); private final Map> listeners = new ConcurrentHashMap<>(); @@ -53,8 +57,11 @@ public class ConnectionManager { public ConnectionManager() { deviceTimeout = Context.getConfig().getLong("status.timeout", DEFAULT_TIMEOUT) * 1000; enableStatusEvents = Context.getConfig().getBoolean("event.enable"); - if (Context.getConfig().getBoolean("status.updateDeviceState")) { + updateDeviceState = Context.getConfig().getBoolean("status.updateDeviceState"); + if (updateDeviceState) { tripsConfig = ReportUtils.initTripsConfig(); + minimalOverspeedDuration = Context.getConfig().getLong("event.overspeed.minimalDuration") * 1000; + overspeedNotRepeat = Context.getConfig().getBoolean("event.overspeed.notRepeat"); } } @@ -87,28 +94,24 @@ public class ConnectionManager { if (enableStatusEvents && !status.equals(oldStatus)) { String eventType; - Event stateEvent = null; + Set events = new HashSet<>(); switch (status) { case Device.STATUS_ONLINE: eventType = Event.TYPE_DEVICE_ONLINE; break; case Device.STATUS_UNKNOWN: eventType = Event.TYPE_DEVICE_UNKNOWN; - if (tripsConfig != null) { - stateEvent = updateDeviceState(deviceId); + if (updateDeviceState) { + events.addAll(updateDeviceState(deviceId)); } break; default: eventType = Event.TYPE_DEVICE_OFFLINE; - if (tripsConfig != null) { - stateEvent = updateDeviceState(deviceId); + if (updateDeviceState) { + events.addAll(updateDeviceState(deviceId)); } break; } - Set events = new HashSet<>(); - if (stateEvent != null) { - events.add(stateEvent); - } events.add(new Event(eventType, deviceId)); Context.getNotificationManager().updateEvents(events, null); } @@ -142,26 +145,41 @@ public class ConnectionManager { updateDevice(device); } - public Event updateDeviceState(long deviceId) { + public Set updateDeviceState(long deviceId) { DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); - if (deviceState == null || deviceState.getMotionState() == null) { - return null; - } - Event result = null; - Boolean oldMotion = deviceState.getMotionState(); + Set result = new HashSet<>(); long currentTime = System.currentTimeMillis(); - boolean newMotion = !oldMotion; - Position motionPosition = deviceState.getMotionPosition(); - if (motionPosition != null) { + if (deviceState.getMotionState() != null && deviceState.getMotionPosition() != null) { + boolean newMotion = !deviceState.getMotionState(); + Position motionPosition = deviceState.getMotionPosition(); long motionTime = motionPosition.getFixTime().getTime() + (newMotion ? tripsConfig.getMinimalTripDuration() : tripsConfig.getMinimalParkingDuration()); if (motionTime <= currentTime) { String eventType = newMotion ? Event.TYPE_DEVICE_MOVING : Event.TYPE_DEVICE_STOPPED; - result = new Event(eventType, motionPosition.getDeviceId(), motionPosition.getId()); + result.add(new Event(eventType, motionPosition.getDeviceId(), motionPosition.getId())); deviceState.setMotionState(newMotion); deviceState.setMotionPosition(null); } } + if (deviceState.getOverspeedState() != null && !deviceState.getOverspeedState() + && deviceState.getOverspeedPosition() != null) { + double speedLimit = Context.getDeviceManager().lookupAttributeDouble(deviceId, + OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, 0, false); + if (speedLimit != 0) { + Position overspeedPosition = deviceState.getOverspeedPosition(); + long overspeedTime = overspeedPosition.getFixTime().getTime(); + if (overspeedTime + minimalOverspeedDuration <= currentTime) { + Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, overspeedPosition.getDeviceId(), + overspeedPosition.getId()); + event.set("speed", overspeedPosition.getSpeed()); + event.set(OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT, speedLimit); + result.add(event); + deviceState.setOverspeedState(overspeedNotRepeat); + deviceState.setOverspeedPosition(null); + } + } + } + return result; } diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 3b7e5c617..a485d6dc6 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -392,7 +392,12 @@ public class DeviceManager extends BaseObjectManager implements Identity } public DeviceState getDeviceState(long deviceId) { - return deviceStates.get(deviceId); + DeviceState deviceState = deviceStates.get(deviceId); + if (deviceState == null) { + deviceState = new DeviceState(); + deviceStates.put(deviceId, deviceState); + } + return deviceState; } public void setDeviceState(long deviceId, DeviceState deviceState) { diff --git a/src/org/traccar/events/MotionEventHandler.java b/src/org/traccar/events/MotionEventHandler.java index 228b43c0f..ed21d7b83 100644 --- a/src/org/traccar/events/MotionEventHandler.java +++ b/src/org/traccar/events/MotionEventHandler.java @@ -77,7 +77,8 @@ public class MotionEventHandler extends BaseEventHandler { @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getById(position.getDeviceId()); + long deviceId = position.getDeviceId(); + Device device = Context.getIdentityManager().getById(deviceId); if (device == null) { return null; } @@ -86,14 +87,9 @@ public class MotionEventHandler extends BaseEventHandler { } Event result = null; - - long deviceId = position.getDeviceId(); DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); - if (deviceState == null) { - deviceState = new DeviceState(); - deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); - } else if (deviceState.getMotionState() == null) { + if (deviceState.getMotionState() == null) { deviceState.setMotionState(position.getBoolean(Position.KEY_MOTION)); } else { result = updateMotionState(deviceState, position, tripsConfig); diff --git a/src/org/traccar/events/OverspeedEventHandler.java b/src/org/traccar/events/OverspeedEventHandler.java index 795892f40..3b91fed4d 100644 --- a/src/org/traccar/events/OverspeedEventHandler.java +++ b/src/org/traccar/events/OverspeedEventHandler.java @@ -21,6 +21,7 @@ import java.util.Collections; import org.traccar.BaseEventHandler; import org.traccar.Context; import org.traccar.model.Device; +import org.traccar.model.DeviceState; import org.traccar.model.Event; import org.traccar.model.Position; @@ -29,15 +30,51 @@ public class OverspeedEventHandler extends BaseEventHandler { public static final String ATTRIBUTE_SPEED_LIMIT = "speedLimit"; private boolean notRepeat; + private long minimalDuration; public OverspeedEventHandler() { notRepeat = Context.getConfig().getBoolean("event.overspeed.notRepeat"); + minimalDuration = Context.getConfig().getLong("event.overspeed.minimalDuration") * 1000; + } + + public static Event updateOverspeedState(DeviceState deviceState, Position position, double speedLimit, + long minimalOverspeedDuration, boolean notRepeat) { + Event result = null; + + Boolean oldOverspeed = deviceState.getOverspeedState(); + + long currentTime = position.getFixTime().getTime(); + boolean newOverspeed = position.getSpeed() > speedLimit; + if (newOverspeed && !oldOverspeed) { + if (deviceState.getOverspeedPosition() == null) { + deviceState.setOverspeedPosition(position); + } + } else if (oldOverspeed && !newOverspeed) { + deviceState.setOverspeedState(false); + deviceState.setOverspeedPosition(null); + } else { + deviceState.setOverspeedPosition(null); + } + Position overspeedPosition = deviceState.getOverspeedPosition(); + if (overspeedPosition != null) { + long overspeedTime = overspeedPosition.getFixTime().getTime(); + if (newOverspeed && overspeedTime + minimalOverspeedDuration <= currentTime) { + result = new Event(Event.TYPE_DEVICE_OVERSPEED, overspeedPosition.getDeviceId(), + overspeedPosition.getId()); + result.set("speed", overspeedPosition.getSpeed()); + result.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); + deviceState.setOverspeedState(notRepeat); + deviceState.setOverspeedPosition(null); + } + } + return result; } @Override protected Collection analyzePosition(Position position) { - Device device = Context.getIdentityManager().getById(position.getDeviceId()); + long deviceId = position.getDeviceId(); + Device device = Context.getIdentityManager().getById(deviceId); if (device == null) { return null; } @@ -45,24 +82,23 @@ public class OverspeedEventHandler extends BaseEventHandler { return null; } - double speed = position.getSpeed(); - double speedLimit = Context.getDeviceManager() - .lookupAttributeDouble(device.getId(), ATTRIBUTE_SPEED_LIMIT, 0, false); + double speedLimit = Context.getDeviceManager().lookupAttributeDouble(deviceId, ATTRIBUTE_SPEED_LIMIT, 0, false); if (speedLimit == 0) { return null; } - double oldSpeed = 0; - if (notRepeat) { - Position lastPosition = Context.getIdentityManager().getLastPosition(position.getDeviceId()); - if (lastPosition != null) { - oldSpeed = lastPosition.getSpeed(); - } + + Event result = null; + DeviceState deviceState = Context.getDeviceManager().getDeviceState(deviceId); + + if (deviceState.getOverspeedState() == null) { + deviceState.setOverspeedState(position.getSpeed() > speedLimit); + } else { + result = updateOverspeedState(deviceState, position, speedLimit, minimalDuration, notRepeat); } - if (speed > speedLimit && oldSpeed <= speedLimit) { - Event event = new Event(Event.TYPE_DEVICE_OVERSPEED, position.getDeviceId(), position.getId()); - event.set("speed", speed); - event.set(ATTRIBUTE_SPEED_LIMIT, speedLimit); - return Collections.singleton(event); + + Context.getDeviceManager().setDeviceState(deviceId, deviceState); + if (result != null) { + return Collections.singleton(result); } return null; } diff --git a/src/org/traccar/model/DeviceState.java b/src/org/traccar/model/DeviceState.java index 3626b9953..f2d0ff614 100644 --- a/src/org/traccar/model/DeviceState.java +++ b/src/org/traccar/model/DeviceState.java @@ -38,4 +38,24 @@ public class DeviceState { return motionPosition; } + private Boolean overspeedState; + + public void setOverspeedState(boolean overspeedState) { + this.overspeedState = overspeedState; + } + + public Boolean getOverspeedState() { + return overspeedState; + } + + private Position overspeedPosition; + + public void setOverspeedPosition(Position overspeedPosition) { + this.overspeedPosition = overspeedPosition; + } + + public Position getOverspeedPosition() { + return overspeedPosition; + } + } diff --git a/test/org/traccar/events/OverspeedEventHandlerTest.java b/test/org/traccar/events/OverspeedEventHandlerTest.java new file mode 100644 index 000000000..25bbb4319 --- /dev/null +++ b/test/org/traccar/events/OverspeedEventHandlerTest.java @@ -0,0 +1,85 @@ +package org.traccar.events; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +import org.junit.Test; +import org.traccar.BaseTest; +import org.traccar.model.DeviceState; +import org.traccar.model.Event; +import org.traccar.model.Position; + +public class OverspeedEventHandlerTest extends BaseTest { + + private Date date(String time) throws ParseException { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + return dateFormat.parse(time); + } + + private void testOverspeed(boolean notRepeat) throws Exception { + Position position = new Position(); + position.setTime(date("2017-01-01 00:00:00")); + position.setSpeed(50); + DeviceState deviceState = new DeviceState(); + deviceState.setOverspeedState(false); + + Event event = OverspeedEventHandler.updateOverspeedState(deviceState, position, 40, 15000, notRepeat); + assertNull(event); + assertFalse(deviceState.getOverspeedState()); + assertEquals(position, deviceState.getOverspeedPosition()); + + Position nextPosition = new Position(); + nextPosition.setTime(date("2017-01-01 00:00:10")); + nextPosition.setSpeed(55); + + event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); + assertNull(event); + + nextPosition.setTime(date("2017-01-01 00:00:20")); + + event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); + assertNotNull(event); + assertEquals(Event.TYPE_DEVICE_OVERSPEED, event.getType()); + assertEquals(50, event.getDouble("speed"), 0.1); + assertEquals(40, event.getDouble(OverspeedEventHandler.ATTRIBUTE_SPEED_LIMIT), 0.1); + + assertEquals(notRepeat, deviceState.getOverspeedState()); + assertNull(deviceState.getOverspeedPosition()); + + nextPosition.setTime(date("2017-01-01 00:00:30")); + event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); + assertNull(event); + assertEquals(notRepeat, deviceState.getOverspeedState()); + + if (notRepeat) { + assertNull(deviceState.getOverspeedPosition()); + } else { + assertNotNull(deviceState.getOverspeedPosition()); + } + + nextPosition.setTime(date("2017-01-01 00:00:40")); + nextPosition.setSpeed(30); + + event = OverspeedEventHandler.updateOverspeedState(deviceState, nextPosition, 40, 15000, notRepeat); + assertNull(event); + assertFalse(deviceState.getOverspeedState()); + assertNull(deviceState.getOverspeedPosition()); + } + + @Test + public void testOverspeedEventHandler() throws Exception { + testOverspeed(false); + testOverspeed(true); + } + +} -- cgit v1.2.3 From 9ebd2a934a5ca3a61863f839733bff321ba30296 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 7 Sep 2017 11:33:22 +0500 Subject: Handle correct and incorrect attribute types --- src/org/traccar/database/DeviceManager.java | 45 ++++++++-------------- src/org/traccar/model/ExtendedModel.java | 2 +- src/org/traccar/notification/NotificationMail.java | 2 +- .../traccar/notification/PropertiesProvider.java | 10 +++++ .../traccar/protocol/OsmAndProtocolDecoder.java | 12 +++++- test/org/traccar/ProtocolTest.java | 4 ++ .../protocol/OsmAndProtocolDecoderTest.java | 3 ++ 7 files changed, 45 insertions(+), 33 deletions(-) (limited to 'src/org/traccar/database/DeviceManager.java') diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index a485d6dc6..9bc221aa3 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -262,59 +262,44 @@ public class DeviceManager extends BaseObjectManager implements Identity public boolean lookupAttributeBoolean( long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return Boolean.parseBoolean(result); - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? Boolean.parseBoolean(result.toString()) : defaultValue; } public String lookupAttributeString( long deviceId, String attributeName, String defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return result; - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? result.toString() : defaultValue; } public int lookupAttributeInteger(long deviceId, String attributeName, int defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return Integer.parseInt(result); - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? Integer.parseInt(result.toString()) : defaultValue; } public long lookupAttributeLong( long deviceId, String attributeName, long defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return Long.parseLong(result); - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? Long.parseLong(result.toString()) : defaultValue; } public double lookupAttributeDouble( long deviceId, String attributeName, double defaultValue, boolean lookupConfig) { - String result = lookupAttribute(deviceId, attributeName, lookupConfig); - if (result != null) { - return Double.parseDouble(result); - } - return defaultValue; + Object result = lookupAttribute(deviceId, attributeName, lookupConfig); + return result != null ? Double.parseDouble(result.toString()) : defaultValue; } - private String lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) { - String result = null; + private Object lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) { + Object result = null; Device device = getById(deviceId); if (device != null) { - result = device.getString(attributeName); + result = device.getAttributes().get(attributeName); if (result == null && lookupGroupsAttribute) { long groupId = device.getGroupId(); while (groupId != 0) { Group group = Context.getGroupsManager().getById(groupId); if (group != null) { - result = group.getString(attributeName); + result = group.getAttributes().get(attributeName); if (result != null) { break; } @@ -329,7 +314,7 @@ public class DeviceManager extends BaseObjectManager implements Identity result = Context.getConfig().getString(attributeName); } else { Server server = Context.getPermissionsManager().getServer(); - result = server.getString(attributeName); + result = server.getAttributes().get(attributeName); } } } diff --git a/src/org/traccar/model/ExtendedModel.java b/src/org/traccar/model/ExtendedModel.java index a4bf00e70..2ce503eea 100644 --- a/src/org/traccar/model/ExtendedModel.java +++ b/src/org/traccar/model/ExtendedModel.java @@ -100,7 +100,7 @@ public class ExtendedModel extends BaseModel { public boolean getBoolean(String key) { if (attributes.containsKey(key)) { - return Boolean.parseBoolean(attributes.get(key).toString()); + return (Boolean) attributes.get(key); } else { return false; } diff --git a/src/org/traccar/notification/NotificationMail.java b/src/org/traccar/notification/NotificationMail.java index d7f3bf64c..fc70a6115 100644 --- a/src/org/traccar/notification/NotificationMail.java +++ b/src/org/traccar/notification/NotificationMail.java @@ -43,7 +43,7 @@ public final class NotificationMail { if (host != null) { properties.put("mail.transport.protocol", provider.getString("mail.transport.protocol", "smtp")); properties.put("mail.smtp.host", host); - properties.put("mail.smtp.port", provider.getString("mail.smtp.port", "25")); + properties.put("mail.smtp.port", String.valueOf(provider.getInteger("mail.smtp.port", 25))); String starttlsEnable = provider.getString("mail.smtp.starttls.enable"); if (starttlsEnable != null) { diff --git a/src/org/traccar/notification/PropertiesProvider.java b/src/org/traccar/notification/PropertiesProvider.java index 2fea901af..1a4104d2b 100644 --- a/src/org/traccar/notification/PropertiesProvider.java +++ b/src/org/traccar/notification/PropertiesProvider.java @@ -48,4 +48,14 @@ public class PropertiesProvider { return value; } + public int getInteger(String key, int defaultValue) { + if (config != null) { + return config.getInteger(key, defaultValue); + } else if (extendedModel.getAttributes().containsKey(key)) { + return Integer.parseInt(extendedModel.getAttributes().get(key).toString()); + } else { + return defaultValue; + } + } + } diff --git a/src/org/traccar/protocol/OsmAndProtocolDecoder.java b/src/org/traccar/protocol/OsmAndProtocolDecoder.java index c06582a15..15a71c88b 100644 --- a/src/org/traccar/protocol/OsmAndProtocolDecoder.java +++ b/src/org/traccar/protocol/OsmAndProtocolDecoder.java @@ -135,7 +135,17 @@ public class OsmAndProtocolDecoder extends BaseProtocolDecoder { try { position.set(entry.getKey(), Double.parseDouble(value)); } catch (NumberFormatException e) { - position.set(entry.getKey(), value); + switch (value) { + case "true": + position.set(entry.getKey(), true); + break; + case "false": + position.set(entry.getKey(), false); + break; + default: + position.set(entry.getKey(), value); + break; + } } break; } diff --git a/test/org/traccar/ProtocolTest.java b/test/org/traccar/ProtocolTest.java index a2c7e4f21..7bff41acd 100644 --- a/test/org/traccar/ProtocolTest.java +++ b/test/org/traccar/ProtocolTest.java @@ -241,6 +241,10 @@ public class ProtocolTest extends BaseTest { Assert.assertTrue(attributes.get(Position.KEY_CHARGE) instanceof Boolean); } + if (attributes.containsKey(Position.KEY_IGNITION)) { + Assert.assertTrue(attributes.get(Position.KEY_IGNITION) instanceof Boolean); + } + if (attributes.containsKey(Position.KEY_MOTION)) { Assert.assertTrue(attributes.get(Position.KEY_MOTION) instanceof Boolean); } diff --git a/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java b/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java index 2d0ef0adf..af860f371 100644 --- a/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java +++ b/test/org/traccar/protocol/OsmAndProtocolDecoderTest.java @@ -37,6 +37,9 @@ public class OsmAndProtocolDecoderTest extends ProtocolTest { verifyPosition(decoder, request( "/?id=123456×tamp=1377177267&location=60.0,30.0")); + verifyPosition(decoder, request( + "/?id=123456789012345×tamp=1504763810&lat=40.7232948571&lon=-74.0061408571&bearing=7.19889788244&speed=40&ignition=true&rpm=933&fuel=24")); + } } -- cgit v1.2.3 From ee28d68243892623df7f718d50cd3ea5791f35ee Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 7 Sep 2017 15:31:28 +0500 Subject: Optimize values parsing --- src/org/traccar/database/DeviceManager.java | 22 +++++++++++++++++----- .../traccar/notification/PropertiesProvider.java | 9 ++++++--- 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'src/org/traccar/database/DeviceManager.java') diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 9bc221aa3..2157e738d 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -263,30 +263,42 @@ public class DeviceManager extends BaseObjectManager implements Identity public boolean lookupAttributeBoolean( long deviceId, String attributeName, boolean defaultValue, boolean lookupConfig) { Object result = lookupAttribute(deviceId, attributeName, lookupConfig); - return result != null ? Boolean.parseBoolean(result.toString()) : defaultValue; + if (result != null) { + return result instanceof String ? Boolean.parseBoolean((String) result) : (Boolean) result; + } + return defaultValue; } public String lookupAttributeString( long deviceId, String attributeName, String defaultValue, boolean lookupConfig) { Object result = lookupAttribute(deviceId, attributeName, lookupConfig); - return result != null ? result.toString() : defaultValue; + return result != null ? (String) result : defaultValue; } public int lookupAttributeInteger(long deviceId, String attributeName, int defaultValue, boolean lookupConfig) { Object result = lookupAttribute(deviceId, attributeName, lookupConfig); - return result != null ? Integer.parseInt(result.toString()) : defaultValue; + if (result != null) { + return result instanceof String ? Integer.parseInt((String) result) : ((Number) result).intValue(); + } + return defaultValue; } public long lookupAttributeLong( long deviceId, String attributeName, long defaultValue, boolean lookupConfig) { Object result = lookupAttribute(deviceId, attributeName, lookupConfig); - return result != null ? Long.parseLong(result.toString()) : defaultValue; + if (result != null) { + return result instanceof String ? Long.parseLong((String) result) : ((Number) result).longValue(); + } + return defaultValue; } public double lookupAttributeDouble( long deviceId, String attributeName, double defaultValue, boolean lookupConfig) { Object result = lookupAttribute(deviceId, attributeName, lookupConfig); - return result != null ? Double.parseDouble(result.toString()) : defaultValue; + if (result != null) { + return result instanceof String ? Double.parseDouble((String) result) : ((Number) result).doubleValue(); + } + return defaultValue; } private Object lookupAttribute(long deviceId, String attributeName, boolean lookupConfig) { diff --git a/src/org/traccar/notification/PropertiesProvider.java b/src/org/traccar/notification/PropertiesProvider.java index 1a4104d2b..c5ba688e8 100644 --- a/src/org/traccar/notification/PropertiesProvider.java +++ b/src/org/traccar/notification/PropertiesProvider.java @@ -51,10 +51,13 @@ public class PropertiesProvider { public int getInteger(String key, int defaultValue) { if (config != null) { return config.getInteger(key, defaultValue); - } else if (extendedModel.getAttributes().containsKey(key)) { - return Integer.parseInt(extendedModel.getAttributes().get(key).toString()); } else { - return defaultValue; + Object result = extendedModel.getAttributes().get(key); + if (result != null) { + return result instanceof String ? Integer.parseInt((String) result) : (Integer) result; + } else { + return defaultValue; + } } } -- cgit v1.2.3 From 925806fe70e10e47bcc12eb8bcc4fe21a9ece220 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Tue, 12 Sep 2017 17:42:16 +0500 Subject: Implement Saved Commands --- schema/changelog-3.15.xml | 64 +++++++++- src/org/traccar/Context.java | 12 ++ src/org/traccar/api/BaseObjectResource.java | 7 ++ src/org/traccar/api/resource/CommandResource.java | 46 ++++++- .../traccar/api/resource/CommandTypeResource.java | 8 +- src/org/traccar/database/CommandsManager.java | 136 +++++++++++++++++++++ src/org/traccar/database/DataManager.java | 3 + src/org/traccar/database/DeviceManager.java | 51 -------- src/org/traccar/database/PermissionsManager.java | 26 ++++ src/org/traccar/model/Command.java | 18 +++ src/org/traccar/model/Server.java | 10 ++ src/org/traccar/model/User.java | 10 ++ 12 files changed, 332 insertions(+), 59 deletions(-) create mode 100644 src/org/traccar/database/CommandsManager.java (limited to 'src/org/traccar/database/DeviceManager.java') diff --git a/schema/changelog-3.15.xml b/schema/changelog-3.15.xml index 37fd2e278..f6ed306dc 100644 --- a/schema/changelog-3.15.xml +++ b/schema/changelog-3.15.xml @@ -7,7 +7,7 @@ logicalFilePath="changelog-3.15"> - + @@ -21,5 +21,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index 87d8257ee..210d52429 100644 --- a/src/org/traccar/Context.java +++ b/src/org/traccar/Context.java @@ -26,6 +26,7 @@ import java.util.Properties; import org.apache.velocity.app.VelocityEngine; import org.eclipse.jetty.util.URIUtil; import org.traccar.database.CalendarManager; +import org.traccar.database.CommandsManager; import org.traccar.database.AttributesManager; import org.traccar.database.BaseObjectManager; import org.traccar.database.ConnectionManager; @@ -56,6 +57,7 @@ import org.traccar.helper.Log; import org.traccar.model.Attribute; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; +import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; @@ -213,6 +215,12 @@ public final class Context { return driversManager; } + private static CommandsManager commandsManager; + + public static CommandsManager getCommandsManager() { + return commandsManager; + } + private static StatisticsManager statisticsManager; public static StatisticsManager getStatisticsManager() { @@ -392,6 +400,8 @@ public final class Context { driversManager = new DriversManager(dataManager); + commandsManager = new CommandsManager(dataManager); + statisticsManager = new StatisticsManager(); if (config.getBoolean("sms.smpp.enable")) { @@ -421,6 +431,8 @@ public final class Context { return (BaseObjectManager) geofenceManager; } else if (clazz.equals(Driver.class)) { return (BaseObjectManager) driversManager; + } else if (clazz.equals(Command.class)) { + return (BaseObjectManager) commandsManager; } return null; } diff --git a/src/org/traccar/api/BaseObjectResource.java b/src/org/traccar/api/BaseObjectResource.java index b13dc2e71..4315832b5 100644 --- a/src/org/traccar/api/BaseObjectResource.java +++ b/src/org/traccar/api/BaseObjectResource.java @@ -32,6 +32,7 @@ import org.traccar.database.ExtendedObjectManager; import org.traccar.database.ManagableObjects; import org.traccar.database.SimpleObjectManager; import org.traccar.model.BaseModel; +import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.User; @@ -73,6 +74,8 @@ public abstract class BaseObjectResource extends BaseResour if (baseClass.equals(Device.class)) { Context.getPermissionsManager().checkDeviceReadonly(getUserId()); Context.getPermissionsManager().checkDeviceLimit(getUserId()); + } else if (baseClass.equals(Command.class)) { + Context.getPermissionsManager().checkLimitCommands(getUserId()); } BaseObjectManager manager = Context.getManager(baseClass); @@ -98,6 +101,8 @@ public abstract class BaseObjectResource extends BaseResour } else if (baseClass.equals(User.class)) { User before = Context.getPermissionsManager().getUser(entity.getId()); Context.getPermissionsManager().checkUserUpdate(getUserId(), before, (User) entity); + } else if (baseClass.equals(Command.class)) { + Context.getPermissionsManager().checkLimitCommands(getUserId()); } Context.getPermissionsManager().checkPermission(baseClass, getUserId(), entity.getId()); @@ -118,6 +123,8 @@ public abstract class BaseObjectResource extends BaseResour Context.getPermissionsManager().checkReadonly(getUserId()); if (baseClass.equals(Device.class)) { Context.getPermissionsManager().checkDeviceReadonly(getUserId()); + } else if (baseClass.equals(Command.class)) { + Context.getPermissionsManager().checkLimitCommands(getUserId()); } Context.getPermissionsManager().checkPermission(baseClass, getUserId(), id); diff --git a/src/org/traccar/api/resource/CommandResource.java b/src/org/traccar/api/resource/CommandResource.java index 9ed92d3d5..f7e7d4f8c 100644 --- a/src/org/traccar/api/resource/CommandResource.java +++ b/src/org/traccar/api/resource/CommandResource.java @@ -16,26 +16,62 @@ package org.traccar.api.resource; import org.traccar.Context; -import org.traccar.api.BaseResource; +import org.traccar.api.ExtendedObjectResource; +import org.traccar.database.CommandsManager; import org.traccar.model.Command; +import java.sql.SQLException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + import javax.ws.rs.Consumes; +import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @Path("commands") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public class CommandResource extends BaseResource { +public class CommandResource extends ExtendedObjectResource { + + public CommandResource() { + super(Command.class); + } + + @GET + @Path("send") + public Collection get(@QueryParam("deviceId") long deviceId, + @QueryParam("textChannel") boolean textChannel) throws SQLException { + Context.getPermissionsManager().checkDevice(getUserId(), deviceId); + CommandsManager commandsManager = Context.getCommandsManager(); + Set result = null; + result = new HashSet<>(commandsManager.getUserItems(getUserId())); + result.retainAll(commandsManager.getProperCommands(deviceId, textChannel)); + return commandsManager.getItems(result); + } @POST - public Response add(Command entity) throws Exception { + @Path("send") + public Response send(Command entity) throws Exception { Context.getPermissionsManager().checkReadonly(getUserId()); - Context.getPermissionsManager().checkDevice(getUserId(), entity.getDeviceId()); - Context.getDeviceManager().sendCommand(entity); + Command command = entity; + long deviceId = command.getDeviceId(); + long id = command.getId(); + if (deviceId != 0 && id != 0) { + Context.getPermissionsManager().checkPermission(Command.class, getUserId(), id); + Context.getPermissionsManager().checkDevice(getUserId(), deviceId); + Context.getPermissionsManager().checkUserDeviceCommand(getUserId(), deviceId, id); + Context.getCommandsManager().sendCommand(id, deviceId); + } else { + Context.getPermissionsManager().checkLimitCommands(getUserId()); + Context.getPermissionsManager().checkDevice(getUserId(), deviceId); + Context.getCommandsManager().sendCommand(command); + } return Response.ok(entity).build(); } diff --git a/src/org/traccar/api/resource/CommandTypeResource.java b/src/org/traccar/api/resource/CommandTypeResource.java index d5d220547..30f9300cb 100644 --- a/src/org/traccar/api/resource/CommandTypeResource.java +++ b/src/org/traccar/api/resource/CommandTypeResource.java @@ -36,8 +36,12 @@ public class CommandTypeResource extends BaseResource { @GET public Collection get(@QueryParam("deviceId") long deviceId, @QueryParam("textChannel") boolean textChannel) { - Context.getPermissionsManager().checkDevice(getUserId(), deviceId); - return Context.getDeviceManager().getCommandTypes(deviceId, textChannel); + if (deviceId != 0) { + Context.getPermissionsManager().checkDevice(getUserId(), deviceId); + return Context.getCommandsManager().getCommandTypes(deviceId, textChannel); + } else { + return Context.getCommandsManager().getAllCommandTypes(); + } } } diff --git a/src/org/traccar/database/CommandsManager.java b/src/org/traccar/database/CommandsManager.java new file mode 100644 index 000000000..9f97c929c --- /dev/null +++ b/src/org/traccar/database/CommandsManager.java @@ -0,0 +1,136 @@ +/* + * 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.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.traccar.BaseProtocol; +import org.traccar.Context; +import org.traccar.helper.Log; +import org.traccar.model.Command; +import org.traccar.model.CommandType; +import org.traccar.model.Position; + +public class CommandsManager extends ExtendedObjectManager { + + private boolean fallbackToText; + + public CommandsManager(DataManager dataManager) { + super(dataManager, Command.class); + fallbackToText = Context.getConfig().getBoolean("command.fallbackToSms"); + } + + public boolean checkDeviceCommand(long deviceId, long commandId) { + return getAllDeviceItems(deviceId).contains(commandId); + } + + public void sendCommand(Command command) throws Exception { + sendCommand(command, command.getDeviceId(), fallbackToText); + } + + public void sendCommand(long commandId, long deviceId) throws Exception { + sendCommand(getById(commandId), deviceId, false); + } + + public void sendCommand(Command command, long deviceId, boolean fallbackToText) throws Exception { + if (command.getTextChannel()) { + Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); + String phone = Context.getIdentityManager().getById(deviceId).getPhone(); + if (lastPosition != null) { + BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); + protocol.sendTextCommand(phone, command); + } else if (command.getType().equals(Command.TYPE_CUSTOM)) { + if (Context.getSmppManager() != null) { + Context.getSmppManager().sendMessageSync(phone, command.getString(Command.KEY_DATA), true); + } else { + throw new RuntimeException("SMPP client is not enabled"); + } + } else { + throw new RuntimeException("Command " + command.getType() + " is not supported"); + } + } else { + ActiveDevice activeDevice = Context.getConnectionManager().getActiveDevice(deviceId); + if (activeDevice != null) { + activeDevice.sendCommand(command); + } else { + if (fallbackToText) { + command.setTextChannel(true); + sendCommand(command, deviceId, false); + } else { + throw new RuntimeException("Device is not online"); + } + } + } + } + + public Collection getProperCommands(long deviceId, boolean textChannel) { + List result = new ArrayList<>(); + Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); + for (long commandId : getAllDeviceItems(deviceId)) { + Command command = getById(commandId); + if (command.getTextChannel() == textChannel) { + if (lastPosition != null) { + BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); + Collection protocolCommands = + textChannel ? protocol.getSupportedTextCommands() : protocol.getSupportedDataCommands(); + if (protocolCommands.contains(command.getType())) { + result.add(commandId); + } + } else if (command.getType().equals(Command.TYPE_CUSTOM)) { + result.add(commandId); + } + } + } + return result; + } + + public Collection getCommandTypes(long deviceId, boolean textChannel) { + List result = new ArrayList<>(); + Position lastPosition = Context.getIdentityManager().getLastPosition(deviceId); + if (lastPosition != null) { + BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); + Collection commands; + commands = textChannel ? protocol.getSupportedTextCommands() : protocol.getSupportedDataCommands(); + for (String commandKey : commands) { + result.add(new CommandType(commandKey)); + } + } else { + result.add(new CommandType(Command.TYPE_CUSTOM)); + } + return result; + } + + public Collection getAllCommandTypes() { + List result = new ArrayList<>(); + Field[] fields = Command.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) { + try { + result.add(new CommandType(field.get(null).toString())); + } catch (IllegalArgumentException | IllegalAccessException error) { + Log.warning(error); + } + } + } + return result; + } + +} diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java index 4535a9c38..261541b4d 100644 --- a/src/org/traccar/database/DataManager.java +++ b/src/org/traccar/database/DataManager.java @@ -51,6 +51,7 @@ import org.traccar.model.ManagedUser; import org.traccar.model.Permission; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; +import org.traccar.model.Command; import org.traccar.model.Position; import org.traccar.model.Server; import org.traccar.model.Statistics; @@ -390,6 +391,8 @@ public class DataManager { return Attribute.class; case "calendar": return Calendar.class; + case "command": + return Command.class; default: throw new ClassNotFoundException(); } diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index 2157e738d..1eb90b7eb 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -16,7 +16,6 @@ package org.traccar.database; import java.sql.SQLException; -import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; @@ -26,12 +25,9 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; -import org.traccar.BaseProtocol; import org.traccar.Config; import org.traccar.Context; import org.traccar.helper.Log; -import org.traccar.model.Command; -import org.traccar.model.CommandType; import org.traccar.model.Device; import org.traccar.model.DeviceState; import org.traccar.model.DeviceTotalDistance; @@ -55,8 +51,6 @@ public class DeviceManager extends BaseObjectManager implements Identity private final Map deviceStates = new ConcurrentHashMap<>(); - private boolean fallbackToText; - public DeviceManager(DataManager dataManager) { super(dataManager, Device.class); this.config = Context.getConfig(); @@ -68,7 +62,6 @@ public class DeviceManager extends BaseObjectManager implements Identity } dataRefreshDelay = config.getLong("database.refreshDelay", DEFAULT_REFRESH_DELAY) * 1000; lookupGroupsAttribute = config.getBoolean("deviceManager.lookupGroupsAttribute"); - fallbackToText = config.getBoolean("command.fallbackToSms"); refreshLastPositions(); } @@ -344,50 +337,6 @@ public class DeviceManager extends BaseObjectManager implements Identity } } - public void sendCommand(Command command) throws Exception { - long deviceId = command.getDeviceId(); - if (command.getTextChannel()) { - Position lastPosition = getLastPosition(deviceId); - if (lastPosition != null) { - BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - protocol.sendTextCommand(getById(deviceId).getPhone(), command); - } else if (command.getType().equals(Command.TYPE_CUSTOM)) { - Context.getSmppManager().sendMessageSync(getById(deviceId).getPhone(), - command.getString(Command.KEY_DATA), true); - } else { - throw new RuntimeException("Command " + command.getType() + " is not supported"); - } - } else { - ActiveDevice activeDevice = Context.getConnectionManager().getActiveDevice(deviceId); - if (activeDevice != null) { - activeDevice.sendCommand(command); - } else { - if (fallbackToText) { - command.setTextChannel(true); - sendCommand(command); - } else { - throw new RuntimeException("Device is not online"); - } - } - } - } - - public Collection getCommandTypes(long deviceId, boolean textChannel) { - List result = new ArrayList<>(); - Position lastPosition = Context.getDeviceManager().getLastPosition(deviceId); - if (lastPosition != null) { - BaseProtocol protocol = Context.getServerManager().getProtocol(lastPosition.getProtocol()); - Collection commands; - commands = textChannel ? protocol.getSupportedTextCommands() : protocol.getSupportedDataCommands(); - for (String commandKey : commands) { - result.add(new CommandType(commandKey)); - } - } else { - result.add(new CommandType(Command.TYPE_CUSTOM)); - } - return result; - } - public DeviceState getDeviceState(long deviceId) { DeviceState deviceState = deviceStates.get(deviceId); if (deviceState == null) { diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 0708cc5c9..3da99dd13 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -20,6 +20,7 @@ import org.traccar.helper.Log; import org.traccar.model.Attribute; import org.traccar.model.BaseModel; import org.traccar.model.Calendar; +import org.traccar.model.Command; import org.traccar.model.Device; import org.traccar.model.Driver; import org.traccar.model.Geofence; @@ -197,6 +198,11 @@ public class PermissionsManager { return user != null && user.getDeviceReadonly(); } + public boolean isLimitCommands(long userId) { + User user = getUser(userId); + return user != null && user.getLimitCommands(); + } + public void checkReadonly(long userId) throws SecurityException { if (!isAdmin(userId) && (server.getReadonly() || isReadonly(userId))) { throw new SecurityException("Account is readonly"); @@ -209,6 +215,18 @@ public class PermissionsManager { } } + public void checkLimitCommands(long userId) throws SecurityException { + if (!isAdmin(userId) && (server.getLimitCommands() || isLimitCommands(userId))) { + throw new SecurityException("Account has limit sending commands"); + } + } + + public void checkUserDeviceCommand(long userId, long deviceId, long commandId) throws SecurityException { + if (!isAdmin(userId) && Context.getCommandsManager().checkDeviceCommand(deviceId, commandId)) { + throw new SecurityException("Command can not be sent to this device"); + } + } + public void checkUserEnabled(long userId) throws SecurityException { User user = getUser(userId); if (user == null) { @@ -300,6 +318,8 @@ public class PermissionsManager { manager = Context.getDriversManager(); } else if (object.equals(Calendar.class)) { manager = Context.getCalendarManager(); + } else if (object.equals(Command.class)) { + manager = Context.getCommandsManager(); } else { throw new IllegalArgumentException("Unknown object type"); } @@ -322,6 +342,7 @@ public class PermissionsManager { Context.getCalendarManager().refreshUserItems(); Context.getDriversManager().refreshUserItems(); Context.getAttributesManager().refreshUserItems(); + Context.getCommandsManager().refreshUserItems(); if (Context.getNotificationManager() != null) { Context.getNotificationManager().refresh(); } @@ -333,6 +354,7 @@ public class PermissionsManager { } Context.getDriversManager().refreshExtendedPermissions(); Context.getAttributesManager().refreshExtendedPermissions(); + Context.getCommandsManager().refreshExtendedPermissions(); } public void refreshPermissions(Permission permission) { @@ -351,6 +373,8 @@ public class PermissionsManager { Context.getAttributesManager().refreshUserItems(); } else if (permission.getPropertyClass().equals(Calendar.class)) { Context.getCalendarManager().refreshUserItems(); + } else if (permission.getPropertyClass().equals(Command.class)) { + Context.getCommandsManager().refreshUserItems(); } } else if (permission.getOwnerClass().equals(Device.class) || permission.getOwnerClass().equals(Group.class)) { if (permission.getPropertyClass().equals(Geofence.class) && Context.getGeofenceManager() != null) { @@ -359,6 +383,8 @@ public class PermissionsManager { Context.getDriversManager().refreshExtendedPermissions(); } else if (permission.getPropertyClass().equals(Attribute.class)) { Context.getAttributesManager().refreshExtendedPermissions(); + } else if (permission.getPropertyClass().equals(Command.class)) { + Context.getCommandsManager().refreshExtendedPermissions(); } } } diff --git a/src/org/traccar/model/Command.java b/src/org/traccar/model/Command.java index 6a48b14e9..67134dc7d 100644 --- a/src/org/traccar/model/Command.java +++ b/src/org/traccar/model/Command.java @@ -15,6 +15,8 @@ */ package org.traccar.model; +import org.traccar.database.QueryIgnore; + import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonIgnoreProperties(ignoreUnknown = true) @@ -85,4 +87,20 @@ public class Command extends Message { this.textChannel = textChannel; } + @QueryIgnore + @Override + public long getDeviceId() { + return super.getDeviceId(); + } + + private String description; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + } diff --git a/src/org/traccar/model/Server.java b/src/org/traccar/model/Server.java index bfe881479..072e85d55 100644 --- a/src/org/traccar/model/Server.java +++ b/src/org/traccar/model/Server.java @@ -147,4 +147,14 @@ public class Server extends ExtendedModel { public void setCoordinateFormat(String coordinateFormat) { this.coordinateFormat = coordinateFormat; } + + private boolean limitCommands; + + public boolean getLimitCommands() { + return limitCommands; + } + + public void setLimitCommands(boolean limitCommands) { + this.limitCommands = limitCommands; + } } diff --git a/src/org/traccar/model/User.java b/src/org/traccar/model/User.java index 043c23036..5d89dcfae 100644 --- a/src/org/traccar/model/User.java +++ b/src/org/traccar/model/User.java @@ -210,6 +210,16 @@ public class User extends ExtendedModel { } } + private boolean limitCommands; + + public boolean getLimitCommands() { + return limitCommands; + } + + public void setLimitCommands(boolean limitCommands) { + this.limitCommands = limitCommands; + } + @QueryIgnore public String getPassword() { return null; -- cgit v1.2.3