From cefba4b9227c8aeb96e290f70689960541755f0d Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Wed, 22 Apr 2015 23:00:35 +1200 Subject: Add latest position cache --- src/org/traccar/BasePipelineFactory.java | 13 +++--- src/org/traccar/ServerManager.java | 31 ++++++++++--- src/org/traccar/TrackerEventHandler.java | 16 +++---- src/org/traccar/database/DataCache.java | 74 ++++++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 24 deletions(-) create mode 100644 src/org/traccar/database/DataCache.java (limited to 'src') diff --git a/src/org/traccar/BasePipelineFactory.java b/src/org/traccar/BasePipelineFactory.java index 3a8d1f48f..469bbc49f 100644 --- a/src/org/traccar/BasePipelineFactory.java +++ b/src/org/traccar/BasePipelineFactory.java @@ -21,26 +21,22 @@ import org.jboss.netty.buffer.ChannelBuffers; import org.jboss.netty.channel.*; import org.jboss.netty.handler.logging.LoggingHandler; import org.jboss.netty.handler.timeout.IdleStateHandler; +import org.traccar.database.DataCache; +import org.traccar.database.DataManager; import org.traccar.geocode.ReverseGeocoder; import org.traccar.helper.Log; -import org.traccar.database.DataManager; -/** - * Base pipeline factory - */ public abstract class BasePipelineFactory implements ChannelPipelineFactory { private final TrackerServer server; private final DataManager dataManager; + private final DataCache dataCache; private final Boolean loggerEnabled; private final ReverseGeocoder reverseGeocoder; private FilterHandler filterHandler; private Integer resetDelay; private Boolean processInvalidPositions; - /** - * Open channel handler - */ protected class OpenChannelHandler extends SimpleChannelHandler { private final TrackerServer server; @@ -90,6 +86,7 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { public BasePipelineFactory(ServerManager serverManager, TrackerServer server, String protocol) { this.server = server; dataManager = serverManager.getDataManager(); + dataCache = serverManager.getDataCache(); loggerEnabled = serverManager.isLoggerEnabled(); reverseGeocoder = serverManager.getReverseGeocoder(); @@ -133,7 +130,7 @@ public abstract class BasePipelineFactory implements ChannelPipelineFactory { if (reverseGeocoder != null) { pipeline.addLast("geocoder", new ReverseGeocoderHandler(reverseGeocoder, processInvalidPositions)); } - pipeline.addLast("handler", new TrackerEventHandler(dataManager)); + pipeline.addLast("handler", new TrackerEventHandler(dataManager, dataCache)); return pipeline; } diff --git a/src/org/traccar/ServerManager.java b/src/org/traccar/ServerManager.java index 184b54078..31da6848f 100644 --- a/src/org/traccar/ServerManager.java +++ b/src/org/traccar/ServerManager.java @@ -15,6 +15,14 @@ */ package org.traccar; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.ByteOrder; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; import org.jboss.netty.bootstrap.ConnectionlessBootstrap; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelPipeline; @@ -26,21 +34,16 @@ import org.jboss.netty.handler.codec.http.HttpRequestDecoder; import org.jboss.netty.handler.codec.http.HttpResponseEncoder; import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringEncoder; +import org.traccar.database.DataCache; import org.traccar.database.DataManager; import org.traccar.geocode.GoogleReverseGeocoder; import org.traccar.geocode.NominatimReverseGeocoder; import org.traccar.geocode.ReverseGeocoder; import org.traccar.helper.Log; import org.traccar.http.WebServer; +import org.traccar.model.Position; import org.traccar.protocol.*; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.ByteOrder; -import java.sql.SQLException; -import java.util.LinkedList; -import java.util.List; -import java.util.Properties; /** * Server Manager @@ -65,6 +68,12 @@ public class ServerManager { return dataManager; } + private DataCache dataCache; + + public DataCache getDataCache() { + return dataCache; + } + private ReverseGeocoder reverseGeocoder; public ReverseGeocoder getReverseGeocoder() { @@ -98,6 +107,14 @@ public class ServerManager { } dataManager = new DataManager(properties); + dataCache = new DataCache(dataManager); + + dataCache.addListener(Arrays.asList(1l), new DataCache.DataCacheListener() { + @Override + public void onUpdate(Position position) { + System.out.println("position: " + position.getLatitude() + ":" + position.getLongitude()); + } + }); initGeocoder(properties); diff --git a/src/org/traccar/TrackerEventHandler.java b/src/org/traccar/TrackerEventHandler.java index 39c70ccc7..ecce97fa4 100644 --- a/src/org/traccar/TrackerEventHandler.java +++ b/src/org/traccar/TrackerEventHandler.java @@ -19,23 +19,20 @@ import java.util.List; import org.jboss.netty.channel.*; import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; import org.jboss.netty.handler.timeout.IdleStateEvent; +import org.traccar.database.DataCache; import org.traccar.helper.Log; import org.traccar.database.DataManager; import org.traccar.model.Position; -/** - * Tracker message handler - */ @ChannelHandler.Sharable public class TrackerEventHandler extends IdleStateAwareChannelHandler { - /** - * Data manager - */ - private DataManager dataManager; + private final DataManager dataManager; + private final DataCache dataCache; - TrackerEventHandler(DataManager newDataManager) { - dataManager = newDataManager; + TrackerEventHandler(DataManager dataManager, DataCache dataCache) { + this.dataManager = dataManager; + this.dataCache = dataCache; } private Long processSinglePosition(Position position) { @@ -77,6 +74,7 @@ public class TrackerEventHandler extends IdleStateAwareChannelHandler { if (lastPostition != null) { try { dataManager.updateLatestPosition(lastPostition, id); + dataCache.update(lastPostition); } catch (Exception error) { Log.warning(error); } diff --git a/src/org/traccar/database/DataCache.java b/src/org/traccar/database/DataCache.java new file mode 100644 index 000000000..f5aa3b1e9 --- /dev/null +++ b/src/org/traccar/database/DataCache.java @@ -0,0 +1,74 @@ +/* + * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) + * + * 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.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import org.traccar.model.Position; + +public class DataCache { + + private final Map positions = new HashMap(); + private final Map> listeners = new HashMap>(); + + public DataCache(DataManager dataManager) { + // TODO: load latest data from datavase + } + + public void update(Position position) { + long device = position.getDeviceId(); + positions.put(device, position); + if (listeners.containsKey(device)) { + for (DataCacheListener listener : listeners.get(device)) { + listener.onUpdate(position); + } + } + } + + public static interface DataCacheListener { + public void onUpdate(Position position); + } + + public void addListener(Collection devices, DataCacheListener listener) { + for (long device : devices) { + addListener(device, listener); + } + } + + public void addListener(long device, DataCacheListener listener) { + if (!listeners.containsKey(device)) { + listeners.put(device, new HashSet()); + } + listeners.get(device).add(listener); + } + + public void removeListener(Collection devices, DataCacheListener listener) { + for (long device : devices) { + removeListener(device, listener); + } + } + + public void removeListener(long device, DataCacheListener listener) { + if (!listeners.containsKey(device)) { + listeners.put(device, new HashSet()); + } + listeners.get(device).remove(listener); + } + +} -- cgit v1.2.3