Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
BUG-9265: Switch empty type mapping from Void to Empty
Using Void means NormalizedNode.getValue() has to be nullable,
which wreaks havoc to a lot of places. Switch mapping to Empty, which
is a singleton dedicated to representing this type.

This flushes out quite a few of null violations, which are also fixed
up.

Change-Id: I4de3afed3d641eda292fdd4116497f3f22a0d770
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
  • Loading branch information
rovarga committed Oct 19, 2017
1 parent 8fdc093 commit 541932e
Show file tree
Hide file tree
Showing 25 changed files with 97 additions and 107 deletions.
Expand Up @@ -8,11 +8,12 @@
package org.opendaylight.yangtools.yang.data.api.codec;

import org.opendaylight.yangtools.concepts.Codec;
import org.opendaylight.yangtools.yang.common.Empty;

public interface EmptyCodec<T> extends Codec<T,Void> {
public interface EmptyCodec<T> extends Codec<T, Empty> {
@Override
T serialize(Void data);
T serialize(Empty data);

@Override
Void deserialize(T data);
Empty deserialize(T data);
}
Expand Up @@ -7,12 +7,13 @@
*/
package org.opendaylight.yangtools.yang.data.api.codec;

import javax.annotation.Nonnull;
import org.opendaylight.yangtools.concepts.Codec;

public interface StringCodec<T> extends Codec<T,String> {
@Override
T serialize(String data);
T serialize(@Nonnull String data);

@Override
String deserialize(T data);
String deserialize(@Nonnull T data);
}
Expand Up @@ -7,6 +7,7 @@
*/
package org.opendaylight.yangtools.yang.data.api.schema;

import javax.annotation.Nonnull;
import javax.xml.transform.dom.DOMSource;
import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
Expand All @@ -15,16 +16,12 @@
* AN normalizedNode.
*/
public interface AnyXmlNode extends AttributesContainer, DataContainerChild<NodeIdentifier, DOMSource> {

@Override
NodeIdentifier getIdentifier();

/**
* Return value represented as a DOMSource. Returned source contains top level element
* that duplicates the anyxml node.
*
* @return anyxml node value represented as DOMSource.
*/
@Override
DOMSource getValue();
@Nonnull DOMSource getValue();
}
Expand Up @@ -8,6 +8,7 @@
package org.opendaylight.yangtools.yang.data.api.schema;

import java.util.Collection;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
Expand All @@ -34,8 +35,8 @@ public interface AugmentationNode extends MixinNode, DataContainerNode<Augmentat
* This is sufficient to identify instance of augmentation, since RFC6020 states that <code>augment</code>
* that augment statement must not add multiple nodes from same namespace / module to the target node.
*
* @return Identifier which uniquelly identifies augmentation in particular subtree.
* @return Identifier which uniquely identifies augmentation in particular subtree.
*/
@Override
AugmentationIdentifier getIdentifier();
@Nonnull AugmentationIdentifier getIdentifier();
}
Expand Up @@ -7,6 +7,7 @@
*/
package org.opendaylight.yangtools.yang.data.api.schema;

import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;

/**
Expand All @@ -29,5 +30,5 @@
*/
public interface DataContainerChild<K extends PathArgument,V> extends NormalizedNode<K, V> {
@Override
K getIdentifier();
@Nonnull K getIdentifier();
}
Expand Up @@ -8,6 +8,7 @@
package org.opendaylight.yangtools.yang.data.api.schema;

import java.util.Collection;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;

/**
Expand Down Expand Up @@ -41,5 +42,5 @@ public interface DataContainerNode<K extends PathArgument> extends //
* @return Iteration of all child nodes
*/
@Override
Collection<DataContainerChild<? extends PathArgument, ?>> getValue();
@Nonnull Collection<DataContainerChild<? extends PathArgument, ?>> getValue();
}
Expand Up @@ -7,6 +7,7 @@
*/
package org.opendaylight.yangtools.yang.data.api.schema;

import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;

