import java.util.LinkedList;
import java.util.List;
import org.opendaylight.netconf.md.sal.rest.common.RestconfValidationUtils;
+import org.opendaylight.netconf.sal.rest.impl.RestUtil;
+import org.opendaylight.netconf.sal.restconf.impl.RestCodec;
import org.opendaylight.netconf.sal.restconf.impl.RestconfError;
import org.opendaylight.restconf.utils.RestconfConstants;
import org.opendaylight.restconf.utils.parser.builder.ParserBuilderConstants;
import org.opendaylight.restconf.utils.schema.context.RestconfSchemaUtil;
+import org.opendaylight.yangtools.concepts.Codec;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
/**
* Deserializer for {@link String} to {@link YangInstanceIdentifier} for
// this is the last identifier (input is consumed) or end of identifier (slash)
if (allCharsConsumed(variables)
- || currentChar(variables.getOffset(), variables.getData()) == RestconfConstants.SLASH) {
+ || (currentChar(variables.getOffset(), variables.getData()) == RestconfConstants.SLASH)) {
prepareIdentifier(qname, path, variables);
path.add(variables.getCurrent().getIdentifier());
} else if (currentChar(variables.getOffset(),
skipCurrentChar(variables);
// read key value separated by comma
- while (keys.hasNext() && !allCharsConsumed(variables) && currentChar(variables.getOffset(),
- variables.getData()) != RestconfConstants.SLASH) {
+ while (keys.hasNext() && !allCharsConsumed(variables) && (currentChar(variables.getOffset(),
+ variables.getData()) != RestconfConstants.SLASH)) {
// empty key value
if (currentChar(variables.getOffset(), variables.getData()) == ParserBuilderConstants.Deserializer.COMMA) {
);
// parse value
- values.put(keys.next(), findAndParsePercentEncoded(nextIdentifierFromNextSequence(
- ParserBuilderConstants.Deserializer.IDENTIFIER_PREDICATE, variables)));
+ final QName key = keys.next();
+ DataSchemaNode leafSchemaNode = null;
+ if (dataSchemaNode instanceof ListSchemaNode) {
+ leafSchemaNode = ((ListSchemaNode) dataSchemaNode).getDataChildByName(key);
+ } else if (dataSchemaNode instanceof LeafListSchemaNode) {
+ leafSchemaNode = dataSchemaNode;
+ }
+ final String value = findAndParsePercentEncoded(nextIdentifierFromNextSequence(
+ ParserBuilderConstants.Deserializer.IDENTIFIER_PREDICATE, variables));
+ final Object valueByType = prepareValueByType(leafSchemaNode, value, variables);
+ values.put(key, valueByType);
+
// skip comma
- if (keys.hasNext() && !allCharsConsumed(variables) && currentChar(
- variables.getOffset(), variables.getData()) == ParserBuilderConstants.Deserializer.COMMA) {
+ if (keys.hasNext() && !allCharsConsumed(variables) && (currentChar(
+ variables.getOffset(), variables.getData()) == ParserBuilderConstants.Deserializer.COMMA)) {
skipCurrentChar(variables);
}
}
// the last key is considered to be empty
if (keys.hasNext()) {
if (allCharsConsumed(variables)
- || currentChar(variables.getOffset(), variables.getData()) == RestconfConstants.SLASH) {
+ || (currentChar(variables.getOffset(), variables.getData()) == RestconfConstants.SLASH)) {
values.put(keys.next(), ParserBuilderConstants.Deserializer.EMPTY_STRING);
}
path.add(new YangInstanceIdentifier.NodeIdentifierWithPredicates(qname, values.build()));
}
+ private static Object prepareValueByType(final DataSchemaNode schemaNode, final String value,
+ final MainVarsWrapper vars) {
+ Object decoded = null;
+
+ TypeDefinition<? extends TypeDefinition<?>> typedef = null;
+ if (schemaNode instanceof LeafListSchemaNode) {
+ typedef = ((LeafListSchemaNode) schemaNode).getType();
+ } else {
+ typedef = ((LeafSchemaNode) schemaNode).getType();
+ }
+ final TypeDefinition<?> baseType = RestUtil.resolveBaseTypeFrom(typedef);
+ if (baseType instanceof LeafrefTypeDefinition) {
+ typedef = SchemaContextUtil.getBaseTypeForLeafRef((LeafrefTypeDefinition) baseType, vars.getSchemaContext(),
+ schemaNode);
+ }
+ final Codec<Object, Object> codec = RestCodec.from(typedef, null);
+ decoded = codec.deserialize(value);
+ if (decoded == null) {
+ if ((baseType instanceof IdentityrefTypeDefinition)) {
+ decoded = toQName(value, schemaNode, vars.getSchemaContext());
+ }
+ }
+ return decoded;
+ }
+
+ private static Object toQName(final String value, final DataSchemaNode schemaNode,
+ final SchemaContext schemaContext) {
+ final String moduleName = toModuleName(value);
+ final String nodeName = toNodeName(value);
+ final Module module = schemaContext.findModuleByName(moduleName, null);
+ for (final IdentitySchemaNode identitySchemaNode : module.getIdentities()) {
+ final QName qName = identitySchemaNode.getQName();
+ if (qName.getLocalName().equals(nodeName)) {
+ return qName;
+ }
+ }
+ return QName.create(schemaNode.getQName().getNamespace(), schemaNode.getQName().getRevision(), value);
+ }
+
+ private static String toNodeName(final String str) {
+ final int idx = str.indexOf(':');
+ if (idx == -1) {
+ return str;
+ }
+
+ if (str.indexOf(':', idx + 1) != -1) {
+ return str;
+ }
+
+ return str.substring(idx + 1);
+ }
+
+ private static String toModuleName(final String str) {
+ final int idx = str.indexOf(':');
+ if (idx == -1) {
+ return null;
+ }
+
+ if (str.indexOf(':', idx + 1) != -1) {
+ return null;
+ }
+
+ return str.substring(0, idx);
+ }
private static QName prepareQName(final MainVarsWrapper variables) {
checkValid(
variables.getOffset());
localName = nextIdentifierFromNextSequence(ParserBuilderConstants.Deserializer.IDENTIFIER, variables);
- if (!allCharsConsumed(variables) && currentChar
- (variables.getOffset(), variables.getData()) == ParserBuilderConstants.Deserializer.EQUAL) {
+ if (!allCharsConsumed(variables) && (currentChar
+ (variables.getOffset(), variables.getData()) == ParserBuilderConstants.Deserializer.EQUAL)) {
return getQNameOfDataSchemaNode(localName, variables);
} else {
final Module module = moduleForPrefix(prefix, variables.getSchemaContext());
RestconfError.ErrorTag.MISSING_ATTRIBUTE,
"Value missing for: " + qname
);
-
- path.add(new YangInstanceIdentifier.NodeWithValue<>(qname, findAndParsePercentEncoded(value)));
+ final DataSchemaNode dataSchemaNode = variables.getCurrent().getDataSchemaNode();
+ final Object valueByType = prepareValueByType(dataSchemaNode, findAndParsePercentEncoded(value), variables);
+ path.add(new YangInstanceIdentifier.NodeWithValue<>(qname, valueByType));
}
private static void prepareIdentifier(final QName qname, final List<PathArgument> path,
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@Before
public void init() throws Exception {
- schemaContext = TestRestconfUtils.loadSchemaContext("/restconf/parser/deserializer");
+ this.schemaContext = TestRestconfUtils.loadSchemaContext("/restconf/parser/deserializer");
}
/**
@Test
public void deserializeContainerTest() {
final Iterable<YangInstanceIdentifier.PathArgument> result = YangInstanceIdentifierDeserializer
- .create(schemaContext, "deserializer-test:contA");
+ .create(this.schemaContext, "deserializer-test:contA");
assertEquals("Result does not contains expected number of path arguments", 1, Iterables.size(result));
assertEquals("Not expected path argument",
@Test
public void deserializeContainerWithLeafTest() {
final Iterable<YangInstanceIdentifier.PathArgument> result = YangInstanceIdentifierDeserializer
- .create(schemaContext, "deserializer-test:contA/leaf-A");
+ .create(this.schemaContext, "deserializer-test:contA/leaf-A");
assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
@Test
public void deserializeContainerWithListWithLeafListTest() {
final Iterable<YangInstanceIdentifier.PathArgument> result = YangInstanceIdentifierDeserializer
- .create(schemaContext, "deserializer-test:contA/list-A=100/leaf-list-AA=instance");
+ .create(this.schemaContext, "deserializer-test:contA/list-A=100/leaf-list-AA=instance");
assertEquals("Result does not contains expected number of path arguments", 5, Iterables.size(result));
@Test
public void deserializeListWithNoKeysTest() {
final Iterable<YangInstanceIdentifier.PathArgument> result = YangInstanceIdentifierDeserializer
- .create(schemaContext, "deserializer-test:list-no-key");
+ .create(this.schemaContext, "deserializer-test:list-no-key");
assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
@Test
public void deserializeListWithOneKeyTest() {
final Iterable<YangInstanceIdentifier.PathArgument> result = YangInstanceIdentifierDeserializer
- .create(schemaContext, "deserializer-test:list-one-key=value");
+ .create(this.schemaContext, "deserializer-test:list-one-key=value");
assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
values.put(QName.create(list, "enabled"), false);
final Iterable<YangInstanceIdentifier.PathArgument> result = YangInstanceIdentifierDeserializer
- .create(schemaContext, "deserializer-test:list-multiple-keys=value,100,false");
+ .create(this.schemaContext, "deserializer-test:list-multiple-keys=value,100,false");
assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
@Test
public void deserializeLeafListTest() {
final Iterable<YangInstanceIdentifier.PathArgument> result = YangInstanceIdentifierDeserializer
- .create(schemaContext, "deserializer-test:leaf-list-0=true");
+ .create(this.schemaContext, "deserializer-test:leaf-list-0=true");
assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
*/
@Test
public void deserializeEmptyDataTest() {
- final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(schemaContext, "");
+ final Iterable<PathArgument> result = YangInstanceIdentifierDeserializer.create(this.schemaContext, "");
assertTrue("Empty result expected", Iterables.isEmpty(result));
}
*/
@Test
public void deserializeNullSchemaContextNegativeTest() {
- thrown.expect(NullPointerException.class);
+ this.thrown.expect(NullPointerException.class);
YangInstanceIdentifierDeserializer.create(null, "deserializer-test:contA");
}
*/
@Test
public void nullDataNegativeNegativeTest() {
- thrown.expect(NullPointerException.class);
- YangInstanceIdentifierDeserializer.create(schemaContext, null);
+ this.thrown.expect(NullPointerException.class);
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, null);
}
/**
*/
@Test
public void deserializeBadCharMissingSlashOrEqualNegativeTest() {
- thrown.expect(IllegalArgumentException.class);
- YangInstanceIdentifierDeserializer.create(schemaContext, "deserializer-test:cont*leaf-A");
+ this.thrown.expect(IllegalArgumentException.class);
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:cont*leaf-A");
}
/**
*/
@Test
public void validArgIdentifierContainerEndsWithSlashNegativeTest() {
- thrown.expect(IllegalArgumentException.class);
- YangInstanceIdentifierDeserializer.create(schemaContext, "deserializer-test:contA/");
+ this.thrown.expect(IllegalArgumentException.class);
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:contA/");
}
/**
*/
@Test
public void validArgIdentifierListEndsWithSlashLNegativeTest() {
- thrown.expect(IllegalArgumentException.class);
- YangInstanceIdentifierDeserializer.create(schemaContext, "deserializer-test:list-one-key=value/");
+ this.thrown.expect(IllegalArgumentException.class);
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:list-one-key=value/");
}
/**
*/
@Test
public void prepareQnameEmptyIdentifierNegativeTest() {
- thrown.expect(IllegalArgumentException.class);
- YangInstanceIdentifierDeserializer.create(schemaContext, "/");
+ this.thrown.expect(IllegalArgumentException.class);
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "/");
}
/**
*/
@Test
public void prepareQnameTwoSlashesNegativeTest() {
- thrown.expect(IllegalArgumentException.class);
- YangInstanceIdentifierDeserializer.create(schemaContext, "deserializer-test:contA//leaf-A");
+ this.thrown.expect(IllegalArgumentException.class);
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:contA//leaf-A");
}
/**
*/
@Test
public void prepareQnameBuildPathNegativeTest() {
- thrown.expect(IllegalArgumentException.class);
- YangInstanceIdentifierDeserializer.create(schemaContext, "deserializer-test*contA");
+ this.thrown.expect(IllegalArgumentException.class);
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test*contA");
}
/**
*/
@Test
public void prepareQnameNotExistingPrefixNegativeTest() {
- thrown.expect(IllegalArgumentException.class);
- YangInstanceIdentifierDeserializer.create(schemaContext, "not-existing:contA");
+ this.thrown.expect(IllegalArgumentException.class);
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "not-existing:contA");
}
/**
*/
@Test
public void prepareQnameNotValidPrefixAndLocalNameNegativeTest() {
- thrown.expect(IllegalArgumentException.class);
- YangInstanceIdentifierDeserializer.create(schemaContext, "deserializer-test:*not-parsable-identifier");
+ this.thrown.expect(IllegalArgumentException.class);
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:*not-parsable-identifier");
}
/**
*/
@Test
public void prepareQnameErrorParsingNegativeTest() {
- thrown.expect(StringIndexOutOfBoundsException.class);
- YangInstanceIdentifierDeserializer.create(schemaContext, "deserializer-test:");
+ this.thrown.expect(StringIndexOutOfBoundsException.class);
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:");
}
/**
@Test
public void prepareQnameNotValidContainerNameNegativeTest() {
try {
- YangInstanceIdentifierDeserializer.create(schemaContext, "deserializer-test:contA/leafB");
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:contA/leafB");
fail("Test should fail due to unknown child node in container");
} catch (final RestconfDocumentedException e) {
assertEquals("Not expected error type",
@Test
public void prepareQnameNotValidListNameNegativeTest() {
try {
- YangInstanceIdentifierDeserializer.create(schemaContext, "deserializer-test:list-no-key/disabled=false");
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:list-no-key/disabled=false");
fail("Test should fail due to unknown child node in list");
} catch (final RestconfDocumentedException e) {
assertEquals("Not expected error type",
*/
@Test
public void prepareIdentifierNotKeyedEntryNegativeTest() {
- thrown.expect(IllegalArgumentException.class);
- YangInstanceIdentifierDeserializer.create(schemaContext, "deserializer-test:list-one-key");
+ this.thrown.expect(IllegalArgumentException.class);
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:list-one-key");
}
/**
*/
@Test
public void deserializeKeysEndsWithComaNegativeTest() {
- thrown.expect(IllegalArgumentException.class);
- YangInstanceIdentifierDeserializer.create( schemaContext,
+ this.thrown.expect(IllegalArgumentException.class);
+ YangInstanceIdentifierDeserializer.create( this.schemaContext,
"deserializer-test:list-multiple-keys=value,100,false,");
}
values.put(QName.create(list, "enabled"), "");
final Iterable<YangInstanceIdentifier.PathArgument> result = YangInstanceIdentifierDeserializer.create(
- schemaContext, "deserializer-test:list-multiple-keys=%3Afoo,,/string-value");
+ this.schemaContext, "deserializer-test:list-multiple-keys=%3Afoo,,/string-value");
assertEquals("Result does not contains expected number of path arguments", 3, Iterables.size(result));
public void notAllListKeysEncodedNegativeTest() {
try {
YangInstanceIdentifierDeserializer.create(
- schemaContext, "deserializer-test:list-multiple-keys=%3Afoo/string-value");
+ this.schemaContext, "deserializer-test:list-multiple-keys=%3Afoo/string-value");
fail("Test should fail due to missing list key values");
} catch (final RestconfDocumentedException e) {
assertEquals("Not expected error type",
*/
@Test
public void percentEncodedKeyEndsWithNoPercentEncodedChars() {
- final String URI = "deserializer-test:list-multiple-keys=%3Afoo,bar%3A,foo%3Abar";
+ final String URI = "deserializer-test:list-multiple-keys=%3Afoo,1,true";
final YangInstanceIdentifier result = YangInstanceIdentifier.create(
- YangInstanceIdentifierDeserializer.create(schemaContext, URI));
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, URI));
final Iterator<Map.Entry<QName, Object>> resultListKeys = ((YangInstanceIdentifier.NodeIdentifierWithPredicates)
result.getLastPathArgument()).getKeyValues().entrySet().iterator();
assertEquals(":foo", resultListKeys.next().getValue());
- assertEquals("bar:", resultListKeys.next().getValue());
- assertEquals("foo:bar", resultListKeys.next().getValue());
+ assertEquals(new Short("1"), resultListKeys.next().getValue());
+ assertEquals(true, resultListKeys.next().getValue());
}
/**
values.put(QName.create(list, "enabled"), "");
final Iterable<YangInstanceIdentifier.PathArgument> result = YangInstanceIdentifierDeserializer
- .create(schemaContext, "deserializer-test:list-multiple-keys=,,");
+ .create(this.schemaContext, "deserializer-test:list-multiple-keys=,,");
assertEquals("Result does not contains expected number of path arguments", 2, Iterables.size(result));
@Test
public void leafListMissingKeyNegativeTest() {
try {
- YangInstanceIdentifierDeserializer.create(schemaContext, "deserializer-test:leaf-list-0=");
+ YangInstanceIdentifierDeserializer.create(this.schemaContext, "deserializer-test:leaf-list-0=");
fail("Test should fail due to missing instance value");
} catch (final RestconfDocumentedException e) {
assertEquals("Not expected error type",
@Test
public void deserializePartInOtherModuleTest() {
final Iterable<YangInstanceIdentifier.PathArgument> result = YangInstanceIdentifierDeserializer.create(
- schemaContext, "deserializer-test-included:augmented-list=100/augmented-leaf");
+ this.schemaContext, "deserializer-test-included:augmented-list=100/augmented-leaf");
assertEquals("Result does not contains expected number of path arguments", 4, Iterables.size(result));