Split out mdsal-binding-runtime-{api,spi}
[mdsal.git] / binding / mdsal-binding-dom-codec-osgi / src / main / java / org / opendaylight / mdsal / binding / dom / codec / osgi / impl / OsgiModuleInfoRegistry.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.mdsal.binding.dom.codec.osgi.impl;
9
10 import static java.util.Objects.requireNonNull;
11
12 import org.checkerframework.checker.lock.qual.GuardedBy;
13 import org.opendaylight.binding.runtime.spi.ModuleInfoRegistry;
14 import org.opendaylight.yangtools.concepts.ObjectRegistration;
15 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
16 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
17 import org.opendaylight.yangtools.yang.model.api.SchemaContextProvider;
18 import org.osgi.framework.ServiceRegistration;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 /**
23  * Update SchemaContext service in Service Registry each time new YangModuleInfo is added or removed.
24  */
25 final class OsgiModuleInfoRegistry implements ModuleInfoRegistry {
26     private static final Logger LOG = LoggerFactory.getLogger(OsgiModuleInfoRegistry.class);
27
28     private final SimpleBindingRuntimeContextService runtimeContext;
29     private final SchemaContextProvider schemaContextProvider;
30     private final ModuleInfoRegistry moduleInfoRegistry;
31
32     @GuardedBy("this")
33     private ServiceRegistration<?> registration;
34     @GuardedBy("this")
35     private long generation;
36
37     OsgiModuleInfoRegistry(final ModuleInfoRegistry moduleInfoRegistry,
38         final SchemaContextProvider schemaContextProvider, final SimpleBindingRuntimeContextService runtimeContext) {
39
40         this.moduleInfoRegistry = requireNonNull(moduleInfoRegistry);
41         this.schemaContextProvider = requireNonNull(schemaContextProvider);
42         this.runtimeContext = requireNonNull(runtimeContext);
43     }
44
45     @Override
46     public ObjectRegistration<YangModuleInfo> registerModuleInfo(final YangModuleInfo yangModuleInfo) {
47         return new ObjectRegistrationWrapper(registerInfo(yangModuleInfo));
48     }
49
50     @SuppressWarnings("checkstyle:illegalCatch")
51     synchronized void updateService() {
52         final SchemaContext context;
53         try {
54             context = schemaContextProvider.getSchemaContext();
55         } catch (final RuntimeException e) {
56             // The ModuleInfoBackedContext throws a RuntimeException if it can't create the schema context.
57             LOG.error("Error updating the schema context", e);
58             return;
59         }
60
61         try {
62             runtimeContext.updateBindingRuntimeContext(context);
63         } catch (final RuntimeException e) {
64             LOG.error("Error updating binding runtime context", e);
65             return;
66         }
67     }
68
69     ObjectRegistration<YangModuleInfo> registerInfo(final YangModuleInfo yangModuleInfo) {
70         return moduleInfoRegistry.registerModuleInfo(yangModuleInfo);
71     }
72
73     private class ObjectRegistrationWrapper implements ObjectRegistration<YangModuleInfo> {
74         private final ObjectRegistration<YangModuleInfo> inner;
75
76         ObjectRegistrationWrapper(final ObjectRegistration<YangModuleInfo> inner) {
77             this.inner = requireNonNull(inner);
78         }
79
80         @Override
81         public YangModuleInfo getInstance() {
82             return inner.getInstance();
83         }
84
85         @Override
86         @SuppressWarnings("checkstyle:illegalCatch")
87         public void close() {
88             try {
89                 inner.close();
90             } finally {
91                 // send modify event when a bundle disappears
92                 updateService();
93             }
94         }
95
96         @Override
97         public String toString() {
98             return inner.toString();
99         }
100     }
101 }