From 99e16edfd8b29d5ef1b751eefcf87a14df35cb9b Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 16 Mar 2017 09:49:34 +0500 Subject: Implement phone to device comparison --- src/org/traccar/database/DeviceManager.java | 48 +++++++++++++++++++++- src/org/traccar/model/Event.java | 2 + src/org/traccar/smpp/ClientSmppSessionHandler.java | 11 ++--- templates/mail/textMessage.vm | 9 ++++ templates/sms/textMessage.vm | 1 + 5 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 templates/mail/textMessage.vm create mode 100644 templates/sms/textMessage.vm diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index f5fde9e1f..ca686b95c 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -34,6 +34,7 @@ import org.traccar.model.Command; import org.traccar.model.CommandType; import org.traccar.model.Device; import org.traccar.model.DeviceTotalDistance; +import org.traccar.model.Event; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Server; @@ -49,6 +50,7 @@ public class DeviceManager implements IdentityManager { private Map devicesById; private Map devicesByUniqueId; + private Map devicesByPhone; private AtomicLong devicesLastUpdate = new AtomicLong(); private Map groupsById; @@ -90,24 +92,39 @@ public class DeviceManager implements IdentityManager { 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.remove(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) { @@ -127,8 +144,14 @@ public class DeviceManager implements IdentityManager { devicesByUniqueId.remove(cachedDeviceUniqId); } } + for (String cachedDevicePhone : devicesByPhone.keySet()) { + if (!databaseDevicesPhones.contains(cachedDevicePhone)) { + devicesByPhone.remove(cachedDevicePhone); + } + } databaseDevicesIds.clear(); databaseDevicesUniqueIds.clear(); + databaseDevicesPhones.clear(); } } @@ -146,6 +169,10 @@ public class DeviceManager implements IdentityManager { return devicesByUniqueId.get(uniqueId); } + public Device getDeviceByPhone(String phone) { + return devicesByPhone.get(phone); + } + public Collection getAllDevices() { boolean forceUpdate = devicesById.isEmpty(); @@ -180,6 +207,9 @@ public class DeviceManager implements IdentityManager { devicesById.put(device.getId(), device); devicesByUniqueId.put(device.getUniqueId(), device); + if (device.getPhone() != null && !device.getPhone().isEmpty()) { + devicesByPhone.put(device.getPhone(), device); + } } public void updateDevice(Device device) throws SQLException { @@ -187,6 +217,9 @@ public class DeviceManager implements IdentityManager { devicesById.put(device.getId(), device); devicesByUniqueId.put(device.getUniqueId(), device); + if (device.getPhone() != null && !device.getPhone().isEmpty()) { + devicesByPhone.put(device.getPhone(), device); + } } public void updateDeviceStatus(Device device) throws SQLException { @@ -202,8 +235,12 @@ public class DeviceManager implements IdentityManager { 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); + } } positions.remove(deviceId); } @@ -470,4 +507,13 @@ public class DeviceManager implements IdentityManager { } return result; } + + public void handleTextMessage(String phone, String message) { + Device device = devicesByPhone.get(phone); + if (device != null && Context.getNotificationManager() != null) { + Event event = new Event(Event.TYPE_TEXT_MESSAGE, device.getId()); + event.set("message", message); + Context.getNotificationManager().updateEvent(event, null); + } + } } diff --git a/src/org/traccar/model/Event.java b/src/org/traccar/model/Event.java index ee62f9776..96b371896 100644 --- a/src/org/traccar/model/Event.java +++ b/src/org/traccar/model/Event.java @@ -58,6 +58,8 @@ public class Event extends Message { public static final String TYPE_MAINTENANCE = "maintenance"; + public static final String TYPE_TEXT_MESSAGE = "textMessage"; + private Date serverTime; public Date getServerTime() { diff --git a/src/org/traccar/smpp/ClientSmppSessionHandler.java b/src/org/traccar/smpp/ClientSmppSessionHandler.java index 2a538a40f..f4d40c3eb 100644 --- a/src/org/traccar/smpp/ClientSmppSessionHandler.java +++ b/src/org/traccar/smpp/ClientSmppSessionHandler.java @@ -16,6 +16,7 @@ */ package org.traccar.smpp; +import org.traccar.Context; import org.traccar.helper.Log; import com.cloudhopper.commons.charset.CharsetUtil; @@ -49,11 +50,11 @@ public class ClientSmppSessionHandler extends DefaultSmppSessionHandler { + ", State: " + request.getOptionalParameter(SmppConstants.TAG_MSG_STATE).getValueAsByte()); } else { - Log.debug("SMS Message Received: " - + CharsetUtil.decode(((DeliverSm) request).getShortMessage(), - smppClient.mapDataCodingToCharset(((DeliverSm) request).getDataCoding())).trim() - + ", Source Address: " - + ((DeliverSm) request).getSourceAddress().getAddress()); + String sourceAddress = ((DeliverSm) request).getSourceAddress().getAddress(); + String message = CharsetUtil.decode(((DeliverSm) request).getShortMessage(), + smppClient.mapDataCodingToCharset(((DeliverSm) request).getDataCoding())); + Log.debug("SMS Message Received: " + message.trim() + ", Source Address: " + sourceAddress); + Context.getDeviceManager().handleTextMessage(sourceAddress, message); } } response = request.createResponse(); diff --git a/templates/mail/textMessage.vm b/templates/mail/textMessage.vm new file mode 100644 index 000000000..174173c85 --- /dev/null +++ b/templates/mail/textMessage.vm @@ -0,0 +1,9 @@ +#set($subject = "$device.name: text message received") + + + +Device: $device.name
+Message: $event.getString("message")
+Time: $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.serverTime, $locale, $timezone)
+ + diff --git a/templates/sms/textMessage.vm b/templates/sms/textMessage.vm new file mode 100644 index 000000000..dc42f29f1 --- /dev/null +++ b/templates/sms/textMessage.vm @@ -0,0 +1 @@ +Text message received from $device.name at $dateTool.format("YYYY-MM-dd HH:mm:ss", $event.serverTime, $locale, $timezone) -- cgit v1.2.3 From 1455ad6ce058f02d812e23fb275265f105272f4d Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Mon, 20 Mar 2017 15:04:54 +0500 Subject: Move handleTextMessage function to separate handler. --- src/org/traccar/database/DeviceManager.java | 19 ++--------- .../traccar/events/TextMessageEventHandler.java | 37 ++++++++++++++++++++++ src/org/traccar/smpp/ClientSmppSessionHandler.java | 4 +-- 3 files changed, 42 insertions(+), 18 deletions(-) create mode 100644 src/org/traccar/events/TextMessageEventHandler.java diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index ca686b95c..f70b9b1a2 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -34,7 +34,6 @@ import org.traccar.model.Command; import org.traccar.model.CommandType; import org.traccar.model.Device; import org.traccar.model.DeviceTotalDistance; -import org.traccar.model.Event; import org.traccar.model.Group; import org.traccar.model.Position; import org.traccar.model.Server; @@ -139,9 +138,9 @@ public class DeviceManager implements IdentityManager { devicesById.remove(cachedDeviceId); } } - for (String cachedDeviceUniqId : devicesByUniqueId.keySet()) { - if (!databaseDevicesUniqueIds.contains(cachedDeviceUniqId)) { - devicesByUniqueId.remove(cachedDeviceUniqId); + for (String cachedDeviceUniqueId : devicesByUniqueId.keySet()) { + if (!databaseDevicesUniqueIds.contains(cachedDeviceUniqueId)) { + devicesByUniqueId.remove(cachedDeviceUniqueId); } } for (String cachedDevicePhone : devicesByPhone.keySet()) { @@ -149,9 +148,6 @@ public class DeviceManager implements IdentityManager { devicesByPhone.remove(cachedDevicePhone); } } - databaseDevicesIds.clear(); - databaseDevicesUniqueIds.clear(); - databaseDevicesPhones.clear(); } } @@ -507,13 +503,4 @@ public class DeviceManager implements IdentityManager { } return result; } - - public void handleTextMessage(String phone, String message) { - Device device = devicesByPhone.get(phone); - if (device != null && Context.getNotificationManager() != null) { - Event event = new Event(Event.TYPE_TEXT_MESSAGE, device.getId()); - event.set("message", message); - Context.getNotificationManager().updateEvent(event, null); - } - } } diff --git a/src/org/traccar/events/TextMessageEventHandler.java b/src/org/traccar/events/TextMessageEventHandler.java new file mode 100644 index 000000000..be4a193a7 --- /dev/null +++ b/src/org/traccar/events/TextMessageEventHandler.java @@ -0,0 +1,37 @@ +/* + * 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.events; + +import org.traccar.Context; +import org.traccar.model.Device; +import org.traccar.model.Event; + +public final class TextMessageEventHandler { + + private TextMessageEventHandler() { + } + + public static void handleTextMessage(String phone, String message) { + Device device = Context.getDeviceManager().getDeviceByPhone(phone); + if (device != null && Context.getNotificationManager() != null) { + Event event = new Event(Event.TYPE_TEXT_MESSAGE, device.getId()); + event.set("message", message); + Context.getNotificationManager().updateEvent(event, null); + } + } + +} diff --git a/src/org/traccar/smpp/ClientSmppSessionHandler.java b/src/org/traccar/smpp/ClientSmppSessionHandler.java index f4d40c3eb..77f75273e 100644 --- a/src/org/traccar/smpp/ClientSmppSessionHandler.java +++ b/src/org/traccar/smpp/ClientSmppSessionHandler.java @@ -16,7 +16,7 @@ */ package org.traccar.smpp; -import org.traccar.Context; +import org.traccar.events.TextMessageEventHandler; import org.traccar.helper.Log; import com.cloudhopper.commons.charset.CharsetUtil; @@ -54,7 +54,7 @@ public class ClientSmppSessionHandler extends DefaultSmppSessionHandler { String message = CharsetUtil.decode(((DeliverSm) request).getShortMessage(), smppClient.mapDataCodingToCharset(((DeliverSm) request).getDataCoding())); Log.debug("SMS Message Received: " + message.trim() + ", Source Address: " + sourceAddress); - Context.getDeviceManager().handleTextMessage(sourceAddress, message); + TextMessageEventHandler.handleTextMessage(sourceAddress, message); } } response = request.createResponse(); -- cgit v1.2.3 From 696ac56a6174a5ebfec939871a579ba54ee96963 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Mon, 20 Mar 2017 15:54:13 +0500 Subject: Use Iterator for maps cleanup --- src/org/traccar/database/DeviceManager.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/org/traccar/database/DeviceManager.java b/src/org/traccar/database/DeviceManager.java index f70b9b1a2..ae5784b01 100644 --- a/src/org/traccar/database/DeviceManager.java +++ b/src/org/traccar/database/DeviceManager.java @@ -19,6 +19,7 @@ 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; @@ -133,19 +134,19 @@ public class DeviceManager implements IdentityManager { device.setStatus(Device.STATUS_OFFLINE); } } - for (Long cachedDeviceId : devicesById.keySet()) { - if (!databaseDevicesIds.contains(cachedDeviceId)) { - devicesById.remove(cachedDeviceId); + for (Iterator iterator = devicesById.keySet().iterator(); iterator.hasNext();) { + if (!databaseDevicesIds.contains(iterator.next())) { + iterator.remove(); } } - for (String cachedDeviceUniqueId : devicesByUniqueId.keySet()) { - if (!databaseDevicesUniqueIds.contains(cachedDeviceUniqueId)) { - devicesByUniqueId.remove(cachedDeviceUniqueId); + for (Iterator iterator = devicesByUniqueId.keySet().iterator(); iterator.hasNext();) { + if (!databaseDevicesUniqueIds.contains(iterator.next())) { + iterator.remove(); } } - for (String cachedDevicePhone : devicesByPhone.keySet()) { - if (!databaseDevicesPhones.contains(cachedDevicePhone)) { - devicesByPhone.remove(cachedDevicePhone); + for (Iterator iterator = devicesByPhone.keySet().iterator(); iterator.hasNext();) { + if (!databaseDevicesPhones.contains(iterator.next())) { + iterator.remove(); } } } -- cgit v1.2.3