From fff8f0c792606daff151624479d9ae9dc54187d5 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 14 Dec 2016 17:34:34 +0500 Subject: Calendars implementation --- pom.xml | 5 + schema/changelog-3.10.xml | 45 +++++++++ schema/changelog-master.xml | 1 + setup/default.xml | 38 ++++++- src/org/traccar/Context.java | 8 ++ .../api/resource/CalendarPermissionResource.java | 57 +++++++++++ src/org/traccar/api/resource/CalendarResource.java | 85 ++++++++++++++++ src/org/traccar/database/CalendarManager.java | 112 +++++++++++++++++++++ src/org/traccar/database/DataManager.java | 43 ++++++++ src/org/traccar/database/PermissionsManager.java | 6 ++ src/org/traccar/database/QueryBuilder.java | 30 ++++++ src/org/traccar/events/GeofenceEventHandler.java | 20 ++-- src/org/traccar/model/Calendar.java | 86 ++++++++++++++++ src/org/traccar/model/CalendarPermission.java | 40 ++++++++ src/org/traccar/model/Geofence.java | 9 ++ test/org/traccar/calendar/CalendarTest.java | 54 ++++++++++ 16 files changed, 631 insertions(+), 8 deletions(-) create mode 100644 schema/changelog-3.10.xml create mode 100644 src/org/traccar/api/resource/CalendarPermissionResource.java create mode 100644 src/org/traccar/api/resource/CalendarResource.java create mode 100644 src/org/traccar/database/CalendarManager.java create mode 100644 src/org/traccar/model/Calendar.java create mode 100644 src/org/traccar/model/CalendarPermission.java create mode 100644 test/org/traccar/calendar/CalendarTest.java diff --git a/pom.xml b/pom.xml index 45df20efc..b93ff8e44 100644 --- a/pom.xml +++ b/pom.xml @@ -143,6 +143,11 @@ velocity 1.7 + + org.mnode.ical4j + ical4j + 2.0.0 + diff --git a/schema/changelog-3.10.xml b/schema/changelog-3.10.xml new file mode 100644 index 000000000..8cd7b3704 --- /dev/null +++ b/schema/changelog-3.10.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/schema/changelog-master.xml b/schema/changelog-master.xml index 448015568..2aed50e72 100644 --- a/schema/changelog-master.xml +++ b/schema/changelog-master.xml @@ -11,4 +11,5 @@ + diff --git a/setup/default.xml b/setup/default.xml index ad23d7bd3..aeb8fbe54 100644 --- a/setup/default.xml +++ b/setup/default.xml @@ -206,14 +206,15 @@ - INSERT INTO geofences (name, description, area, attributes) - VALUES (:name, :description, :area, :attributes) + INSERT INTO geofences (name, description, calendarid, area, attributes) + VALUES (:name, :description, :calendarid, :area, :attributes) UPDATE geofences SET name = :name, description = :description, + calendarid = :calendarid, area = :area, attributes = :attributes WHERE id = :id @@ -315,6 +316,39 @@ INSERT INTO statistics (captureTime, activeUsers, activeDevices, requests, messagesReceived, messagesStored, attributes) VALUES (:captureTime, :activeUsers, :activeDevices, :requests, :messagesReceived, :messagesStored, :attributes) + + + SELECT * FROM calendars + + + + INSERT INTO calendars (name, calendarData, attributes) + VALUES (:name, :calendarData, :attributes) + + + + UPDATE calendars SET + name = :name, + calendarData = :calendarData, + attributes = :attributes + WHERE id = :id + + + + DELETE FROM calendars WHERE id = :id + + + + SELECT userId, calendarId FROM user_calendar + + + + INSERT INTO user_calendar (userId, calendarId) VALUES (:userId, :calendarId) + + + + DELETE FROM user_calendar WHERE userId = :userId AND calendarId = :calendarId + diff --git a/src/org/traccar/Context.java b/src/org/traccar/Context.java index 2b8860187..03e4635b6 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() { @@ -253,6 +260,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/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 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 calendars = new ConcurrentHashMap<>(); + private final Map> 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 getUserCalendarIds(long userId) { + if (!userCalendars.containsKey(userId)) { + userCalendars.put(userId, new HashSet()); + } + return userCalendars.get(userId); + } + + public Collection getUserCalendars(long userId) { + ArrayList 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 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 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 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() { + @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 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/model/Calendar.java b/src/org/traccar/model/Calendar.java new file mode 100644 index 000000000..e1ae5a93d --- /dev/null +++ b/src/org/traccar/model/Calendar.java @@ -0,0 +1,86 @@ +/* + * 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 { + setCalendar(calendarData); + } + + private net.fortuna.ical4j.model.Calendar calendar; + + @JsonIgnore + public net.fortuna.ical4j.model.Calendar getCalendar() { + return calendar; + } + + public void setCalendar(byte[] calendarData) throws IOException, ParserException, SQLException { + CalendarBuilder builder = new CalendarBuilder(); + calendar = builder.build(new ByteArrayInputStream(calendarData)); + this.calendarData = calendarData.clone(); + } + + public boolean checkMoment(Date date) { + if (calendar != null) { + Period period = new Period(new DateTime(date), new Dur(0, 0, 0, 1)); + Rule periodRule = new PeriodRule(period); + Filter filter = new Filter(new Rule[] {periodRule}, Filter.MATCH_ANY); + Collection 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/test/org/traccar/calendar/CalendarTest.java b/test/org/traccar/calendar/CalendarTest.java new file mode 100644 index 000000000..44fc9539b --- /dev/null +++ b/test/org/traccar/calendar/CalendarTest.java @@ -0,0 +1,54 @@ +package org.traccar.calendar; + +import java.io.IOException; +import java.sql.SQLException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.junit.Assert; +import org.junit.Test; +import org.traccar.model.Calendar; + +import net.fortuna.ical4j.data.ParserException; + +public class CalendarTest { + + @Test + public void testCalendar() throws IOException, ParserException, ParseException, SQLException { + String calendarString = "BEGIN:VCALENDAR\n" + + "PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN\n" + + "VERSION:2.0\n" + + "BEGIN:VTIMEZONE\n" + + "TZID:Asia/Yekaterinburg\n" + + "BEGIN:STANDARD\n" + + "TZOFFSETFROM:+0500\n" + + "TZOFFSETTO:+0500\n" + + "TZNAME:YEKT\n" + + "DTSTART:19700101T000000\n" + + "END:STANDARD\n" + + "END:VTIMEZONE\n" + + "BEGIN:VEVENT\n" + + "CREATED:20161213T045151Z\n" + + "LAST-MODIFIED:20161213T045242Z\n" + + "DTSTAMP:20161213T045242Z\n" + + "UID:9d000df0-6354-479d-a407-218dac62c7c9\n" + + "SUMMARY:Every night\n" + + "RRULE:FREQ=DAILY\n" + + "DTSTART;TZID=Asia/Yekaterinburg:20161130T230000\n" + + "DTEND;TZID=Asia/Yekaterinburg:20161201T070000\n" + + "TRANSP:OPAQUE\n" + + "END:VEVENT\n" + + "END:VCALENDAR"; + Calendar calendar = new Calendar(); + calendar.setCalendar(calendarString.getBytes()); + DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ssX"); + + Date date = format.parse("2016-12-13 23:01:00+05"); + Assert.assertTrue(calendar.checkMoment(date)); + + date = format.parse("2016-12-13 07:01:00+05"); + Assert.assertTrue(!calendar.checkMoment(date)); + } +} -- cgit v1.2.3 From ef9148eea8dd404aba5707898f244a4b7bc26feb Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Thu, 15 Dec 2016 09:45:29 +0500 Subject: - Set period duration to 0 - Remove setter - Added test cases - Style fix --- pom.xml | 6 +++--- src/org/traccar/model/Calendar.java | 12 ++++-------- test/org/traccar/calendar/CalendarTest.java | 14 +++++++++----- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pom.xml b/pom.xml index b93ff8e44..3d142b7cf 100644 --- a/pom.xml +++ b/pom.xml @@ -144,9 +144,9 @@ 1.7 - org.mnode.ical4j - ical4j - 2.0.0 + org.mnode.ical4j + ical4j + 2.0.0 diff --git a/src/org/traccar/model/Calendar.java b/src/org/traccar/model/Calendar.java index e1ae5a93d..19b5fde16 100644 --- a/src/org/traccar/model/Calendar.java +++ b/src/org/traccar/model/Calendar.java @@ -55,7 +55,9 @@ public class Calendar extends Extensible { } public void setCalendarData(byte[] calendarData) throws IOException, ParserException, SQLException { - setCalendar(calendarData); + CalendarBuilder builder = new CalendarBuilder(); + calendar = builder.build(new ByteArrayInputStream(calendarData)); + this.calendarData = calendarData.clone(); } private net.fortuna.ical4j.model.Calendar calendar; @@ -65,15 +67,9 @@ public class Calendar extends Extensible { return calendar; } - public void setCalendar(byte[] calendarData) throws IOException, ParserException, SQLException { - CalendarBuilder builder = new CalendarBuilder(); - calendar = builder.build(new ByteArrayInputStream(calendarData)); - this.calendarData = calendarData.clone(); - } - public boolean checkMoment(Date date) { if (calendar != null) { - Period period = new Period(new DateTime(date), new Dur(0, 0, 0, 1)); + Period period = new Period(new DateTime(date), new Dur(0, 0, 0, 0)); Rule periodRule = new PeriodRule(period); Filter filter = new Filter(new Rule[] {periodRule}, Filter.MATCH_ANY); Collection events = filter.filter(calendar.getComponents(Component.VEVENT)); diff --git a/test/org/traccar/calendar/CalendarTest.java b/test/org/traccar/calendar/CalendarTest.java index 44fc9539b..7f5bd7d29 100644 --- a/test/org/traccar/calendar/CalendarTest.java +++ b/test/org/traccar/calendar/CalendarTest.java @@ -42,13 +42,17 @@ public class CalendarTest { "END:VEVENT\n" + "END:VCALENDAR"; Calendar calendar = new Calendar(); - calendar.setCalendar(calendarString.getBytes()); + calendar.setCalendarData(calendarString.getBytes()); DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ssX"); - - Date date = format.parse("2016-12-13 23:01:00+05"); + + Date date = format.parse("2016-12-13 22:59:59+05"); + Assert.assertTrue(!calendar.checkMoment(date)); + date = format.parse("2016-12-13 23:00:01+05"); + Assert.assertTrue(calendar.checkMoment(date)); + + date = format.parse("2016-12-13 06:59:59+05"); Assert.assertTrue(calendar.checkMoment(date)); - - date = format.parse("2016-12-13 07:01:00+05"); + date = format.parse("2016-12-13 07:00:01+05"); Assert.assertTrue(!calendar.checkMoment(date)); } } -- cgit v1.2.3