b813a878788ed52f5a47438cf11f0a260081af52
[yangtools.git] / yang / yang-model-util / src / main / java / org / opendaylight / yangtools / yang / model / util / SimpleSchemaContext.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies, 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.yangtools.yang.model.util;
9
10 import com.google.common.annotations.Beta;
11 import com.google.common.base.MoreObjects;
12 import com.google.common.base.MoreObjects.ToStringHelper;
13 import com.google.common.collect.ImmutableMap;
14 import com.google.common.collect.ImmutableSet;
15 import com.google.common.collect.ImmutableSetMultimap;
16 import com.google.common.collect.Multimaps;
17 import com.google.common.collect.SetMultimap;
18 import java.net.URI;
19 import java.util.HashSet;
20 import java.util.Map;
21 import java.util.Optional;
22 import java.util.Set;
23 import java.util.TreeMap;
24 import org.opendaylight.yangtools.yang.model.api.Module;
25 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
26
27 /**
28  * Simple subclass of {@link AbstractSchemaContext} which performs some amount of indexing to speed up common
29  * SchemaContext operations. This implementation assumes input modules are consistent and does not perform
30  * any extensive analysis to ensure the resulting object complies to SchemaContext interface.
31  */
32 @Beta
33 public class SimpleSchemaContext extends AbstractSchemaContext {
34     private final SetMultimap<URI, Module> namespaceToModules;
35     private final SetMultimap<String, Module> nameToModules;
36     private final Set<ModuleIdentifier> moduleIdentifiers;
37     private final Set<Module> modules;
38
39     protected SimpleSchemaContext(final Set<Module> modules) {
40         /*
41          * Instead of doing this on each invocation of getModules(), pre-compute
42          * it once and keep it around -- better than the set we got in.
43          */
44         this.modules = ImmutableSet.copyOf(ModuleDependencySort.sort(modules));
45
46         /*
47          * The most common lookup is from Namespace->Module.
48          *
49          * RESTCONF performs lookups based on module name only, where it wants
50          * to receive the latest revision
51          *
52          * Invest some quality time in building up lookup tables for both.
53          */
54         final SetMultimap<URI, Module> nsMap = Multimaps.newSetMultimap(new TreeMap<>(), MODULE_SET_SUPPLIER);
55         final SetMultimap<String, Module> nameMap = Multimaps.newSetMultimap(new TreeMap<>(), MODULE_SET_SUPPLIER);
56         final Set<ModuleIdentifier> modIdBuilder = new HashSet<>();
57         for (Module m : modules) {
58             nameMap.put(m.getName(), m);
59             nsMap.put(m.getNamespace(), m);
60             modIdBuilder.add(ModuleIdentifierImpl.create(m.getName(), Optional.of(m.getNamespace()),
61                 Optional.of(m.getRevision())));
62             resolveSubmoduleIdentifiers(m.getSubmodules(), modIdBuilder);
63         }
64
65         namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
66         nameToModules = ImmutableSetMultimap.copyOf(nameMap);
67         moduleIdentifiers = ImmutableSet.copyOf(modIdBuilder);
68     }
69
70     /**
71      * Create a new instance from specified modules. Note that no module validation is done and hence the consistency
72      * of the resulting SchemaContext is completely in hands of the caller.
73      */
74     public static SimpleSchemaContext forModules(final Set<Module> modules) {
75         return new SimpleSchemaContext(modules);
76     }
77
78     private static void resolveSubmoduleIdentifiers(final Set<Module> submodules,
79             final Set<ModuleIdentifier> modIdBuilder) {
80         for (Module submodule : submodules) {
81             modIdBuilder.add(ModuleIdentifierImpl.create(submodule.getName(),
82                 Optional.of(submodule.getNamespace()), Optional.of(submodule.getRevision())));
83         }
84     }
85
86     @Override
87     public final Set<Module> getModules() {
88         return modules;
89     }
90
91     @Override
92     public final Set<ModuleIdentifier> getAllModuleIdentifiers() {
93         return moduleIdentifiers;
94     }
95
96     @Override
97     public final String toString() {
98         return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
99     }
100
101     protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
102         return toStringHelper.add("modules", modules);
103     }
104
105     @Override
106     protected final Map<ModuleIdentifier, String> getIdentifiersToSources() {
107         return ImmutableMap.of();
108     }
109
110     @Override
111     protected final SetMultimap<URI, Module> getNamespaceToModules() {
112         return namespaceToModules;
113     }
114
115     @Override
116     protected final SetMultimap<String, Module> getNameToModules() {
117         return nameToModules;
118     }
119 }