Expand All @@ -27,5 +28,5 @@ public interface LeafNode<T> extends AttributesContainer, DataContainerChild<Nod
* @return Returned value of this leaf node. Value SHOULD meet criteria defined by schema.
*/
@Override
T getValue();
@Nonnull T getValue();
}
Expand Up @@ -7,6 +7,7 @@
*/
package org.opendaylight.yangtools.yang.data.api.schema;

import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;

Expand Down Expand Up @@ -38,5 +39,5 @@ public interface LeafSetEntryNode<T> extends AttributesContainer, NormalizedNode
* @return {@link NodeWithValue} which identifies this leaf set entry.
*/
@Override
NodeWithValue getIdentifier();
@Nonnull NodeWithValue getIdentifier();
}
Expand Up @@ -20,9 +20,7 @@
*
* @param <T> Type of leaf node values.
*/
public interface LeafSetNode<T> extends
MixinNode, //
DataContainerChild<NodeIdentifier, Collection<LeafSetEntryNode<T>>>, //
NormalizedNodeContainer<NodeIdentifier, NodeWithValue,LeafSetEntryNode<T>> {
public interface LeafSetNode<T> extends MixinNode, DataContainerChild<NodeIdentifier, Collection<LeafSetEntryNode<T>>>,
NormalizedNodeContainer<NodeIdentifier, NodeWithValue, LeafSetEntryNode<T>> {

}
Expand Up @@ -7,6 +7,7 @@
*/
package org.opendaylight.yangtools.yang.data.api.schema;

import javax.annotation.Nonnull;
import org.opendaylight.yangtools.concepts.Identifiable;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
Expand Down Expand Up @@ -35,12 +36,12 @@ public interface NormalizedNode<K extends PathArgument, V> extends Identifiable<
* @return Node identifier, non-null.
*/
@Override
K getIdentifier();
@Nonnull K getIdentifier();

/**
* Value of node.
*
* @return Value of the node, may be null.
*/
V getValue();
@Nonnull V getValue();
}
Expand Up @@ -7,6 +7,7 @@
*/
package org.opendaylight.yangtools.yang.data.api.schema;

import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;

/**
Expand All @@ -30,5 +31,5 @@ public interface ValueNode<K extends PathArgument, V> extends NormalizedNode<K,
*
*/
@Override
V getValue();
@Nonnull V getValue();
}
Expand Up @@ -10,8 +10,9 @@

import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import org.opendaylight.yangtools.yang.common.Empty;

