mirror of
https://github.com/danieldemus/openhab-core.git
synced 2026-07-29 12:34:22 +02:00
[rest] refactored the Stream2JSONInputStream to simplify the logic (#4099)
Signed-off-by: Jörg Sautter <joerg.sautter@gmx.net>
This commit is contained in:
+60
-47
@@ -15,11 +15,15 @@ package org.openhab.core.io.rest;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.SequenceInputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
@@ -32,17 +36,14 @@ import com.google.gson.GsonBuilder;
|
||||
* nested collections JSON representation will be fully transformed into memory.
|
||||
*
|
||||
* @author Henning Treu - Initial contribution
|
||||
* @author Jörg Sautter - Use as SequenceInputStream to simplify the logic
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Stream2JSONInputStream extends InputStream implements JSONInputStream {
|
||||
|
||||
private final Iterator<String> iterator;
|
||||
private static final Gson GSON = new GsonBuilder().setDateFormat(DateTimeType.DATE_PATTERN_WITH_TZ_AND_MS).create();
|
||||
|
||||
private InputStream jsonElementStream;
|
||||
|
||||
private boolean firstIteratorElement;
|
||||
|
||||
private final Gson gson = new GsonBuilder().setDateFormat(DateTimeType.DATE_PATTERN_WITH_TZ_AND_MS).create();
|
||||
private final InputStream stream;
|
||||
|
||||
/**
|
||||
* Creates a new {@link Stream2JSONInputStream} backed by the given {@link Stream} source.
|
||||
@@ -50,56 +51,68 @@ public class Stream2JSONInputStream extends InputStream implements JSONInputStre
|
||||
* @param source the {@link Stream} backing this input stream. Must not be null.
|
||||
*/
|
||||
public Stream2JSONInputStream(Stream<?> source) {
|
||||
iterator = source.map(e -> gson.toJson(e)).iterator();
|
||||
jsonElementStream = new ByteArrayInputStream(new byte[0]);
|
||||
firstIteratorElement = true;
|
||||
Iterator<String> iterator = source.map(e -> GSON.toJson(e)).iterator();
|
||||
|
||||
Enumeration<InputStream> enumeration = new Enumeration<>() {
|
||||
private boolean consumed = false;
|
||||
private @Nullable InputStream next = toStream("[");
|
||||
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return next != null || iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream nextElement() {
|
||||
InputStream is;
|
||||
|
||||
if (next != null) {
|
||||
is = next;
|
||||
if (!consumed && !iterator.hasNext()) {
|
||||
next = toStream("]");
|
||||
consumed = true;
|
||||
} else {
|
||||
next = null;
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
is = toStream(iterator.next());
|
||||
|
||||
if (iterator.hasNext()) {
|
||||
next = toStream(",");
|
||||
} else {
|
||||
next = toStream("]");
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
private static InputStream toStream(String data) {
|
||||
return new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
};
|
||||
stream = new SequenceInputStream(enumeration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
int result = jsonElementStream.read();
|
||||
return stream.read();
|
||||
}
|
||||
|
||||
if (result == -1) { // the current JSON element was completely streamed
|
||||
if (finished()) { // we are done streaming the collection
|
||||
return -1;
|
||||
}
|
||||
@Override
|
||||
public int read(byte @Nullable [] b, int off, int len) throws IOException {
|
||||
return stream.read(b, off, len);
|
||||
}
|
||||
|
||||
fillBuffer(); // get the next element into a new jsonElementStream
|
||||
result = jsonElementStream.read();
|
||||
}
|
||||
|
||||
return result;
|
||||
@Override
|
||||
public long transferTo(OutputStream target) throws IOException {
|
||||
return stream.transferTo(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
jsonElementStream.close();
|
||||
}
|
||||
|
||||
private void fillBuffer() {
|
||||
String prefix;
|
||||
if (firstIteratorElement) {
|
||||
prefix = "[";
|
||||
firstIteratorElement = false;
|
||||
} else {
|
||||
prefix = ",";
|
||||
}
|
||||
|
||||
String entity = iterator.hasNext() ? iterator.next() : "";
|
||||
|
||||
String postfix = "";
|
||||
if (!iterator.hasNext()) {
|
||||
postfix = "]";
|
||||
}
|
||||
|
||||
try {
|
||||
jsonElementStream.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
jsonElementStream = new ByteArrayInputStream((prefix + entity + postfix).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
private boolean finished() {
|
||||
return !firstIteratorElement && !iterator.hasNext();
|
||||
stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user