Skip to content

Commit 874b27b

Browse files
authored
0.70.7
* Fix potential NPE with action parameters. * Fix potential NPE with list. * Make DSElementType a DSIEnum, rework how typing is handled with list. * More generic notation in the public api.
1 parent aa3ea19 commit 874b27b

File tree

11 files changed

+129
-43
lines changed

11 files changed

+129
-43
lines changed

dslink-v2-api/src/main/java/org/iot/dsa/dslink/ActionRequest.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ public interface ActionRequest {
2727
* A convenience for getting a single parameter out of the parameters map.
2828
*/
2929
public default DSElement getParameter(String key) {
30-
return getParameters().get(key);
30+
DSMap map = getParameters();
31+
if (map == null) {
32+
return null;
33+
}
34+
return map.get(key);
3135
}
3236

3337
/**
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package org.iot.dsa.node;
22

3+
import java.util.HashMap;
4+
import java.util.Map;
5+
36
/**
47
* The primitive types of the SDK.
58
*
69
* @author Aaron Hansen
710
*/
8-
public enum DSElementType {
11+
public enum DSElementType implements DSIEnum, DSIValue {
912

1013
BOOLEAN,
1114
BYTES,
@@ -16,13 +19,76 @@ public enum DSElementType {
1619
NULL,
1720
STRING;
1821

19-
private String display;
22+
private static Map<String, DSElementType> nameMap;
23+
private DSString display;
2024

21-
public String toString() {
25+
@Override
26+
public DSIObject copy() {
27+
return this;
28+
}
29+
30+
@Override
31+
public DSList getEnums(DSList bucket) {
32+
if (bucket == null) {
33+
bucket = new DSList();
34+
}
35+
for (DSElementType e : values()) {
36+
bucket.add(e.toElement());
37+
}
38+
return bucket;
39+
}
40+
41+
@Override
42+
public DSValueType getValueType() {
43+
return DSValueType.ENUM;
44+
}
45+
46+
@Override
47+
public boolean isNull() {
48+
return false;
49+
}
50+
51+
/**
52+
* Returns a DSString representation of the name() in lowercase.
53+
*/
54+
@Override
55+
public DSElement toElement() {
2256
if (display == null) {
23-
display = name().toLowerCase();
57+
display = DSString.valueOf(name().toLowerCase());
2458
}
2559
return display;
2660
}
2761

62+
public String toString() {
63+
return toElement().toString();
64+
}
65+
66+
/**
67+
* Unlike Enum.valueOf, this will handle the lowercase display.
68+
*/
69+
public static DSElementType valueFor(String type) {
70+
DSElementType ret = nameMap.get(type);
71+
return ret == null ? NULL : ret;
72+
}
73+
74+
@Override
75+
public DSElementType valueOf(DSElement element) {
76+
DSElementType ret = nameMap.get(element.toString());
77+
return ret == null ? NULL : ret;
78+
}
79+
80+
static {
81+
DSRegistry.registerDecoder(DSElementType.class, BOOLEAN);
82+
nameMap = new HashMap<>();
83+
for (DSElementType e : values()) {
84+
nameMap.put(e.name(), e);
85+
nameMap.put(e.toString(), e);
86+
}
87+
//DSA types
88+
nameMap.put("bool", BOOLEAN);
89+
nameMap.put("number", DOUBLE);
90+
nameMap.put("array", LIST);
91+
nameMap.put("binary", BYTES);
92+
nameMap.put("dynamic", NULL);
93+
}
2894
}

dslink-v2-api/src/main/java/org/iot/dsa/node/DSMetadata.java

+3-7
Original file line numberDiff line numberDiff line change
@@ -370,11 +370,9 @@ public DSMetadata setPrecision(DSLong arg) {
370370
* Sets the type and if the given implements DSIMetadata, adds it's metadata as well.
371371
*/
372372
public DSMetadata setType(DSIValue arg) {
373-
if (arg != null) {
374-
map.put(TYPE, arg.getValueType().toString());
375-
}
373+
map.put(DSMetadata.TYPE, arg.toElement().getElementType().toString());
376374
if (arg instanceof DSIMetadata) {
377-
((DSIMetadata)arg).getMetadata(map);
375+
((DSIMetadata) arg).getMetadata(map);
378376
}
379377
return this;
380378
}
@@ -383,9 +381,7 @@ public DSMetadata setType(DSIValue arg) {
383381
* The type for action parameters, can be used to override types in the responder api.
384382
*/
385383
public DSMetadata setType(DSValueType arg) {
386-
if (arg != null) {
387-
map.put(TYPE, arg.toString());
388-
}
384+
map.put(TYPE, arg.toString());
389385
return this;
390386
}
391387

dslink-v2-api/src/main/java/org/iot/dsa/node/action/DSAction.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public int getParameterCount() {
215215
* @see #prepareParameter(DSInfo, DSMap)
216216
*/
217217
@Override
218-
public void getParameterMetadata(DSInfo target, int idx, DSMap bucket) {
218+
public void getParameterMetadata(DSInfo<?> target, int idx, DSMap bucket) {
219219
bucket.putAll(parameters.get(idx));
220220
prepareParameter(target, bucket);
221221
}
@@ -243,7 +243,7 @@ public ActionResults invoke(DSIActionRequest request) {
243243
* @param target The target of the action.
244244
* @param parameter Map representing a single parameter.
245245
*/
246-
public void prepareParameter(DSInfo target, DSMap parameter) {
246+
public void prepareParameter(DSInfo<?> target, DSMap parameter) {
247247
}
248248

249249
/**

dslink-v2-api/src/main/java/org/iot/dsa/node/action/DSIAction.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public interface DSIAction extends Action, DSIObject {
2626
*
2727
* @see Action#getColumnCount()
2828
*/
29-
public default int getColumnCount(DSInfo target) {
29+
public default int getColumnCount(DSInfo<?> target) {
3030
return getColumnCount();
3131
}
3232

@@ -36,7 +36,7 @@ public default int getColumnCount(DSInfo target) {
3636
*
3737
* @see Action#getColumnMetadata(int, DSMap)
3838
*/
39-
public default void getColumnMetadata(DSInfo target, int idx, DSMap bucket) {
39+
public default void getColumnMetadata(DSInfo<?> target, int idx, DSMap bucket) {
4040
getColumnMetadata(idx, bucket);
4141
}
4242

@@ -46,7 +46,7 @@ public default void getColumnMetadata(DSInfo target, int idx, DSMap bucket) {
4646
*
4747
* @see Action#getParameterCount()
4848
*/
49-
public default int getParameterCount(DSInfo target) {
49+
public default int getParameterCount(DSInfo<?> target) {
5050
return getParameterCount();
5151
}
5252

@@ -56,7 +56,7 @@ public default int getParameterCount(DSInfo target) {
5656
*
5757
* @see Action#getParameterMetadata(int, DSMap)
5858
*/
59-
public default void getParameterMetadata(DSInfo target, int idx, DSMap bucket) {
59+
public default void getParameterMetadata(DSInfo<?> target, int idx, DSMap bucket) {
6060
getParameterMetadata(idx, bucket);
6161
}
6262

dslink-v2-api/src/main/java/org/iot/dsa/node/action/DSIActionRequest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public default DSIAction getAction() {
1919
/**
2020
* The info for the action being invoked.
2121
*/
22-
public DSInfo getActionInfo();
22+
public DSInfo<DSIAction> getActionInfo();
2323

2424
/**
2525
* The target of the action, such as a node or value.
@@ -31,6 +31,6 @@ public default DSIObject getTarget() {
3131
/**
3232
* The target info of the action, such as a node or value.
3333
*/
34-
public DSInfo getTargetInfo();
34+
public DSInfo<?> getTargetInfo();
3535

3636
}

dslink-v2-api/src/main/java/org/iot/dsa/node/action/DuplicateAction.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public ActionResults invoke(DSIActionRequest request) {
4646
}
4747

4848
@Override
49-
public void prepareParameter(DSInfo target, DSMap parameter) {
49+
public void prepareParameter(DSInfo<?> target, DSMap parameter) {
5050
parameter.put(DSMetadata.DEFAULT, target.getName());
5151
}
5252

dslink-v2-api/src/main/java/org/iot/dsa/node/action/RenameAction.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public ActionResults invoke(DSIActionRequest request) {
4646
}
4747

4848
@Override
49-
public void prepareParameter(DSInfo target, DSMap parameter) {
49+
public void prepareParameter(DSInfo<?> target, DSMap parameter) {
5050
parameter.put(DSMetadata.DEFAULT, target.getName());
5151
}
5252

dslink-v2-api/src/main/java/org/iot/dsa/table/DSIResultsCursor.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
public interface DSIResultsCursor extends DSIResults {
99

1010
/**
11-
* Returns true when the cursor
11+
* The cursor must start before the first row of results. If there is another row, this
12+
* should advance the cursor and return true. Otherwise return false.
1213
*/
1314
public boolean next();
1415

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/responder/DSInboundList.java

+35-14
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.iot.dsa.dslink.responder.InboundListRequest;
1919
import org.iot.dsa.dslink.responder.ListCloseHandler;
2020
import org.iot.dsa.node.DSElement;
21+
import org.iot.dsa.node.DSElementType;
2122
import org.iot.dsa.node.DSIEnum;
2223
import org.iot.dsa.node.DSIMetadata;
2324
import org.iot.dsa.node.DSIValue;
@@ -35,6 +36,7 @@
3536
import org.iot.dsa.node.event.DSISubscription;
3637
import org.iot.dsa.time.DSDateTime;
3738
import org.iot.dsa.util.DSException;
39+
import org.iot.dsa.util.DSUtil;
3840

3941
/**
4042
* List implementation for a responder.
@@ -609,19 +611,38 @@ private void encodeTargetMetadata(DSMap metadata) {
609611
}
610612

611613
private DSElement encodeType(DSIValue value, DSMetadata meta) {
612-
String type = meta.getType();
613-
if (getResponder().isV1()) {
614-
if ((type == null) && (value != null)) {
615-
meta.setType(value);
616-
}
617-
} else {
618-
if ((type == null) && (value != null)) {
619-
if (value instanceof DSIEnum) {
620-
meta.setType(DSString.NULL);
621-
} else {
622-
meta.setType(value);
623-
}
624-
}
614+
String orig = meta.getType();
615+
String type = orig;
616+
if ((type == null) && (value != null)) {
617+
meta.setType(value);
618+
type = meta.getType();
619+
}
620+
DSElementType et = DSElementType.valueFor(type);
621+
switch (et) {
622+
case BOOLEAN:
623+
type = "bool";
624+
break;
625+
case DOUBLE:
626+
case LONG:
627+
type = "number";
628+
break;
629+
case LIST:
630+
type = "array";
631+
break;
632+
case MAP:
633+
type = "map";
634+
break;
635+
case BYTES:
636+
type = "binary";
637+
break;
638+
case STRING:
639+
type = "string";
640+
break;
641+
default:
642+
type = "dynamic";
643+
}
644+
if (!DSUtil.equal(orig, type)) {
645+
cacheMap.put(DSMetadata.TYPE, DSString.valueOf(type));
625646
}
626647
fixRangeTypes(meta.getMap());
627648
DSElement e = cacheMap.remove(DSMetadata.TYPE);
@@ -678,7 +699,7 @@ private void encodeValue(Value object) {
678699
cacheMap.clear();
679700
DSIValue val = object.toValue();
680701
if (val instanceof DSIMetadata) {
681-
((DSIMetadata)val).getMetadata(cacheMap);
702+
((DSIMetadata) val).getMetadata(cacheMap);
682703
}
683704
object.getMetadata(cacheMap);
684705
DSElement e = cacheMap.remove("$is");

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/v1/requester/DS1Requester.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,13 @@ private void handleError(DSOutboundStub stub, DSElement details) {
7373
String detail = null;
7474
DSMap map = details.toMap();
7575
String tmp = map.getString("type");
76-
if (tmp == null) {
77-
type = ErrorType.internalError;
78-
} else if (tmp.equals("permissionDenied")) {
76+
if ("permissionDenied".equals(tmp)) {
7977
type = ErrorType.permissionDenied;
80-
} else if (tmp.equals("invalidRequest")) {
78+
} else if ("invalidRequest".equals(tmp)) {
8179
type = ErrorType.badRequest;
82-
} else if (tmp.equals("invalidPath")) {
80+
} else if ("invalidPath".equals(tmp)) {
8381
type = ErrorType.badRequest;
84-
} else if (tmp.equals("notSupported")) {
82+
} else if ("notSupported".equals(tmp)) {
8583
type = ErrorType.notSupported;
8684
} else {
8785
type = ErrorType.internalError;

0 commit comments

Comments
 (0)