final class EmptyJSONCodec implements JSONCodec<Void> {
final class EmptyJSONCodec implements JSONCodec<Empty> {

static final EmptyJSONCodec INSTANCE = new EmptyJSONCodec();

Expand All @@ -20,17 +21,17 @@ private EmptyJSONCodec() {
}

@Override
public Class<Void> getDataType() {
return Void.class;
public Class<Empty> getDataType() {
return Empty.class;
}

@Override
public Void parseValue(final Object ctx, final String input) {
return null;
public Empty parseValue(final Object ctx, final String input) {
return Empty.getInstance();
}

@Override
public void writeValue(final JsonWriter ctx, final Void value) throws IOException {
public void writeValue(final JsonWriter ctx, final Empty value) throws IOException {
ctx.beginArray();
ctx.value((String) null);
ctx.endArray();
Expand Down
Expand Up @@ -24,6 +24,7 @@
import java.util.Collections;
import org.junit.BeforeClass;
import org.junit.Test;
import org.opendaylight.yangtools.yang.common.Empty;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
Expand Down Expand Up @@ -164,7 +165,7 @@ public void emptyTypeTest() throws IOException, URISyntaxException {
final String inputJson = loadTextFile("/complexjson/type-empty.json");
final ContainerNode awaitedStructure = containerBuilder()
.withNodeIdentifier(new NodeIdentifier(CONT_1))
.addChild(leafNode(EMPTY_LEAF, null))
.addChild(leafNode(EMPTY_LEAF, Empty.getInstance()))
.build();

verifyTransformationToNormalizedNode(inputJson, awaitedStructure);
Expand Down
Expand Up @@ -29,6 +29,7 @@
import java.util.Iterator;
import org.junit.BeforeClass;
import org.junit.Test;
import org.opendaylight.yangtools.yang.common.Empty;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
Expand Down Expand Up @@ -297,7 +298,7 @@ public void emptyTypeTest() throws IOException, URISyntaxException {
final StringWriter writer = new StringWriter();
final ContainerNode emptyStructure = Builders.containerBuilder()
.withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CONT_1))
.addChild(ImmutableNodes.leafNode(EMPTY_LEAF, null)).build();
.addChild(ImmutableNodes.leafNode(EMPTY_LEAF, Empty.getInstance())).build();
final String jsonOutput = normalizedNodeToJsonStreamTransformation(writer, emptyStructure);
final JsonObject cont1 = resolveCont1(jsonOutput);
final JsonElement emptyObj = cont1.get("empty");
Expand Down
Expand Up @@ -5,14 +5,16 @@
* 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.xml;

import static java.util.Objects.requireNonNull;

import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.opendaylight.yangtools.yang.common.Empty;

final class EmptyXmlCodec implements XmlCodec<Void> {
final class EmptyXmlCodec implements XmlCodec<Empty> {

static final EmptyXmlCodec INSTANCE = new EmptyXmlCodec();

Expand All @@ -21,17 +23,18 @@ private EmptyXmlCodec() {
}

@Override
public Class<Void> getDataType() {
return Void.class;
public Class<Empty> getDataType() {
return Empty.class;
}

@Override
public Void parseValue(final NamespaceContext ctx, final String str) {
return null;
public Empty parseValue(final NamespaceContext ctx, final String str) {
return Empty.getInstance();
}

@Override
public void writeValue(final XMLStreamWriter ctx, final Void value) throws XMLStreamException {
public void writeValue(final XMLStreamWriter ctx, final Empty value) throws XMLStreamException {
requireNonNull(value);
ctx.writeCharacters("");
}
}
Expand Up @@ -8,28 +8,30 @@
package org.opendaylight.yangtools.yang.data.impl.codec;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;

import com.google.common.base.Strings;
import java.util.Optional;
import org.opendaylight.yangtools.yang.common.Empty;
import org.opendaylight.yangtools.yang.data.api.codec.EmptyCodec;
import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;

final class EmptyStringCodec extends TypeDefinitionAwareCodec<Void, EmptyTypeDefinition> implements
final class EmptyStringCodec extends TypeDefinitionAwareCodec<Empty, EmptyTypeDefinition> implements
EmptyCodec<String> {
static final EmptyStringCodec INSTANCE = new EmptyStringCodec();

private EmptyStringCodec() {
super(Optional.empty(), Void.class);
super(Optional.empty(), Empty.class);
}

@Override
public String serialize(final Void data) {
public String serialize(final Empty data) {
requireNonNull(data);
return "";
}

@Override
public Void deserialize(final String stringRepresentation) {
checkArgument(Strings.isNullOrEmpty(stringRepresentation), "The value must be empty");
return null;
public Empty deserialize(final String stringRepresentation) {
checkArgument(stringRepresentation.isEmpty(), "The value must be empty");
return Empty.getInstance();
}
}
Expand Up @@ -8,14 +8,14 @@
package org.opendaylight.yangtools.yang.data.impl.codec;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;

import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableRangeSet;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import org.opendaylight.yangtools.yang.data.api.codec.StringCodec;
import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
Expand Down Expand Up @@ -56,17 +56,13 @@ public static StringStringCodec from(final StringTypeDefinition normalizedType)

@Override
public final String deserialize(final String stringRepresentation) {
if (stringRepresentation == null) {
// FIXME: These seems buggy, but someone may be using this behaviour
return "";
}
validate(stringRepresentation);
validate(requireNonNull(stringRepresentation));
return stringRepresentation;
}

@Override
public final String serialize(final String data) {
return Objects.toString(data, "");
return requireNonNull(data);
}

void validate(final String str) {
Expand Down

0 comments on commit 541932e

Please sign in to comment.