2 * Copyright (c) 2013 Cisco Systems, Inc. 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.yang.parser.impl;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.Collections;
14 import java.util.Date;
15 import java.util.HashSet;
16 import java.util.LinkedHashSet;
17 import java.util.List;
20 import java.util.TreeMap;
22 import org.opendaylight.yangtools.yang.common.QName;
23 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
24 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
25 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
26 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
27 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
28 import org.opendaylight.yangtools.yang.model.api.Module;
29 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
30 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
31 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
32 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
33 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
34 import org.opendaylight.yangtools.yang.model.api.Status;
35 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
36 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
37 import org.opendaylight.yangtools.yang.model.api.UsesNode;
38 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
40 import com.google.common.base.Optional;
41 import com.google.common.base.Supplier;
42 import com.google.common.collect.ImmutableSetMultimap;
43 import com.google.common.collect.Multimaps;
44 import com.google.common.collect.SetMultimap;
46 final class SchemaContextImpl implements SchemaContext {
47 private static final Supplier<HashSet<Module>> URI_SET_SUPPLIER = new Supplier<HashSet<Module>>() {
49 public HashSet<Module> get() {
50 return new HashSet<>();
54 private final Map<ModuleIdentifier, String> identifiersToSources;
55 private final SetMultimap<URI, Module> namespaceToModules;
56 private final Set<Module> modules;
58 SchemaContextImpl(final Set<Module> modules, final Map<ModuleIdentifier, String> identifiersToSources) {
59 this.modules = modules;
60 this.identifiersToSources = identifiersToSources;
63 * The most common lookup is from Namespace->Module. Invest some quality time in
66 final SetMultimap<URI, Module> multimap = Multimaps.newSetMultimap(
67 new TreeMap<URI, Collection<Module>>(), URI_SET_SUPPLIER);
68 for (Module m : modules) {
69 multimap.put(m.getNamespace(), m);
72 namespaceToModules = ImmutableSetMultimap.copyOf(multimap);
76 public Set<DataSchemaNode> getDataDefinitions() {
77 final Set<DataSchemaNode> dataDefs = new HashSet<DataSchemaNode>();
78 for (Module m : modules) {
79 dataDefs.addAll(m.getChildNodes());
85 public Set<Module> getModules() {
86 // FIXME: can we pre-compute this in the constructor?
87 List<Module> sorted = ModuleDependencySort.sort(modules.toArray(new Module[modules.size()]));
88 return new LinkedHashSet<Module>(sorted);
92 public Set<NotificationDefinition> getNotifications() {
93 final Set<NotificationDefinition> notifications = new HashSet<NotificationDefinition>();
94 for (Module m : modules) {
95 notifications.addAll(m.getNotifications());
101 public Set<RpcDefinition> getOperations() {
102 final Set<RpcDefinition> rpcs = new HashSet<RpcDefinition>();
103 for (Module m : modules) {
104 rpcs.addAll(m.getRpcs());
110 public Set<ExtensionDefinition> getExtensions() {
111 final Set<ExtensionDefinition> extensions = new HashSet<ExtensionDefinition>();
112 for (Module m : modules) {
113 extensions.addAll(m.getExtensionSchemaNodes());
119 public Module findModuleByName(final String name, final Date revision) {
121 for (final Module module : modules) {
122 if (revision == null) {
123 if (module.getName().equals(name)) {
126 } else if (module.getName().equals(name) && module.getRevision().equals(revision)) {
135 public Set<Module> findModuleByNamespace(final URI namespace) {
136 final Set<Module> ret = namespaceToModules.get(namespace);
137 return ret == null ? Collections.<Module>emptySet() : ret;
141 public Module findModuleByNamespaceAndRevision(final URI namespace, final Date revision) {
142 if (namespace != null) {
143 Set<Module> modules = findModuleByNamespace(namespace);
145 if (revision == null) {
146 TreeMap<Date, Module> map = new TreeMap<Date, Module>();
147 for (Module module : modules) {
148 map.put(module.getRevision(), module);
153 return map.lastEntry().getValue();
155 for (Module module : modules) {
156 if (module.getRevision().equals(revision)) {
166 public boolean isAugmenting() {
171 public boolean isAddedByUses() {
176 public boolean isConfiguration() {
181 public ConstraintDefinition getConstraints() {
186 public QName getQName() {
187 return SchemaContext.NAME;
191 public SchemaPath getPath() {
196 public String getDescription() {
201 public String getReference() {
206 public Status getStatus() {
207 return Status.CURRENT;
211 public List<UnknownSchemaNode> getUnknownSchemaNodes() {
212 final List<UnknownSchemaNode> result = new ArrayList<>();
213 for (Module module : modules) {
214 result.addAll(module.getUnknownSchemaNodes());
216 return Collections.unmodifiableList(result);
220 public Set<TypeDefinition<?>> getTypeDefinitions() {
221 final Set<TypeDefinition<?>> result = new LinkedHashSet<>();
222 for (Module module : modules) {
223 result.addAll(module.getTypeDefinitions());
225 return Collections.unmodifiableSet(result);
229 public Set<DataSchemaNode> getChildNodes() {
230 final Set<DataSchemaNode> result = new LinkedHashSet<>();
231 for (Module module : modules) {
232 result.addAll(module.getChildNodes());
234 return Collections.unmodifiableSet(result);
238 public Set<GroupingDefinition> getGroupings() {
239 final Set<GroupingDefinition> result = new LinkedHashSet<>();
240 for (Module module : modules) {
241 result.addAll(module.getGroupings());
243 return Collections.unmodifiableSet(result);
247 public DataSchemaNode getDataChildByName(final QName name) {
248 DataSchemaNode result = null;
249 for (Module module : modules) {
250 result = module.getDataChildByName(name);
251 if (result != null) {
259 public DataSchemaNode getDataChildByName(final String name) {
260 DataSchemaNode result = null;
261 for (Module module : modules) {
262 result = module.getDataChildByName(name);
263 if (result != null) {
271 public Set<UsesNode> getUses() {
272 return Collections.emptySet();
276 public boolean isPresenceContainer() {
281 public Set<AugmentationSchema> getAvailableAugmentations() {
282 return Collections.emptySet();
285 //FIXME: should work for submodules too
287 public Set<ModuleIdentifier> getAllModuleIdentifiers() {
288 return identifiersToSources.keySet();
292 public Optional<String> getModuleSource(final ModuleIdentifier moduleIdentifier) {
293 String maybeSource = identifiersToSources.get(moduleIdentifier);
294 return Optional.fromNullable(maybeSource);