aboutsummaryrefslogtreecommitdiff
path: root/src/org/traccar
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/traccar')
-rw-r--r--src/org/traccar/BaseProtocolDecoder.java27
-rw-r--r--src/org/traccar/Context.java14
-rw-r--r--src/org/traccar/ExtendedObjectDecoder.java5
-rw-r--r--src/org/traccar/api/resource/CalendarPermissionResource.java57
-rw-r--r--src/org/traccar/api/resource/CalendarResource.java85
-rw-r--r--src/org/traccar/database/CalendarManager.java112
-rw-r--r--src/org/traccar/database/DataManager.java43
-rw-r--r--src/org/traccar/database/PermissionsManager.java6
-rw-r--r--src/org/traccar/database/QueryBuilder.java30
-rw-r--r--src/org/traccar/events/GeofenceEventHandler.java20
-rw-r--r--src/org/traccar/location/MozillaLocationProvider.java8
-rw-r--r--src/org/traccar/model/Calendar.java82
-rw-r--r--src/org/traccar/model/CalendarPermission.java40
-rw-r--r--src/org/traccar/model/Geofence.java9
-rw-r--r--src/org/traccar/protocol/AplicomProtocolDecoder.java5
-rw-r--r--src/org/traccar/protocol/AutoGradeProtocolDecoder.java2
-rw-r--r--src/org/traccar/web/WebServer.java2
17 files changed, 528 insertions, 19 deletions
diff --git a/src/org/traccar/BaseProtocolDecoder.java b/src/org/traccar/BaseProtocolDecoder.java
index ea0905bf2..8748a9be6 100644
--- a/src/org/traccar/BaseProtocolDecoder.java
+++ b/src/org/traccar/BaseProtocolDecoder.java
@@ -23,6 +23,7 @@ import org.traccar.model.Position;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
+import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@@ -165,13 +166,31 @@ public abstract class BaseProtocolDecoder extends ExtendedObjectDecoder {
}
@Override
- protected void onMessageEvent(Channel channel, SocketAddress remoteAddress, Object msg) {
+ protected void onMessageEvent(
+ Channel channel, SocketAddress remoteAddress, Object originalMessage, Object decodedMessage) {
if (Context.getStatisticsManager() != null) {
Context.getStatisticsManager().registerMessageReceived();
}
- DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
- if (deviceSession != null) {
- Context.getConnectionManager().updateDevice(deviceSession.getDeviceId(), Device.STATUS_ONLINE, new Date());
+ Position position = null;
+ if (decodedMessage != null) {
+ if (decodedMessage instanceof Position) {
+ position = (Position) decodedMessage;
+ } else if (decodedMessage instanceof Collection) {
+ Collection positions = (Collection) decodedMessage;
+ if (!positions.isEmpty()) {
+ position = (Position) positions.iterator().next();
+ }
+ }
+ }
+ if (position != null) {
+ Context.getConnectionManager().updateDevice(
+ position.getDeviceId(), Device.STATUS_ONLINE, new Date());
+ } else {
+ DeviceSession deviceSession = getDeviceSession(channel, remoteAddress);
+ if (deviceSession != null) {
+ Context.getConnectionManager().updateDevice(
+ deviceSession.getDeviceId(), Device.STATUS_ONLINE, new Date());
+ }
}
}
diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java
index 2b8860187..d859e91bb 100644
--- a/src/org/traccar/Context.java
+++ b/src/org/traccar/Context.java
@@ -23,6 +23,7 @@ import java.util.Properties;
import org.apache.velocity.app.VelocityEngine;
import org.eclipse.jetty.util.URIUtil;
import org.traccar.database.AliasesManager;
+import org.traccar.database.CalendarManager;
import org.traccar.database.ConnectionManager;
import org.traccar.database.DataManager;
import org.traccar.database.DeviceManager;
@@ -124,6 +125,12 @@ public final class Context {
return geofenceManager;
}
+ private static CalendarManager calendarManager;
+
+ public static CalendarManager getCalendarManager() {
+ return calendarManager;
+ }
+
private static NotificationManager notificationManager;
public static NotificationManager getNotificationManager() {
@@ -235,7 +242,11 @@ public final class Context {
switch (type) {
case "mozilla":
- locationProvider = new MozillaLocationProvider();
+ if (key != null) {
+ locationProvider = new MozillaLocationProvider(key);
+ } else {
+ locationProvider = new MozillaLocationProvider();
+ }
break;
default:
locationProvider = new OpenCellIdLocationProvider(key);
@@ -253,6 +264,7 @@ public final class Context {
if (config.getBoolean("event.geofenceHandler")) {
geofenceManager = new GeofenceManager(dataManager);
+ calendarManager = new CalendarManager(dataManager);
}
if (config.getBoolean("event.enable")) {
diff --git a/src/org/traccar/ExtendedObjectDecoder.java b/src/org/traccar/ExtendedObjectDecoder.java
index ec03afa60..268e6f688 100644
--- a/src/org/traccar/ExtendedObjectDecoder.java
+++ b/src/org/traccar/ExtendedObjectDecoder.java
@@ -56,7 +56,7 @@ public abstract class ExtendedObjectDecoder implements ChannelUpstreamHandler {
MessageEvent e = (MessageEvent) evt;
Object originalMessage = e.getMessage();
Object decodedMessage = decode(e.getChannel(), e.getRemoteAddress(), originalMessage);
- onMessageEvent(e.getChannel(), e.getRemoteAddress(), originalMessage); // call after decode
+ onMessageEvent(e.getChannel(), e.getRemoteAddress(), originalMessage, decodedMessage);
if (originalMessage == decodedMessage) {
ctx.sendUpstream(evt);
} else {
@@ -77,7 +77,8 @@ public abstract class ExtendedObjectDecoder implements ChannelUpstreamHandler {
}
}
- protected void onMessageEvent(Channel channel, SocketAddress remoteAddress, Object msg) {
+ protected void onMessageEvent(
+ Channel channel, SocketAddress remoteAddress, Object originalMessage, Object decodedMessage) {
}
protected Object handleEmptyMessage(Channel channel, SocketAddress remoteAddress, Object msg) {
diff --git a/src/org/traccar/api/resource/CalendarPermissionResource.java b/src/org/traccar/api/resource/CalendarPermissionResource.java
new file mode 100644
index 000000000..a49254b6b
--- /dev/null
+++ b/src/org/traccar/api/resource/CalendarPermissionResource.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 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.api.resource;
+
+import java.sql.SQLException;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.traccar.Context;
+import org.traccar.api.BaseResource;
+import org.traccar.model.CalendarPermission;
+
+@Path("permissions/calendars")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class CalendarPermissionResource extends BaseResource {
+
+ @POST
+ public Response add(CalendarPermission entity) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkUser(getUserId(), entity.getUserId());
+ Context.getPermissionsManager().checkCalendar(getUserId(), entity.getCalendarId());
+ Context.getDataManager().linkCalendar(entity.getUserId(), entity.getCalendarId());
+ Context.getCalendarManager().refreshUserCalendars();
+ return Response.ok(entity).build();
+ }
+
+ @DELETE
+ public Response remove(CalendarPermission entity) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkUser(getUserId(), entity.getUserId());
+ Context.getPermissionsManager().checkCalendar(getUserId(), entity.getCalendarId());
+ Context.getDataManager().unlinkCalendar(entity.getUserId(), entity.getCalendarId());
+ Context.getCalendarManager().refreshUserCalendars();
+ return Response.noContent().build();
+ }
+}
diff --git a/src/org/traccar/api/resource/CalendarResource.java b/src/org/traccar/api/resource/CalendarResource.java
new file mode 100644
index 000000000..0a9bb5daf
--- /dev/null
+++ b/src/org/traccar/api/resource/CalendarResource.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 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.api.resource;
+
+import java.sql.SQLException;
+import java.util.Collection;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.traccar.Context;
+import org.traccar.api.BaseResource;
+import org.traccar.model.Calendar;
+
+@Path("calendars")
+@Produces(MediaType.APPLICATION_JSON)
+@Consumes(MediaType.APPLICATION_JSON)
+public class CalendarResource extends BaseResource {
+
+ @GET
+ public Collection<Calendar> get(
+ @QueryParam("all") boolean all, @QueryParam("userId") long userId) throws SQLException {
+
+ if (all) {
+ Context.getPermissionsManager().checkAdmin(getUserId());
+ return Context.getCalendarManager().getAllCalendars();
+ } else {
+ if (userId == 0) {
+ userId = getUserId();
+ }
+ Context.getPermissionsManager().checkUser(getUserId(), userId);
+ return Context.getCalendarManager().getUserCalendars(userId);
+ }
+ }
+
+ @POST
+ public Response add(Calendar entity) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getCalendarManager().addCalendar(entity);
+ Context.getDataManager().linkCalendar(getUserId(), entity.getId());
+ Context.getCalendarManager().refreshUserCalendars();
+ return Response.ok(entity).build();
+ }
+
+ @Path("{id}")
+ @PUT
+ public Response update(Calendar entity) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkCalendar(getUserId(), entity.getId());
+ Context.getCalendarManager().updateCalendar(entity);
+ return Response.ok(entity).build();
+ }
+
+ @Path("{id}")
+ @DELETE
+ public Response remove(@PathParam("id") long id) throws SQLException {
+ Context.getPermissionsManager().checkReadonly(getUserId());
+ Context.getPermissionsManager().checkCalendar(getUserId(), id);
+ Context.getCalendarManager().removeCalendar(id);
+ return Response.noContent().build();
+ }
+}
diff --git a/src/org/traccar/database/CalendarManager.java b/src/org/traccar/database/CalendarManager.java
new file mode 100644
index 000000000..3e95f6698
--- /dev/null
+++ b/src/org/traccar/database/CalendarManager.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 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.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.traccar.helper.Log;
+import org.traccar.model.Calendar;
+import org.traccar.model.CalendarPermission;
+
+public class CalendarManager {
+
+ private final DataManager dataManager;
+
+ private final Map<Long, Calendar> calendars = new ConcurrentHashMap<>();
+ private final Map<Long, Set<Long>> userCalendars = new ConcurrentHashMap<>();
+
+ public CalendarManager(DataManager dataManager) {
+ this.dataManager = dataManager;
+ refreshCalendars();
+ }
+
+ public final void refreshCalendars() {
+ if (dataManager != null) {
+ try {
+ calendars.clear();
+ for (Calendar calendar : dataManager.getCalendars()) {
+ calendars.put(calendar.getId(), calendar);
+ }
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+ }
+ refreshUserCalendars();
+ }
+
+ private Set<Long> getUserCalendarIds(long userId) {
+ if (!userCalendars.containsKey(userId)) {
+ userCalendars.put(userId, new HashSet<Long>());
+ }
+ return userCalendars.get(userId);
+ }
+
+ public Collection<Calendar> getUserCalendars(long userId) {
+ ArrayList<Calendar> result = new ArrayList<>();
+ for (long calendarId : getUserCalendarIds(userId)) {
+ result.add(calendars.get(calendarId));
+ }
+ return result;
+ }
+
+ public final void refreshUserCalendars() {
+ if (dataManager != null) {
+ try {
+ userCalendars.clear();
+ for (CalendarPermission calendarsPermission : dataManager.getCalendarPermissions()) {
+ getUserCalendarIds(calendarsPermission.getUserId()).add(calendarsPermission.getCalendarId());
+ }
+ } catch (SQLException error) {
+ Log.warning(error);
+ }
+ }
+ }
+
+ public Calendar getCalendar(long calendarId) {
+ return calendars.get(calendarId);
+ }
+
+ public final void addCalendar(Calendar calendar) throws SQLException {
+ dataManager.addCalendar(calendar);
+ calendars.put(calendar.getId(), calendar);
+ }
+
+ public final void updateCalendar(Calendar calendar) throws SQLException {
+ dataManager.updateCalendar(calendar);
+ calendars.put(calendar.getId(), calendar);
+ }
+
+ public final void removeCalendar(long calendarId) throws SQLException {
+ dataManager.removeCalendar(calendarId);
+ calendars.remove(calendarId);
+ refreshUserCalendars();
+ }
+
+ public Collection<Calendar> getAllCalendars() {
+ return calendars.values();
+ }
+
+ public boolean checkCalendar(long userId, long calendarId) {
+ return getUserCalendarIds(userId).contains(calendarId);
+ }
+}
diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java
index 8be53ad7b..278109229 100644
--- a/src/org/traccar/database/DataManager.java
+++ b/src/org/traccar/database/DataManager.java
@@ -37,6 +37,8 @@ import liquibase.resource.ResourceAccessor;
import org.traccar.Config;
import org.traccar.helper.Log;
import org.traccar.model.AttributeAlias;
+import org.traccar.model.Calendar;
+import org.traccar.model.CalendarPermission;
import org.traccar.model.Device;
import org.traccar.model.DevicePermission;
import org.traccar.model.Event;
@@ -484,4 +486,45 @@ public class DataManager {
.executeUpdate());
}
+ public Collection<Calendar> getCalendars() throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectCalendarsAll"))
+ .executeQuery(Calendar.class);
+ }
+
+ public void addCalendar(Calendar calendar) throws SQLException {
+ calendar.setId(QueryBuilder.create(dataSource, getQuery("database.insertCalendar"), true)
+ .setObject(calendar)
+ .executeUpdate());
+ }
+
+ public void updateCalendar(Calendar calendar) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.updateCalendar"))
+ .setObject(calendar)
+ .executeUpdate();
+ }
+
+ public void removeCalendar(long calendarId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.deleteCalendar"))
+ .setLong("id", calendarId)
+ .executeUpdate();
+ }
+
+ public Collection<CalendarPermission> getCalendarPermissions() throws SQLException {
+ return QueryBuilder.create(dataSource, getQuery("database.selectCalendarPermissions"))
+ .executeQuery(CalendarPermission.class);
+ }
+
+ public void linkCalendar(long userId, long calendarId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.linkCalendar"))
+ .setLong("userId", userId)
+ .setLong("calendarId", calendarId)
+ .executeUpdate();
+ }
+
+ public void unlinkCalendar(long userId, long calendarId) throws SQLException {
+ QueryBuilder.create(dataSource, getQuery("database.unlinkCalendar"))
+ .setLong("userId", userId)
+ .setLong("calendarId", calendarId)
+ .executeUpdate();
+ }
}
diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java
index 078a5f935..6c0610655 100644
--- a/src/org/traccar/database/PermissionsManager.java
+++ b/src/org/traccar/database/PermissionsManager.java
@@ -207,6 +207,12 @@ public class PermissionsManager {
}
}
+ public void checkCalendar(long userId, long calendarId) throws SecurityException {
+ if (!Context.getCalendarManager().checkCalendar(userId, calendarId) && !isAdmin(userId)) {
+ throw new SecurityException("Calendar access denied");
+ }
+ }
+
public Server getServer() {
return server;
}
diff --git a/src/org/traccar/database/QueryBuilder.java b/src/org/traccar/database/QueryBuilder.java
index 50d689a2a..201240f2f 100644
--- a/src/org/traccar/database/QueryBuilder.java
+++ b/src/org/traccar/database/QueryBuilder.java
@@ -240,6 +240,23 @@ public final class QueryBuilder {
return this;
}
+ public QueryBuilder setBlob(String name, byte[] value) throws SQLException {
+ for (int i : indexes(name)) {
+ try {
+ if (value == null) {
+ statement.setNull(i, Types.BLOB);
+ } else {
+ statement.setBytes(i, value);
+ }
+ } catch (SQLException error) {
+ statement.close();
+ connection.close();
+ throw error;
+ }
+ }
+ return this;
+ }
+
public QueryBuilder setObject(Object object) throws SQLException {
Method[] methods = object.getClass().getMethods();
@@ -260,6 +277,8 @@ public final class QueryBuilder {
setString(name, (String) method.invoke(object));
} else if (method.getReturnType().equals(Date.class)) {
setDate(name, (Date) method.invoke(object));
+ } else if (method.getReturnType().equals(byte[].class)) {
+ setBlob(name, (byte[]) method.invoke(object));
} else if (method.getReturnType().equals(Map.class)) {
if (Context.getConfig().getBoolean("database.xml")) {
setString(name, MiscFormatter.toXmlString((Map) method.invoke(object)));
@@ -375,6 +394,17 @@ public final class QueryBuilder {
}
}
});
+ } else if (parameterType.equals(byte[].class)) {
+ processors.add(new ResultSetProcessor<T>() {
+ @Override
+ public void process(T object, ResultSet resultSet) throws SQLException {
+ try {
+ method.invoke(object, resultSet.getBytes(name));
+ } catch (IllegalAccessException | InvocationTargetException error) {
+ Log.warning(error);
+ }
+ }
+ });
}
}
diff --git a/src/org/traccar/events/GeofenceEventHandler.java b/src/org/traccar/events/GeofenceEventHandler.java
index d31e516ef..fbec932b1 100644
--- a/src/org/traccar/events/GeofenceEventHandler.java
+++ b/src/org/traccar/events/GeofenceEventHandler.java
@@ -57,14 +57,22 @@ public class GeofenceEventHandler extends BaseEventHandler {
Collection<Event> events = new ArrayList<>();
for (long geofenceId : newGeofences) {
- Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position.getDeviceId(), position.getId());
- event.setGeofenceId(geofenceId);
- events.add(event);
+ long calendarId = geofenceManager.getGeofence(geofenceId).getCalendarId();
+ if (calendarId == 0 || Context.getCalendarManager().getCalendar(calendarId) == null
+ || Context.getCalendarManager().getCalendar(calendarId).checkMoment(position.getFixTime())) {
+ Event event = new Event(Event.TYPE_GEOFENCE_ENTER, position.getDeviceId(), position.getId());
+ event.setGeofenceId(geofenceId);
+ events.add(event);
+ }
}
for (long geofenceId : oldGeofences) {
- Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position.getDeviceId(), position.getId());
- event.setGeofenceId(geofenceId);
- events.add(event);
+ long calendarId = geofenceManager.getGeofence(geofenceId).getCalendarId();
+ if (calendarId == 0 || Context.getCalendarManager().getCalendar(calendarId) == null
+ || Context.getCalendarManager().getCalendar(calendarId).checkMoment(position.getFixTime())) {
+ Event event = new Event(Event.TYPE_GEOFENCE_EXIT, position.getDeviceId(), position.getId());
+ event.setGeofenceId(geofenceId);
+ events.add(event);
+ }
}
return events;
}
diff --git a/src/org/traccar/location/MozillaLocationProvider.java b/src/org/traccar/location/MozillaLocationProvider.java
index 37040a95e..cbfc19550 100644
--- a/src/org/traccar/location/MozillaLocationProvider.java
+++ b/src/org/traccar/location/MozillaLocationProvider.java
@@ -25,15 +25,17 @@ import javax.json.JsonReader;
public class MozillaLocationProvider extends BaseLocationProvider {
+ private static final String URL = "https://location.services.mozilla.com/v1/geolocate";
+
private String url;
private String template;
public MozillaLocationProvider() {
- this("https://location.services.mozilla.com/v1/geolocate", "test");
+ this("test");
}
- public MozillaLocationProvider(String url, String key) {
- this.url = url + "?key=" + key;
+ public MozillaLocationProvider(String key) {
+ this.url = URL + "?key=" + key;
template = new StringBuilder()
.append("{\"cellTowers\":[{")
diff --git a/src/org/traccar/model/Calendar.java b/src/org/traccar/model/Calendar.java
new file mode 100644
index 000000000..19b5fde16
--- /dev/null
+++ b/src/org/traccar/model/Calendar.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import net.fortuna.ical4j.data.CalendarBuilder;
+import net.fortuna.ical4j.data.ParserException;
+import net.fortuna.ical4j.filter.Filter;
+import net.fortuna.ical4j.filter.PeriodRule;
+import net.fortuna.ical4j.filter.Rule;
+import net.fortuna.ical4j.model.Component;
+import net.fortuna.ical4j.model.DateTime;
+import net.fortuna.ical4j.model.Dur;
+import net.fortuna.ical4j.model.Period;
+import net.fortuna.ical4j.model.component.CalendarComponent;
+import net.fortuna.ical4j.validate.ValidationException;
+
+public class Calendar extends Extensible {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ private byte[] calendarData;
+
+ public byte[] getCalendarData() throws ValidationException, IOException {
+ return calendarData.clone();
+ }
+
+ public void setCalendarData(byte[] calendarData) throws IOException, ParserException, SQLException {
+ CalendarBuilder builder = new CalendarBuilder();
+ calendar = builder.build(new ByteArrayInputStream(calendarData));
+ this.calendarData = calendarData.clone();
+ }
+
+ private net.fortuna.ical4j.model.Calendar calendar;
+
+ @JsonIgnore
+ public net.fortuna.ical4j.model.Calendar getCalendar() {
+ return calendar;
+ }
+
+ public boolean checkMoment(Date date) {
+ if (calendar != null) {
+ Period period = new Period(new DateTime(date), new Dur(0, 0, 0, 0));
+ Rule<Component> periodRule = new PeriodRule<Component>(period);
+ Filter<CalendarComponent> filter = new Filter<CalendarComponent>(new Rule[] {periodRule}, Filter.MATCH_ANY);
+ Collection<CalendarComponent> events = filter.filter(calendar.getComponents(Component.VEVENT));
+ if (events != null && !events.isEmpty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/org/traccar/model/CalendarPermission.java b/src/org/traccar/model/CalendarPermission.java
new file mode 100644
index 000000000..59f54e07b
--- /dev/null
+++ b/src/org/traccar/model/CalendarPermission.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2016 Anton Tananaev (anton@traccar.org)
+ * Copyright 2016 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 CalendarPermission {
+
+ private long userId;
+
+ public long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(long userId) {
+ this.userId = userId;
+ }
+
+ private long calendarId;
+
+ public long getCalendarId() {
+ return calendarId;
+ }
+
+ public void setCalendarId(long calendarId) {
+ this.calendarId = calendarId;
+ }
+}
diff --git a/src/org/traccar/model/Geofence.java b/src/org/traccar/model/Geofence.java
index 326c45b5f..f10ce6862 100644
--- a/src/org/traccar/model/Geofence.java
+++ b/src/org/traccar/model/Geofence.java
@@ -84,4 +84,13 @@ public class Geofence extends Extensible {
this.geometry = geometry;
}
+ private long calendarId;
+
+ public long getCalendarId() {
+ return calendarId;
+ }
+
+ public void setCalendarId(long calendarId) {
+ this.calendarId = calendarId;
+ }
}
diff --git a/src/org/traccar/protocol/AplicomProtocolDecoder.java b/src/org/traccar/protocol/AplicomProtocolDecoder.java
index 8c06aad6f..bcaac5349 100644
--- a/src/org/traccar/protocol/AplicomProtocolDecoder.java
+++ b/src/org/traccar/protocol/AplicomProtocolDecoder.java
@@ -466,7 +466,10 @@ public class AplicomProtocolDecoder extends BaseProtocolDecoder {
position.set("tripDistance", buf.readUnsignedInt() * 5);
position.set("serviceDistance", (buf.readUnsignedInt() - 2105540607) * 5);
} else if (type == 0x0A) {
- position.set("brakeData", ChannelBuffers.hexDump(buf.readBytes(length)));
+ ChannelBuffer brakeData = buf.readBytes(length);
+ position.set("absStatusCounter", brakeData.readUnsignedShort());
+ position.set("atvbStatusCounter", brakeData.readUnsignedShort());
+ position.set("vdcActiveCounter", brakeData.readUnsignedShort());
} else if (type == 0x0B) {
position.set("brakeMinMaxData", ChannelBuffers.hexDump(buf.readBytes(length)));
} else if (type == 0x0C) {
diff --git a/src/org/traccar/protocol/AutoGradeProtocolDecoder.java b/src/org/traccar/protocol/AutoGradeProtocolDecoder.java
index d8fe8b1a2..744117cfe 100644
--- a/src/org/traccar/protocol/AutoGradeProtocolDecoder.java
+++ b/src/org/traccar/protocol/AutoGradeProtocolDecoder.java
@@ -89,7 +89,7 @@ public class AutoGradeProtocolDecoder extends BaseProtocolDecoder {
position.setCourse(parser.nextDouble());
- int status = (byte) parser.next().charAt(0);
+ int status = parser.next().charAt(0);
position.set(Position.KEY_STATUS, status);
position.set(Position.KEY_IGNITION, BitUtil.check(status, 0));
diff --git a/src/org/traccar/web/WebServer.java b/src/org/traccar/web/WebServer.java
index 8201f8d16..4dd37f4cc 100644
--- a/src/org/traccar/web/WebServer.java
+++ b/src/org/traccar/web/WebServer.java
@@ -102,7 +102,7 @@ public class WebServer {
ResourceHandler resourceHandler = new ResourceHandler();
resourceHandler.setResourceBase(config.getString("web.path"));
if (config.getBoolean("web.debug")) {
- resourceHandler.setWelcomeFiles(new String[] {"debug.html"});
+ resourceHandler.setWelcomeFiles(new String[] {"debug.html", "index.html"});
resourceHandler.setMinMemoryMappedContentLength(-1); // avoid locking files on Windows
} else {
resourceHandler.setWelcomeFiles(new String[] {"release.html", "index.html"});