+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. 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.impl.tree;
import java.io.InputStream;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
/**
- * @author Lukas Sedlak <lsedlak@cisco.com>
+ * @author Lukas Sedlak <lsedlak@cisco.com>
*/
public class BenchmarkModel {
*
* JMH is used for microbenchmarking.
*
- * @author Lukas Sedlak <lsedlak@cisco.com>
+ * @author Lukas Sedlak <lsedlak@cisco.com>
*
* @see <a href="http://openjdk.java.net/projects/code-tools/jmh/">JMH</a>
*/
import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.opendaylight.yangtools.sal.binding.generator.impl.YangTemplate;
import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
import org.opendaylight.yangtools.binding.generator.util.BindingTypes;
import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
-
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
if ("char[]".equals(name)) {
return char[].class;
}
+ return loadClass0(cls,name);
+ }
+ private static Class<?> loadClass0(final ClassLoader cls, final String name) throws ClassNotFoundException {
try {
return cls.loadClass(name);
- } catch (ClassNotFoundException e) {
- String[] components = name.split("\\.");
- String potentialOuter;
- int length = components.length;
- if (length > 2 && (potentialOuter = components[length - 2]) != null && Character.isUpperCase(potentialOuter.charAt(0))) {
- String outerName = Joiner.on(".").join(Arrays.asList(components).subList(0, length - 1));
- String innerName = outerName + "$" + components[length-1];
+ } catch (final ClassNotFoundException e) {
+ final String[] components = name.split("\\.");
+
+ if (isInnerClass(components)) {
+ final int length = components.length;
+ final String outerName = Joiner.on(".").join(Arrays.asList(components).subList(0, length - 1));
+ final String innerName = outerName + "$" + components[length-1];
return cls.loadClass(innerName);
} else {
throw e;
}
}
+ private static boolean isInnerClass(final String[] components) {
+ final int length = components.length;
+ if(length < 2) {
+ return false;
+ }
+ final String potentialOuter = components[length - 2];
+ if(potentialOuter == null) {
+ return false;
+ }
+ return Character.isUpperCase(potentialOuter.charAt(0));
+ }
+
public static Class<?> loadClassWithTCCL(final String name) throws ClassNotFoundException {
return loadClass(Thread.currentThread().getContextClassLoader(), name);
}
public static Class<?> tryToLoadClassWithTCCL(final String fullyQualifiedName) {
try {
return loadClassWithTCCL(fullyQualifiedName);
- } catch (ClassNotFoundException e) {
+ } catch (final ClassNotFoundException e) {
LOG.debug("Failed to load class {}", fullyQualifiedName, e);
return null;
}
Preconditions.checkNotNull(subclass);
Preconditions.checkNotNull(genericType);
- for (Type type : subclass.getGenericInterfaces()) {
+ for (final Type type : subclass.getGenericInterfaces()) {
if (type instanceof ParameterizedType && genericType.equals(((ParameterizedType) type).getRawType())) {
return (ParameterizedType) type;
}
throw new IllegalArgumentException("Parameter 'localName' must be a non-empty string.");
}
- for (char c : ILLEGAL_CHARACTERS) {
+ for (final char c : ILLEGAL_CHARACTERS) {
if (localName.indexOf(c) != -1) {
throw new IllegalArgumentException(String.format(
"Parameter 'localName':'%s' contains illegal character '%s'", localName, c));
public static QName create(final String input) {
Matcher matcher = QNAME_PATTERN_FULL.matcher(input);
if (matcher.matches()) {
- String namespace = matcher.group(1);
- String revision = matcher.group(2);
- String localName = matcher.group(3);
+ final String namespace = matcher.group(1);
+ final String revision = matcher.group(2);
+ final String localName = matcher.group(3);
return create(namespace, revision, localName);
}
matcher = QNAME_PATTERN_NO_REVISION.matcher(input);
if (matcher.matches()) {
- URI namespace = URI.create(matcher.group(1));
- String localName = matcher.group(2);
+ final URI namespace = URI.create(matcher.group(1));
+ final String localName = matcher.group(2);
return new QName(namespace, localName);
}
matcher = QNAME_PATTERN_NO_NAMESPACE_NO_REVISION.matcher(input);
if (matcher.matches()) {
- String localName = matcher.group(1);
+ final String localName = matcher.group(1);
return new QName((URI) null, localName);
}
throw new IllegalArgumentException("Invalid input:" + input);
* <code>revision</code> is not according to format
* <code>YYYY-mm-dd</code>.
*/
- public static QName create(final String namespace, final String revision, final String localName)
- throws IllegalArgumentException {
+ public static QName create(final String namespace, final String revision, final String localName) {
final URI namespaceUri = parseNamespace(namespace);
final Date revisionDate = parseRevision(revision);
return create(namespaceUri, revisionDate, localName);
private static URI parseNamespace(final String namespace) {
try {
return new URI(namespace);
- } catch (URISyntaxException ue) {
+ } catch (final URISyntaxException ue) {
throw new IllegalArgumentException(String.format("Namespace '%s' is not a valid URI", namespace), ue);
}
}
* @throws IllegalArgumentException
* If <code>namespace</code> is not valid URI.
*/
- public static QName create(final String namespace, final String localName) throws IllegalArgumentException {
+ public static QName create(final String namespace, final String localName) {
return create(parseNamespace(namespace), null, localName);
}
@Override
public String toString() {
- StringBuilder sb = new StringBuilder();
+ final StringBuilder sb = new StringBuilder();
if (getNamespace() != null) {
sb.append(QNAME_LEFT_PARENTHESIS + getNamespace());
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Date;
+import java.util.Objects;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.objcache.ObjectCache;
import org.opendaylight.yangtools.objcache.ObjectCacheFactory;
return false;
}
final QNameModule other = (QNameModule) obj;
- if (revision == null) {
- if (other.revision != null) {
- return false;
- }
- } else if (!revision.equals(other.revision)) {
+ if (!Objects.equals(revision, other.revision)) {
return false;
}
- if (namespace == null) {
- if (other.namespace != null) {
- return false;
- }
- } else if (!namespace.equals(other.namespace)) {
+ if (!Objects.equals(namespace, other.namespace)) {
return false;
}
return true;
try {
compositeURI = new URI(namespace.getScheme(), namespace.getUserInfo(), namespace.getHost(),
namespace.getPort(), namespace.getPath(), query, namespace.getFragment());
- } catch (URISyntaxException e) {
+ } catch (final URISyntaxException e) {
LOG.error("", e);
}
return compositeURI;
private static final String REVISION_SIMPLE_DATE = "yyyy-MM-dd";
private static final String DEFAULT_DATE = "1970-01-01";
- public static Date DEFAULT_DATE_REV;
- public static Date DEFAULT_DATE_IMP;
+ public static final Date DEFAULT_DATE_REV;
+ public static final Date DEFAULT_DATE_IMP;
static {
- SimpleDateFormat simpleDateFormat = new SimpleDateFormat(REVISION_SIMPLE_DATE);
+ final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(REVISION_SIMPLE_DATE);
try {
DEFAULT_DATE_REV = simpleDateFormat.parse(DEFAULT_DATE);
DEFAULT_DATE_IMP = simpleDateFormat.parse(DEFAULT_DATE);
- } catch (ParseException e) {
+ } catch (final ParseException e) {
throw new ExceptionInInitializerError(e);
}
}
}
@Override
- public void set(SimpleDateFormat value) {
+ public void set(final SimpleDateFormat value) {
throw new UnsupportedOperationException();
}
package org.opendaylight.yangtools.yang.data.api.schema.tree;
import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.Iterator;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@Beta
public static DataTreeCandidateNode fromNormalizedNode(final NormalizedNode<?, ?> node) {
return new NormalizedNodeDataTreeCandidateNode(node);
}
+
+ public static void applyToCursor(final DataTreeModificationCursor cursor, final DataTreeCandidateNode node) {
+ switch (node.getModificationType()) {
+ case DELETE:
+ cursor.delete(node.getIdentifier());
+ break;
+ case SUBTREE_MODIFIED:
+ cursor.enter(node.getIdentifier());
+ NodeIterator iterator = new NodeIterator(null, node.getChildNodes().iterator());
+ do {
+ iterator = iterator.next(cursor);
+ } while (iterator != null);
+ break;
+ case UNMODIFIED:
+ // No-op
+ break;
+ case WRITE:
+ cursor.write(node.getIdentifier(), node.getDataAfter().get());
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+ }
+ }
+
+ private static final class NodeIterator {
+ private final Iterator<DataTreeCandidateNode> iterator;
+ private final NodeIterator parent;
+
+ NodeIterator(final NodeIterator parent, final Iterator<DataTreeCandidateNode> iterator) {
+ this.parent = Preconditions.checkNotNull(parent);
+ this.iterator = Preconditions.checkNotNull(iterator);
+ }
+
+ NodeIterator next(final DataTreeModificationCursor cursor) {
+ while (iterator.hasNext()) {
+ final DataTreeCandidateNode node = iterator.next();
+ switch (node.getModificationType()) {
+ case DELETE:
+ cursor.delete(node.getIdentifier());
+ break;
+ case SUBTREE_MODIFIED:
+ final Collection<DataTreeCandidateNode> children = node.getChildNodes();
+ if (!children.isEmpty()) {
+ cursor.enter(node.getIdentifier());
+ return new NodeIterator(this, children.iterator());
+ }
+ break;
+ case UNMODIFIED:
+ // No-op
+ break;
+ case WRITE:
+ cursor.write(node.getIdentifier(), node.getDataAfter().get());
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+ }
+ }
+
+ cursor.exit();
+ return parent;
+ }
+ }
}
package org.opendaylight.yangtools.yang.data.api.schema.tree;
import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.util.Iterator;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.slf4j.Logger;
return new DefaultDataTreeCandidate(rootPath, new NormalizedNodeDataTreeCandidateNode(node));
}
+ public static void applyToCursor(final DataTreeModificationCursor cursor, final DataTreeCandidate candidate) {
+ DataTreeCandidateNodes.applyToCursor(cursor, candidate.getRootNode());
+ }
+
public static void applyToModification(final DataTreeModification modification, final DataTreeCandidate candidate) {
if (modification instanceof CursorAwareDataTreeModification) {
try (DataTreeModificationCursor cursor = ((CursorAwareDataTreeModification) modification).createCursor(candidate.getRootPath())) {
- applyNode(cursor, candidate.getRootNode());
+ applyToCursor(cursor, candidate);
}
- } else {
- applyNode(modification, candidate.getRootPath(), candidate.getRootNode());
+ return;
}
- }
- private static void applyNode(final DataTreeModification modification, final YangInstanceIdentifier path, final DataTreeCandidateNode node) {
+ final DataTreeCandidateNode node = candidate.getRootNode();
+ final YangInstanceIdentifier path = candidate.getRootPath();
switch (node.getModificationType()) {
case DELETE:
modification.delete(path);
break;
case SUBTREE_MODIFIED:
LOG.debug("Modification {} modified path {}", modification, path);
- for (DataTreeCandidateNode child : node.getChildNodes()) {
- applyNode(modification, path.node(child.getIdentifier()), child);
- }
+
+ NodeIterator iterator = new NodeIterator(null, path, node.getChildNodes().iterator());
+ do {
+ iterator = iterator.next(modification);
+ } while (iterator != null);
break;
case UNMODIFIED:
LOG.debug("Modification {} unmodified path {}", modification, path);
}
}
- private static void applyNode(final DataTreeModificationCursor cursor, final DataTreeCandidateNode node) {
- switch (node.getModificationType()) {
- case DELETE:
- cursor.delete(node.getIdentifier());
- break;
- case SUBTREE_MODIFIED:
- cursor.enter(node.getIdentifier());
- for (DataTreeCandidateNode child : node.getChildNodes()) {
- applyNode(cursor, child);
+ private static final class NodeIterator {
+ private final Iterator<DataTreeCandidateNode> iterator;
+ private final YangInstanceIdentifier path;
+ private final NodeIterator parent;
+
+ public NodeIterator(final NodeIterator parent, final YangInstanceIdentifier path, final Iterator<DataTreeCandidateNode> iterator) {
+ this.iterator = Preconditions.checkNotNull(iterator);
+ this.parent = Preconditions.checkNotNull(parent);
+ this.path = Preconditions.checkNotNull(path);
+ }
+
+ NodeIterator next(final DataTreeModification modification) {
+ while (iterator.hasNext()) {
+ final DataTreeCandidateNode node = iterator.next();
+ final YangInstanceIdentifier child = path.node(node.getIdentifier());
+
+ switch (node.getModificationType()) {
+ case DELETE:
+ modification.delete(child);
+ LOG.debug("Modification {} deleted path {}", modification, child);
+ break;
+ case SUBTREE_MODIFIED:
+ LOG.debug("Modification {} modified path {}", modification, child);
+ return new NodeIterator(this, child, node.getChildNodes().iterator());
+ case UNMODIFIED:
+ LOG.debug("Modification {} unmodified path {}", modification, child);
+ // No-op
+ break;
+ case WRITE:
+ modification.write(child, node.getDataAfter().get());
+ LOG.debug("Modification {} written path {}", modification, child);
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+ }
}
- cursor.exit();
- break;
- case UNMODIFIED:
- // No-op
- break;
- case WRITE:
- cursor.write(node.getIdentifier(), node.getDataAfter().get());
- break;
- default:
- throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+
+ return parent;
}
}
}
root = (DataNodeContainer) current;
}
- private Optional<SchemaNode> tryFindGroupings(final SchemaContext ctx, final QName qname) {
+ private static Optional<SchemaNode> tryFindGroupings(final SchemaContext ctx, final QName qname) {
return Optional.<SchemaNode> fromNullable(Iterables.find(ctx.getGroupings(), new SchemaNodePredicate(qname), null));
}
- private Optional<SchemaNode> tryFindRpc(final SchemaContext ctx, final QName qname) {
+ private static Optional<SchemaNode> tryFindRpc(final SchemaContext ctx, final QName qname) {
return Optional.<SchemaNode>fromNullable(Iterables.find(ctx.getOperations(), new SchemaNodePredicate(qname), null));
}
- private Optional<SchemaNode> tryFindNotification(final SchemaContext ctx, final QName qname) {
+ private static Optional<SchemaNode> tryFindNotification(final SchemaContext ctx, final QName qname) {
return Optional.<SchemaNode>fromNullable(Iterables.find(ctx.getNotifications(), new SchemaNodePredicate(qname), null));
}
return schema;
}
- private SchemaNode findChildInCases(final ChoiceSchemaNode parent, final QName qname) {
+ private static SchemaNode findChildInCases(final ChoiceSchemaNode parent, final QName qname) {
DataSchemaNode schema = null;
for(final ChoiceCaseNode caze : parent.getCases()) {
final DataSchemaNode potential = caze.getDataChildByName(qname);
return schema;
}
- private SchemaNode findCaseByChild(final ChoiceSchemaNode parent, final QName qname) {
+ private static SchemaNode findCaseByChild(final ChoiceSchemaNode parent, final QName qname) {
DataSchemaNode schema = null;
for(final ChoiceCaseNode caze : parent.getCases()) {
final DataSchemaNode potential = caze.getDataChildByName(qname);
import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public final class XmlDocumentUtils {
public static final QName OPERATION_ATTRIBUTE_QNAME = QName.create(SchemaContext.NAME, "operation");
- private static final Logger LOG = LoggerFactory.getLogger(XmlDocumentUtils.class);
private XmlDocumentUtils() {
throw new UnsupportedOperationException("Utility class should not be instantiated");
}
- private LeafRefContext getReferencingCtxChild(
+ private static LeafRefContext getReferencingCtxChild(
final LeafRefContext referencingCtx, final DataTreeCandidateNode childNode) {
LeafRefContext childReferencingCtx = null;
return childReferencingCtx;
}
- private LeafRefContext getReferencedByCtxChild(
+ private static LeafRefContext getReferencedByCtxChild(
final LeafRefContext referencedByCtx, final DataTreeCandidateNode childNode) {
LeafRefContext childReferencedByCtx = null;
// FIXME if(node instance of UnkeyedListNode ...
}
- private LeafRefContext findReferencingCtxUnderChoice(
+ private static LeafRefContext findReferencingCtxUnderChoice(
final LeafRefContext referencingCtx, final QName qname) {
final Map<QName, LeafRefContext> referencingChilds = referencingCtx
return null;
}
- private LeafRefContext findReferencedByCtxUnderChoice(
+ private static LeafRefContext findReferencedByCtxUnderChoice(
final LeafRefContext referencedByCtx, final QName qname) {
final Map<QName, LeafRefContext> referencedByChilds = referencedByCtx
validatedLeafRefCtx.add(referencedByCtx);
}
- private StringBuilder createInvalidTargetMessage(final NormalizedNode<?, ?> leaf,
+ private static StringBuilder createInvalidTargetMessage(final NormalizedNode<?, ?> leaf,
final HashSet<?> leafRefTargetNodeValues, final LeafRefContext leafRefContext,
final Object leafRefsValue) {
final StringBuilder sb = new StringBuilder();
sb.append("Invalid leafref value [");
sb.append(leafRefsValue);
- sb.append("]");
- sb.append(" allowed values ");
+ sb.append("] allowed values ");
sb.append(leafRefTargetNodeValues);
sb.append(" by validation of leafref TARGET node: ");
sb.append(leaf.getNodeType());
final LeafRefContext referencingCtx, final ModificationType modificationType,
final YangInstanceIdentifier current) {
- final StringBuilder header_log = new StringBuilder();
+ final StringBuilder headerLog = new StringBuilder();
final StringBuilder log = new StringBuilder();
- header_log.append("Operation [" + modificationType
- + "] validate data of LEAFREF node: name["
- + referencingCtx.getNodeName() + "] = value["
- + leaf.getValue() + "]");
+ headerLog.append("Operation [");
+ headerLog.append(modificationType);
+ headerLog.append("] validate data of LEAFREF node: name[");
+ headerLog.append(referencingCtx.getNodeName());
+ headerLog.append("] = value[");
+ headerLog.append(leaf.getValue());
+ headerLog.append(']');
final HashSet<Object> values = new HashSet<>();
final LeafRefPath targetPath = referencingCtx.getAbsoluteLeafRefTargetPath();
referencingCtx, values);
errorsMessages.add(sb.toString());
- header_log.append(" -> FAILED");
+ headerLog.append(" -> FAILED");
log.append(sb.toString());
} else {
- header_log.append(" -> OK");
+ headerLog.append(" -> OK");
}
- LOG.debug(header_log.toString());
- if (!log.toString().equals(""))
+ LOG.debug(headerLog.toString());
+ if (log.length() != 0) {
LOG.debug(log.toString());
+ }
}
- private StringBuilder createInvalidLeafRefMessage(
+ private static StringBuilder createInvalidLeafRefMessage(
final NormalizedNode<?, ?> leaf, final LeafRefContext referencingCtx,
final Set<?> values) {
final StringBuilder sb = new StringBuilder();
sb.append("Invalid leafref value [");
sb.append(leaf.getValue());
- sb.append("]");
- sb.append(" allowed values ");
+ sb.append("] allowed values ");
sb.append(values);
sb.append(" of LEAFREF node: ");
sb.append(leaf.getNodeType());
}
}
- private Iterable<ChoiceNode> getChoiceNodes(
- final DataContainerNode<?> dataContainerNode) {
+ private static Iterable<ChoiceNode> getChoiceNodes(final DataContainerNode<?> dataContainerNode) {
final LinkedList<ChoiceNode> choiceNodes = new LinkedList<ChoiceNode>();
return choiceNodes;
}
- private boolean isMatchingPredicate(final MapEntryNode mapEntryNode,
+ private static boolean isMatchingPredicate(final MapEntryNode mapEntryNode,
final Map<QName, Set<?>> allowedKeyValues) {
final NodeIdentifierWithPredicates identifier = mapEntryNode.getIdentifier();
return values;
}
- private Optional<NormalizedNode<?, ?>> findParentNode(
+ private static Optional<NormalizedNode<?, ?>> findParentNode(
final Optional<NormalizedNode<?, ?>> root, final YangInstanceIdentifier path) {
Optional<NormalizedNode<?, ?>> currentNode = root;
final Iterator<PathArgument> pathIterator = path.getPathArguments()
return Optional.absent();
}
- private Iterable<QNameWithPredicate> nextLevel(
- final Iterable<QNameWithPredicate> path) {
+ private static Iterable<QNameWithPredicate> nextLevel(final Iterable<QNameWithPredicate> path) {
return Iterables.skip(path, 1);
}
- private PathArgument toPathArgument(final QName qName) {
+ private static PathArgument toPathArgument(final QName qName) {
return YangInstanceIdentifier.of(qName).getLastPathArgument();
}
}
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
return childOp;
}
- @SuppressWarnings("rawtypes")
protected abstract NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final YangInstanceIdentifier.PathArgument compositeNode);
static abstract class DataContainerNormalizationOperation<T extends YangInstanceIdentifier.PathArgument> extends
*/
package org.opendaylight.yangtools.yang.data.impl.schema;
-import com.google.common.base.Preconditions;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
/**
}
void setResult(final NormalizedNode<?, ?> result) {
- Preconditions.checkState(!this.finished, "Result was already set.");
+ if (finished) {
+ throw new ResultAlreadySetException("Normalized Node result was already set.", this.result);
+ }
this.finished = true;
this.result = result;
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. 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.impl.schema;
+
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class ResultAlreadySetException extends IllegalStateException {
+ private static final long serialVersionUID = 1L;
+ private final NormalizedNode<?, ?> resultData;
+
+ public ResultAlreadySetException(final String message, final NormalizedNode<?, ?> resultData) {
+ this(message, resultData, null);
+ }
+
+ public ResultAlreadySetException(final String message, final NormalizedNode<?, ?> resultData, final Throwable cause) {
+ super(message, cause);
+ this.resultData = resultData;
+ }
+
+ public NormalizedNode<?, ?> getResultData() {
+ return resultData;
+ }
+}
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
public final class SchemaUtils {
private SchemaUtils() {
+ throw new UnsupportedOperationException();
}
/**
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform;
+import javax.annotation.Nullable;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
/**
* @param schema
* @return NormalizedNode as a result of parsing list of E elements with schema S
*/
+ @Nullable
N parse(Iterable<E> xmlDom, S schema);
}
* @param <E> type of elements to be parsed
*/
public abstract class AugmentationNodeBaseParser<E> extends
- BaseDispatcherParser<E,AugmentationNode, AugmentationSchema> {
+ BaseDispatcherParser<E, YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode, AugmentationSchema> {
+
+ public AugmentationNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode> buildingStrategy) {
+ super(buildingStrategy);
+ }
+
+ public AugmentationNodeBaseParser() {}
@Override
protected final DataContainerNodeBuilder<YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode> getBuilder(final AugmentationSchema schema) {
import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.annotation.Nullable;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.AttributesBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
/**
* Abstract(base) Parser for DataContainerNodes e.g. ContainerNode, AugmentationNode.
*/
-public abstract class BaseDispatcherParser<E, N extends DataContainerNode<?>, S>
- implements ToNormalizedNodeParser<E, N, S> {
+public abstract class BaseDispatcherParser<E, P extends YangInstanceIdentifier.PathArgument, N extends DataContainerNode<P>, S>
+ implements ExtensibleParser<P, E, N, S> {
+
+ private final BuildingStrategy<P, N> buildingStrategy;
+
+ public BaseDispatcherParser(final BuildingStrategy<P, N> buildingStrategy) {
+ this.buildingStrategy = buildingStrategy;
+ }
+
+ public BaseDispatcherParser() {
+ this.buildingStrategy = new SimpleBuildingStrategy<>();
+ }
/**
*
* @param schema
* @return New(empty) instance of a builder to build node identified by schema.
*/
- protected abstract DataContainerNodeBuilder<?, N> getBuilder(S schema);
+ protected abstract DataContainerNodeBuilder<P, N> getBuilder(S schema);
/**
*
*/
protected abstract NodeParserDispatcher<E> getDispatcher();
+ /**
+ * can return null only if you override ParsingStrategy and explicitely return null
+ * @param elements
+ * @param schema
+ * @return
+ */
+ @Nullable
@Override
public N parse(final Iterable<E> elements, final S schema) {
checkAtLeastOneNode(schema, elements);
- DataContainerNodeBuilder<?, N> containerBuilder = getBuilder(schema);
+ DataContainerNodeBuilder<P, N> containerBuilder = getBuilder(schema);
// Map child nodes to QName
LinkedListMultimap<QName, E> mappedChildElements = mapChildElements(elements);
Map<QName, ChoiceSchemaNode> mappedChoiceChildNodes = mapChildElementsFromChoices(schema);
LinkedListMultimap<ChoiceSchemaNode, E> choicesToElements = LinkedListMultimap.create();
+ Map<QName, String> attributes = getAttributes(elements.iterator().next());
+ if (containerBuilder instanceof AttributesBuilder) {
+ final int size = Iterables.size(elements);
+ Preconditions.checkArgument(size == 1, "Unexpected number of elements: %s, should be 1 for: %s",
+ size, schema);
+ ((AttributesBuilder<?>) containerBuilder).withAttributes(attributes);
+ }
+
+ //parse keys first
+ if (schema instanceof ListSchemaNode) {
+ for (QName qname : ((ListSchemaNode) schema).getKeyDefinition()) {
+ if(mappedChildElements.get(qname.withoutRevision()).isEmpty()) {
+ continue;
+ }
+
+ DataSchemaNode childSchema = getSchemaForChild(schema, qname);
+ List<E> childrenForQName = mappedChildElements.removeAll(qname.withoutRevision());
+
+
+ DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> optionalChildNode = getDispatcher()
+ .dispatchChildElement(childSchema, childrenForQName);
+ if (optionalChildNode != null) {
+ containerBuilder.withChild(optionalChildNode);
+ }
+ }
+ }
+
+ //stage attribues for strategy before going deeper in the recursion
+ buildingStrategy.prepareAttributes(attributes, containerBuilder);
+
// process Child nodes
for (QName childPartialQName : mappedChildElements.keySet()) {
DataSchemaNode childSchema = getSchemaForChild(schema, childPartialQName);
choicesToElements.putAll(choiceSchema, childrenForQName);
// Regular child nodes
} else {
- DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> builtChildNode = getDispatcher()
+ DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> optionalChildNode = getDispatcher()
.dispatchChildElement(childSchema, childrenForQName);
- containerBuilder.withChild(builtChildNode);
+ if (optionalChildNode != null) {
+ containerBuilder.withChild(optionalChildNode);
+ }
}
}
// TODO ordering is not preserved for choice and augment elements
for (ChoiceSchemaNode choiceSchema : choicesToElements.keySet()) {
- containerBuilder.withChild(getDispatcher().dispatchChildElement(choiceSchema,
- choicesToElements.get(choiceSchema)));
+ DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> optionalChild = getDispatcher()
+ .dispatchChildElement(choiceSchema, choicesToElements.get(choiceSchema));
+ if (optionalChild != null) {
+ containerBuilder.withChild(optionalChild);
+ }
}
for (AugmentationSchema augmentSchema : augmentsToElements.keySet()) {
Set<DataSchemaNode> realChildSchemas = getRealSchemasForAugment(schema, augmentSchema);
EffectiveAugmentationSchema augSchemaProxy = new EffectiveAugmentationSchema(augmentSchema, realChildSchemas);
- containerBuilder.withChild(getDispatcher().dispatchChildElement(augSchemaProxy, augmentsToElements.get(augmentSchema)));
+ DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> optionalChild = getDispatcher()
+ .dispatchChildElement(augSchemaProxy, augmentsToElements.get(augmentSchema));
+ if (optionalChild != null) {
+ containerBuilder.withChild(optionalChild);
+ }
}
- if (containerBuilder instanceof AttributesBuilder) {
- final int size = Iterables.size(elements);
- Preconditions.checkArgument(size == 1, "Unexpected number of elements: %s, should be 1 for: %s",
- size, schema);
- ((AttributesBuilder<?>) containerBuilder).withAttributes(getAttributes(elements.iterator().next()));
- }
+ return buildingStrategy.build(containerBuilder);
+ }
- return containerBuilder.build();
+ @Override
+ public BuildingStrategy<P, N> getBuildingStrategy() {
+ return buildingStrategy;
}
protected Map<QName, String> getAttributes(final E e) {
return true;
}
- private boolean isMarkedAs(final Map<QName, ?> mappedAugmentChildNodes, final QName qName) {
+ private static boolean isMarkedAs(final Map<QName, ?> mappedAugmentChildNodes, final QName qName) {
return mappedAugmentChildNodes.containsKey(qName);
}
Preconditions.checkArgument(!Iterables.isEmpty(childNodes),
"Node detected 0 times, should be at least 1, identified by: %s, found: %s", schema, childNodes);
}
+
+ public static class SimpleBuildingStrategy<P extends YangInstanceIdentifier.PathArgument, N extends DataContainerNode<P>> implements BuildingStrategy<P, N> {
+ @Override
+ public N build(final NormalizedNodeBuilder<P, ?, N> builder) {
+ return builder.build();
+ }
+
+ @Override
+ public void prepareAttributes(final Map<QName, String> attributes, final NormalizedNodeBuilder<P, ?, N> containerBuilder) {
+ // NOOP
+ }
+ }
}
*
* @param <E> type of elements to be parsed
*/
-public abstract class ChoiceNodeBaseParser<E> extends BaseDispatcherParser<E, ChoiceNode, ChoiceSchemaNode> {
+public abstract class ChoiceNodeBaseParser<E> extends BaseDispatcherParser<E, YangInstanceIdentifier.NodeIdentifier, ChoiceNode, ChoiceSchemaNode> {
+
+ protected ChoiceNodeBaseParser() {}
+
+ protected ChoiceNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, ChoiceNode> buildingStrategy) {
+ super(buildingStrategy);
+ }
@Override
protected final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ChoiceNode> getBuilder(
* @param <E> type of elements to be parsed
*/
public abstract class ContainerNodeBaseParser<E> extends
- BaseDispatcherParser<E, ContainerNode, ContainerSchemaNode> {
+ BaseDispatcherParser<E, YangInstanceIdentifier.NodeIdentifier, ContainerNode, ContainerSchemaNode> {
+
+ public ContainerNodeBaseParser() {}
+
+ public ContainerNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, ContainerNode> buildingStrategy) {
+ super(buildingStrategy);
+ }
@Override
protected final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> getBuilder(
@Override
protected abstract Map<QName, String> getAttributes(E e);
+
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. 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.impl.schema.transform.base.parser;
+
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
+
+/**
+ * Extensible parser allows its subclasses to customize the building process of normalized nodes
+ *
+ * @param <P>
+ * @param <E>
+ * @param <N>
+ * @param <S>
+ */
+public interface ExtensibleParser<P extends YangInstanceIdentifier.PathArgument, E, N extends NormalizedNode<P, ?>, S>
+ extends ToNormalizedNodeParser<E, N, S> {
+
+ /**
+ * Provide building strategy
+ */
+ BuildingStrategy<P, N> getBuildingStrategy();
+
+ /**
+ * Building strategy serves as a set of hooks into the parsing process.
+ *
+ * @param <P>
+ * @param <N>
+ */
+ interface BuildingStrategy<P extends YangInstanceIdentifier.PathArgument, N extends NormalizedNode<P, ?>> {
+
+ /**
+ * Build normalized node from its builder
+ *
+ * @param builder filled builder for node
+ * @return built normalized node or null if the node should not be built
+ */
+ @Nullable N build(NormalizedNodeBuilder<P, ?, N> builder);
+
+ /**
+ * Hook for subclasses to handle attributes associated with current node. This is called before the build method
+ * and allows subclasses to react to node's attributes e.g. modification operation
+ *
+ * @param attributes attributes for node
+ * @param containerBuilder builder created for node. Can be modified according to attributes e.g. remove attribute
+ */
+ void prepareAttributes(Map<QName, String> attributes, NormalizedNodeBuilder<P, ?, N> containerBuilder);
+ }
+}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
import java.util.Map;
-
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
-
/**
* Abstract(base) parser for LeafNodes, parses elements of type E.
*
* @param <E> type of elements to be parsed
*/
-public abstract class LeafNodeBaseParser<E> implements
- ToNormalizedNodeParser<E, LeafNode<?>, LeafSchemaNode> {
+public abstract class LeafNodeBaseParser<E> implements ExtensibleParser<NodeIdentifier, E, LeafNode<?>, LeafSchemaNode> {
+
+ private final BuildingStrategy<NodeIdentifier, LeafNode<?>> buildingStrategy;
+
+ public LeafNodeBaseParser() {
+ buildingStrategy = new SimpleLeafBuildingStrategy();
+ }
+ public LeafNodeBaseParser(final BuildingStrategy<NodeIdentifier, LeafNode<?>> buildingStrategy) {
+ this.buildingStrategy = buildingStrategy;
+ }
+
+ @SuppressWarnings("unchecked")
@Override
public final LeafNode<?> parse(Iterable<E> elements, LeafSchemaNode schema) {
final int size = Iterables.size(elements);
final E e = elements.iterator().next();
Object value = parseLeaf(e, schema);
- NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier,Object,LeafNode<Object>> leafBuilder = Builders.leafBuilder(schema);
+ NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
+ Builders.leafBuilder(schema);
leafBuilder.withAttributes(getAttributes(e));
- return leafBuilder.withValue(value).build();
+ final BuildingStrategy rawBuildingStrat = buildingStrategy;
+ return (LeafNode<?>) rawBuildingStrat.build(leafBuilder.withValue(value));
}
/**
* @return attributes mapped to QNames
*/
protected abstract Map<QName, String> getAttributes(E e);
+
+ @Override
+ public BuildingStrategy<NodeIdentifier, LeafNode<?>> getBuildingStrategy() {
+ return buildingStrategy;
+ }
+
+ public static class SimpleLeafBuildingStrategy implements BuildingStrategy<NodeIdentifier, LeafNode<?>> {
+ @Override
+ public LeafNode<?> build(final NormalizedNodeBuilder<NodeIdentifier, ?, LeafNode<?>> builder) {
+ return builder.build();
+ }
+
+ @Override
+ public void prepareAttributes(final Map<QName, String> attributes, final NormalizedNodeBuilder<NodeIdentifier, ?, LeafNode<?>> containerBuilder) {
+ // NOOP
+ }
+ }
}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
import java.util.Map;
-
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
-
/**
* Abstract(base) parser for LeafSetEntryNodes, parses elements of type E.
*
* @param <E> type of elements to be parsed
*/
-public abstract class LeafSetEntryNodeBaseParser<E> implements
- ToNormalizedNodeParser<E, LeafSetEntryNode<?>, LeafListSchemaNode> {
+public abstract class LeafSetEntryNodeBaseParser<E> implements ExtensibleParser<YangInstanceIdentifier.NodeWithValue, E, LeafSetEntryNode<?>, LeafListSchemaNode> {
+
+ private final BuildingStrategy<YangInstanceIdentifier.NodeWithValue, LeafSetEntryNode<?>> buildingStrategy;
+
+ public LeafSetEntryNodeBaseParser() {
+ buildingStrategy = new SimpleLeafSetEntryBuildingStrategy();
+ }
+ public LeafSetEntryNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.NodeWithValue, LeafSetEntryNode<?>> buildingStrategy) {
+ this.buildingStrategy = buildingStrategy;
+ }
+
+ @SuppressWarnings("unchecked")
@Override
- public final LeafSetEntryNode<Object> parse(Iterable<E> elements, LeafListSchemaNode schema) {
+ public final LeafSetEntryNode<?> parse(Iterable<E> elements, LeafListSchemaNode schema) {
final int size = Iterables.size(elements);
Preconditions.checkArgument(size == 1, "Xml elements mapped to leaf node illegal count: %s", size);
NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeWithValue, Object, LeafSetEntryNode<Object>> leafEntryBuilder = Builders
.leafSetEntryBuilder(schema);
leafEntryBuilder.withAttributes(getAttributes(e));
+ leafEntryBuilder.withValue(value);
+
+ final BuildingStrategy rawBuildingStrat = buildingStrategy;
+ return (LeafSetEntryNode<?>) rawBuildingStrat.build(leafEntryBuilder);
+ }
- return leafEntryBuilder.withValue(value).build();
+ @Override
+ public BuildingStrategy<NodeWithValue, LeafSetEntryNode<?>> getBuildingStrategy() {
+ return buildingStrategy;
}
/**
*/
protected abstract Map<QName, String> getAttributes(E e);
+ public static class SimpleLeafSetEntryBuildingStrategy implements BuildingStrategy<YangInstanceIdentifier.NodeWithValue, LeafSetEntryNode<?>> {
+
+ @Override
+ public LeafSetEntryNode<?> build(final NormalizedNodeBuilder<NodeWithValue, ?, LeafSetEntryNode<?>> builder) {
+ return builder.build();
+ }
+
+ @Override
+ public void prepareAttributes(final Map<QName, String> attributes, final NormalizedNodeBuilder<NodeWithValue, ?, LeafSetEntryNode<?>> containerBuilder) {
+ }
+ }
}
package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
import java.util.Collections;
-
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import java.util.Map;
import java.util.Set;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
* @param <E>
* type of elements to be parsed
*/
-public abstract class ListEntryNodeBaseParser<E, N extends DataContainerNode<?>> extends
- BaseDispatcherParser<E, N, ListSchemaNode> {
+public abstract class ListEntryNodeBaseParser<P extends YangInstanceIdentifier.PathArgument, E, N extends DataContainerNode<P>> extends
+ BaseDispatcherParser<E, P, N, ListSchemaNode> {
+
+ public ListEntryNodeBaseParser(final BuildingStrategy<P, N> buildingStrategy) {
+ super(buildingStrategy);
+ }
+
+ public ListEntryNodeBaseParser() {
+ }
@Override
protected final Set<DataSchemaNode> getRealSchemasForAugment(final ListSchemaNode schema, final AugmentationSchema augmentSchema) {
package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
import java.util.Collections;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
* type of elements to be parsed
*/
public abstract class ListNodeBaseParser<E, N extends NormalizedNode<?, ?>, O extends NormalizedNode<YangInstanceIdentifier.NodeIdentifier, ?>, S extends ListSchemaNode>
- implements ToNormalizedNodeParser<E, O, S> {
+ implements ExtensibleParser<YangInstanceIdentifier.NodeIdentifier, E, O, S> {
+
+ private final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, O> buildingStrategy;
+
+ public ListNodeBaseParser() {
+ buildingStrategy = new SimpleListNodeBuildingStrategy<>();
+ }
+
+ public ListNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, O> buildingStrategy) {
+ this.buildingStrategy = buildingStrategy;
+ }
@Override
- public final O parse(Iterable<E> childNodes, S schema) {
+ public O parse(Iterable<E> childNodes, S schema) {
CollectionNodeBuilder<N, O> listBuilder = provideBuilder(schema);
+
+ buildingStrategy.prepareAttributes(Collections.<QName, String>emptyMap(), listBuilder);
+
for (E childNode : childNodes) {
N listChild = getListEntryNodeParser().parse(Collections.singletonList(childNode), schema);
- listBuilder.withChild(listChild);
+ if (listChild != null) {
+ listBuilder.withChild(listChild);
+ }
}
- return listBuilder.build();
+ return buildingStrategy.build(listBuilder);
}
/**
* @return prepares builder which will contain entries of list according to concrete list type
*/
protected abstract CollectionNodeBuilder<N, O> provideBuilder(S schema);
+
+ @Override
+ public BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, O> getBuildingStrategy() {
+ return buildingStrategy;
+ }
+
+ public static class SimpleListNodeBuildingStrategy<O extends NormalizedNode<YangInstanceIdentifier.NodeIdentifier, ?>> implements BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, O> {
+ @Override
+ public O build(final NormalizedNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ?, O> builder) {
+ return builder.build();
+ }
+
+ @Override
+ public void prepareAttributes(final Map<QName, String> attributes, final NormalizedNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ?, O> containerBuilder) {
+ // NOOP
+ }
+ }
}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
*/
public abstract class MapNodeBaseParser<E> extends ListNodeBaseParser<E, MapEntryNode, MapNode, ListSchemaNode> {
+ public MapNodeBaseParser() {
+ }
+
+ public MapNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, MapNode> buildingStrategy) {
+ super(buildingStrategy);
+ }
+
protected CollectionNodeBuilder<MapEntryNode, MapNode> provideBuilder(ListSchemaNode schema) {
return Builders.mapBuilder(schema);
}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
*/
public abstract class OrderedListNodeBaseParser<E> extends
ListNodeBaseParser<E, MapEntryNode, OrderedMapNode, ListSchemaNode> {
+
+ public OrderedListNodeBaseParser() {
+ }
+
+ public OrderedListNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, OrderedMapNode> buildingStrategy) {
+ super(buildingStrategy);
+ }
+
@Override
protected CollectionNodeBuilder<MapEntryNode, OrderedMapNode> provideBuilder(ListSchemaNode schema) {
return Builders.orderedMapBuilder(schema);
}
+
}
*/
public abstract class UnkeyedListNodeBaseParser<E> extends
ListNodeBaseParser<E, UnkeyedListEntryNode, UnkeyedListNode, ListSchemaNode> {
+
+ public UnkeyedListNodeBaseParser(final BuildingStrategy<NodeIdentifier, UnkeyedListNode> buildingStrategy) {
+ super(buildingStrategy);
+ }
+
+ public UnkeyedListNodeBaseParser() {
+ }
+
@Override
protected CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> provideBuilder(ListSchemaNode schema) {
CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> listBuilder = Builders.unkeyedListBuilder();
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.LinkedListMultimap;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.AugmentationNodeBaseParser;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
import org.w3c.dom.Element;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.LinkedListMultimap;
-
final class AugmentationNodeDomParser extends AugmentationNodeBaseParser<Element> {
private final NodeParserDispatcher<Element> dispatcher;
this.strictParsing = strictParsing;
}
+ public AugmentationNodeDomParser(final BuildingStrategy<YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode> buildingStrategy,
+ final NodeParserDispatcher<Element> dispatcher, final boolean strictParsing) {
+ super(buildingStrategy);
+ this.dispatcher = Preconditions.checkNotNull(dispatcher);
+ this.strictParsing = strictParsing;
+ }
+
@Override
protected LinkedListMultimap<QName, Element> mapChildElements(Iterable<Element> elements) {
return DomUtils.mapChildElements(elements);
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.LinkedListMultimap;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ChoiceNodeBaseParser;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
import org.w3c.dom.Element;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.LinkedListMultimap;
-
final class ChoiceNodeDomParser extends ChoiceNodeBaseParser<Element> {
private final NodeParserDispatcher<Element> dispatcher;
- ChoiceNodeDomParser(NodeParserDispatcher<Element> dispatcher) {
+ ChoiceNodeDomParser(final NodeParserDispatcher<Element> dispatcher) {
+ this.dispatcher = Preconditions.checkNotNull(dispatcher);
+ }
+
+ ChoiceNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, ChoiceNode> buildingStrategy) {
+ super(buildingStrategy);
this.dispatcher = Preconditions.checkNotNull(dispatcher);
}
@Override
- protected LinkedListMultimap<QName, Element> mapChildElements(Iterable<Element> xml) {
+ protected LinkedListMultimap<QName, Element> mapChildElements(final Iterable<Element> xml) {
return DomUtils.mapChildElements(xml);
}
protected NodeParserDispatcher<Element> getDispatcher() {
return dispatcher;
}
+
}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.LinkedListMultimap;
import java.util.Map;
-
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ContainerNodeBaseParser;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
import org.w3c.dom.Element;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.LinkedListMultimap;
-
final class ContainerNodeDomParser extends ContainerNodeBaseParser<Element> {
private final NodeParserDispatcher<Element> dispatcher;
ContainerNodeDomParser(final NodeParserDispatcher<Element> dispatcher) {
this.dispatcher = Preconditions.checkNotNull(dispatcher);
- this.strictParsing = super.strictParsing();
+ strictParsing = super.strictParsing();
+ }
+
+ public ContainerNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final boolean strictParsing) {
+ this.dispatcher = dispatcher;
+ this.strictParsing = strictParsing;
}
- ContainerNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final boolean strictParsing) {
+ ContainerNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, ContainerNode> parsingStrategy, final boolean strictParsing) {
+ super(parsingStrategy);
this.dispatcher = Preconditions.checkNotNull(dispatcher);
this.strictParsing = strictParsing;
}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.BaseDispatcherParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ExtensibleParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.LeafNodeBaseParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.LeafSetEntryNodeBaseParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ListNodeBaseParser;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher;
import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
import org.w3c.dom.Element;
public final class DomToNormalizedNodeParserFactory implements ToNormalizedNodeParserFactory<Element> {
+
private final AugmentationNodeDomParser augmentationNodeParser;
private final ChoiceNodeDomParser choiceNodeParser;
private final ContainerNodeDomParser containerNodeParser;
augmentationNodeParser = new AugmentationNodeDomParser(dispatcher, strictParsing);
}
+ private DomToNormalizedNodeParserFactory(final XmlCodecProvider codecProvider, final SchemaContext schema,
+ final BuildingStrategyProvider buildingStratProvider, final boolean strictParsing) {
+ leafNodeParser = new LeafNodeDomParser(codecProvider, schema, buildingStratProvider.forLeaf());
+ leafSetEntryNodeParser = new LeafSetEntryNodeDomParser(codecProvider, schema, buildingStratProvider.forLeafSetEntry());
+
+ // no buildingStrategy for Augment (no use case for now)
+ leafSetNodeParser = new LeafSetNodeDomParser(leafSetEntryNodeParser);
+ // no buildingStrategy for anyXml (probably not necessary)
+ anyXmlNodeParser = new AnyXmlDomParser();
+
+ final NodeParserDispatcher<Element> dispatcher = new NodeParserDispatcher.BaseNodeParserDispatcher<Element>(this) {
+
+ };
+
+ containerNodeParser = new ContainerNodeDomParser(dispatcher, buildingStratProvider.forContainer(), strictParsing);
+ mapEntryNodeParser = new MapEntryNodeDomParser(dispatcher, buildingStratProvider.forMapEntry(), strictParsing);
+ mapNodeParser = new MapNodeDomParser(mapEntryNodeParser, buildingStratProvider.forMap());
+ orderedListNodeParser = new OrderedListNodeDomParser(mapEntryNodeParser, buildingStratProvider.forOrderedList());
+ unkeyedListEntryNodeParser = new UnkeyedListEntryNodeDomParser(buildingStratProvider.forUnkeyedListEntry(), dispatcher);
+ unkeyedListNodeParser = new UnkeyedListNodeDomParser(buildingStratProvider.forUnkeyedList(), unkeyedListEntryNodeParser);
+ choiceNodeParser = new ChoiceNodeDomParser(dispatcher, buildingStratProvider.forChoice());
+ // no buildingStrategy for Augment (no use case for now)
+ augmentationNodeParser = new AugmentationNodeDomParser(buildingStratProvider.forAugmentation(), dispatcher, strictParsing);
+ }
+
@Deprecated
private DomToNormalizedNodeParserFactory(final XmlCodecProvider codecProvider) {
leafNodeParser = new LeafNodeDomParser(codecProvider);
return new DomToNormalizedNodeParserFactory(codecProvider, schema, true);
}
+ public static DomToNormalizedNodeParserFactory getInstance(final XmlCodecProvider codecProvider, final SchemaContext schema,
+ final BuildingStrategyProvider buildingStratProvider) {
+ return new DomToNormalizedNodeParserFactory(codecProvider, schema, buildingStratProvider, true);
+ }
+
+ public static DomToNormalizedNodeParserFactory getInstance(final XmlCodecProvider codecProvider, final SchemaContext schema,
+ final BuildingStrategyProvider buildingStratProvider,
+ final boolean strictParsing) {
+ return new DomToNormalizedNodeParserFactory(codecProvider, schema, buildingStratProvider, strictParsing);
+ }
+
@Deprecated
public static DomToNormalizedNodeParserFactory getInstance(final XmlCodecProvider codecProvider) {
return new DomToNormalizedNodeParserFactory(codecProvider);
public ToNormalizedNodeParser<Element, AnyXmlNode, AnyXmlSchemaNode> getAnyXmlNodeParser() {
return anyXmlNodeParser;
}
+
+ /**
+ * Base provider of building strategies used for customizing parsing process
+ */
+ public static abstract class BuildingStrategyProvider {
+
+ protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,LeafNode<?>> forLeaf() {
+ return new LeafNodeBaseParser.SimpleLeafBuildingStrategy();
+ }
+
+ protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeWithValue,LeafSetEntryNode<?>> forLeafSetEntry() {
+ return new LeafSetEntryNodeBaseParser.SimpleLeafSetEntryBuildingStrategy();
+ }
+
+ protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,ContainerNode> forContainer() {
+ return new BaseDispatcherParser.SimpleBuildingStrategy<>();
+ }
+
+ protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifierWithPredicates,MapEntryNode> forMapEntry() {
+ return new BaseDispatcherParser.SimpleBuildingStrategy<>();
+ }
+
+ protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,MapNode> forMap() {
+ return new ListNodeBaseParser.SimpleListNodeBuildingStrategy<>();
+ }
+
+ protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,OrderedMapNode> forOrderedList() {
+ return new ListNodeBaseParser.SimpleListNodeBuildingStrategy<>();
+ }
+
+ protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,UnkeyedListEntryNode> forUnkeyedListEntry() {
+ return new BaseDispatcherParser.SimpleBuildingStrategy<>();
+ }
+
+ protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,UnkeyedListNode> forUnkeyedList() {
+ return new ListNodeBaseParser.SimpleListNodeBuildingStrategy<>();
+ }
+
+ protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,ChoiceNode> forChoice() {
+ return new BaseDispatcherParser.SimpleBuildingStrategy<>();
+ }
+
+ public ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode> forAugmentation() {
+ return new BaseDispatcherParser.SimpleBuildingStrategy<>();
+ }
+ }
}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
+import com.google.common.base.Preconditions;
import java.util.Map;
-
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.LeafNodeBaseParser;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.w3c.dom.Element;
-import com.google.common.base.Preconditions;
-
final class LeafNodeDomParser extends LeafNodeBaseParser<Element> {
private final XmlCodecProvider codecProvider;
this.codecProvider = Preconditions.checkNotNull(codecProvider);
}
+ LeafNodeDomParser(XmlCodecProvider codecProvider, final SchemaContext schema, final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, LeafNode<?>> strategy) {
+ super(strategy);
+ this.ctx = schema;
+ this.codecProvider = Preconditions.checkNotNull(codecProvider);
+ }
+
@Deprecated
LeafNodeDomParser(XmlCodecProvider codecProvider) {
this(codecProvider, null);
protected Map<QName, String> getAttributes(Element element) {
return DomUtils.toAttributes(element.getAttributes());
}
+
}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
+import com.google.common.base.Preconditions;
import java.util.Map;
-
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.LeafSetEntryNodeBaseParser;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.w3c.dom.Element;
-import com.google.common.base.Preconditions;
-
final class LeafSetEntryNodeDomParser extends LeafSetEntryNodeBaseParser<Element> {
private final XmlCodecProvider codecProvider;
private final SchemaContext ctx;
- LeafSetEntryNodeDomParser(XmlCodecProvider codecProvider, final SchemaContext schema) {
- ctx = schema;
+ LeafSetEntryNodeDomParser(final XmlCodecProvider codecProvider, final SchemaContext schema) {
+ this.ctx = schema;
+ this.codecProvider = Preconditions.checkNotNull(codecProvider);
+ }
+
+ LeafSetEntryNodeDomParser(final XmlCodecProvider codecProvider, final SchemaContext schema, final BuildingStrategy<YangInstanceIdentifier.NodeWithValue, LeafSetEntryNode<?>> strategy) {
+ super(strategy);
+ this.ctx = schema;
this.codecProvider = Preconditions.checkNotNull(codecProvider);
}
protected Map<QName, String> getAttributes(Element element) {
return DomUtils.toAttributes(element.getAttributes());
}
+
}
import com.google.common.collect.LinkedListMultimap;
import java.util.Map;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ListEntryNodeBaseParser;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
import org.w3c.dom.Element;
-abstract class ListEntryNodeDomParser<N extends DataContainerNode<?>> extends ListEntryNodeBaseParser<Element, N> {
+abstract class ListEntryNodeDomParser<P extends YangInstanceIdentifier.PathArgument, N extends DataContainerNode<P>> extends ListEntryNodeBaseParser<P, Element, N> {
private final NodeParserDispatcher<Element> dispatcher;
this.dispatcher = Preconditions.checkNotNull(dispatcher);
}
+ ListEntryNodeDomParser(final BuildingStrategy<P, N> buildingStrategy, final NodeParserDispatcher<Element> dispatcher) {
+ super(buildingStrategy);
+ this.dispatcher = dispatcher;
+ }
+
@Override
protected LinkedListMultimap<QName, Element> mapChildElements(Iterable<Element> elements) {
return DomUtils.mapChildElementsForSingletonNode(elements.iterator().next());
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.w3c.dom.Element;
-final class MapEntryNodeDomParser extends ListEntryNodeDomParser<MapEntryNode> {
+final class MapEntryNodeDomParser extends ListEntryNodeDomParser<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> {
private final boolean strictParsing;
MapEntryNodeDomParser(final NodeParserDispatcher<Element> dispatcher) {
super(dispatcher);
+ // TODO strict parsing attribute should be injected into superclass via a constructor
+ // WIth current approach (getter) we have to call super.strictParsing in constructor and cannot reuse constructors
this.strictParsing = super.strictParsing();
}
this.strictParsing = strictParsing;
}
+ MapEntryNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final BuildingStrategy<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> strategy,
+ final boolean strictParsing) {
+ super(strategy, dispatcher);
+ this.strictParsing = strictParsing;
+ }
+
@Override
protected final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> getBuilder(
ListSchemaNode schema) {
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.MapNodeBaseParser;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
private final MapEntryNodeDomParser mapEntryParser;
- MapNodeDomParser(MapEntryNodeDomParser mapEntryParser) {
+ MapNodeDomParser(final MapEntryNodeDomParser mapEntryParser) {
+ this.mapEntryParser = mapEntryParser;
+ }
+
+ MapNodeDomParser(MapEntryNodeDomParser mapEntryParser, final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, MapNode> strategy) {
+ super(strategy);
this.mapEntryParser = mapEntryParser;
}
protected ToNormalizedNodeParser<Element, MapEntryNode, ListSchemaNode> getListEntryNodeParser() {
return mapEntryParser;
}
+
}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.OrderedListNodeBaseParser;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
private final MapEntryNodeDomParser mapEntryNodeParser;
- OrderedListNodeDomParser(MapEntryNodeDomParser mapEntryNodeParser) {
+ OrderedListNodeDomParser(final MapEntryNodeDomParser mapEntryNodeParser) {
+ this.mapEntryNodeParser = mapEntryNodeParser;
+ }
+
+ OrderedListNodeDomParser(MapEntryNodeDomParser mapEntryNodeParser, final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, OrderedMapNode> strategy) {
+ super(strategy);
this.mapEntryNodeParser = mapEntryNodeParser;
}
protected ToNormalizedNodeParser<Element, MapEntryNode, ListSchemaNode> getListEntryNodeParser() {
return mapEntryNodeParser;
}
+
}
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.w3c.dom.Element;
-final class UnkeyedListEntryNodeDomParser extends ListEntryNodeDomParser<UnkeyedListEntryNode> {
+final class UnkeyedListEntryNodeDomParser extends ListEntryNodeDomParser<YangInstanceIdentifier.NodeIdentifier, UnkeyedListEntryNode> {
UnkeyedListEntryNodeDomParser(final NodeParserDispatcher<Element> dispatcher) {
super(dispatcher);
}
+ UnkeyedListEntryNodeDomParser(final BuildingStrategy<NodeIdentifier, UnkeyedListEntryNode> buildingStrategy, final NodeParserDispatcher<Element> dispatcher) {
+ super(buildingStrategy, dispatcher);
+ }
+
@Override
protected final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifier, UnkeyedListEntryNode> getBuilder(
ListSchemaNode schema) {
*/
package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.UnkeyedListNodeBaseParser;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
this.unkeyedListEntryNodeParser = unkeyedListEntryNodeParser;
}
+ UnkeyedListNodeDomParser(final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, UnkeyedListNode> buildingStrategy, final UnkeyedListEntryNodeDomParser unkeyedListEntryNodeParser) {
+ super(buildingStrategy);
+ this.unkeyedListEntryNodeParser = unkeyedListEntryNodeParser;
+ }
+
@Override
protected ToNormalizedNodeParser<Element, UnkeyedListEntryNode, ListSchemaNode> getListEntryNodeParser() {
return unkeyedListEntryNodeParser;
}
+
}
return Verify.verifyNotNull(mod.getModificationType(), "Node %s does not have resolved modification type", mod);
}
- private Optional<NormalizedNode<?, ?>> optionalData(final TreeNode meta) {
+ private static Optional<NormalizedNode<?, ?>> optionalData(final TreeNode meta) {
if (meta != null) {
return Optional.<NormalizedNode<?,?>>of(meta.getData());
} else {
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. 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.impl.schema.tree;
+
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.Iterator;
+
+abstract class AbstractReadyIterator {
+ final Iterator<ModifiedNode> children;
+ final ModifiedNode node;
+
+ private AbstractReadyIterator(final ModifiedNode node, final Iterator<ModifiedNode> children) {
+ this.children = Preconditions.checkNotNull(children);
+ this.node = Preconditions.checkNotNull(node);
+ }
+
+ static AbstractReadyIterator create(final ModifiedNode root) {
+ return new RootReadyIterator(root, root.getChildren().iterator());
+ }
+
+ final AbstractReadyIterator process() {
+ // Walk all child nodes and remove any children which have not
+ // been modified. If a child
+ while (children.hasNext()) {
+ final ModifiedNode child = children.next();
+ final Collection<ModifiedNode> grandChildren = child.getChildren();
+ if (grandChildren.isEmpty()) {
+ child.seal();
+ if (child.getOperation() == LogicalOperation.NONE) {
+ children.remove();
+ }
+ } else {
+ return new NestedReadyIterator(this, child, grandChildren.iterator());
+ }
+ }
+
+ node.seal();
+
+ // Remove from parent if we have one and this is a no-op
+ if (node.getOperation() == LogicalOperation.NONE) {
+ removeFromParent();
+ }
+ return getParent();
+ }
+
+ abstract AbstractReadyIterator getParent();
+ abstract void removeFromParent();
+
+ private static final class NestedReadyIterator extends AbstractReadyIterator {
+ private final AbstractReadyIterator parent;
+
+ private NestedReadyIterator(final AbstractReadyIterator parent, final ModifiedNode node, final Iterator<ModifiedNode> children) {
+ super(node, children);
+ this.parent = Preconditions.checkNotNull(parent);
+ }
+
+ @Override
+ AbstractReadyIterator getParent() {
+ return parent;
+ }
+
+ @Override
+ void removeFromParent() {
+ parent.children.remove();
+ }
+ }
+
+ private static final class RootReadyIterator extends AbstractReadyIterator {
+ private RootReadyIterator(final ModifiedNode node, final Iterator<ModifiedNode> children) {
+ super(node, children);
+ }
+
+ @Override
+ AbstractReadyIterator getParent() {
+ return null;
+ }
+
+ @Override
+ void removeFromParent() {
+ // No-op, since root node cannot be removed
+ }
+ }
+
+}
\ No newline at end of file
ModifiedNode modification = rootNode;
int i = 1;
- for(PathArgument pathArg : path.getPathArguments()) {
+ for (PathArgument pathArg : path.getPathArguments()) {
Optional<ModificationApplyOperation> potential = operation.getChild(pathArg);
if (!potential.isPresent()) {
throw new IllegalArgumentException(String.format("Child %s is not present in schema tree.",
return OperationWithModification.from(operation, modification);
}
- @Override
- public void ready() {
- final boolean wasRunning = UPDATER.compareAndSet(this, 0, 1);
- Preconditions.checkState(wasRunning, "Attempted to seal an already-sealed Data Tree.");
-
- rootNode.seal();
- }
-
private void checkSealed() {
Preconditions.checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed.");
}
applyNode(cursor, child);
}
}
+
+ @Override
+ public void ready() {
+ final boolean wasRunning = UPDATER.compareAndSet(this, 0, 1);
+ Preconditions.checkState(wasRunning, "Attempted to seal an already-sealed Data Tree.");
+
+ AbstractReadyIterator current = AbstractReadyIterator.create(rootNode);
+ do {
+ current = current.process();
+ } while (current != null);
+ }
+
}
this.maxElements = maxElements;
}
- static final SchemaAwareApplyOperation from(final SchemaAwareApplyOperation delegate, final DataSchemaNode schema) {
+ static SchemaAwareApplyOperation from(final SchemaAwareApplyOperation delegate, final DataSchemaNode schema) {
final ConstraintDefinition constraints = schema.getConstraints();
if (constraints == null || (constraints.getMinElements() == null && constraints.getMaxElements() == null)) {
return delegate;
}
+ private static int findChildrenBefore(final Optional<TreeNode> current) {
+ if (current.isPresent()) {
+ return numOfChildrenFromValue(current.get().getData());
+ } else {
+ return 0;
+ }
+ }
+
+ private static int findChildrenAfter(final ModifiedNode modification) {
+ if (modification.getWrittenValue() != null) {
+ return numOfChildrenFromValue(modification.getWrittenValue());
+ } else {
+ return 0;
+ }
+ }
+
private void checkMinMaxElements(final YangInstanceIdentifier path, final NodeModification nodeMod,
final Optional<TreeNode> current) throws DataValidationFailedException {
if (!(nodeMod instanceof ModifiedNode)) {
return;
}
final ModifiedNode modification = (ModifiedNode) nodeMod;
- final int childrenBefore;
- if (current.isPresent()) {
- childrenBefore = numOfChildrenFromValue(current.get().getData());
- } else {
- childrenBefore = 0;
- }
- final int childrenAfter;
- if (modification.getWrittenValue() != null) {
- childrenAfter = numOfChildrenFromValue(modification.getWrittenValue());
- } else {
- childrenAfter = 0;
- }
+ final int childrenBefore = findChildrenBefore(current);
+
+ final int childrenAfter = findChildrenAfter(modification);
final int childrenTotal = childrenBefore + childrenAfter + numOfChildrenFromChildMods(modification, current);
if (minElements != null && minElements > childrenTotal) {
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.annotation.Nonnull;
}
/**
- * Seal the modification node and prune any children which has not been
- * modified.
+ * Seal the modification node.
*/
void seal() {
clearSnapshot();
- // Walk all child nodes and remove any children which have not
- // been modified.
- final Iterator<ModifiedNode> it = children.values().iterator();
- while (it.hasNext()) {
- final ModifiedNode child = it.next();
- child.seal();
-
- if (child.operation == LogicalOperation.NONE) {
- it.remove();
- }
- }
-
// A TOUCH node without any children is a no-op
if (operation == LogicalOperation.TOUCH && children.isEmpty()) {
updateOperationType(LogicalOperation.NONE);
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-
import com.google.common.base.Optional;
import com.google.common.collect.Maps;
import java.io.ByteArrayOutputStream;
return targetBaseType;
}
- private Map<String, String> mapPrefixed(final Iterable<Map.Entry<URI, String>> prefixes) {
+ private static Map<String, String> mapPrefixed(final Iterable<Map.Entry<URI, String>> prefixes) {
final Map<String, String> mappedPrefixes = Maps.newHashMap();
for (final Map.Entry<URI, String> prefix : prefixes) {
mappedPrefixes.put(prefix.getKey().toString(), prefix.getValue());
return mappedPrefixes;
}
- private QName getAttrQName(final String namespace, final String revision, final String localName, final Optional<String> prefix) {
-
- if(prefix.isPresent()) {
+ private static QName getAttrQName(final String namespace, final String revision, final String localName, final Optional<String> prefix) {
+ if (prefix.isPresent()) {
final QName moduleQName = QName.create(namespace, revision, "module");
final QNameModule module = QNameModule.create(moduleQName.getNamespace(), moduleQName.getRevision());
return QName.create(module, localName);
return null;
}
- private LeafrefTypeDefinition findLeafrefType(final LeafSchemaNode schemaNode) {
+ private static LeafrefTypeDefinition findLeafrefType(final LeafSchemaNode schemaNode) {
final TypeDefinition<?> type = schemaNode.getType();
if (type instanceof LeafrefTypeDefinition) {
return (LeafrefTypeDefinition)type;
// .build());
}
- private AugmentationSchema getAugmentationSchemaForChild(final ContainerSchemaNode containerNode, final QName qName) {
+ private static AugmentationSchema getAugmentationSchemaForChild(final ContainerSchemaNode containerNode, final QName qName) {
for (AugmentationSchema augmentationSchema : containerNode.getAvailableAugmentations()) {
if (augmentationSchema.getDataChildByName(qName) != null) {
return augmentationSchema;
throw new IllegalStateException("Unable to find child augmentation in " + containerNode);
}
- private YangInstanceIdentifier.NodeWithValue getNodeWithValueIdentifier(final String localName, final Object value) {
+ private static YangInstanceIdentifier.NodeWithValue getNodeWithValueIdentifier(final String localName, final Object value) {
return new YangInstanceIdentifier.NodeWithValue(getQName(localName), value);
}
- private QName getQName(final String localName) {
+ private static QName getQName(final String localName) {
String namespace = "namespace";
return new QName(URI.create(namespace), localName);
}
- private YangInstanceIdentifier.NodeIdentifier getNodeIdentifier(final String localName) {
+ private static YangInstanceIdentifier.NodeIdentifier getNodeIdentifier(final String localName) {
return new YangInstanceIdentifier.NodeIdentifier(getQName(localName));
}
XML_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
}
- private void writeNormalizedNode(final NormalizedNode<?, ?> normalized, final DOMResult result, final SchemaPath schemaPath, final SchemaContext context)
+ private static void writeNormalizedNode(final NormalizedNode<?, ?> normalized, final DOMResult result, final SchemaPath schemaPath, final SchemaContext context)
throws IOException, XMLStreamException {
NormalizedNodeWriter normalizedNodeWriter = null;
NormalizedNodeStreamWriter normalizedNodeStreamWriter = null;
}
}
- private Document loadDocument(final String xmlPath) throws Exception {
+ private static Document loadDocument(final String xmlPath) throws IOException, SAXException {
final InputStream resourceAsStream = NormalizedDataBuilderTest.class.getResourceAsStream(xmlPath);
final Document currentConfigElement = readXmlToDocument(resourceAsStream);
BUILDERFACTORY = factory;
}
- private Document readXmlToDocument(final InputStream xmlContent) throws IOException, SAXException {
+ private static Document readXmlToDocument(final InputStream xmlContent) throws IOException, SAXException {
final DocumentBuilder dBuilder;
try {
dBuilder = BUILDERFACTORY.newDocumentBuilder();
inMemoryDataTree.setSchemaContext(schemaContext);
}
- private ContainerNode createFooTestContainerNode() {
+ private static ContainerNode createFooTestContainerNode() {
return ImmutableContainerNodeBuilder
.create()
.withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME))
.withChild(FOO_NODE).build()).build();
}
- private ContainerNode createBarTestContainerNode() {
+ private static ContainerNode createBarTestContainerNode() {
return ImmutableContainerNodeBuilder
.create()
.withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME))
import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
-
+import com.google.common.base.Optional;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import com.google.common.base.Optional;
-
-
-
-
-
-
/**
*
* Schema structure of document is
}
- private ContainerNode createTestContainer() {
+ private static ContainerNode createTestContainer() {
return ImmutableContainerNodeBuilder
.create()
.withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
}
- private ContainerNode createTestContainer() {
+ private static ContainerNode createTestContainer() {
return ImmutableContainerNodeBuilder
.create()
.withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME))
Document currentConfigElement = readXmlToDocument(resourceAsStream);
Preconditions.checkNotNull(currentConfigElement);
- return Optional.of(DomToNormalizedNodeParserFactory.getInstance(DomUtils.defaultValueCodecProvider(), schema).getContainerNodeParser().parse(
+ return Optional.fromNullable(DomToNormalizedNodeParserFactory.getInstance(DomUtils.defaultValueCodecProvider(), schema).getContainerNodeParser().parse(
Collections.singletonList(currentConfigElement.getDocumentElement()), containerNode));
}
return result;
}
+ private boolean checkQname(AnyXmlEffectiveStatementImpl other) {
+ if (qname == null) {
+ if (other.qname != null) {
+ return false;
+ }
+ } else if (!qname.equals(other.qname)) {
+ return false;
+ }
+ return true;
+ }
+
+ private boolean checkPath(AnyXmlEffectiveStatementImpl other) {
+ if (path == null) {
+ if (other.path != null) {
+ return false;
+ }
+ } else if (!path.equals(other.path)) {
+ return false;
+ }
+ return true;
+ }
+
+ private boolean checkObject(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ return true;
+ }
+
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
+
+ if (!checkObject(obj)) {
+ return false;
}
+
AnyXmlEffectiveStatementImpl other = (AnyXmlEffectiveStatementImpl) obj;
- if (qname == null) {
- if (other.qname != null) {
- return false;
- }
- } else if (!qname.equals(other.qname)) {
+
+ if (!checkQname(other)) {
return false;
}
- if (path == null) {
- if (other.path != null) {
- return false;
- }
- } else if (!path.equals(other.path)) {
+
+ if (!checkPath(other)) {
return false;
}
+
return true;
}
return sb.toString();
}
-}
\ No newline at end of file
+}