Skip to content

Commit

Permalink
[rest] refactored the Stream2JSONInputStream to simplify the logic
Browse files Browse the repository at this point in the history
Signed-off-by: Jörg Sautter <joerg.sautter@gmx.net>
  • Loading branch information
joerg1985 committed Feb 19, 2024
1 parent b64e972 commit 3e571d9
Showing 1 changed file with 47 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@
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;
Expand All @@ -32,74 +36,71 @@
* 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 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.
*
* @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;
}
Gson gson = new GsonBuilder().setDateFormat(DateTimeType.DATE_PATTERN_WITH_TZ_AND_MS).create();
Iterator<String> iterator = source.map(e -> gson.toJson(e)).iterator();

@Override
public int read() throws IOException {
int result = jsonElementStream.read();
Enumeration<InputStream> enumeration = new Enumeration<>() {
private boolean eos = false;
private @Nullable InputStream next = toStream("[");

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

fillBuffer(); // get the next element into a new jsonElementStream
result = jsonElementStream.read();
}
@Override
public InputStream nextElement() {
InputStream is;

if (next != null) {
is = next;
next = (!eos && (eos = !iterator.hasNext())) ? toStream("]") : null;
return is;
}

is = toStream(iterator.next());
next = (eos = !iterator.hasNext()) ? toStream("]") : toStream(",");

return is;
}

return result;
private static InputStream toStream(String data) {
return new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
}
};
stream = new SequenceInputStream(enumeration);
}

@Override
public void close() throws IOException {
jsonElementStream.close();
public int read() throws IOException {
return stream.read();
}

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));
@Override
public int read(byte @Nullable [] b, int off, int len) throws IOException {
return stream.read(b, off, len);
}

private boolean finished() {
return !firstIteratorElement && !iterator.hasNext();
@Override
public long transferTo(OutputStream target) throws IOException {
return stream.transferTo(target);
}

@Override
public void close() throws IOException {
stream.close();
}
}

0 comments on commit 3e571d9

Please sign in to comment.