aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar/database
diff options
context:
space:
mode:
authorAnton Tananaev <anton.tananaev@gmail.com>2016-06-28 14:09:44 +1200
committerGitHub <noreply@github.com>2016-06-28 14:09:44 +1200
commit7327681f0bd2338f9c8ee3ea1b4a19dcc5f0de48 (patch)
tree0ea99ab937fbae96b35cc5dc62edbc74594af9e4 /src/org/traccar/database
parent67f46c80d3b5e34440a2644f52b81dddfbaba5fa (diff)
parent61b2486353c742afe6214f0a0c5c2e9956ea3b97 (diff)
downloadtrackermap-server-7327681f0bd2338f9c8ee3ea1b4a19dcc5f0de48.tar.gz
trackermap-server-7327681f0bd2338f9c8ee3ea1b4a19dcc5f0de48.tar.bz2
trackermap-server-7327681f0bd2338f9c8ee3ea1b4a19dcc5f0de48.zip
Merge pull request #2052 from Abyss777/master
Notifications via email
Diffstat (limited to 'src/org/traccar/database')
-rw-r--r--src/org/traccar/database/DataManager.java24
-rw-r--r--src/org/traccar/database/NotificationManager.java139
2 files changed, 162 insertions, 1 deletions
diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java
index 860bf1b84..031703023 100644
--- a/src/org/traccar/database/DataManager.java
+++ b/src/org/traccar/database/DataManager.java
@@ -52,6 +52,7 @@ import org.traccar.model.Geofence;
import org.traccar.model.Group;
import org.traccar.model.GroupGeofence;
import org.traccar.model.GroupPermission;
+import org.traccar.model.Notification;
import org.traccar.model.Position;
import org.traccar.model.Server;
import org.traccar.model.User;
@@ -644,4 +645,27 @@ public class DataManager implements IdentityManager {
.setLong("geofenceId", geofenceId)
.executeUpdate();
}
+
+ public Collection<Notification> getNotifications() throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectNotifications"))
+ .executeQuery(Notification.class);
+ }
+
+ public void addNotification(Notification notification) throws SQLException {
+ notification.setId(QueryBuilder.create(dataSource, getQuery("database.insertNotification"), true)
+ .setObject(notification)
+ .executeUpdate());
+ }
+
+ public void updateNotification(Notification notification) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.updateNotification"))
+ .setObject(notification)
+ .executeUpdate();
+ }
+
+ public void removeNotification(Notification notification) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.deleteNotification"))
+ .setLong("id", notification.getId())
+ .executeUpdate();
+ }
}
diff --git a/src/org/traccar/database/NotificationManager.java b/src/org/traccar/database/NotificationManager.java
index ab6b2230a..ae91d81cc 100644
--- a/src/org/traccar/database/NotificationManager.java
+++ b/src/org/traccar/database/NotificationManager.java
@@ -15,21 +15,35 @@
*/
package org.traccar.database;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
import java.sql.SQLException;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.traccar.Context;
import org.traccar.helper.Log;
import org.traccar.model.Event;
+import org.traccar.model.Notification;
import org.traccar.model.Position;
+import org.traccar.notification.NotificationMail;
public class NotificationManager {
private final DataManager dataManager;
+ private final Map<Long, Set<Notification>> userNotifications = new HashMap<>();
+
+ private final ReadWriteLock notificationsLock = new ReentrantReadWriteLock();
+
public NotificationManager(DataManager dataManager) {
this.dataManager = dataManager;
+ refresh();
}
public void updateEvent(Event event, Position position) {
@@ -43,7 +57,15 @@ public class NotificationManager {
for (Long userId : users) {
if (event.getGeofenceId() == 0 || Context.getGeofenceManager() != null
&& Context.getGeofenceManager().checkGeofence(userId, event.getGeofenceId())) {
- Context.getConnectionManager().updateEvent(userId, event, position);
+ Notification notification = getUserNotificationByType(userId, event.getType());
+ if (notification != null) {
+ if (notification.getAttributes().containsKey("web")) {
+ Context.getConnectionManager().updateEvent(userId, event, position);
+ }
+ if (notification.getAttributes().containsKey("mail")) {
+ NotificationMail.sendMailAsync(userId, event, position);
+ }
+ }
}
}
}
@@ -54,4 +76,119 @@ public class NotificationManager {
updateEvent(event, position);
}
}
+
+ private Set<Notification> getUserNotificationsUnsafe(long userId) {
+ if (!userNotifications.containsKey(userId)) {
+ userNotifications.put(userId, new HashSet<Notification>());
+ }
+ return userNotifications.get(userId);
+ }
+
+ public Set<Notification> getUserNotifications(long userId) {
+ notificationsLock.readLock().lock();
+ try {
+ return getUserNotificationsUnsafe(userId);
+ } finally {
+ notificationsLock.readLock().unlock();
+ }
+ }
+
+ public final void refresh() {
+ if (dataManager != null) {
+ try {
+ notificationsLock.writeLock().lock();
+ try {
+ userNotifications.clear();
+ for (Notification notification : dataManager.getNotifications()) {
+ getUserNotificationsUnsafe(notification.getUserId()).add(notification);
+ }
+ } finally {
+ notificationsLock.writeLock().unlock();
+ }
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+ }
+ }
+
+ public Notification getUserNotificationByType(long userId, String type) {
+ notificationsLock.readLock().lock();
+ try {
+ for (Notification notification : getUserNotificationsUnsafe(userId)) {
+ if (notification.getType().equals(type)) {
+ return notification;
+ }
+ }
+ } finally {
+ notificationsLock.readLock().unlock();
+ }
+ return null;
+ }
+
+ public void updateNotification(Notification notification) {
+ Notification cachedNotification = getUserNotificationByType(notification.getUserId(), notification.getType());
+ if (cachedNotification != null) {
+ if (!cachedNotification.getAttributes().equals(notification.getAttributes())) {
+ if (notification.getAttributes().isEmpty()) {
+ try {
+ dataManager.removeNotification(cachedNotification);
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+ notificationsLock.writeLock().lock();
+ try {
+ getUserNotificationsUnsafe(notification.getUserId()).remove(cachedNotification);
+ } finally {
+ notificationsLock.writeLock().unlock();
+ }
+ } else {
+ notificationsLock.writeLock().lock();
+ try {
+ cachedNotification.setAttributes(notification.getAttributes());
+ } finally {
+ notificationsLock.writeLock().unlock();
+ }
+ try {
+ dataManager.updateNotification(cachedNotification);
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+ }
+ } else {
+ notification.setId(cachedNotification.getId());
+ }
+ } else if (!notification.getAttributes().isEmpty()) {
+ try {
+ dataManager.addNotification(notification);
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+ notificationsLock.writeLock().lock();
+ try {
+ getUserNotificationsUnsafe(notification.getUserId()).add(notification);
+ } finally {
+ notificationsLock.writeLock().unlock();
+ }
+ }
+ }
+
+ public Set<Notification> getAllNotifications() {
+
+ Set<Notification> notifications = new HashSet<>();
+ long id = 0;
+ Field[] fields = Event.class.getDeclaredFields();
+ for (Field field : fields) {
+ if (Modifier.isStatic(field.getModifiers()) && field.getName().startsWith("TYPE_")) {
+ try {
+ Notification notification = new Notification();
+ notification.setType(field.get(null).toString());
+ notification.setId(id++);
+ notifications.add(notification);
+ } catch (IllegalArgumentException | IllegalAccessException error) {
+ Log.warning(error);
+ }
+ }
+ }
+ return notifications;
+ }
}