X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fblueprint%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fblueprint%2Fext%2FBindingContext.java;h=86d7c45379019bd1d028a3e7b90d8a76c5da2a89;hb=58cc305ac41b7edd861611c95cf3a5faa48a7495;hp=91899301aa6879c3ce82a390b7757d7546540ba5;hpb=821944277049bbb3949021626844ef7a80101f70;p=controller.git diff --git a/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/ext/BindingContext.java b/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/ext/BindingContext.java index 91899301aa..86d7c45379 100644 --- a/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/ext/BindingContext.java +++ b/opendaylight/blueprint/src/main/java/org/opendaylight/controller/blueprint/ext/BindingContext.java @@ -7,25 +7,39 @@ */ package org.opendaylight.controller.blueprint.ext; -import com.google.common.base.Preconditions; +import static com.google.common.base.Preconditions.checkArgument; + import com.google.common.base.Strings; +import com.google.common.collect.Iterables; +import java.io.IOException; import java.lang.reflect.InvocationTargetException; -import java.util.Collections; -import java.util.List; +import java.net.URISyntaxException; +import java.util.Set; +import javax.xml.stream.XMLStreamException; +import javax.xml.transform.dom.DOMSource; +import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections; import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.Identifiable; -import org.opendaylight.yangtools.yang.binding.Identifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.binding.util.BindingReflections; +import org.opendaylight.yangtools.yang.binding.Key; +import org.opendaylight.yangtools.yang.binding.KeyAware; +import org.opendaylight.yangtools.yang.binding.contract.Naming; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.schema.MapNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream; import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; -import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.impl.schema.NormalizationResultHolder; import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.ListSchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaTreeInference; +import org.opendaylight.yangtools.yang.model.api.stmt.KeyEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement; import org.osgi.service.blueprint.container.ComponentDefinitionException; import org.w3c.dom.Element; +import org.xml.sax.SAXException; /** * Base class to abstract binding type-specific behavior. @@ -33,10 +47,9 @@ import org.w3c.dom.Element; * @author Thomas Pantelis (originally; re-factored by Michael Vorburger.ch) */ public abstract class BindingContext { - - public static BindingContext create(String logName, Class klass, - String appConfigListKeyValue) { - if (Identifiable.class.isAssignableFrom(klass)) { + public static BindingContext create(final String logName, final Class klass, + final String appConfigListKeyValue) { + if (KeyAware.class.isAssignableFrom(klass)) { // The binding class corresponds to a yang list. if (Strings.isNullOrEmpty(appConfigListKeyValue)) { throw new ComponentDefinitionException(String.format( @@ -59,12 +72,12 @@ public abstract class BindingContext { } public final InstanceIdentifier appConfigPath; - public final Class appConfigBindingClass; + public final Class appConfigBindingClass; public final Class schemaType; public final QName bindingQName; - private BindingContext(final Class appConfigBindingClass, - final InstanceIdentifier appConfigPath, final Class schemaType) { + private BindingContext(final Class appConfigBindingClass, final InstanceIdentifier appConfigPath, + final Class schemaType) { this.appConfigBindingClass = appConfigBindingClass; this.appConfigPath = appConfigPath; this.schemaType = schemaType; @@ -72,10 +85,18 @@ public abstract class BindingContext { bindingQName = BindingReflections.findQName(appConfigBindingClass); } - public abstract NormalizedNode parseDataElement(Element element, DataSchemaNode dataSchema, - DomToNormalizedNodeParserFactory parserFactory); + public NormalizedNode parseDataElement(final Element element, final SchemaTreeInference dataSchema) + throws XMLStreamException, IOException, SAXException, URISyntaxException { + final NormalizationResultHolder resultHolder = new NormalizationResultHolder(); + final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder); + final XmlParserStream xmlParser = XmlParserStream.create(writer, dataSchema); + xmlParser.traverse(new DOMSource(element)); + + final NormalizedNode result = resultHolder.getResult().data(); + return result instanceof MapNode mapNode ? mapNode.body().iterator().next() : result; + } - public abstract NormalizedNode newDefaultNode(DataSchemaNode dataSchema); + public abstract NormalizedNode newDefaultNode(SchemaTreeInference dataSchema); /** * BindingContext implementation for a container binding. @@ -83,21 +104,14 @@ public abstract class BindingContext { private static class ContainerBindingContext extends BindingContext { @SuppressWarnings("unchecked") ContainerBindingContext(final Class appConfigBindingClass) { - super((Class) appConfigBindingClass, - InstanceIdentifier.create((Class) appConfigBindingClass), ContainerSchemaNode.class); + super(appConfigBindingClass, InstanceIdentifier.create((Class) appConfigBindingClass), + ContainerSchemaNode.class); } @Override - public NormalizedNode newDefaultNode(final DataSchemaNode dataSchema) { + public NormalizedNode newDefaultNode(final SchemaTreeInference dataSchema) { return ImmutableNodes.containerNode(bindingQName); } - - @Override - public NormalizedNode parseDataElement(final Element element, final DataSchemaNode dataSchema, - final DomToNormalizedNodeParserFactory parserFactory) { - return parserFactory.getContainerNodeParser().parse(Collections.singletonList(element), - (ContainerSchemaNode)dataSchema); - } } /** @@ -115,30 +129,27 @@ public abstract class BindingContext { } @SuppressWarnings({ "rawtypes", "unchecked" }) - private static ListBindingContext newInstance(final Class bindingClass, + static ListBindingContext newInstance(final Class bindingClass, final String listKeyValue) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { // We assume the yang list key type is string. - Identifier keyInstance = (Identifier) bindingClass.getMethod("getKey").getReturnType() - .getConstructor(String.class).newInstance(listKeyValue); + Key keyInstance = (Key) bindingClass.getMethod(Naming.KEY_AWARE_KEY_NAME) + .getReturnType().getConstructor(String.class).newInstance(listKeyValue); InstanceIdentifier appConfigPath = InstanceIdentifier.builder((Class)bindingClass, keyInstance).build(); return new ListBindingContext(bindingClass, appConfigPath, listKeyValue); } @Override - public NormalizedNode newDefaultNode(final DataSchemaNode dataSchema) { + public NormalizedNode newDefaultNode(final SchemaTreeInference dataSchema) { + final SchemaTreeEffectiveStatement stmt = Iterables.getLast(dataSchema.statementPath()); + // We assume there's only one key for the list. - List keys = ((ListSchemaNode)dataSchema).getKeyDefinition(); - Preconditions.checkArgument(keys.size() == 1, "Expected only 1 key for list %s", appConfigBindingClass); - QName listKeyQName = keys.get(0); - return ImmutableNodes.mapEntryBuilder(bindingQName, listKeyQName, appConfigListKeyValue).build(); - } + final Set keys = stmt.findFirstEffectiveSubstatementArgument(KeyEffectiveStatement.class) + .orElseThrow(); - @Override - public NormalizedNode parseDataElement(final Element element, final DataSchemaNode dataSchema, - final DomToNormalizedNodeParserFactory parserFactory) { - return parserFactory.getMapEntryNodeParser().parse(Collections.singletonList(element), - (ListSchemaNode)dataSchema); + checkArgument(keys.size() == 1, "Expected only 1 key for list %s", appConfigBindingClass); + QName listKeyQName = keys.iterator().next(); + return ImmutableNodes.mapEntryBuilder(bindingQName, listKeyQName, appConfigListKeyValue).build(); } } }