From 3478efd74c34754d9cf2750f265e6baba46b3526 Mon Sep 17 00:00:00 2001 From: JaroslawLegierski Date: Tue, 12 Nov 2024 14:08:43 +0100 Subject: [PATCH] GH-1504: Make SenMLPack,SenMLRecord,JsonArrayEntry,JsonRootObject final See : https://github.com/eclipse-leshan/leshan/issues/1504#issuecomment-2368320188 --- .../leshan/core/json/JsonArrayEntry.java | 46 ++++------- .../leshan/core/json/JsonRootObject.java | 24 ++---- .../json/jackson/JsonArrayEntrySerDes.java | 22 +++-- .../json/jackson/JsonRootObjectSerDes.java | 14 ++-- .../node/codec/json/LwM2mNodeJsonEncoder.java | 39 +++++---- .../codec/senml/LwM2mNodeSenMLEncoder.java | 53 ++++++++---- .../codec/senml/LwM2mPathSenMLEncoder.java | 4 +- .../org/eclipse/leshan/senml/SenMLPack.java | 16 +--- .../org/eclipse/leshan/senml/SenMLRecord.java | 67 +++++---------- .../cbor/upokecenter/SenMLCborPackSerDes.java | 82 ++++++++++--------- .../json/jackson/SenMLJsonRecordSerDes.java | 32 +++++--- .../leshan/core/json/JsonArrayEntryTest.java | 3 +- .../leshan/core/json/JsonRootObjectTest.java | 3 +- .../leshan/core/json/JsonSerializerTest.java | 63 ++++---------- .../core/senml/cbor/AbstractSenMLTest.java | 16 ++-- .../eclipse/leshan/senml/SenMLPackTest.java | 3 +- .../eclipse/leshan/senml/SenMLRecordTest.java | 3 +- 17 files changed, 219 insertions(+), 271 deletions(-) diff --git a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/JsonArrayEntry.java b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/JsonArrayEntry.java index f8b71e9858..17415698d2 100644 --- a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/JsonArrayEntry.java +++ b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/JsonArrayEntry.java @@ -25,17 +25,27 @@ public class JsonArrayEntry { - private String name; + private final String name; - private Number floatValue; + private final Number floatValue; - private Boolean booleanValue; + private final Boolean booleanValue; - private String objectLinkValue; + private final String objectLinkValue; - private String stringValue; + private final String stringValue; - private BigDecimal time; + private final BigDecimal time; + + public JsonArrayEntry(String name, Number floatValue, Boolean booleanValue, String objectLinkValue, + String stringValue, BigDecimal time) { + this.name = name; + this.floatValue = floatValue; + this.booleanValue = booleanValue; + this.objectLinkValue = objectLinkValue; + this.stringValue = stringValue; + this.time = time; + } public ResourceModel.Type getType() { if (booleanValue != null) { @@ -57,50 +67,26 @@ public String getName() { return name; } - public void setName(String name) { - this.name = name; - } - public BigDecimal getTime() { return time; } - public void setTime(BigDecimal time) { - this.time = time; - } - public Number getFloatValue() { return floatValue; } - public void setFloatValue(Number floatValue) { - this.floatValue = floatValue; - } - public Boolean getBooleanValue() { return booleanValue; } - public void setBooleanValue(Boolean booleanValue) { - this.booleanValue = booleanValue; - } - public String getObjectLinkValue() { return objectLinkValue; } - public void setObjectLinkValue(String objectLinkValue) { - this.objectLinkValue = objectLinkValue; - } - public String getStringValue() { return stringValue; } - public void setStringValue(String stringValue) { - this.stringValue = stringValue; - } - public Object getResourceValue() { if (booleanValue != null) { diff --git a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/JsonRootObject.java b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/JsonRootObject.java index 6a5eeed7d9..cdb0a6a45c 100644 --- a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/JsonRootObject.java +++ b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/JsonRootObject.java @@ -18,6 +18,7 @@ package org.eclipse.leshan.core.json; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -27,35 +28,26 @@ */ public class JsonRootObject { - private String baseName = null; + private final String baseName; - private List jsonArray; + private final List jsonArray; - private BigDecimal baseTime; + private final BigDecimal baseTime; - public JsonRootObject() { + public JsonRootObject(String baseName, List jsonArray, BigDecimal baseTime) { + this.baseName = baseName; + this.jsonArray = Collections.unmodifiableList(new ArrayList<>(jsonArray)); + this.baseTime = baseTime; } public String getBaseName() { return baseName; } - public void setBaseName(String baseName) { - this.baseName = baseName; - } - public BigDecimal getBaseTime() { return baseTime; } - public void setBaseTime(BigDecimal baseTime) { - this.baseTime = baseTime; - } - - public void setResourceList(List jsonArray) { - this.jsonArray = jsonArray; - } - public List getResourceList() { if (jsonArray == null) return Collections.emptyList(); diff --git a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/jackson/JsonArrayEntrySerDes.java b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/jackson/JsonArrayEntrySerDes.java index 385ff45995..202dd8c951 100644 --- a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/jackson/JsonArrayEntrySerDes.java +++ b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/jackson/JsonArrayEntrySerDes.java @@ -88,30 +88,38 @@ public JsonArrayEntry deserialize(JsonNode o) throws JsonException { if (o == null) return null; - JsonArrayEntry jae = new JsonArrayEntry(); + String name = null; + BigDecimal time = null; + Number floatValue = null; + Boolean booleanValue = null; + String stringValue = null; + String objectLinkValue = null; + JsonNode n = o.get("n"); if (n != null && n.isTextual()) - jae.setName(n.asText()); + name = n.asText(); JsonNode t = o.get("t"); if (t != null && t.isNumber()) - jae.setTime(new BigDecimal(t.asText())); + time = new BigDecimal(t.asText()); JsonNode v = o.get("v"); if (v != null && v.isNumber()) - jae.setFloatValue(v.numberValue()); + floatValue = v.numberValue(); JsonNode bv = o.get("bv"); if (bv != null && bv.isBoolean()) - jae.setBooleanValue(bv.asBoolean()); + booleanValue = bv.asBoolean(); JsonNode sv = o.get("sv"); if (sv != null && sv.isTextual()) - jae.setStringValue(sv.asText()); + stringValue = sv.asText(); JsonNode ov = o.get("ov"); if (ov != null && ov.isTextual()) - jae.setObjectLinkValue(ov.asText()); + objectLinkValue = ov.asText(); + + JsonArrayEntry jae = new JsonArrayEntry(name, floatValue, booleanValue, objectLinkValue, stringValue, time); if (jae.getType() == null) { throw new JsonException("Missing value(v,bv,ov,sv) field for entry %s", o.toString()); diff --git a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/jackson/JsonRootObjectSerDes.java b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/jackson/JsonRootObjectSerDes.java index 640088dc0a..9ecec69554 100644 --- a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/jackson/JsonRootObjectSerDes.java +++ b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/json/jackson/JsonRootObjectSerDes.java @@ -16,7 +16,9 @@ package org.eclipse.leshan.core.json.jackson; import java.math.BigDecimal; +import java.util.List; +import org.eclipse.leshan.core.json.JsonArrayEntry; import org.eclipse.leshan.core.json.JsonRootObject; import org.eclipse.leshan.core.util.json.JacksonJsonSerDes; import org.eclipse.leshan.core.util.json.JsonException; @@ -52,22 +54,24 @@ public JsonRootObject deserialize(JsonNode jsonNode) throws JsonException { if (jsonNode == null) return null; - JsonRootObject jro = new JsonRootObject(); + List ResourceList; + String baseName = null; + BigDecimal baseTime = null; JsonNode e = jsonNode.get("e"); if (e != null && e.isArray()) - jro.setResourceList(serDes.deserialize(e.elements())); + ResourceList = serDes.deserialize(e.elements()); else throw new JsonException("'e' field is missing for %s", jsonNode.toString()); JsonNode bn = jsonNode.get("bn"); if (bn != null && bn.isTextual()) - jro.setBaseName(bn.asText()); + baseName = bn.asText(); JsonNode bt = jsonNode.get("bt"); if (bt != null && bt.isNumber()) - jro.setBaseTime(new BigDecimal(bt.asText())); + baseTime = new BigDecimal(bt.asText()); - return jro; + return new JsonRootObject(baseName, ResourceList, baseTime); } } diff --git a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/node/codec/json/LwM2mNodeJsonEncoder.java b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/node/codec/json/LwM2mNodeJsonEncoder.java index 45f397db95..d8ddac2265 100644 --- a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/node/codec/json/LwM2mNodeJsonEncoder.java +++ b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/node/codec/json/LwM2mNodeJsonEncoder.java @@ -87,9 +87,7 @@ public byte[] encode(LwM2mNode node, String rootPath, LwM2mPath path, LwM2mModel internalEncoder.requestPath = path; internalEncoder.converter = converter; node.accept(internalEncoder); - JsonRootObject jsonObject = new JsonRootObject(); - jsonObject.setResourceList(internalEncoder.resourceList); - jsonObject.setBaseName(internalEncoder.baseName); + JsonRootObject jsonObject = new JsonRootObject(internalEncoder.baseName, internalEncoder.resourceList, null); try { return encoder.toJsonLwM2m(jsonObject).getBytes(); } catch (LwM2mJsonException e) { @@ -126,9 +124,7 @@ public byte[] encodeTimestampedData(List timestampedNodes, baseName = internalEncoder.baseName; } } - JsonRootObject jsonObject = new JsonRootObject(); - jsonObject.setResourceList(entries); - jsonObject.setBaseName(internalEncoder.baseName); + JsonRootObject jsonObject = new JsonRootObject(internalEncoder.baseName, entries, null); try { return encoder.toJsonLwM2m(jsonObject).getBytes(); } catch (LwM2mJsonException e) { @@ -263,19 +259,18 @@ private ArrayList lwM2mResourceToJsonArrayEntry(String resourceP private JsonArrayEntry createJsonArrayEntry(String name, BigDecimal timestampInSeconds, Type type, Type expectedType, Object value) { // Create resource element - JsonArrayEntry jsonResourceElt = new JsonArrayEntry(); - jsonResourceElt.setName(name); - jsonResourceElt.setTime(timestampInSeconds); + JsonArrayEntry jsonResourceElt = new JsonArrayEntry(name, null, null, null, null, timestampInSeconds); // Convert value using expected type LwM2mPath lwM2mResourcePath = name != null ? new LwM2mPath(name) : null; Object convertedValue = converter.convertValue(value, type, expectedType, lwM2mResourcePath); - this.setResourceValue(convertedValue, expectedType, jsonResourceElt, lwM2mResourcePath); + jsonResourceElt = this.setResourceValue(convertedValue, expectedType, jsonResourceElt, lwM2mResourcePath); return jsonResourceElt; } - private void setResourceValue(Object value, Type type, JsonArrayEntry jsonResource, LwM2mPath resourcePath) { + private JsonArrayEntry setResourceValue(Object value, Type type, JsonArrayEntry jsonResource, + LwM2mPath resourcePath) { LOG.trace("Encoding value {} in JSON", value); if (type == null || type == Type.NONE) { @@ -283,41 +278,49 @@ private void setResourceValue(Object value, Type type, JsonArrayEntry jsonResour "Unable to encode value for resource {} without type(probably a executable one)", resourcePath); } + String name = jsonResource.getName(); + BigDecimal time = jsonResource.getTime(); + Number floatValue = jsonResource.getFloatValue(); + Boolean booleanValue = jsonResource.getBooleanValue(); + String stringValue = jsonResource.getStringValue(); + String objectLinkValue = jsonResource.getObjectLinkValue(); + // Following table 20 in the Specs switch (type) { case STRING: - jsonResource.setStringValue((String) value); + stringValue = (String) value; break; case INTEGER: case UNSIGNED_INTEGER: case FLOAT: - jsonResource.setFloatValue((Number) value); + floatValue = (Number) value; break; case BOOLEAN: - jsonResource.setBooleanValue((Boolean) value); + booleanValue = (Boolean) value; break; case TIME: // Specs device object example page 44, rec 13 is Time // represented as float? - jsonResource.setFloatValue((((Date) value).getTime() / 1000L)); + floatValue = (((Date) value).getTime() / 1000L); break; case OPAQUE: - jsonResource.setStringValue(base64Encoder.encode((byte[]) value)); + stringValue = base64Encoder.encode((byte[]) value); break; case OBJLNK: try { - jsonResource.setStringValue(((ObjectLink) value).encodeToString()); + stringValue = ((ObjectLink) value).encodeToString(); } catch (IllegalArgumentException e) { throw new CodecException(e, "Invalid value [%s] for objectLink resource [%s] ", value, resourcePath); } break; case CORELINK: - jsonResource.setStringValue(linkSerializer.serializeCoreLinkFormat((Link[]) value)); + stringValue = linkSerializer.serializeCoreLinkFormat((Link[]) value); break; default: throw new CodecException("Invalid value type %s for %s", type, resourcePath); } + return new JsonArrayEntry(name, floatValue, booleanValue, objectLinkValue, stringValue, time); } } } diff --git a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/node/codec/senml/LwM2mNodeSenMLEncoder.java b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/node/codec/senml/LwM2mNodeSenMLEncoder.java index 8d5862e850..4b6b4a83f1 100644 --- a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/node/codec/senml/LwM2mNodeSenMLEncoder.java +++ b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/node/codec/senml/LwM2mNodeSenMLEncoder.java @@ -82,8 +82,7 @@ public byte[] encode(LwM2mNode node, String rootPath, LwM2mPath path, LwM2mModel internalEncoder.converter = converter; node.accept(internalEncoder); - SenMLPack pack = new SenMLPack(); - pack.setRecords(internalEncoder.records); + SenMLPack pack = new SenMLPack(internalEncoder.records); try { return encoder.toSenML(pack); @@ -157,7 +156,12 @@ public byte[] encodeTimestampedData(List timestampedNodes, internalEncoder.records = new ArrayList<>(); timestampedLwM2mNode.getNode().accept(internalEncoder); BigDecimal timestampInSeconds = TimestampUtil.fromInstant(timestampedLwM2mNode.getTimestamp()); - internalEncoder.records.get(0).setBaseTime(timestampInSeconds); + + SenMLRecord record = internalEncoder.records.get(0); + SenMLRecord timestampedrecord = new SenMLRecord(record.getBaseName(), timestampInSeconds, record.getName(), + record.getTime(), record.getNumberValue(), record.getBooleanValue(), record.getObjectLinkValue(), + record.getStringValue(), record.getOpaqueValue()); + internalEncoder.records.set(0, timestampedrecord); pack.addRecords(internalEncoder.records); } @@ -191,7 +195,13 @@ public byte[] encodeTimestampedNodes(String rootPath, TimestampedLwM2mNodes time List records = internalEncoder.records; if (!records.isEmpty()) { - records.get(0).setBaseTime(TimestampUtil.fromInstant(timestamp)); + SenMLRecord record = internalEncoder.records.get(0); + SenMLRecord timestampedrecord = new SenMLRecord(record.getBaseName(), + TimestampUtil.fromInstant(timestamp), record.getName(), record.getTime(), + record.getNumberValue(), record.getBooleanValue(), record.getObjectLinkValue(), + record.getStringValue(), record.getOpaqueValue()); + internalEncoder.records.set(0, timestampedrecord); + pack.addRecords(records); } } @@ -324,8 +334,9 @@ private void lwM2mResourceToSenMLRecord(String recordName, LwM2mResource resourc } private void addSenMLRecord(String recordName, Type valueType, Type expectedType, Object value) { - // Create SenML record - SenMLRecord record = new SenMLRecord(); + // Create SenML record attributes + String recordbasename = null; + String recordname = null; // Compute baseName and name for SenML record String bn = requestPath.toString(); @@ -338,48 +349,54 @@ private void addSenMLRecord(String recordName, Type valueType, Type expectedType // Set basename only for first record if (records.isEmpty()) { - record.setBaseName(rootPath != null ? rootPath + bn : bn); + recordbasename = (rootPath != null ? rootPath + bn : bn); } - record.setName(n); + recordname = n; // Convert value using expected type LwM2mPath lwM2mResourcePath = new LwM2mPath(bn + n); Object convertedValue = converter.convertValue(value, valueType, expectedType, lwM2mResourcePath); - setResourceValue(convertedValue, expectedType, lwM2mResourcePath, record); + SenMLRecord record = setResourceValue(convertedValue, expectedType, lwM2mResourcePath, recordbasename, + recordname); // Add record to the List records.add(record); } - private void setResourceValue(Object value, Type type, LwM2mPath resourcePath, SenMLRecord record) { + private SenMLRecord setResourceValue(Object value, Type type, LwM2mPath resourcePath, String recordBaseName, + String recordName) { LOG.trace("Encoding resource value {} in SenML", value); if (type == null || type == Type.NONE) { throw new CodecException( "Unable to encode value for resource {} without type(probably a executable one)", resourcePath); } + String recordStringValue = null; + Number recordNumberValue = null; + Boolean recordBooleanValue = null; + byte[] recordopaqueValue = null; switch (type) { case STRING: - record.setStringValue((String) value); + recordStringValue = (String) value; break; case INTEGER: case UNSIGNED_INTEGER: case FLOAT: - record.setNumberValue((Number) value); + recordNumberValue = (Number) value; break; case BOOLEAN: - record.setBooleanValue((Boolean) value); + recordBooleanValue = (Boolean) value; break; case TIME: - record.setNumberValue((((Date) value).getTime() / 1000L)); + recordNumberValue = ((Date) value).getTime() / 1000L; break; case OPAQUE: - record.setOpaqueValue((byte[]) value); + recordopaqueValue = (byte[]) value; break; case OBJLNK: try { - record.setStringValue(((ObjectLink) value).encodeToString()); + recordStringValue = ((ObjectLink) value).encodeToString(); } catch (IllegalArgumentException e) { throw new CodecException(e, "Invalid value [%s] for objectLink resource [%s] ", value, resourcePath); @@ -387,11 +404,13 @@ private void setResourceValue(Object value, Type type, LwM2mPath resourcePath, S break; case CORELINK: - record.setStringValue(linkSerializer.serializeCoreLinkFormat((Link[]) value)); + recordStringValue = linkSerializer.serializeCoreLinkFormat((Link[]) value); break; default: throw new CodecException("Invalid value type %s for %s", type, resourcePath); } + return new SenMLRecord(recordBaseName, null, recordName, null, recordNumberValue, recordBooleanValue, null, + recordStringValue, recordopaqueValue); } } } diff --git a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/node/codec/senml/LwM2mPathSenMLEncoder.java b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/node/codec/senml/LwM2mPathSenMLEncoder.java index 2c72eb2555..3514c7d380 100644 --- a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/node/codec/senml/LwM2mPathSenMLEncoder.java +++ b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/core/node/codec/senml/LwM2mPathSenMLEncoder.java @@ -41,8 +41,8 @@ public byte[] encode(String rootPath, List paths) { // Create SenML Pack SenMLPack pack = new SenMLPack(); for (LwM2mPath path : paths) { - SenMLRecord record = new SenMLRecord(); - record.setName(rootPath != null ? rootPath + path.toString() : path.toString()); + String Name = (rootPath != null ? rootPath + path.toString() : path.toString()); + SenMLRecord record = new SenMLRecord(null, null, Name, null, null, null, null, null, null); pack.addRecord(record); } diff --git a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/SenMLPack.java b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/SenMLPack.java index 9b16fe303e..f576c7f56e 100644 --- a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/SenMLPack.java +++ b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/SenMLPack.java @@ -26,34 +26,24 @@ */ public class SenMLPack { - private List records; + private final List records; public SenMLPack() { + records = new ArrayList<>(); } public SenMLPack(List records) { - this.records = records; + this.records = Collections.unmodifiableList(new ArrayList<>(records)); } public void addRecord(SenMLRecord record) { - if (records == null) { - records = new ArrayList<>(); - } - records.add(record); } public void addRecords(List records) { - if (this.records == null) { - this.records = new ArrayList<>(); - } this.records.addAll(records); } - public void setRecords(List records) { - this.records = records; - } - public List getRecords() { if (records == null) return Collections.emptyList(); diff --git a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/SenMLRecord.java b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/SenMLRecord.java index 2b26353920..f1ee25b1d2 100644 --- a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/SenMLRecord.java +++ b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/SenMLRecord.java @@ -31,17 +31,30 @@ public enum Type { STRING, NUMBER, BOOLEAN, OPAQUE, OBJLNK } - private String baseName = null; - private BigDecimal baseTime; + private final String baseName; + private final BigDecimal baseTime; - private String name; - private BigDecimal time; + private final String name; + private final BigDecimal time; - private Number numberValue; - private Boolean booleanValue; - private String objectLinkValue; - private String stringValue; - private byte[] opaqueValue; + private final Number numberValue; + private final Boolean booleanValue; + private final String objectLinkValue; + private final String stringValue; + private final byte[] opaqueValue; + + public SenMLRecord(String baseName, BigDecimal baseTime, String name, BigDecimal time, Number numberValue, + Boolean booleanValue, String objectLinkValue, String stringValue, byte[] opaqueValue) { + this.baseName = baseName; + this.baseTime = baseTime; + this.name = name; + this.time = time; + this.numberValue = numberValue; + this.booleanValue = booleanValue; + this.objectLinkValue = objectLinkValue; + this.stringValue = stringValue; + this.opaqueValue = opaqueValue; + } public Type getType() { if (booleanValue != null) { @@ -62,10 +75,6 @@ public Type getType() { return null; } - public void setTime(BigDecimal time) { - this.time = time; - } - public BigDecimal getTime() { return time; } @@ -74,46 +83,22 @@ public String getName() { return name; } - public void setName(String name) { - this.name = name; - } - public Number getNumberValue() { return numberValue; } - public void setNumberValue(Number numberValue) { - this.numberValue = numberValue; - } - public Boolean getBooleanValue() { return booleanValue; } - public void setBooleanValue(Boolean booleanValue) { - this.booleanValue = booleanValue; - } - public String getObjectLinkValue() { return objectLinkValue; } - public void setObjectLinkValue(String objectLinkValue) { - this.objectLinkValue = objectLinkValue; - } - public String getStringValue() { return stringValue; } - public void setStringValue(String stringValue) { - this.stringValue = stringValue; - } - - public void setOpaqueValue(byte[] opaqueValue) { - this.opaqueValue = opaqueValue; - } - public byte[] getOpaqueValue() { return opaqueValue; } @@ -122,18 +107,10 @@ public String getBaseName() { return baseName; } - public void setBaseName(String baseName) { - this.baseName = baseName; - } - public BigDecimal getBaseTime() { return baseTime; } - public void setBaseTime(BigDecimal baseTime) { - this.baseTime = baseTime; - } - public Object getResourceValue() { if (booleanValue != null) { return booleanValue; diff --git a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/cbor/upokecenter/SenMLCborPackSerDes.java b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/cbor/upokecenter/SenMLCborPackSerDes.java index 7a6f426330..9595fdc518 100644 --- a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/cbor/upokecenter/SenMLCborPackSerDes.java +++ b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/cbor/upokecenter/SenMLCborPackSerDes.java @@ -68,17 +68,19 @@ public SenMLPack deserializeFromCbor(Collection objects) throws SenM } protected SenMLRecord deserializeRecord(CBORObject o) throws SenMLException { - SenMLRecord record = new SenMLRecord(); - - deserializeBaseName(o, record); - deserializeBaseTime(o, record); - deserializeName(o, record); - deserializeTime(o, record); - boolean hasValue = deserializeValue(o, record); - hasValue |= deserializeBooleanValue(o, record); - hasValue |= deserializeStringValue(o, record); - hasValue |= deserializeObjectLinkValue(o, record); - hasValue |= deserializeOpaqueValue(o, record); + + String recordBaseName = deserializeBaseName(o); + BigDecimal recordBaseTime = deserializeBaseTime(o); + String recordName = deserializeName(o); + BigDecimal recordTime = deserializeTime(o); + Number recordNumberValue = deserializeValue(o); + Boolean recordBooleanValue = deserializeBooleanValue(o); + String recordStringValue = deserializeStringValue(o); + String recordObjectLinkValue = deserializeObjectLinkValue(o); + byte[] recordOpaqueValue = deserializeOpaqueValue(o); + + boolean hasValue = (recordNumberValue != null || recordBooleanValue != null || recordStringValue != null + || recordObjectLinkValue != null || recordOpaqueValue != null); if (!allowNoValue && !hasValue) { throw new SenMLException( @@ -86,48 +88,52 @@ protected SenMLRecord deserializeRecord(CBORObject o) throws SenMLException { o); } - return record; + return new SenMLRecord(recordBaseName, recordBaseTime, recordName, recordTime, recordNumberValue, + recordBooleanValue, recordObjectLinkValue, recordStringValue, recordOpaqueValue); } - protected void deserializeBaseName(CBORObject o, SenMLRecord record) throws SenMLException { + protected String deserializeBaseName(CBORObject o) throws SenMLException { CBORObject bn = o.get(-2); if (bn != null) { - record.setBaseName(deserializeString(bn, "bn")); + return deserializeString(bn, "bn"); } + return null; } - protected void deserializeBaseTime(CBORObject o, SenMLRecord record) throws SenMLException { + protected BigDecimal deserializeBaseTime(CBORObject o) throws SenMLException { CBORObject bt = o.get(-3); if (bt != null) { - record.setBaseTime(deserializeTime(bt, "bt")); + return deserializeTime(bt, "bt"); } + return null; } - protected void deserializeName(CBORObject o, SenMLRecord record) throws SenMLException { + protected String deserializeName(CBORObject o) throws SenMLException { CBORObject n = o.get(0); if (n != null) { - record.setName(deserializeString(n, "n")); + return deserializeString(n, "n"); } + return null; } - protected void deserializeTime(CBORObject o, SenMLRecord record) throws SenMLException { + protected BigDecimal deserializeTime(CBORObject o) throws SenMLException { CBORObject t = o.get(6); if (t != null) { - record.setTime(deserializeTime(t, "t")); + return deserializeTime(t, "t"); } + return null; } - protected boolean deserializeValue(CBORObject o, SenMLRecord record) throws SenMLException { + protected Number deserializeValue(CBORObject o) throws SenMLException { CBORObject v = o.get(2); if (v != null) { - record.setNumberValue(deserializeNumber(v, "v")); - return true; + return deserializeNumber(v, "v"); } - return false; + return null; } - protected boolean deserializeBooleanValue(CBORObject o, SenMLRecord record) throws SenMLException { + protected Boolean deserializeBooleanValue(CBORObject o) throws SenMLException { CBORObject vb = o.get(4); if (vb != null) { if (!(vb.getType() == CBORType.Boolean)) { @@ -135,31 +141,28 @@ protected boolean deserializeBooleanValue(CBORObject o, SenMLRecord record) thro "Invalid SenML record : 'boolean' type was expected but was '%s' for 'vb' field", o.getType().toString()); } - record.setBooleanValue(vb.AsBoolean()); - return true; + return vb.AsBoolean(); } - return false; + return null; } - protected boolean deserializeStringValue(CBORObject o, SenMLRecord record) throws SenMLException { + protected String deserializeStringValue(CBORObject o) throws SenMLException { CBORObject vs = o.get(3); if (vs != null) { - record.setStringValue(deserializeString(vs, "vs")); - return true; + return deserializeString(vs, "vs"); } - return false; + return null; } - protected boolean deserializeObjectLinkValue(CBORObject o, SenMLRecord record) throws SenMLException { + protected String deserializeObjectLinkValue(CBORObject o) throws SenMLException { CBORObject vlo = o.get("vlo"); if (vlo != null) { - record.setObjectLinkValue(deserializeString(vlo, "vlo")); - return true; + return deserializeString(vlo, "vlo"); } - return false; + return null; } - protected boolean deserializeOpaqueValue(CBORObject o, SenMLRecord record) throws SenMLException { + protected byte[] deserializeOpaqueValue(CBORObject o) throws SenMLException { // The RFC says : https://datatracker.ietf.org/doc/html/rfc8428#section-6 // // > Octets in the Data Value are encoded using @@ -174,10 +177,9 @@ protected boolean deserializeOpaqueValue(CBORObject o, SenMLRecord record) throw "Invalid SenML record : 'byteString' type was expected but was '%s' for 'vd' field", o.getType().toString()); } - record.setOpaqueValue(vd.GetByteString()); - return true; + return vd.GetByteString(); } - return false; + return null; } protected String deserializeString(CBORObject o, String fieldname) throws SenMLException { diff --git a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/json/jackson/SenMLJsonRecordSerDes.java b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/json/jackson/SenMLJsonRecordSerDes.java index f6da781303..c12b03f319 100644 --- a/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/json/jackson/SenMLJsonRecordSerDes.java +++ b/leshan-lwm2m-core/src/main/java/org/eclipse/leshan/senml/json/jackson/SenMLJsonRecordSerDes.java @@ -128,54 +128,61 @@ else if (value instanceof Float) { public SenMLRecord deserialize(JsonNode o) throws JsonException { if (o == null) return null; - - SenMLRecord record = new SenMLRecord(); + String recordBaseName = null; + BigDecimal recordBaseTime = null; + String recordName = null; + BigDecimal recordTime = null; + Number recordNumberValue = null; + Boolean recordBooleanValue = null; + String recordStringValue = null; + String recordObjectLinkValue = null; + byte[] recordOpaqueValue = null; JsonNode bn = o.get("bn"); if (bn != null && bn.isTextual()) - record.setBaseName(bn.asText()); + recordBaseName = bn.asText(); JsonNode bt = o.get("bt"); if (bt != null && bt.isNumber()) - record.setBaseTime(new BigDecimal(bt.asText())); + recordBaseTime = new BigDecimal(bt.asText()); JsonNode n = o.get("n"); if (n != null && n.isTextual()) - record.setName(n.asText()); + recordName = n.asText(); JsonNode t = o.get("t"); if (t != null && t.isNumber()) - record.setTime(new BigDecimal(t.asText())); + recordTime = new BigDecimal(t.asText()); JsonNode v = o.get("v"); boolean hasValue = false; if (v != null && v.isNumber()) { - record.setNumberValue(v.numberValue()); + recordNumberValue = v.numberValue(); hasValue = true; } JsonNode vb = o.get("vb"); if (vb != null && vb.isBoolean()) { - record.setBooleanValue(vb.asBoolean()); + recordBooleanValue = vb.asBoolean(); hasValue = true; } JsonNode vs = o.get("vs"); if (vs != null && vs.isTextual()) { - record.setStringValue(vs.asText()); + recordStringValue = vs.asText(); hasValue = true; } JsonNode vlo = o.get("vlo"); if (vlo != null && vlo.isTextual()) { - record.setObjectLinkValue(vlo.asText()); + recordObjectLinkValue = vlo.asText(); hasValue = true; } JsonNode vd = o.get("vd"); if (vd != null && vd.isTextual()) { try { - record.setOpaqueValue(base64Decoder.decode(vd.asText())); + recordOpaqueValue = base64Decoder.decode(vd.asText()); } catch (InvalidBase64Exception exception) { throw new JsonException(exception, "Node vd with value '%s' is not in valid Base64 format.", vd.asText()); @@ -186,6 +193,7 @@ public SenMLRecord deserialize(JsonNode o) throws JsonException { if (!allowNoValue && !hasValue) throw new JsonException("Invalid SenML record : record must have a value (v,vb,vlo,vd,vs) : %s", o); - return record; + return new SenMLRecord(recordBaseName, recordBaseTime, recordName, recordTime, recordNumberValue, + recordBooleanValue, recordObjectLinkValue, recordStringValue, recordOpaqueValue); } } diff --git a/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/json/JsonArrayEntryTest.java b/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/json/JsonArrayEntryTest.java index 41ce8b550c..588d120c08 100644 --- a/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/json/JsonArrayEntryTest.java +++ b/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/json/JsonArrayEntryTest.java @@ -19,11 +19,10 @@ import org.junit.jupiter.api.Test; import nl.jqno.equalsverifier.EqualsVerifier; -import nl.jqno.equalsverifier.Warning; class JsonArrayEntryTest { @Test public void assertEqualsHashcode() { - EqualsVerifier.forClass(JsonArrayEntry.class).suppress(Warning.NONFINAL_FIELDS).verify(); + EqualsVerifier.forClass(JsonArrayEntry.class).verify(); } } diff --git a/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/json/JsonRootObjectTest.java b/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/json/JsonRootObjectTest.java index 956c5ccd78..523a8a47c8 100644 --- a/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/json/JsonRootObjectTest.java +++ b/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/json/JsonRootObjectTest.java @@ -19,11 +19,10 @@ import org.junit.jupiter.api.Test; import nl.jqno.equalsverifier.EqualsVerifier; -import nl.jqno.equalsverifier.Warning; class JsonRootObjectTest { @Test public void assertEqualsHashcode() { - EqualsVerifier.forClass(JsonRootObject.class).suppress(Warning.NONFINAL_FIELDS).verify(); + EqualsVerifier.forClass(JsonRootObject.class).verify(); } } diff --git a/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/json/JsonSerializerTest.java b/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/json/JsonSerializerTest.java index 142aa29485..3b79ffbe6e 100644 --- a/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/json/JsonSerializerTest.java +++ b/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/json/JsonSerializerTest.java @@ -35,69 +35,38 @@ public class JsonSerializerTest { public void serialize_device_object() throws LwM2mJsonException { ArrayList elements = new ArrayList<>(); - JsonArrayEntry elt1 = new JsonArrayEntry(); - elt1.setName("0"); - elt1.setStringValue("Open Mobile Alliance"); + JsonArrayEntry elt1 = new JsonArrayEntry("0", null, null, null, "Open Mobile Alliance", null); elements.add(elt1); - JsonArrayEntry elt2 = new JsonArrayEntry(); - elt2.setName("1"); - elt2.setStringValue("Lightweight M2M Client"); + JsonArrayEntry elt2 = new JsonArrayEntry("1", null, null, null, "Lightweight M2M Client", null); elements.add(elt2); - JsonArrayEntry elt3 = new JsonArrayEntry(); - elt3.setName("2"); - elt3.setStringValue("345000123"); + JsonArrayEntry elt3 = new JsonArrayEntry("2", null, null, null, "345000123", null); elements.add(elt3); - JsonArrayEntry elt4 = new JsonArrayEntry(); - elt4.setName("6/0"); - elt4.setFloatValue(1); + JsonArrayEntry elt4 = new JsonArrayEntry("6/0", 1, null, null, null, null); elements.add(elt4); - JsonArrayEntry elt5 = new JsonArrayEntry(); - elt5.setName("6/1"); - elt5.setFloatValue(5); + JsonArrayEntry elt5 = new JsonArrayEntry("6/1", 5, null, null, null, null); elements.add(elt5); - JsonArrayEntry elt6 = new JsonArrayEntry(); - elt6.setName("7/0"); - elt6.setFloatValue(3800); + JsonArrayEntry elt6 = new JsonArrayEntry("7/0", 3800, null, null, null, null); elements.add(elt6); - JsonArrayEntry elt7 = new JsonArrayEntry(); - elt7.setName("7/1"); - elt7.setFloatValue(5000); + JsonArrayEntry elt7 = new JsonArrayEntry("7/1", 5000, null, null, null, null); elements.add(elt7); - JsonArrayEntry elt8 = new JsonArrayEntry(); - elt8.setName("8/0"); - elt8.setFloatValue(125); + JsonArrayEntry elt8 = new JsonArrayEntry("8/0", 125, null, null, null, null); elements.add(elt8); - JsonArrayEntry elt9 = new JsonArrayEntry(); - elt9.setName("8/1"); - elt9.setFloatValue(900); + JsonArrayEntry elt9 = new JsonArrayEntry("8/1", 900, null, null, null, null); elements.add(elt9); - JsonArrayEntry elt10 = new JsonArrayEntry(); - elt10.setName("9"); - elt10.setFloatValue(100); + JsonArrayEntry elt10 = new JsonArrayEntry("9", 100, null, null, null, null); elements.add(elt10); - JsonArrayEntry elt11 = new JsonArrayEntry(); - elt11.setName("10"); - elt11.setFloatValue(15); + JsonArrayEntry elt11 = new JsonArrayEntry("10", 15, null, null, null, null); elements.add(elt11); - JsonArrayEntry elt12 = new JsonArrayEntry(); - elt12.setName("11/0"); - elt12.setFloatValue(0); + JsonArrayEntry elt12 = new JsonArrayEntry("11/0", 0, null, null, null, null); elements.add(elt12); - JsonArrayEntry elt13 = new JsonArrayEntry(); - elt13.setName("13"); - elt13.setFloatValue(1367491215); + JsonArrayEntry elt13 = new JsonArrayEntry("13", 1367491215, null, null, null, null); elements.add(elt13); - JsonArrayEntry elt14 = new JsonArrayEntry(); - elt14.setName("14"); - elt14.setStringValue("+02:00"); + JsonArrayEntry elt14 = new JsonArrayEntry("14", null, null, null, "+02:00", null); elements.add(elt14); - JsonArrayEntry elt15 = new JsonArrayEntry(); - elt15.setName("15"); - elt15.setStringValue("U"); + JsonArrayEntry elt15 = new JsonArrayEntry("15", null, null, null, "U", null); elements.add(elt15); - JsonRootObject element = new JsonRootObject(); - element.setResourceList(elements); + JsonRootObject element = new JsonRootObject(null, elements, null); String json = LWM2M_JSON_ENCODER_DECODER.toJsonLwM2m(element); LOG.debug(" JSON String: " + json); diff --git a/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/senml/cbor/AbstractSenMLTest.java b/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/senml/cbor/AbstractSenMLTest.java index 991501554d..1a8175371b 100644 --- a/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/senml/cbor/AbstractSenMLTest.java +++ b/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/core/senml/cbor/AbstractSenMLTest.java @@ -20,9 +20,7 @@ public abstract class AbstractSenMLTest { private void givenResourceWithFloatValue(SenMLPack pack, String n, Number value) { - SenMLRecord elt = new SenMLRecord(); - elt.setName(n); - elt.setNumberValue(value); + SenMLRecord elt = new SenMLRecord(null, null, n, null, value, null, null, null, null); pack.addRecord(elt); } @@ -31,13 +29,11 @@ private void givenResourceWithStringValue(SenMLPack pack, String n, String value } private void givenResourceWithStringValue(SenMLPack pack, String bn, String n, String value) { - SenMLRecord elt = new SenMLRecord(); + String baseName = null; if (bn != null) { - elt.setBaseName(bn); + baseName = bn; } - - elt.setName(n); - elt.setStringValue(value); + SenMLRecord elt = new SenMLRecord(baseName, null, n, null, null, null, null, value, null); pack.addRecord(elt); } @@ -105,9 +101,7 @@ protected SenMLPack givenDeviceObjectInstance() { protected SenMLPack getPackWithSingleOpaqueValue(String path, byte[] value) { SenMLPack pack = new SenMLPack(); - SenMLRecord r = new SenMLRecord(); - r.setBaseName(path); - r.setOpaqueValue(value); + SenMLRecord r = new SenMLRecord(path, null, null, null, null, null, null, null, value); pack.addRecord(r); return pack; diff --git a/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/senml/SenMLPackTest.java b/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/senml/SenMLPackTest.java index e7cccf367e..224cd598f1 100644 --- a/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/senml/SenMLPackTest.java +++ b/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/senml/SenMLPackTest.java @@ -18,11 +18,10 @@ import org.junit.jupiter.api.Test; import nl.jqno.equalsverifier.EqualsVerifier; -import nl.jqno.equalsverifier.Warning; class SenMLPackTest { @Test public void assertEqualsHashcode() { - EqualsVerifier.forClass(SenMLPack.class).suppress(Warning.NONFINAL_FIELDS).verify(); + EqualsVerifier.forClass(SenMLPack.class).verify(); } } diff --git a/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/senml/SenMLRecordTest.java b/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/senml/SenMLRecordTest.java index 9efc32a4f4..55537a50e9 100644 --- a/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/senml/SenMLRecordTest.java +++ b/leshan-lwm2m-core/src/test/java/org/eclipse/leshan/senml/SenMLRecordTest.java @@ -18,12 +18,11 @@ import org.junit.jupiter.api.Test; import nl.jqno.equalsverifier.EqualsVerifier; -import nl.jqno.equalsverifier.Warning; class SenMLRecordTest { @Test public void assertEqualsHashcode() { - EqualsVerifier.forClass(SenMLRecord.class).suppress(Warning.NONFINAL_FIELDS).verify(); + EqualsVerifier.forClass(SenMLRecord.class).verify(); } }