2 * Copyright (c) 2019 PANTHEON.tech s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.rcf8528.data.util;
10 import com.google.common.annotations.Beta;
11 import java.io.IOException;
13 import java.util.Map.Entry;
14 import java.util.Optional;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.opendaylight.yangtools.concepts.AbstractIdentifiable;
17 import org.opendaylight.yangtools.rfc8528.data.api.MountPointChild;
18 import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext;
19 import org.opendaylight.yangtools.rfc8528.data.api.MountPointContextFactory;
20 import org.opendaylight.yangtools.rfc8528.data.api.MountPointIdentifier;
21 import org.opendaylight.yangtools.rfc8528.data.api.YangLibraryConstants.ContainerName;
22 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
23 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
24 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
25 import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
30 * Abstract base class for dynamic resolvers.
33 // FIXME: 7.0.0: consider integrating into AbstractMountPointContextFactory
34 public abstract class AbstractDynamicMountPointContextFactory extends AbstractIdentifiable<MountPointIdentifier>
35 implements MountPointContextFactory {
36 private static final Logger LOG = LoggerFactory.getLogger(AbstractDynamicMountPointContextFactory.class);
38 protected AbstractDynamicMountPointContextFactory(final @NonNull MountPointIdentifier mountId) {
43 public final MountPointContext createContext(final Map<ContainerName, MountPointChild> libraryContainers,
44 final MountPointChild schemaMounts) throws YangParserException {
46 for (Entry<ContainerName, MountPointChild> entry : libraryContainers.entrySet()) {
47 // Context for the specific code word
48 final Optional<EffectiveModelContext> optLibContext = findSchemaForLibrary(entry.getKey());
49 if (optLibContext.isEmpty()) {
50 LOG.debug("YANG Library context for mount point {} container {} not found", getIdentifier(),
55 final NormalizedNode<?, ?> libData;
57 libData = entry.getValue().normalizeTo(optLibContext.get());
58 } catch (IOException e) {
59 throw new YangParserException("Failed to interpret yang-library data", e);
61 if (!(libData instanceof ContainerNode)) {
62 throw new YangParserException("Invalid yang-library non-container " + libData);
65 final EffectiveModelContext schemaContext = bindLibrary(entry.getKey(), (ContainerNode) libData);
66 if (schemaMounts == null) {
67 return new EmptyMountPointContext(schemaContext);
70 final NormalizedNode<?, ?> mountData;
72 mountData = schemaMounts.normalizeTo(schemaContext);
73 } catch (IOException e) {
74 throw new YangParserException("Failed to interpret schema-mount data", e);
76 if (!(mountData instanceof ContainerNode)) {
77 throw new YangParserException("Invalid schema-mount non-container " + mountData);
80 return createMountPointContext(schemaContext, (ContainerNode) mountData);
83 throw new YangParserException("Failed to interpret " + libraryContainers);
86 protected abstract @NonNull MountPointContext createMountPointContext(@NonNull EffectiveModelContext schemaContext,
87 @NonNull ContainerNode mountData);
90 * Assemble the MountPointContext for specified normalized YANG Library top-level container.
92 * @param containerName Top-level YANG Library container
93 * @param libData Top-level YANG Library container data
94 * @return An assembled MountPointContext
95 * @throws NullPointerException if container is null
96 * @throws YangParserException if the schema context cannot be assembled
98 protected abstract @NonNull EffectiveModelContext bindLibrary(@NonNull ContainerName containerName,
99 @NonNull ContainerNode libData) throws YangParserException;
102 * Return the schema in which YANG Library container content should be interpreted.
105 * Note this schema is not guaranteed to contain any augmentations, hence parsing could fail.
107 * @param containerName Top-level YANG Library container name
108 * @return The LibraryContext to use when interpreting the specified YANG Library container, or empty
109 * @throws NullPointerException if container is null
111 protected abstract Optional<EffectiveModelContext> findSchemaForLibrary(@NonNull ContainerName containerName);