X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-data-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fdata%2Futil%2FAbstractStringInstanceIdentifierCodec.java;h=ef6ac8eb31860a72325d98d7436f82ba291f8e24;hb=052bd27d118a2addb3eae2253515890369a60182;hp=3e47e966cf94a1f1f6b0e6b485fb922678f02ce0;hpb=293e30675df598724ff6020e85ce3018bbc1c1b3;p=yangtools.git diff --git a/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringInstanceIdentifierCodec.java b/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringInstanceIdentifierCodec.java index 3e47e966cf..ef6ac8eb31 100644 --- a/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringInstanceIdentifierCodec.java +++ b/yang/yang-data-util/src/main/java/org/opendaylight/yangtools/yang/data/util/AbstractStringInstanceIdentifierCodec.java @@ -9,17 +9,10 @@ package org.opendaylight.yangtools.yang.data.util; import com.google.common.annotations.Beta; import com.google.common.base.Preconditions; -import com.google.common.base.Splitter; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; @@ -31,20 +24,21 @@ import org.opendaylight.yangtools.yang.data.api.codec.InstanceIdentifierCodec; */ @Beta public abstract class AbstractStringInstanceIdentifierCodec extends AbstractNamespaceCodec implements InstanceIdentifierCodec { - private static final Pattern PREDICATE_PATTERN = Pattern.compile("\\[(.*?)\\]"); - private static final Splitter SLASH_SPLITTER = Splitter.on('/'); @Override public final String serialize(final YangInstanceIdentifier data) { StringBuilder sb = new StringBuilder(); + DataSchemaContextNode current = getDataContextTree().getRoot(); for (PathArgument arg : data.getPathArguments()) { - if(arg instanceof AugmentationIdentifier) { + current = current.getChild(arg); + + if(current.isMixin()) { /* * XML/YANG instance identifier does not have concept - * of augmentation identifier, which identifies - * mixin (same as paretn element), so we can safely - * ignore it if it is part of path (since child node) - * is identified in same fashion. + * of augmentation identifier, or list as whole which + * identifies mixin (same as paretn element), + * so we can safely ignore it if it is part of path + * (since child node) is identified in same fashion. * */ continue; @@ -67,90 +61,33 @@ public abstract class AbstractStringInstanceIdentifierCodec extends AbstractName sb.append("']"); } } - return sb.toString(); } + /** + * + * Returns DataSchemaContextTree associated with SchemaContext for which + * serialization / deserialization occurs. + * + * Implementations MUST provide non-null Data Tree context, in order + * for correct serialization / deserialization of PathArguments, + * since XML representation does not have Augmentation arguments + * and does not provide path arguments for cases. + * + * This effectively means same input XPath representation of Path Argument + * may result in different YangInstanceIdentifiers if models are different + * in uses of choices and cases. + * + * @return DataSchemaContextTree associated with SchemaContext for which + * serialization / deserialization occurs. + */ + protected abstract @Nonnull DataSchemaContextTree getDataContextTree(); + @Override public final YangInstanceIdentifier deserialize(final String data) { Preconditions.checkNotNull(data, "Data may not be null"); - - final Iterator xPathParts = SLASH_SPLITTER.split(data).iterator(); - - // must be at least "/pr:node" - if (!xPathParts.hasNext() || !xPathParts.next().isEmpty() || !xPathParts.hasNext()) { - return null; - } - - List result = new ArrayList<>(); - while (xPathParts.hasNext()) { - String xPathPartTrimmed = xPathParts.next().trim(); - - PathArgument pathArgument = toPathArgument(xPathPartTrimmed); - if (pathArgument != null) { - result.add(pathArgument); - } - } - return YangInstanceIdentifier.create(result); + XpathStringParsingPathArgumentBuilder builder = new XpathStringParsingPathArgumentBuilder(this, data); + return YangInstanceIdentifier.create(builder.build()); } - private PathArgument toPathArgument(final String xPathArgument) { - final QName mainQName = parseQName(xPathArgument); - - // predicates - final Matcher matcher = PREDICATE_PATTERN.matcher(xPathArgument); - final Map predicates = new LinkedHashMap<>(); - QName currentQName = mainQName; - - while (matcher.find()) { - final String predicateStr = matcher.group(1).trim(); - final int indexOfEqualityMark = predicateStr.indexOf('='); - if (indexOfEqualityMark != -1) { - final String predicateValue = toPredicateValue(predicateStr.substring(indexOfEqualityMark + 1)); - if (predicateValue == null) { - return null; - } - - if (predicateStr.charAt(0) != '.') { - // target is not a leaf-list - currentQName = parseQName(predicateStr.substring(0, indexOfEqualityMark)); - if (currentQName == null) { - return null; - } - } - predicates.put(currentQName, predicateValue); - } - } - - if (predicates.isEmpty()) { - return new YangInstanceIdentifier.NodeIdentifier(mainQName); - } else { - return new YangInstanceIdentifier.NodeIdentifierWithPredicates(mainQName, predicates); - } - } - - private static String toPredicateValue(final String predicatedValue) { - final String predicatedValueTrimmed = predicatedValue.trim(); - if (predicatedValue.isEmpty()) { - return null; - } - - switch (predicatedValueTrimmed.charAt(0)) { - case '"': - return trimIfEndIs(predicatedValueTrimmed, '"'); - case '\'': - return trimIfEndIs(predicatedValueTrimmed, '\''); - default: - return null; - } - } - - private static String trimIfEndIs(final String str, final char end) { - final int l = str.length() - 1; - if (str.charAt(l) != end) { - return null; - } - - return str.substring(1, l); - } }