Skip to content

Commit

Permalink
Cleaning the code
Browse files Browse the repository at this point in the history
  • Loading branch information
Michał Wadowski authored and Michał Wadowski committed Mar 8, 2022
1 parent 6836683 commit 2ee77ba
Show file tree
Hide file tree
Showing 21 changed files with 449 additions and 213 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public void visit(SendRequest request) {

ContentFormat format = request.getFormat();
coapRequest.getOptions().setContentFormat(format.getCode());
coapRequest.setPayload(encoder.encodeMultiTimestampedNodes(request.getData(), format, model));
coapRequest.setPayload(encoder.encodeMultiTimestampedNodes(request.getTimestampedNodes(), format, model));
}

public Request getRequest() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,50 @@
/*******************************************************************************
* Copyright (c) 2021 Orange.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
* Orange - Send with multiple-timestamped values
*******************************************************************************/
package org.eclipse.leshan.core.node;

import java.util.Map;
import java.util.Set;

/**
* A container for path {@link LwM2mPath} - nodes {@link LwM2mNode} map with optional timestamp segregation.
*
* @see TimestampedLwM2mNodesImpl
*/
public interface TimestampedLwM2mNodes {
Map<Long, Map<LwM2mPath, LwM2mNode>> getTimestampedPathNodesMap();

Map<String, LwM2mNode> getStrPathNodesMap();
/**
* Get timestamp grouped map of {@link LwM2mPath}-{@link LwM2mNode} map.
*/
Map<Long, Map<LwM2mPath, LwM2mNode>> getTimestampedNodes();

Map<LwM2mPath, LwM2mNode> getPathNodesMap();
/**
* Get all collected nodes represented as {@link LwM2mPath}-{@link LwM2mNode} map.
*/
Map<LwM2mPath, LwM2mNode> getNodes();

LwM2mNode getFirstNode();

Set<LwM2mPath> getPaths();
/**
* Get nodes for specific timestamp. Null timestamp is allowed.
*
* @param timestamp
* @return map of {@link LwM2mPath}-{@link LwM2mNode} or null if there is no value for asked timestamp.
*/
Map<LwM2mPath, LwM2mNode> getNodesForTimestamp(Long timestamp);

/**
* Returns the contained timestamps.
*/
Set<Long> getTimestamps();
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
/*******************************************************************************
* Copyright (c) 2021 Orange.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
* Orange - Send with multiple-timestamped values
*******************************************************************************/
package org.eclipse.leshan.core.node;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
* The default implementation of {@link TimestampedLwM2mNodes}
*/
public class TimestampedLwM2mNodesImpl implements TimestampedLwM2mNodes {

private final Map<Long, Map<LwM2mPath, LwM2mNode>> timestampedPathNodesMap = new TreeMap<>((o1, o2) -> {
Expand Down Expand Up @@ -34,54 +50,29 @@ public TimestampedLwM2mNodesImpl(Long timestamp, LwM2mPath path, LwM2mNode node)
}

@Override
public Map<Long, Map<LwM2mPath, LwM2mNode>> getTimestampedPathNodesMap() {
public Map<Long, Map<LwM2mPath, LwM2mNode>> getTimestampedNodes() {
return timestampedPathNodesMap;
}

@Override
public Map<String, LwM2mNode> getStrPathNodesMap() {
Map<String, LwM2mNode> result = new HashMap<>();
for (Map.Entry<LwM2mPath, LwM2mNode> entry : getPathNodesMap().entrySet()) {
result.put(entry.getKey().toString(), entry.getValue());
}
return result;
public Map<LwM2mPath, LwM2mNode> getNodesForTimestamp(Long timestamp) {
return timestampedPathNodesMap.get(timestamp);
}

@Override
public Map<LwM2mPath, LwM2mNode> getPathNodesMap() {
Iterator<Map.Entry<Long, Map<LwM2mPath, LwM2mNode>>> iterator = timestampedPathNodesMap.entrySet().iterator();
if (iterator.hasNext()) {
return iterator.next().getValue();
} else {
return null;
public Map<LwM2mPath, LwM2mNode> getNodes() {
Map<LwM2mPath, LwM2mNode> result = new HashMap<>();
for (Map.Entry<Long, Map<LwM2mPath, LwM2mNode>> entry : timestampedPathNodesMap.entrySet()) {
result.putAll(entry.getValue());
}
}

@Override
public LwM2mNode getFirstNode() {
return getPathNodesMap().entrySet().iterator().next().getValue();
}

@Override
public Set<LwM2mPath> getPaths() {
Set<LwM2mPath> paths = new HashSet<>();
for (Map.Entry<Long, Map<LwM2mPath, LwM2mNode>> tsEntry: timestampedPathNodesMap.entrySet()) {
for (Map.Entry<LwM2mPath, LwM2mNode> entry: tsEntry.getValue().entrySet()) {
paths.add(entry.getKey());
}
}
return paths;
return result;
}

@Override
public Set<Long> getTimestamps() {
return timestampedPathNodesMap.keySet();
}

public void put(String path, LwM2mNode node) {
put(new LwM2mPath(path), node);
}

public void put(Long timestamp, LwM2mPath path, LwM2mNode node) {
if (!timestampedPathNodesMap.containsKey(timestamp)) {
timestampedPathNodesMap.put(timestamp, new HashMap<>());
Expand All @@ -93,16 +84,48 @@ public void put(LwM2mPath path, LwM2mNode node) {
put(null, path, node);
}

public void add(TimestampedLwM2mNodes parseRecords) {
for( Map.Entry<Long, Map<LwM2mPath, LwM2mNode>> timestampEntry : parseRecords.getTimestampedPathNodesMap().entrySet()) {
Long timestamp = timestampEntry.getKey();
Map<LwM2mPath, LwM2mNode> pathNodeMap = timestampEntry.getValue();
public void add(TimestampedLwM2mNodes timestampedNodes) {
for (Map.Entry<Long, Map<LwM2mPath, LwM2mNode>> entry : timestampedNodes.getTimestampedNodes().entrySet()) {
Long timestamp = entry.getKey();
Map<LwM2mPath, LwM2mNode> pathNodeMap = entry.getValue();

for (Map.Entry<LwM2mPath, LwM2mNode> pathNodeEntry: pathNodeMap.entrySet()) {
for (Map.Entry<LwM2mPath, LwM2mNode> pathNodeEntry : pathNodeMap.entrySet()) {
LwM2mPath path = pathNodeEntry.getKey();
LwM2mNode node = pathNodeEntry.getValue();
put(timestamp, path, node);
}
}
}

@Override
public String toString() {
return String.format("TimestampedLwM2mNodesImpl [timestampedPathNodesMap=%s, timestampedNodes=%s]",
timestampedPathNodesMap);
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((timestampedPathNodesMap == null) ? 0 : timestampedPathNodesMap.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TimestampedLwM2mNodesImpl other = (TimestampedLwM2mNodesImpl) obj;
if (timestampedPathNodesMap == null) {
if (other.timestampedPathNodesMap != null)
return false;
} else if (!timestampedPathNodesMap.equals(other.timestampedPathNodesMap))
return false;
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ public TimestampedLwM2mNodes decodeMultiTimestampedNodes(byte[] content, Content
if (decoder instanceof TimestampedMultiNodeDecoder) {
return ((TimestampedMultiNodeDecoder) decoder).decodeMultiTimestampedNodes(content, model);
} else {
throw new CodecException("Decoder does not support multi node decoding for this content format %s [%s] ", format);
throw new CodecException(
"Decoder does not support multiple timestamped nodes decoding for this content format %s [%s] ",
format);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ public Set<ContentFormat> getSupportedContentFormat() {
}

@Override
public byte[] encodeMultiTimestampedNodes(TimestampedLwM2mNodes data, ContentFormat format, LwM2mModel model) {
return encodeNodes(data.getPathNodesMap(), format, model);
public byte[] encodeMultiTimestampedNodes(TimestampedLwM2mNodes data, ContentFormat format, LwM2mModel model)
throws CodecException {
return encodeNodes(data.getNodes(), format, model);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,18 @@ <T extends LwM2mNode> T decode(byte[] content, ContentFormat format, LwM2mPath p
Map<LwM2mPath, LwM2mNode> decodeNodes(byte[] content, ContentFormat format, List<LwM2mPath> paths, LwM2mModel model)
throws CodecException;

TimestampedLwM2mNodes decodeMultiTimestampedNodes(byte[] content, ContentFormat format, LwM2mModel model) throws CodecException;
/**
* Deserializes a binary content into a {@link TimestampedLwM2mNodes}.
* <p>
*
* @param content the content
* @param format the content format
* @param model the collection of supported object models
* @return the decoded timestamped nodes represented by {@link TimestampedLwM2mNodes}
* @throws CodecException if content is malformed.
*/
TimestampedLwM2mNodes decodeMultiTimestampedNodes(byte[] content, ContentFormat format, LwM2mModel model)
throws CodecException;

/**
* Deserializes a binary content into a list of time-stamped {@link LwM2mNode} ordering by time-stamp.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,16 @@ byte[] encodeTimestampedData(List<TimestampedLwM2mNode> timestampedNodes, Conten
*/
Set<ContentFormat> getSupportedContentFormat();

byte[] encodeMultiTimestampedNodes(TimestampedLwM2mNodes data, ContentFormat format, LwM2mModel model);
/**
* Serializes a multiple time-stamped nodes contained in {@link TimestampedLwM2mNodes} with the given content
* format.
*
* @param data the {@link TimestampedLwM2mNodes} to serialize
* @param format the content format
* @param model the collection of supported object models
* @return the encoded node as a byte array
* @throws CodecException if encoding failed.
*/
byte[] encodeMultiTimestampedNodes(TimestampedLwM2mNodes data, ContentFormat format, LwM2mModel model)
throws CodecException;
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,38 @@
/*******************************************************************************
* Copyright (c) 2021 Orange.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
* Orange - Send with multiple-timestamped values
*******************************************************************************/
package org.eclipse.leshan.core.node.codec;

import org.eclipse.leshan.core.model.LwM2mModel;
import org.eclipse.leshan.core.node.TimestampedLwM2mNodes;

/**
* A decoder for {@link TimestampedLwM2mNodes}.
*
* @see DefaultLwM2mDecoder
*/
public interface TimestampedMultiNodeDecoder {

/**
* Deserializes a binary content into a {@link TimestampedLwM2mNodes}.
* <p>
*
* @param content the content
* @param model the collection of supported object models
* @return the decoded timestamped nodes represented by {@link TimestampedLwM2mNodes}
* @throws CodecException if content is malformed.
*/
TimestampedLwM2mNodes decodeMultiTimestampedNodes(byte[] content, LwM2mModel model) throws CodecException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,30 @@ public List<TimestampedLwM2mNode> decodeTimestampedData(byte[] content, LwM2mPat
}
}

@Override
public TimestampedLwM2mNodes decodeMultiTimestampedNodes(byte[] content, LwM2mModel model) throws CodecException {
try {
// Decode SenML pack
SenMLPack pack = decoder.fromSenML(content);

TimestampedLwM2mNodesImpl nodes = new TimestampedLwM2mNodesImpl();

LwM2mSenMLResolver resolver = new LwM2mSenMLResolver();
for (SenMLRecord record : pack.getRecords()) {
LwM2mResolvedSenMLRecord resolvedRecord = resolver.resolve(record);
LwM2mPath path = resolvedRecord.getPath();
LwM2mNode node = parseRecords(Arrays.asList(resolvedRecord), path, model,
DefaultLwM2mDecoder.nodeClassFromPath(path));
nodes.add(new TimestampedLwM2mNodesImpl(resolvedRecord.getTimeStamp(), path, node));
}

return nodes;
} catch (SenMLException e) {
String hexValue = content != null ? Hex.encodeHexString(content) : "";
throw new CodecException(e, "Unable to decode nodes : %s", hexValue, e);
}
}

/**
* Parse records for a given LWM2M path.
*/
Expand Down Expand Up @@ -275,32 +299,6 @@ private LwM2mNode parseRecords(Collection<LwM2mResolvedSenMLRecord> records, LwM
return node;
}

@Override
public TimestampedLwM2mNodes decodeMultiTimestampedNodes(byte[] content, LwM2mModel model) throws CodecException {
try {
// Decode SenML pack
SenMLPack pack = decoder.fromSenML(content);

TimestampedLwM2mNodesImpl nodes = new TimestampedLwM2mNodesImpl();

// Paths are not given so we given so we can not regroup by path
// let's assume that each path refer to a single resource or single resource instances.
LwM2mSenMLResolver resolver = new LwM2mSenMLResolver();
for (SenMLRecord record : pack.getRecords()) {
LwM2mResolvedSenMLRecord resolvedRecord = resolver.resolve(record);
LwM2mPath path = resolvedRecord.getPath();
LwM2mNode node = parseRecords(Arrays.asList(resolvedRecord), path, model,
DefaultLwM2mDecoder.nodeClassFromPath(path));
nodes.add(new TimestampedLwM2mNodesImpl(resolvedRecord.getTimeStamp(), path, node));
}

return nodes;
} catch (SenMLException e) {
String hexValue = content != null ? Hex.encodeHexString(content) : "";
throw new CodecException(e, "Unable to decode nodes : %s", hexValue, e);
}
}

/**
* Resolved record then group it by LwM2mPath
*/
Expand Down
Loading

0 comments on commit 2ee77ba

Please sign in to comment.