5f4c79f478b28a1f7410996907be092d4aff7621
[mdsal.git] / yanglib / mdsal-yanglib-rfc8525 / src / main / java / org / opendaylight / mdsal / yanglib / rfc8525 / YangLibraryContentBuilderImpl.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech s.r.o. and others. All rights reserved.
3  *
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
7  */
8 package org.opendaylight.mdsal.yanglib.rfc8525;
9
10 import static com.google.common.base.Preconditions.checkState;
11 import static com.google.common.base.Verify.verifyNotNull;
12
13 import java.util.HashMap;
14 import java.util.Map;
15 import java.util.Objects;
16 import java.util.Optional;
17 import java.util.stream.Collectors;
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree;
20 import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode;
21 import org.opendaylight.mdsal.yanglib.api.YangLibraryContentBuilder;
22 import org.opendaylight.mdsal.yanglib.api.YangLibraryContentBuilderWithLegacy;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.RevisionIdentifier;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.YangLibrary;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.YangLibraryBuilder;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.set.parameters.Module;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.set.parameters.ModuleBuilder;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.module.set.parameters.module.SubmoduleBuilder;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.yang.library.parameters.ModuleSet;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.yang.library.parameters.ModuleSetBuilder;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev190104.yang.library.parameters.ModuleSetKey;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
36 import org.opendaylight.yangtools.yang.common.Revision;
37 import org.opendaylight.yangtools.yang.data.api.DatastoreIdentifier;
38 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
39 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
40
41 final class YangLibraryContentBuilderImpl implements YangLibraryContentBuilder {
42     private static final String MODULE_SET_NAME = "ODL_modules";
43
44     private final Map<DatastoreIdentifier, EffectiveModelContext> datastores = new HashMap<>();
45     private final BindingDataObjectCodecTreeNode<YangLibrary> codec;
46     private final BindingCodecTree codecTree;
47
48     private EffectiveModelContext modelContext;
49
50     YangLibraryContentBuilderImpl(final BindingCodecTree codecTree) {
51         this.codecTree = Objects.requireNonNull(codecTree);
52         codec = verifyNotNull(codecTree.getSubtreeCodec(InstanceIdentifier.create(YangLibrary.class)));
53     }
54
55     @Override
56     public YangLibraryContentBuilder defaultContext(final EffectiveModelContext context) {
57         modelContext = context;
58         return this;
59     }
60
61     EffectiveModelContext getModelContext() {
62         return modelContext;
63     }
64
65     @Override
66     public YangLibraryContentBuilderWithLegacy includeLegacy() {
67         return new LegacyContentBuilder(this, codecTree);
68     }
69
70     @Override
71     public YangLibraryContentBuilder addDatastore(final DatastoreIdentifier identifier,
72                                                   final EffectiveModelContext context) {
73         datastores.put(identifier, context);
74         return this;
75     }
76
77     @Override
78     public ContainerNode formatYangLibraryContent() {
79         checkState(modelContext != null, "EffectiveModelContext is required to format YangLibrary content");
80         return formatYangLibrary();
81     }
82
83     @NonNull ContainerNode formatYangLibrary() {
84         // Two-step process: we first build the content and then use hashCode() to generate module-set-id
85         final YangLibraryBuilder builder = new YangLibraryBuilder().setContentId("");
86         final ModuleSetBuilder moduleSetBuilder = new ModuleSetBuilder()
87             .setModule(modelContext.getModules().stream()
88                 .map(YangLibraryContentBuilderImpl::buildModule)
89                 .collect(BindingMap.toMap()))
90             .setName(MODULE_SET_NAME);
91         final ModuleSet moduleSet = moduleSetBuilder.build();
92
93         builder.setModuleSet(Map.of(new ModuleSetKey(moduleSet.getName()), moduleSet));
94         return (ContainerNode) codec.serialize(builder.setContentId(String.valueOf(builder.build().hashCode()))
95             .build());
96     }
97
98     private static Module buildModule(final org.opendaylight.yangtools.yang.model.api.Module module) {
99         return new ModuleBuilder()
100             .setName(new YangIdentifier(module.getName()))
101             .setNamespace(new Uri(module.getQNameModule().getNamespace().toString()))
102             .setRevision(convertRevision(module.getRevision()))
103             .setSubmodule(module.getSubmodules().stream()
104                 .map(submodule -> new SubmoduleBuilder()
105                     .setName(new YangIdentifier(submodule.getName()))
106                     .setRevision(convertRevision(submodule.getRevision()))
107                     .build())
108                 .collect(BindingMap.toMap()))
109             .setFeature(module.getFeatures().stream()
110                 .map(feat -> new YangIdentifier(feat.getQName().getLocalName()))
111                 .collect(Collectors.toUnmodifiableSet()))
112             .build();
113     }
114
115     private static RevisionIdentifier convertRevision(final Optional<Revision> revision) {
116         return revision.map(rev -> new RevisionIdentifier(rev.toString())).orElse(null);
117     }
118 }