Iterate over models in PathsStream
[netconf.git] / restconf / restconf-openapi / src / main / java / org / opendaylight / restconf / openapi / impl / OpenApiInputStream.java
index 7d7eea749278ba1f5220e00283f031e10af4eca4..6a158907b6781e42b0c2d5f4282b9f6df055a854 100644 (file)
@@ -9,25 +9,30 @@ package org.opendaylight.restconf.openapi.impl;
 
 import com.fasterxml.jackson.core.JsonFactoryBuilder;
 import com.fasterxml.jackson.core.JsonGenerator;
+import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayDeque;
+import java.util.Collection;
 import java.util.Deque;
 import java.util.List;
 import java.util.Map;
 import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
-import org.opendaylight.restconf.openapi.model.Info;
 import org.opendaylight.restconf.openapi.model.InfoEntity;
 import org.opendaylight.restconf.openapi.model.OpenApiVersionEntity;
-import org.opendaylight.restconf.openapi.model.Server;
+import org.opendaylight.restconf.openapi.model.SecurityEntity;
 import org.opendaylight.restconf.openapi.model.ServerEntity;
 import org.opendaylight.restconf.openapi.model.ServersEntity;
 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.Module;
 
 public final class OpenApiInputStream extends InputStream {
     private final ByteArrayOutputStream stream = new ByteArrayOutputStream();
@@ -35,20 +40,22 @@ public final class OpenApiInputStream extends InputStream {
     private final Deque<InputStream> stack = new ArrayDeque<>();
 
     private Reader reader;
+    private ReadableByteChannel channel;
 
     private boolean eof;
 
-    public OpenApiInputStream(final EffectiveModelContext context, final String openApiVersion, final Info info,
-            final List<Server> servers, final List<Map<String, List<String>>> security, final String deviceName,
-            final String urlPrefix) throws IOException {
+    public OpenApiInputStream(final EffectiveModelContext context, final String title, final String url,
+            final List<Map<String, List<String>>> security, final String deviceName, final String urlPrefix,
+            final boolean isForSingleModule, final boolean includeDataStore, final Collection<? extends Module> modules,
+            final String basePath) throws IOException {
         final OpenApiBodyWriter writer = new OpenApiBodyWriter(generator, stream);
         stack.add(new OpenApiVersionStream(new OpenApiVersionEntity(), writer));
-        stack.add(new InfoStream(new InfoEntity(info.version(), info.title(), info.description()), writer));
-        stack.add(new ServersStream(new ServersEntity(
-            List.of(new ServerEntity(servers.iterator().next().url()))), writer));
-        stack.add(new PathsSteam(context, writer, generator, stream, deviceName, urlPrefix));
-        stack.add(new SchemasStream(context, writer, generator, stream));
-        stack.add(new SecurityStream(writer));
+        stack.add(new InfoStream(new InfoEntity(title), writer));
+        stack.add(new ServersStream(new ServersEntity(List.of(new ServerEntity(url))), writer));
+        stack.add(new PathsStream(context, writer, deviceName, urlPrefix, isForSingleModule, includeDataStore,
+            modules.iterator(), basePath, stream, generator));
+        stack.add(new ComponentsStream(context, writer, generator, stream, modules.iterator(), isForSingleModule));
+        stack.add(new SecurityStream(writer, new SecurityEntity(security)));
     }
 
     @Override
@@ -59,7 +66,8 @@ public final class OpenApiInputStream extends InputStream {
         if (reader == null) {
             generator.writeStartObject();
             generator.flush();
-            reader = new InputStreamReader(new ByteArrayInputStream(stream.toByteArray()), StandardCharsets.UTF_8);
+            reader = new BufferedReader(
+                new InputStreamReader(new ByteArrayInputStream(stream.toByteArray()), StandardCharsets.UTF_8));
             stream.reset();
         }
 
@@ -68,12 +76,13 @@ public final class OpenApiInputStream extends InputStream {
             if (stack.isEmpty()) {
                 generator.writeEndObject();
                 generator.flush();
-                reader = new InputStreamReader(new ByteArrayInputStream(stream.toByteArray()), StandardCharsets.UTF_8);
+                reader = new BufferedReader(
+                    new InputStreamReader(new ByteArrayInputStream(stream.toByteArray()), StandardCharsets.UTF_8));
                 stream.reset();
                 eof = true;
                 return reader.read();
             }
-            reader = new InputStreamReader(stack.pop(), StandardCharsets.UTF_8);
+            reader = new BufferedReader(new InputStreamReader(stack.pop(), StandardCharsets.UTF_8));
             read = reader.read();
         }
 
@@ -82,6 +91,30 @@ public final class OpenApiInputStream extends InputStream {
 
     @Override
     public int read(final byte[] array, final int off, final int len) throws IOException {
-        return super.read(array, off, len);
+        if (eof) {
+            return -1;
+        }
+        if (channel == null) {
+            generator.writeStartObject();
+            generator.flush();
+            channel = Channels.newChannel(new ByteArrayInputStream(stream.toByteArray()));
+            stream.reset();
+        }
+
+        var read = channel.read(ByteBuffer.wrap(array, off, len));
+        while (read == -1) {
+            if (stack.isEmpty()) {
+                generator.writeEndObject();
+                generator.flush();
+                channel = Channels.newChannel(new ByteArrayInputStream(stream.toByteArray()));
+                stream.reset();
+                eof = true;
+                return channel.read(ByteBuffer.wrap(array, off, len));
+            }
+            channel = Channels.newChannel(stack.pop());
+            read = channel.read(ByteBuffer.wrap(array, off, len));
+        }
+
+        return read;
     }
 }