Deprecate CopyableNode at al.
[yangtools.git] / yang / yang-model-util / src / main / java / org / opendaylight / yangtools / yang / model / util / AbstractSchemaContext.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. 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
9 package org.opendaylight.yangtools.yang.model.util;
10
11 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.collect.SetMultimap;
14 import java.net.URI;
15 import java.util.ArrayList;
16 import java.util.Collections;
17 import java.util.Comparator;
18 import java.util.HashSet;
19 import java.util.LinkedHashSet;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Optional;
23 import java.util.Set;
24 import java.util.TreeSet;
25 import javax.annotation.Nonnull;
26 import org.opendaylight.yangtools.yang.common.QName;
27 import org.opendaylight.yangtools.yang.common.QNameModule;
28 import org.opendaylight.yangtools.yang.common.Revision;
29 import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
30 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
31 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
32 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
33 import org.opendaylight.yangtools.yang.model.api.Module;
34 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
35 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
36 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
37 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
38 import org.opendaylight.yangtools.yang.model.api.Status;
39 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
40 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
41 import org.opendaylight.yangtools.yang.model.api.UsesNode;
42
43 public abstract class AbstractSchemaContext implements SchemaContext {
44     /**
45      * A {@link Module} comparator based on {@link Module#getRevision()}, placing latest revision first. Note this
46      * comparator does not take into account module name and so two modules with different names but same revisions
47      * compare as equal.
48      */
49     protected static final Comparator<Module> REVISION_COMPARATOR =
50         (first, second) -> Revision.compare(second.getRevision(), first.getRevision());
51
52     /**
53      * A {@link Module} comparator based on {@link Module#getName()} and {@link Module#getRevision()}, ordering modules
54      * lexicographically by their name and then in order of descending revision. This comparator assumes that
55      * the combination of these two attributes is sufficient to be consistent with hashCode/equals.
56      */
57     protected static final Comparator<Module> NAME_REVISION_COMPARATOR = (first, second) -> {
58         final int cmp = first.getName().compareTo(second.getName());
59         return cmp != 0 ? cmp : REVISION_COMPARATOR.compare(first, second);
60     };
61
62     /**
63      * Create a TreeSet for containing Modules with the same name, such that the set is ordered
64      * by {@link #REVISION_COMPARATOR}.
65      *
66      * @return A fresh TreeSet instance.
67      */
68     protected static final TreeSet<Module> createModuleSet() {
69         return new TreeSet<>(REVISION_COMPARATOR);
70     }
71
72     /**
73      * Returns the namespace-to-module mapping.
74      *
75      * @return Map of modules where key is namespace
76      */
77     protected abstract SetMultimap<URI, Module> getNamespaceToModules();
78
79     /**
80      * Returns the module name-to-module mapping.
81      *
82      * @return Map of modules where key is name of module
83      */
84     protected abstract SetMultimap<String, Module> getNameToModules();
85
86     /**
87      * Returns the namespace+revision-to-module mapping.
88      *
89      * @return Map of modules where key is Module's QNameModule.
90      */
91     protected abstract Map<QNameModule, Module> getModuleMap();
92
93     @Override
94     public Set<DataSchemaNode> getDataDefinitions() {
95         final Set<DataSchemaNode> dataDefs = new HashSet<>();
96         for (Module m : getModules()) {
97             dataDefs.addAll(m.getChildNodes());
98         }
99         return dataDefs;
100     }
101
102     @Override
103     public Set<NotificationDefinition> getNotifications() {
104         final Set<NotificationDefinition> notifications = new HashSet<>();
105         for (Module m : getModules()) {
106             notifications.addAll(m.getNotifications());
107         }
108         return notifications;
109     }
110
111     @Override
112     public Set<RpcDefinition> getOperations() {
113         final Set<RpcDefinition> rpcs = new HashSet<>();
114         for (Module m : getModules()) {
115             rpcs.addAll(m.getRpcs());
116         }
117         return rpcs;
118     }
119
120     @Override
121     public Set<ExtensionDefinition> getExtensions() {
122         final Set<ExtensionDefinition> extensions = new HashSet<>();
123         for (Module m : getModules()) {
124             extensions.addAll(m.getExtensionSchemaNodes());
125         }
126         return extensions;
127     }
128
129     @Override
130     public Optional<Module> findModule(final String name, final Optional<Revision> revision) {
131         for (final Module module : getNameToModules().get(name)) {
132             if (revision.equals(module.getRevision())) {
133                 return Optional.of(module);
134             }
135         }
136
137         return Optional.empty();
138     }
139
140     @Override
141     public Optional<Module> findModule(final QNameModule qnameModule) {
142         return Optional.ofNullable(getModuleMap().get(qnameModule));
143     }
144
145     @Override
146     public Set<Module> findModules(final URI namespace) {
147         return getNamespaceToModules().get(namespace);
148     }
149
150     @Override
151     public Set<Module> findModules(final String name) {
152         return getNameToModules().get(name);
153     }
154
155     @Deprecated
156     @Override
157     public boolean isAugmenting() {
158         return false;
159     }
160
161     @Deprecated
162     @Override
163     public boolean isAddedByUses() {
164         return false;
165     }
166
167     @Override
168     public boolean isConfiguration() {
169         return false;
170     }
171
172     @Nonnull
173     @Override
174     public QName getQName() {
175         return SchemaContext.NAME;
176     }
177
178     @Nonnull
179     @Override
180     public SchemaPath getPath() {
181         return SchemaPath.ROOT;
182     }
183
184     @Nonnull
185     @Override
186     public Status getStatus() {
187         return Status.CURRENT;
188     }
189
190     @Nonnull
191     @Override
192     public List<UnknownSchemaNode> getUnknownSchemaNodes() {
193         final List<UnknownSchemaNode> result = new ArrayList<>();
194         for (Module module : getModules()) {
195             result.addAll(module.getUnknownSchemaNodes());
196         }
197         return Collections.unmodifiableList(result);
198     }
199
200     @Override
201     public Set<TypeDefinition<?>> getTypeDefinitions() {
202         final Set<TypeDefinition<?>> result = new LinkedHashSet<>();
203         for (Module module : getModules()) {
204             result.addAll(module.getTypeDefinitions());
205         }
206         return Collections.unmodifiableSet(result);
207     }
208
209     @Override
210     public Set<DataSchemaNode> getChildNodes() {
211         final Set<DataSchemaNode> result = new LinkedHashSet<>();
212         for (Module module : getModules()) {
213             result.addAll(module.getChildNodes());
214         }
215         return Collections.unmodifiableSet(result);
216     }
217
218     @Override
219     public Set<GroupingDefinition> getGroupings() {
220         final Set<GroupingDefinition> result = new LinkedHashSet<>();
221         for (Module module : getModules()) {
222             result.addAll(module.getGroupings());
223         }
224         return Collections.unmodifiableSet(result);
225     }
226
227     @Override
228     public Optional<DataSchemaNode> findDataChildByName(final QName name) {
229         requireNonNull(name);
230         for (Module module : getModules()) {
231             final Optional<DataSchemaNode> result = module.findDataChildByName(name);
232             if (result.isPresent()) {
233                 return result;
234             }
235         }
236         return Optional.empty();
237     }
238
239     @Override
240     public Set<UsesNode> getUses() {
241         return Collections.emptySet();
242     }
243
244     @Override
245     public boolean isPresenceContainer() {
246         return false;
247     }
248
249     @Override
250     public Set<AugmentationSchemaNode> getAvailableAugmentations() {
251         return Collections.emptySet();
252     }
253 }