From a5f47492857a175548beff07cfb565129f687ae2 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Tue, 28 Apr 2015 22:41:07 +1200 Subject: Implement API to create devices --- src/org/traccar/database/Convertable.java | 31 ++++++++ src/org/traccar/database/DataManager.java | 35 ++++++++- src/org/traccar/database/JsonConvertable.java | 30 -------- src/org/traccar/database/ObjectConverter.java | 97 +++++++++++++++++++++++- src/org/traccar/database/ResultSetConverter.java | 6 +- src/org/traccar/http/DeviceServlet.java | 29 +++++++ src/org/traccar/http/MainServlet.java | 2 +- src/org/traccar/model/Data.java | 19 +++-- src/org/traccar/model/Device.java | 53 ++++++++----- src/org/traccar/model/Position.java | 23 +++--- src/org/traccar/model/User.java | 11 ++- web/DeviceView.js | 25 ++++-- 12 files changed, 278 insertions(+), 83 deletions(-) create mode 100644 src/org/traccar/database/Convertable.java delete mode 100644 src/org/traccar/database/JsonConvertable.java diff --git a/src/org/traccar/database/Convertable.java b/src/org/traccar/database/Convertable.java new file mode 100644 index 000000000..4653a815a --- /dev/null +++ b/src/org/traccar/database/Convertable.java @@ -0,0 +1,31 @@ +/* + * 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.sql.ResultSet; +import javax.json.JsonObject; + +public interface Convertable { + + public JsonObject toJson(); + + public void fromJson(JsonObject json) throws Exception; + + //public void toRecord(); + + public void fromRecord(ResultSet record); + +} diff --git a/src/org/traccar/database/DataManager.java b/src/org/traccar/database/DataManager.java index f60fd4cb3..417fbb6b4 100644 --- a/src/org/traccar/database/DataManager.java +++ b/src/org/traccar/database/DataManager.java @@ -266,8 +266,8 @@ public class DataManager { "device_id INT NOT NULL," + "read BOOLEAN DEFAULT true NOT NULL," + "write BOOLEAN DEFAULT true NOT NULL," + - "FOREIGN KEY (user_id) REFERENCES user(id)," + - "FOREIGN KEY (device_id) REFERENCES device(id));" + + "FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE CASCADE," + + "FOREIGN KEY (device_id) REFERENCES device(id) ON DELETE CASCADE);" + "CREATE INDEX user_device_user_id ON user_device(user_id);" + @@ -391,7 +391,6 @@ public class DataManager { } public JsonArray getDevices(long userId) throws SQLException { - Connection connection = dataSource.getConnection(); try { PreparedStatement statement = connection.prepareStatement( @@ -400,7 +399,16 @@ public class DataManager { try { statement.setLong(1, userId); - return ResultSetConverter.convert(statement.executeQuery()); + ResultSet result = statement.executeQuery(); + + List list = new LinkedList(); + while (result.next()) { + Device device = new Device(); + device.fromRecord(result); + list.add(device); + } + + return ObjectConverter.arrayToJson(list); } finally { statement.close(); } @@ -471,5 +479,24 @@ public class DataManager { connection.close(); } } + + public void linkDevice(long userId, long deviceId) throws SQLException { + + Connection connection = dataSource.getConnection(); + try { + PreparedStatement statement = connection.prepareStatement( + "INSERT INTO user_device (user_id, device_id) VALUES (?, ?);"); + try { + statement.setLong(1, userId); + statement.setLong(2, deviceId); + + statement.execute(); + } finally { + statement.close(); + } + } finally { + connection.close(); + } + } } diff --git a/src/org/traccar/database/JsonConvertable.java b/src/org/traccar/database/JsonConvertable.java deleted file mode 100644 index 37af9a617..000000000 --- a/src/org/traccar/database/JsonConvertable.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.text.DateFormat; -import java.text.SimpleDateFormat; -import javax.json.JsonObject; - -public interface JsonConvertable { - - public static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ"); - - public JsonObject toJson(); - - public void fromJson(JsonObject json) throws Exception; - -} diff --git a/src/org/traccar/database/ObjectConverter.java b/src/org/traccar/database/ObjectConverter.java index 4ab83faec..8d6e73123 100644 --- a/src/org/traccar/database/ObjectConverter.java +++ b/src/org/traccar/database/ObjectConverter.java @@ -15,22 +15,113 @@ */ package org.traccar.database; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Collection; +import java.util.Date; import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonArrayBuilder; +import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; +import org.traccar.helper.Log; public class ObjectConverter { - - public static JsonArray convert(Collection collection) { + + public static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ"); + + public static JsonArray arrayToJson(Collection collection) { JsonArrayBuilder array = Json.createArrayBuilder(); - for (JsonConvertable object : collection) { + for (Convertable object : collection) { array.add(object.toJson()); } return array.build(); } + private static String getColumnName(String key) { + return key.replaceAll("([A-Z])", "_$1").toLowerCase(); + } + + private static boolean hasColumn(ResultSet resultSet, String columnName) throws SQLException { + ResultSetMetaData metaData = resultSet.getMetaData(); + for (int i = 1; i <= metaData.getColumnCount(); i++) { + if (columnName.equalsIgnoreCase(metaData.getColumnName(i))) { + return true; + } + } + return false; + } + + public static String getString(JsonObject json, String key) { + if (json.containsKey(key)) { + return json.getString(key); + } + return null; + } + + public static String getString(ResultSet record, String key) throws SQLException { + String column = getColumnName(key); + if (hasColumn(record, column)) { + return record.getString(column); + } + return null; + } + + public static void putString(JsonObjectBuilder json, String key, String value) { + if (value != null) { + json.add(key, value); + } + } + + public static long getLong(JsonObject json, String key) { + if (json.containsKey(key)) { + return json.getJsonNumber(key).longValue(); + } + return 0; + } + + public static long getLong(ResultSet record, String key) throws SQLException { + String column = getColumnName(key); + if (hasColumn(record, column)) { + return record.getLong(column); + } + return 0; + } + + public static void putLong(JsonObjectBuilder json, String key, long value) { + json.add(key, value); + } + + public static Date getDate(JsonObject json, String key) { + if (json.containsKey(key)) { + try { + return dateFormat.parse(json.getString(key)); + } catch (ParseException error) { + Log.warning(error); + } + } + return null; + } + + public static Date getDate(ResultSet record, String key) throws SQLException { + String column = getColumnName(key); + if (hasColumn(record, column)) { + return record.getDate(column); + } + return null; + } + + public static void putDate(JsonObjectBuilder json, String key, Date value) { + if (value != null) { + json.add(key, dateFormat.format(value)); + } + } + } diff --git a/src/org/traccar/database/ResultSetConverter.java b/src/org/traccar/database/ResultSetConverter.java index 92cb8fa4e..2bac01393 100644 --- a/src/org/traccar/database/ResultSetConverter.java +++ b/src/org/traccar/database/ResultSetConverter.java @@ -18,8 +18,6 @@ package org.traccar.database; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; -import java.text.DateFormat; -import java.text.SimpleDateFormat; import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonArrayBuilder; @@ -64,10 +62,10 @@ public class ResultSetConverter { obj.add(columnName, rs.getString(columnName)); break; case java.sql.Types.DATE: - obj.add(columnName, JsonConvertable.dateFormat.format(rs.getDate(columnName))); + obj.add(columnName, ObjectConverter.dateFormat.format(rs.getDate(columnName))); break; case java.sql.Types.TIMESTAMP: - obj.add(columnName, JsonConvertable.dateFormat.format(rs.getTimestamp(columnName))); + obj.add(columnName, ObjectConverter.dateFormat.format(rs.getTimestamp(columnName))); break; default: break; diff --git a/src/org/traccar/http/DeviceServlet.java b/src/org/traccar/http/DeviceServlet.java index 260083e0e..5cda5708e 100644 --- a/src/org/traccar/http/DeviceServlet.java +++ b/src/org/traccar/http/DeviceServlet.java @@ -17,13 +17,18 @@ package org.traccar.http; import java.io.IOException; import java.sql.SQLException; +import java.text.ParseException; import javax.json.Json; +import javax.json.JsonObject; import javax.json.JsonObjectBuilder; +import javax.json.JsonReader; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.traccar.Context; +import org.traccar.helper.Log; +import org.traccar.model.Device; public class DeviceServlet extends HttpServlet { @@ -65,6 +70,30 @@ public class DeviceServlet extends HttpServlet { } private void add(HttpServletRequest req, HttpServletResponse resp) throws IOException { + + long userId = (Long) req.getSession().getAttribute(MainServlet.USER_ID); + + JsonReader jsonReader = Json.createReader(req.getReader()); + JsonObject jsonObject = jsonReader.readObject(); + Device device = new Device(); + try { + device.fromJson(jsonObject); + } catch (ParseException error) { + Log.warning(error); + } + + JsonObjectBuilder result = Json.createObjectBuilder(); + + try { + result.add("success", true); + Context.getDataManager().addDevice(device); + Context.getDataManager().linkDevice(userId, device.getId()); + } catch(SQLException error) { + result.add("success", false); + result.add("error", error.getMessage()); + } + + resp.getWriter().println(result.build().toString()); } private void update(HttpServletRequest req, HttpServletResponse resp) throws IOException { diff --git a/src/org/traccar/http/MainServlet.java b/src/org/traccar/http/MainServlet.java index 62345489e..10920accb 100644 --- a/src/org/traccar/http/MainServlet.java +++ b/src/org/traccar/http/MainServlet.java @@ -173,7 +173,7 @@ public class MainServlet extends HttpServlet { JsonObjectBuilder result = Json.createObjectBuilder(); result.add("success", true); - result.add("data", ObjectConverter.convert(positions.values())); + result.add("data", ObjectConverter.arrayToJson(positions.values())); positions.clear(); try { diff --git a/src/org/traccar/model/Data.java b/src/org/traccar/model/Data.java index 1cef813a3..e329e6c1e 100644 --- a/src/org/traccar/model/Data.java +++ b/src/org/traccar/model/Data.java @@ -15,15 +15,16 @@ */ package org.traccar.model; +import java.sql.ResultSet; import java.text.ParseException; import java.util.Date; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonObjectBuilder; -import org.traccar.database.JsonConvertable; -import static org.traccar.database.JsonConvertable.dateFormat; +import org.traccar.database.Convertable; +import org.traccar.database.ObjectConverter; -public class Data implements JsonConvertable { +public class Data implements Convertable { private long id; public long getId() { return id; } @@ -50,8 +51,8 @@ public class Data implements JsonConvertable { JsonObjectBuilder json = Json.createObjectBuilder(); json.add("id", id); json.add("deviceId", deviceId); - json.add("serverTime", dateFormat.format(serverTime)); - json.add("deviceTime", dateFormat.format(deviceTime)); + json.add("serverTime", ObjectConverter.dateFormat.format(serverTime)); + json.add("deviceTime", ObjectConverter.dateFormat.format(deviceTime)); //json.add("extendedInfo", extendedInfo); return json.build(); } @@ -60,9 +61,13 @@ public class Data implements JsonConvertable { public void fromJson(JsonObject json) throws ParseException { id = json.getJsonNumber("id").longValue(); deviceId = json.getJsonNumber("deviceId").longValue(); - serverTime = dateFormat.parse(json.getString("serverTime")); - deviceTime = dateFormat.parse(json.getString("deviceTime")); + serverTime = ObjectConverter.dateFormat.parse(json.getString("serverTime")); + deviceTime = ObjectConverter.dateFormat.parse(json.getString("deviceTime")); //extendedInfo = json.getString("extendedInfo"); } + @Override + public void fromRecord(ResultSet record) { + } + } diff --git a/src/org/traccar/model/Device.java b/src/org/traccar/model/Device.java index 4e2f57690..067d80f36 100644 --- a/src/org/traccar/model/Device.java +++ b/src/org/traccar/model/Device.java @@ -15,21 +15,25 @@ */ package org.traccar.model; +import java.sql.ResultSet; +import java.sql.SQLException; import java.text.ParseException; import java.util.Date; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonObjectBuilder; -import org.traccar.database.JsonConvertable; +import org.traccar.database.Convertable; +import org.traccar.database.ObjectConverter; +import org.traccar.helper.Log; -public class Device implements JsonConvertable { +public class Device implements Convertable { private long id; public long getId() { return id; } public void setId(long id) { this.id = id; } private String name; - public String getName() { return uniqueId; } + public String getName() { return name; } public void setName(String name) { this.name = name; } private String uniqueId; @@ -47,25 +51,40 @@ public class Device implements JsonConvertable { @Override public JsonObject toJson() { JsonObjectBuilder json = Json.createObjectBuilder(); - json.add("id", id); - json.add("name", name); - json.add("uniqueId", uniqueId); - json.add("status", status); - json.add("lastUpdate", dateFormat.format(lastUpdate)); - json.add("positionId", positionId); - json.add("dataId", dataId); + ObjectConverter.putLong(json, "id", id); + ObjectConverter.putString(json, "name", name); + ObjectConverter.putString(json, "uniqueId", uniqueId); + ObjectConverter.putString(json, "status", status); + ObjectConverter.putDate(json, "lastUpdate", lastUpdate); + ObjectConverter.putLong(json, "positionId", positionId); + ObjectConverter.putLong(json, "dataId", dataId); return json.build(); } @Override public void fromJson(JsonObject json) throws ParseException { - id = json.getJsonNumber("id").longValue(); - name = json.getString("name"); - uniqueId = json.getString("uniqueId"); - status = json.getString("status"); - lastUpdate = dateFormat.parse(json.getString("lastUpdate")); - positionId = json.getJsonNumber("positionId").longValue(); - dataId = json.getJsonNumber("dataId").longValue(); + id = ObjectConverter.getLong(json, "id"); + name = ObjectConverter.getString(json, "name"); + uniqueId = ObjectConverter.getString(json, "uniqueId"); + status = ObjectConverter.getString(json, "status"); + lastUpdate = ObjectConverter.getDate(json, "lastUpdate"); + positionId = ObjectConverter.getLong(json, "positionId"); + dataId = ObjectConverter.getLong(json, "dataId"); + } + + @Override + public void fromRecord(ResultSet record) { + try { + id = ObjectConverter.getLong(record, "id"); + name = ObjectConverter.getString(record, "name"); + uniqueId = ObjectConverter.getString(record, "uniqueId"); + status = ObjectConverter.getString(record, "status"); + lastUpdate = ObjectConverter.getDate(record, "lastUpdate"); + positionId = ObjectConverter.getLong(record, "positionId"); + dataId = ObjectConverter.getLong(record, "dataId"); + } catch (SQLException error) { + Log.warning(error); + } } } diff --git a/src/org/traccar/model/Position.java b/src/org/traccar/model/Position.java index 7f042c409..92d5bbe5e 100644 --- a/src/org/traccar/model/Position.java +++ b/src/org/traccar/model/Position.java @@ -15,15 +15,16 @@ */ package org.traccar.model; +import java.sql.ResultSet; import java.text.ParseException; import java.util.Date; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonObjectBuilder; -import org.traccar.database.JsonConvertable; -import static org.traccar.database.JsonConvertable.dateFormat; +import org.traccar.database.Convertable; +import org.traccar.database.ObjectConverter; -public class Position implements JsonConvertable { +public class Position implements Convertable { private long id; public long getId() { return id; } @@ -87,9 +88,9 @@ public class Position implements JsonConvertable { JsonObjectBuilder json = Json.createObjectBuilder(); json.add("id", id); json.add("deviceId", deviceId); - json.add("serverTime", dateFormat.format(serverTime)); - json.add("deviceTime", dateFormat.format(deviceTime)); - json.add("fixTime", dateFormat.format(fixTime)); + json.add("serverTime", ObjectConverter.dateFormat.format(serverTime)); + json.add("deviceTime", ObjectConverter.dateFormat.format(deviceTime)); + json.add("fixTime", ObjectConverter.dateFormat.format(fixTime)); json.add("valid", valid); json.add("latitude", latitude); json.add("longitude", longitude); @@ -105,9 +106,9 @@ public class Position implements JsonConvertable { public void fromJson(JsonObject json) throws ParseException { id = json.getJsonNumber("id").longValue(); deviceId = json.getJsonNumber("deviceId").longValue(); - serverTime = dateFormat.parse(json.getString("serverTime")); - deviceTime = dateFormat.parse(json.getString("deviceTime")); - fixTime = dateFormat.parse(json.getString("fixTime")); + serverTime = ObjectConverter.dateFormat.parse(json.getString("serverTime")); + deviceTime = ObjectConverter.dateFormat.parse(json.getString("deviceTime")); + fixTime = ObjectConverter.dateFormat.parse(json.getString("fixTime")); valid = json.getBoolean("valid"); latitude = json.getJsonNumber("latitude").doubleValue(); longitude = json.getJsonNumber("longitude").doubleValue(); @@ -118,4 +119,8 @@ public class Position implements JsonConvertable { //extendedInfo = json.getString("extendedInfo"); } + @Override + public void fromRecord(ResultSet record) { + } + } diff --git a/src/org/traccar/model/User.java b/src/org/traccar/model/User.java index a3eaf5a10..77740e987 100644 --- a/src/org/traccar/model/User.java +++ b/src/org/traccar/model/User.java @@ -15,12 +15,13 @@ */ package org.traccar.model; +import java.sql.ResultSet; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonObjectBuilder; -import org.traccar.database.JsonConvertable; +import org.traccar.database.Convertable; -public class User implements JsonConvertable { +public class User implements Convertable { private long id; @@ -79,5 +80,9 @@ public class User implements JsonConvertable { longitude = json.getJsonNumber("longitude").doubleValue(); zoom = json.getJsonNumber("zoom").intValue(); } - + + @Override + public void fromRecord(ResultSet record) { + } + } diff --git a/web/DeviceView.js b/web/DeviceView.js index 4414b67ea..06cec7779 100644 --- a/web/DeviceView.js +++ b/web/DeviceView.js @@ -21,7 +21,22 @@ Ext.define('DeviceView', { title: Strings.device_title, tbar: [{ - text:'Add' + text:'Add', + handler: function() { + + var device = { + name: "AjaxTest", + uniqueId: "UniqueId" + }; + + Ext.Ajax.request({ + url: '/api/device/add', + jsonData: Ext.encode(device), + success: function() { + alert("success"); + } + }); + } }, { text:'Edit' }, { @@ -56,14 +71,14 @@ Ext.define('DeviceView', { fields:[ 'id', 'name', - 'unique_id', - 'position_id', - 'data_id' + 'uniqueId', + 'positionId', + 'dataId' ] }, columns: [ { text: Strings.device_name, dataIndex: 'name', flex: 1 }, - { text: Strings.device_identifier, dataIndex: 'unique_id', flex: 1 } + { text: Strings.device_identifier, dataIndex: 'uniqueId', flex: 1 } ] }); -- cgit v1.2.3