From a5c431069ca0dfe8240f0c8b43f0508189f8fc86 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 3 Aug 2016 10:05:40 +0500 Subject: - Added getGroupDevices to PermissionsManager - Implemented Route Report --- src/org/traccar/api/resource/ReportResource.java | 43 +++++++ src/org/traccar/database/PermissionsManager.java | 16 ++- src/org/traccar/reports/Events.java | 5 + src/org/traccar/reports/ReportUtils.java | 35 ++++++ src/org/traccar/reports/Route.java | 43 +++++++ src/org/traccar/web/CsvBuilder.java | 150 +++++++++++++++++++++++ src/org/traccar/web/WebServer.java | 3 +- 7 files changed, 293 insertions(+), 2 deletions(-) create mode 100644 src/org/traccar/api/resource/ReportResource.java create mode 100644 src/org/traccar/reports/Events.java create mode 100644 src/org/traccar/reports/ReportUtils.java create mode 100644 src/org/traccar/reports/Route.java create mode 100644 src/org/traccar/web/CsvBuilder.java (limited to 'src/org/traccar') diff --git a/src/org/traccar/api/resource/ReportResource.java b/src/org/traccar/api/resource/ReportResource.java new file mode 100644 index 000000000..598cbebf6 --- /dev/null +++ b/src/org/traccar/api/resource/ReportResource.java @@ -0,0 +1,43 @@ +package org.traccar.api.resource; + +import java.sql.SQLException; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; + +import org.traccar.api.BaseResource; +import org.traccar.reports.ReportUtils; +import org.traccar.reports.Route; +import org.traccar.web.JsonConverter; + +@Path("reports") +public class ReportResource extends BaseResource { + + @Path("route") + @GET + public Response getRoute(@Context HttpHeaders headers, + @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, + @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException { + MultivaluedMap headerParams = headers.getRequestHeaders(); + String accept = headerParams.getFirst("Accept"); + if (accept.equals("application/ms-excel")) { + ResponseBuilder response = Response.ok(ReportUtils.getOut(Route.getCsv(getUserId(), deviceIds, groupIds, + JsonConverter.parseDate(from), JsonConverter.parseDate(to)))); + response.type("application/ms-excel"); + return response.build(); + } + ResponseBuilder response = Response.ok(Route.getJson(getUserId(), deviceIds, groupIds, + JsonConverter.parseDate(from), JsonConverter.parseDate(to))); + response.type(MediaType.APPLICATION_JSON); + return response.build(); + } + +} diff --git a/src/org/traccar/database/PermissionsManager.java b/src/org/traccar/database/PermissionsManager.java index 92fcc3ebd..3c2cc252b 100644 --- a/src/org/traccar/database/PermissionsManager.java +++ b/src/org/traccar/database/PermissionsManager.java @@ -41,6 +41,7 @@ public class PermissionsManager { private final Map> groupPermissions = new HashMap<>(); private final Map> devicePermissions = new HashMap<>(); private final Map> deviceUsers = new HashMap<>(); + private final Map> groupDevices = new HashMap<>(); public Set getGroupPermissions(long userId) { if (!groupPermissions.containsKey(userId)) { @@ -63,6 +64,13 @@ public class PermissionsManager { return deviceUsers.get(deviceId); } + public Set getGroupDevices(long groupId) { + if (!groupDevices.containsKey(groupId)) { + groupDevices.put(groupId, new HashSet()); + } + return groupDevices.get(groupId); + } + public PermissionsManager(DataManager dataManager) { this.dataManager = dataManager; refresh(); @@ -91,11 +99,17 @@ public class PermissionsManager { userDevicePermissions.add(device.getId()); } } - for (DevicePermission permission : dataManager.getDevicePermissions()) { getDevicePermissions(permission.getUserId()).add(permission.getDeviceId()); } + groupDevices.clear(); + for (Group group : Context.getDeviceManager().getAllGroups()) { + for (Device device : groupTree.getDevices(group.getId())) { + getGroupDevices(group.getId()).add(device.getId()); + } + } + } catch (SQLException error) { Log.warning(error); } diff --git a/src/org/traccar/reports/Events.java b/src/org/traccar/reports/Events.java new file mode 100644 index 000000000..1edeb0773 --- /dev/null +++ b/src/org/traccar/reports/Events.java @@ -0,0 +1,5 @@ +package org.traccar.reports; + +public final class Events { + +} diff --git a/src/org/traccar/reports/ReportUtils.java b/src/org/traccar/reports/ReportUtils.java new file mode 100644 index 000000000..e8048f1f2 --- /dev/null +++ b/src/org/traccar/reports/ReportUtils.java @@ -0,0 +1,35 @@ +package org.traccar.reports; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Collection; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.StreamingOutput; + +import org.traccar.Context; + +public final class ReportUtils { + + private ReportUtils() { + } + + public static Collection getReportedDevices(Collection deviceIds, Collection groupIds) { + Collection result = new ArrayList<>(); + result.addAll(deviceIds); + for (long groupId : groupIds) { + result.addAll(Context.getPermissionsManager().getGroupDevices(groupId)); + } + return result; + } + + public static StreamingOutput getOut(final byte[] csvBytes) { + return new StreamingOutput() { + @Override + public void write(OutputStream out) throws IOException, WebApplicationException { + out.write(csvBytes); + } + }; + } +} diff --git a/src/org/traccar/reports/Route.java b/src/org/traccar/reports/Route.java new file mode 100644 index 000000000..3602c4758 --- /dev/null +++ b/src/org/traccar/reports/Route.java @@ -0,0 +1,43 @@ +package org.traccar.reports; + +import java.sql.SQLException; +import java.util.Collection; +import java.util.Date; + +import javax.json.Json; +import javax.json.JsonObjectBuilder; + +import org.traccar.Context; +import org.traccar.model.Position; +import org.traccar.web.CsvBuilder; +import org.traccar.web.JsonConverter; + +public final class Route { + + private Route() { + } + + public static String getJson(long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws SQLException { + JsonObjectBuilder json = Json.createObjectBuilder(); + for (long deviceId: ReportUtils.getReportedDevices(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + json.add(String.valueOf(deviceId), JsonConverter.arrayToJson(Context.getDataManager() + .getPositions(deviceId, from, to))); + } + return json.build().toString(); + } + + public static byte[] getCsv(long userId, Collection deviceIds, Collection groupIds, + Date from, Date to) throws SQLException { + CsvBuilder csv = new CsvBuilder(); + for (long deviceId: ReportUtils.getReportedDevices(deviceIds, groupIds)) { + Context.getPermissionsManager().checkDevice(userId, deviceId); + csv.addLine(deviceId); + csv.addHeaderLine(new Position()); + csv.addArray(Context.getDataManager().getPositions(deviceId, from, to)); + } + return csv.get(); + } + +} diff --git a/src/org/traccar/web/CsvBuilder.java b/src/org/traccar/web/CsvBuilder.java new file mode 100644 index 000000000..cfebec3b4 --- /dev/null +++ b/src/org/traccar/web/CsvBuilder.java @@ -0,0 +1,150 @@ +package org.traccar.web; + +import java.beans.Introspector; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Date; +import java.util.Map; + +import org.joda.time.DateTime; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; +import org.traccar.helper.Log; +import org.traccar.model.MiscFormatter; + +public class CsvBuilder { + + private static final String LINE_ENDING = "\r\n"; + private static final String SEPARATOR = ";"; + private static final DateTimeFormatter DATE_FORMAT = ISODateTimeFormat.dateTime(); + + private StringBuilder builder = new StringBuilder(); + + private void addLineEnding() { + builder.append(LINE_ENDING); + } + private void addSeparator() { + builder.append(SEPARATOR); + } + public void addLine(String value) { + if (value != null) { + builder.append(value); + } + addLineEnding(); + } + + public void addLine(long value) { + builder.append(value); + addLineEnding(); + } + + public void addLine(double value) { + builder.append(value); + addLineEnding(); + } + + public void addLine(boolean value) { + builder.append(value); + addLineEnding(); + } + + public void addField(String value) { + builder.append(value); + addSeparator(); + } + + public void addField(long value) { + builder.append(value); + addSeparator(); + } + + public void addField(int value) { + builder.append(value); + addSeparator(); + } + + public void addField(double value) { + builder.append(value); + addSeparator(); + } + + public void addField(boolean value) { + builder.append(value); + addSeparator(); + } + + public void addLine(Object object) { + + Method[] methods = object.getClass().getMethods(); + + for (Method method : methods) { + if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { + try { + if (method.getReturnType().equals(boolean.class)) { + addField((Boolean) method.invoke(object)); + } else if (method.getReturnType().equals(int.class)) { + addField((Integer) method.invoke(object)); + } else if (method.getReturnType().equals(long.class)) { + addField((Long) method.invoke(object)); + } else if (method.getReturnType().equals(double.class)) { + addField((Double) method.invoke(object)); + } else if (method.getReturnType().equals(String.class)) { + addField((String) method.invoke(object)); + } else if (method.getReturnType().equals(Date.class)) { + Date value = (Date) method.invoke(object); + addField(DATE_FORMAT.print(new DateTime(value))); + } else if (method.getReturnType().equals(Map.class)) { + Map value = (Map) method.invoke(object); + if (value != null) { + addField(MiscFormatter.toJson(value).toString()); + } + } + } catch (IllegalAccessException | InvocationTargetException error) { + Log.warning(error); + } + } + } + addLineEnding(); + } + + public void addHeaderLine(Object object) { + Method[] methods = object.getClass().getMethods(); + + for (Method method : methods) { + if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { + String name = Introspector.decapitalize(method.getName().substring(3)); + if (!name.equals("class")) { + addField(name); + } + } + } + addLineEnding(); + } + + public void addArray(Collection array) { + for (Object object : array) { + switch (object.getClass().getSimpleName().toLowerCase()) { + case "string": + addLine(object.toString()); + break; + case "long": + addLine((long) object); + break; + case "double": + addLine((double) object); + break; + case "boolean": + addLine((boolean) object); + break; + default: + addLine(object); + break; + } + } + } + + public byte[] get() { + return String.valueOf(builder).getBytes(); + } +} diff --git a/src/org/traccar/web/WebServer.java b/src/org/traccar/web/WebServer.java index 4ef31b1df..e022a9285 100644 --- a/src/org/traccar/web/WebServer.java +++ b/src/org/traccar/web/WebServer.java @@ -44,6 +44,7 @@ import org.traccar.api.resource.GroupResource; import org.traccar.api.resource.NotificationResource; import org.traccar.api.resource.DeviceResource; import org.traccar.api.resource.PositionResource; +import org.traccar.api.resource.ReportResource; import org.traccar.api.resource.CommandTypeResource; import org.traccar.api.resource.DeviceGeofenceResource; import org.traccar.api.resource.EventResource; @@ -160,7 +161,7 @@ public class WebServer { GroupResource.class, DeviceResource.class, PositionResource.class, CommandTypeResource.class, EventResource.class, GeofenceResource.class, DeviceGeofenceResource.class, GeofencePermissionResource.class, GroupGeofenceResource.class, - NotificationResource.class); + NotificationResource.class, ReportResource.class); servletHandler.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/*"); handlers.addHandler(servletHandler); -- cgit v1.2.3