Skip to content

Commit 3d83c70

Browse files
authored
[rest] refactored the Stream2JSONInputStream to simplify the logic (#4099)
Signed-off-by: Jörg Sautter <[email protected]>
1 parent 977fa03 commit 3d83c70

File tree

1 file changed

+58
-45
lines changed

1 file changed

+58
-45
lines changed

Diff for: bundles/org.openhab.core.io.rest/src/main/java/org/openhab/core/io/rest/Stream2JSONInputStream.java

+58-45
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@
1515
import java.io.ByteArrayInputStream;
1616
import java.io.IOException;
1717
import java.io.InputStream;
18+
import java.io.OutputStream;
19+
import java.io.SequenceInputStream;
1820
import java.nio.charset.StandardCharsets;
21+
import java.util.Enumeration;
1922
import java.util.Iterator;
2023
import java.util.stream.Stream;
2124

2225
import org.eclipse.jdt.annotation.NonNullByDefault;
26+
import org.eclipse.jdt.annotation.Nullable;
2327
import org.openhab.core.library.types.DateTimeType;
2428

2529
import com.google.gson.Gson;
@@ -32,74 +36,83 @@
3236
* nested collections JSON representation will be fully transformed into memory.
3337
*
3438
* @author Henning Treu - Initial contribution
39+
* @author Jörg Sautter - Use as SequenceInputStream to simplify the logic
3540
*/
3641
@NonNullByDefault
3742
public class Stream2JSONInputStream extends InputStream implements JSONInputStream {
3843

39-
private final Iterator<String> iterator;
44+
private static final Gson GSON = new GsonBuilder().setDateFormat(DateTimeType.DATE_PATTERN_WITH_TZ_AND_MS).create();
4045

41-
private InputStream jsonElementStream;
42-
43-
private boolean firstIteratorElement;
44-
45-
private final Gson gson = new GsonBuilder().setDateFormat(DateTimeType.DATE_PATTERN_WITH_TZ_AND_MS).create();
46+
private final InputStream stream;
4647

4748
/**
4849
* Creates a new {@link Stream2JSONInputStream} backed by the given {@link Stream} source.
4950
*
5051
* @param source the {@link Stream} backing this input stream. Must not be null.
5152
*/
5253
public Stream2JSONInputStream(Stream<?> source) {
53-
iterator = source.map(e -> gson.toJson(e)).iterator();
54-
jsonElementStream = new ByteArrayInputStream(new byte[0]);
55-
firstIteratorElement = true;
56-
}
54+
Iterator<String> iterator = source.map(e -> GSON.toJson(e)).iterator();
5755

58-
@Override
59-
public int read() throws IOException {
60-
int result = jsonElementStream.read();
56+
Enumeration<InputStream> enumeration = new Enumeration<>() {
57+
private boolean consumed = false;
58+
private @Nullable InputStream next = toStream("[");
6159

62-
if (result == -1) { // the current JSON element was completely streamed
63-
if (finished()) { // we are done streaming the collection
64-
return -1;
60+
@Override
61+
public boolean hasMoreElements() {
62+
return next != null || iterator.hasNext();
6563
}
6664

67-
fillBuffer(); // get the next element into a new jsonElementStream
68-
result = jsonElementStream.read();
69-
}
65+
@Override
66+
public InputStream nextElement() {
67+
InputStream is;
68+
69+
if (next != null) {
70+
is = next;
71+
if (!consumed && !iterator.hasNext()) {
72+
next = toStream("]");
73+
consumed = true;
74+
} else {
75+
next = null;
76+
}
77+
return is;
78+
}
79+
80+
is = toStream(iterator.next());
81+
82+
if (iterator.hasNext()) {
83+
next = toStream(",");
84+
} else {
85+
next = toStream("]");
86+
consumed = true;
87+
}
88+
89+
return is;
90+
}
7091

71-
return result;
92+
private static InputStream toStream(String data) {
93+
return new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
94+
}
95+
};
96+
stream = new SequenceInputStream(enumeration);
7297
}
7398

7499
@Override
75-
public void close() throws IOException {
76-
jsonElementStream.close();
100+
public int read() throws IOException {
101+
return stream.read();
77102
}
78103

79-
private void fillBuffer() {
80-
String prefix;
81-
if (firstIteratorElement) {
82-
prefix = "[";
83-
firstIteratorElement = false;
84-
} else {
85-
prefix = ",";
86-
}
87-
88-
String entity = iterator.hasNext() ? iterator.next() : "";
89-
90-
String postfix = "";
91-
if (!iterator.hasNext()) {
92-
postfix = "]";
93-
}
94-
95-
try {
96-
jsonElementStream.close();
97-
} catch (IOException e) {
98-
}
99-
jsonElementStream = new ByteArrayInputStream((prefix + entity + postfix).getBytes(StandardCharsets.UTF_8));
104+
@Override
105+
public int read(byte @Nullable [] b, int off, int len) throws IOException {
106+
return stream.read(b, off, len);
100107
}
101108

102-
private boolean finished() {
103-
return !firstIteratorElement && !iterator.hasNext();
109+
@Override
110+
public long transferTo(OutputStream target) throws IOException {
111+
return stream.transferTo(target);
112+
}
113+
114+
@Override
115+
public void close() throws IOException {
116+
stream.close();
104117
}
105118
}

0 commit comments

Comments
 (0)