d20a9032251863e132deaa79d6c58d330d303fdf
[netconf.git] / netconf / mdsal-netconf-connector / src / main / java / org / opendaylight / netconf / mdsal / connector / CurrentSchemaContext.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 package org.opendaylight.netconf.mdsal.connector;
9
10 import static com.google.common.base.Preconditions.checkState;
11
12 import java.util.Collections;
13 import java.util.HashSet;
14 import java.util.Set;
15 import java.util.concurrent.atomic.AtomicReference;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
18 import org.opendaylight.netconf.api.capability.Capability;
19 import org.opendaylight.netconf.api.monitoring.CapabilityListener;
20 import org.opendaylight.yangtools.concepts.ListenerRegistration;
21 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
22 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContextListener;
23 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
24 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceProvider;
25
26 // Non-final for mocking
27 @SuppressWarnings("checkstyle:FinalClass")
28 public class CurrentSchemaContext implements EffectiveModelContextListener, AutoCloseable {
29     private final AtomicReference<EffectiveModelContext> currentContext = new AtomicReference<>();
30     private ListenerRegistration<?> schemaContextListenerListenerRegistration;
31     private final Set<CapabilityListener> listeners1 = Collections.synchronizedSet(new HashSet<>());
32     private final SchemaSourceProvider<YangTextSchemaSource> rootSchemaSourceProvider;
33
34     private CurrentSchemaContext(final SchemaSourceProvider<YangTextSchemaSource> rootSchemaSourceProvider) {
35         this.rootSchemaSourceProvider = rootSchemaSourceProvider;
36     }
37
38     // keep spotbugs from complaining about overridable method in constructor
39     public static CurrentSchemaContext create(final DOMSchemaService schemaService,
40                          final SchemaSourceProvider<YangTextSchemaSource> rootSchemaSourceProvider) {
41         var context = new CurrentSchemaContext(rootSchemaSourceProvider);
42         final ListenerRegistration<EffectiveModelContextListener> registration =
43                 schemaService.registerSchemaContextListener(context);
44         context.setRegistration(registration);
45         return context;
46     }
47
48     private void setRegistration(ListenerRegistration<EffectiveModelContextListener> registration) {
49         schemaContextListenerListenerRegistration = registration;
50     }
51
52     public @NonNull EffectiveModelContext getCurrentContext() {
53         final var ret = currentContext.get();
54         checkState(ret != null, "Current context not received");
55         return ret;
56     }
57
58     @Override
59     public void onModelContextUpdated(final EffectiveModelContext schemaContext) {
60         currentContext.set(schemaContext);
61         // FIXME is notifying all the listeners from this callback wise ?
62         final Set<Capability> addedCaps = MdsalNetconfOperationServiceFactory.transformCapabilities(
63                 currentContext.get(), rootSchemaSourceProvider);
64         for (final CapabilityListener listener : listeners1) {
65             listener.onCapabilitiesChanged(addedCaps, Collections.emptySet());
66         }
67     }
68
69     @Override
70     public void close() {
71         listeners1.clear();
72         schemaContextListenerListenerRegistration.close();
73         currentContext.set(null);
74     }
75
76     public AutoCloseable registerCapabilityListener(final CapabilityListener listener) {
77         listener.onCapabilitiesChanged(MdsalNetconfOperationServiceFactory.transformCapabilities(currentContext.get(),
78                 rootSchemaSourceProvider), Collections.emptySet());
79         listeners1.add(listener);
80         return () -> listeners1.remove(listener);
81     }
82 }