Add support for formatting EffectiveModelContext
[mdsal.git] / yanglib / mdsal-yanglib-rfc7895 / src / main / java / org / opendaylight / mdsal / yanglib / rfc7895 / Rfc7895ContentBuilder.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.rfc7895;
9
10 import static com.google.common.base.Verify.verifyNotNull;
11
12 import com.google.common.annotations.VisibleForTesting;
13 import java.util.Map;
14 import java.util.Optional;
15 import java.util.function.Function;
16 import java.util.stream.Collectors;
17 import org.opendaylight.mdsal.binding.dom.codec.api.BindingCodecTree;
18 import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode;
19 import org.opendaylight.mdsal.yanglib.api.YangLibraryContentBuilder;
20 import org.opendaylight.mdsal.yanglib.api.YangLibraryContentBuilderWithLegacy;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.ModulesState;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.ModulesStateBuilder;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.RevisionIdentifier;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.module.list.CommonLeafs;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.module.list.Module;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.module.list.ModuleBuilder;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.module.list.module.Submodule;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.module.list.module.SubmoduleBuilder;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.library.rev160621.module.list.module.SubmoduleKey;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.YangIdentifier;
32 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
33 import org.opendaylight.yangtools.yang.common.Revision;
34 import org.opendaylight.yangtools.yang.data.api.DatastoreIdentifier;
35 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
36 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
37
38 class Rfc7895ContentBuilder implements YangLibraryContentBuilderWithLegacy {
39     private static final CommonLeafs.Revision EMPTY_REV = new CommonLeafs.Revision("");
40
41     private final BindingDataObjectCodecTreeNode<ModulesState> legacyCodec;
42
43     private EffectiveModelContext context;
44
45     Rfc7895ContentBuilder(final BindingCodecTree codecTree) {
46         this.legacyCodec = verifyNotNull(codecTree.getSubtreeCodec(InstanceIdentifier.create(ModulesState.class)));
47     }
48
49     @Override
50     public Rfc7895ContentBuilder defaultContext(final EffectiveModelContext modelContext) {
51         this.context = modelContext;
52         return this;
53     }
54
55     @Override
56     public YangLibraryContentBuilder addDatastore(final DatastoreIdentifier identifier,
57             final EffectiveModelContext newContext) {
58         // NOOP does not apply for rfc7895
59         return this;
60     }
61
62     @Override
63     public YangLibraryContentBuilderWithLegacy includeLegacy() {
64         // NOOP does not apply for rfc7895
65         return this;
66     }
67
68     @Override
69     public ContainerNode formatYangLibraryContent() {
70         return formatModulesState(context);
71     }
72
73     @VisibleForTesting
74     ContainerNode formatModulesState(final EffectiveModelContext effectiveModelContext) {
75         Map<SubmoduleKey, Submodule> vals;
76         // Two-step process: we first build the content and then use hashCode() to generate module-set-id
77         final ModulesStateBuilder builder = new ModulesStateBuilder().setModuleSetId("")
78                 .setModule(effectiveModelContext.getModules().stream()
79                         .map(module -> new ModuleBuilder()
80                                 .setName(new YangIdentifier(module.getName()))
81                                 .setNamespace(new Uri(module.getNamespace().toString()))
82                                 .setRevision(convertRevision(module.getRevision()))
83                                 .setSubmodule(module.getSubmodules().stream()
84                                         .map(submodule -> new SubmoduleBuilder()
85                                                 .setName(new YangIdentifier(submodule.getName()))
86                                                 .setRevision(convertRevision(submodule.getRevision()))
87                                                 .build())
88                                         .collect(Collectors.toUnmodifiableMap(Submodule::key, Function.identity())))
89                                 .setFeature(module.getFeatures().stream()
90                                         .map(feat -> new YangIdentifier(feat.getQName().getLocalName()))
91                                         .collect(Collectors.toUnmodifiableList()))
92                                 .setConformanceType(Module.ConformanceType.Implement)
93                                 .build())
94                         .collect(Collectors.toUnmodifiableMap(Module::key, Function.identity())));
95
96         return (ContainerNode) legacyCodec.serialize(builder.setModuleSetId(String.valueOf(builder.build().hashCode()))
97             .build());
98     }
99
100     private static CommonLeafs.Revision convertRevision(final Optional<Revision> revision) {
101         return revision.map(rev -> new CommonLeafs.Revision(new RevisionIdentifier(rev.toString()))).orElse(EMPTY_REV);
102     }
103
104     @Override
105     public Optional<ContainerNode> formatYangLibraryLegacyContent() {
106         return Optional.of(formatYangLibraryContent());
107     }
108 }