*/
package org.opendaylight.yangtools.yang.data.codec.gson;
-import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import org.opendaylight.yangtools.yang.data.impl.codec.DataStringCodec;
}
@Override
- public void writeValue(final JsonWriter ctx, final Boolean value) throws IOException {
- ctx.value(value.booleanValue());
+ public void writeValue(final JSONValueWriter ctx, final Boolean value) throws IOException {
+ ctx.writeBoolean(value);
}
}
--- /dev/null
+/*
+ * Copyright (c) 2024 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.codec.gson;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.base.MoreObjects;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+
+/**
+ * A {@link JSONValueWriter} backed by a {@link JsonWriter}.
+ */
+public final class DefaultJSONValueWriter implements JSONValueWriter {
+ private final JsonWriter writer;
+
+ public DefaultJSONValueWriter(final JsonWriter writer) {
+ this.writer = requireNonNull(writer);
+ }
+
+ @Override
+ public void writeBoolean(final boolean value) throws IOException {
+ writer.value(value);
+ }
+
+ @Override
+ public void writeEmpty() throws IOException {
+ writer.beginArray().nullValue().endArray();
+ }
+
+ @Override
+ public void writeNumber(final Number value) throws IOException {
+ writer.value(requireNonNull(value));
+ }
+
+ @Override
+ public void writeString(final String value) throws IOException {
+ writer.value(requireNonNull(value));
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("writer", writer).toString();
+ }
+}
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.yangtools.yang.data.codec.gson;
-import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import org.opendaylight.yangtools.yang.common.Empty;
}
@Override
- public void writeValue(final JsonWriter ctx, final Empty value) throws IOException {
- ctx.beginArray();
- ctx.nullValue();
- ctx.endArray();
+ public void writeValue(final JSONValueWriter ctx, final Empty value) throws IOException {
+ ctx.writeEmpty();
}
}
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
-import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
}).getQName();
}
- /**
- * Serialize QName with specified JsonWriter.
- *
- * @param writer JsonWriter
- * @param value QName
- */
@Override
- public void writeValue(final JsonWriter writer, final QName value) throws IOException {
- writer.value(QNameCodecUtil.encodeQName(value, uri -> context.findModuleStatement(uri)
+ public void writeValue(final JSONValueWriter ctx, final QName value) throws IOException {
+ ctx.writeString(QNameCodecUtil.encodeQName(value, uri -> context.findModuleStatement(uri)
.map(module -> module.argument().getLocalName())
.orElseThrow(() -> new IllegalArgumentException("Cannot find module for " + uri))));
}
* {@inheritDoc}.
*
* @throws IOException if the write fails
+ * @deprecated Use {@link #writeValue(JSONValueWriter, Object)} instead.
*/
@Override
- void writeValue(JsonWriter ctx, T value) throws IOException;
+ @Deprecated(since = "13.0.3", forRemoval = true)
+ default void writeValue(final JsonWriter writer, final T value) throws IOException {
+ writeValue(new DefaultJSONValueWriter(writer), value);
+ }
+
+ /**
+ * Serialize specified value with specified {@link JSONValueWriter}.
+ *
+ * @param ctx Write context
+ * @param value Value in native format
+ * @throws IOException if the write fails
+ */
+ void writeValue(JSONValueWriter ctx, T value) throws IOException;
/**
* {@inheritDoc}.
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
-import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
}
@Override
- public final void writeValue(final JsonWriter ctx, final YangInstanceIdentifier value) throws IOException {
+ public final void writeValue(final JSONValueWriter ctx, final YangInstanceIdentifier value) throws IOException {
final String str;
try {
str = serialize(value);
} catch (IllegalArgumentException e) {
throw new IOException("Failed to encode instance-identifier", e);
}
- ctx.value(str);
+ ctx.writeString(str);
}
}
private final NormalizedNodeStreamWriterStack tracker;
private final JSONCodecFactory codecs;
private final JsonWriter writer;
+ private final DefaultJSONValueWriter valueWriter;
private JSONStreamWriterContext context;
JSONNormalizedNodeStreamWriter(final JSONCodecFactory codecFactory, final NormalizedNodeStreamWriterStack tracker,
codecs = requireNonNull(codecFactory);
this.tracker = requireNonNull(tracker);
context = requireNonNull(rootContext);
+ valueWriter = new DefaultJSONValueWriter(writer);
}
/**
@SuppressWarnings("unchecked")
private void writeValue(final Object value, final JSONCodec<?> codec) throws IOException {
- ((JSONCodec<Object>) codec).writeValue(writer, value);
+ ((JSONCodec<Object>) codec).writeValue(valueWriter, value);
}
private void writeAnydataValue(final Object value) throws IOException {
--- /dev/null
+/*
+ * Copyright (c) 2024 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.codec.gson;
+
+import java.io.IOException;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * A handler used to write out JSON-encoded values.
+ */
+@NonNullByDefault
+public interface JSONValueWriter {
+ /**
+ * Write a {@code boolean} value, as per
+ * <a href="https://www.rfc-editor.org/rfc/rfc7951#section-6.3">RFC7951, section 6.3</a>.
+ *
+ * @param value Value to write
+ * @throws IOException when an IO error occurs
+ */
+ void writeBoolean(boolean value) throws IOException;
+
+ /**
+ * Write an {@code empty} value, as per
+ * <a href="https://www.rfc-editor.org/rfc/rfc7951#section-6.9">RFC7951, section 6.9</a>.
+ *
+ * @throws IOException when an IO error occurs
+ */
+ void writeEmpty() throws IOException;
+
+ /**
+ * Write a numeric value, as per
+ * <a href="https://www.rfc-editor.org/rfc/rfc7951#section-6.1">RFC7951, section 6.1</a>.
+ *
+ * @param value Value to write
+ * @throws IOException when an IO error occurs
+ */
+ void writeNumber(Number value) throws IOException;
+
+ /**
+ * Write a string value, as per
+ * <a href="https://www.rfc-editor.org/rfc/rfc7951#section-6.2">RFC7951, section 6.2</a> and other types which have
+ * are represented as JSON strings.
+ *
+ * @param value Value to write
+ * @throws IOException when an IO error occurs
+ */
+ void writeString(String value) throws IOException;
+}
*/
package org.opendaylight.yangtools.yang.data.codec.gson;
-import com.google.gson.stream.JsonWriter;
-import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
@Override
- public void writeValue(final JsonWriter ctx, final Object value) throws IOException {
+ public void writeValue(final JSONValueWriter ctx, final Object value) {
// NOOP since codec is unknown.
LOG.warn("Call of the serializeToWriter method on null codec. No operation performed.");
}
*/
package org.opendaylight.yangtools.yang.data.codec.gson;
-import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import org.opendaylight.yangtools.yang.data.impl.codec.DataStringCodec;
}
@Override
- public void writeValue(final JsonWriter ctx, final T value) throws IOException {
- ctx.value(value);
+ public void writeValue(final JSONValueWriter ctx, final T value) throws IOException {
+ ctx.writeNumber(value);
}
}
\ No newline at end of file
*/
package org.opendaylight.yangtools.yang.data.codec.gson;
-import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import org.opendaylight.yangtools.yang.data.impl.codec.DataStringCodec;
}
@Override
- public void writeValue(final JsonWriter ctx, final T value) throws IOException {
- ctx.value(serialize(value));
+ public void writeValue(final JSONValueWriter ctx, final T value) throws IOException {
+ ctx.writeString(serialize(value));
}
}
\ No newline at end of file
import static java.util.Objects.requireNonNull;
import com.google.common.collect.ImmutableList;
-import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
@Override
@SuppressWarnings("checkstyle:illegalCatch")
- public final void writeValue(final JsonWriter ctx, final T value) throws IOException {
+ public final void writeValue(final JSONValueWriter ctx, final T value) throws IOException {
for (var codec : codecs) {
if (!codec.getDataType().isInstance(value)) {
LOG.debug("Codec {} cannot accept input {}, skipping it", codec, value);
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.opendaylight.yangtools.yang.data.codec.gson.TestUtils.loadTextFile;
import com.google.common.collect.ImmutableMap;
import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.io.StringReader;
import java.net.URISyntaxException;
}
private static String writeInstanceIdentifier(final JSONCodecFactorySupplier supplier) throws IOException {
- final var writer = mock(JsonWriter.class);
- final var captor = ArgumentCaptor.forClass(String.class);
- doReturn(writer).when(writer).value(captor.capture());
+ final var writer = mock(JSONValueWriter.class);
+ doNothing().when(writer).writeString(any());
getCodec(supplier).writeValue(writer, TEST_IID);
- verify(writer).value(any(String.class));
+
+ final var captor = ArgumentCaptor.forClass(String.class);
+ verify(writer).writeString(captor.capture());
return captor.getValue();
}
}
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doReturn;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableSet;
-import com.google.gson.stream.JsonWriter;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
}
private static void assertSerdes(final String expected, final YangInstanceIdentifier id) throws Exception {
- final var writer = mock(JsonWriter.class);
- final var captor = ArgumentCaptor.forClass(String.class);
- doReturn(writer).when(writer).value(anyString());
+ final var writer = mock(JSONValueWriter.class);
+ doNothing().when(writer).writeString(any());
CODEC.writeValue(writer, id);
- verify(writer).value(captor.capture());
+
+ final var captor = ArgumentCaptor.forClass(String.class);
+ verify(writer).writeString(captor.capture());
assertEquals(expected, captor.getValue());
assertEquals(id, CODEC.parseValue(expected));
void writeInstanceIdentifierReportsIOException() {
final var codec = JSONCodecFactorySupplier.RFC7951.createSimple(YangParserTestUtils.parseYang())
.instanceIdentifierCodec();
- final var ex = assertThrows(IOException.class, () -> codec.writeValue(null,
+ final var ex = assertThrows(IOException.class, () -> codec.writeValue((JSONValueWriter) null,
YangInstanceIdentifier.of(QName.create("foo", "bar"))));
assertEquals("Failed to encode instance-identifier", ex.getMessage());
assertInstanceOf(IllegalArgumentException.class, ex.getCause());