BUG-8360: add mdsal-binding-dom-codec-osgi
[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 com.google.common.base.Preconditions.checkNotNull;
11
12 import javax.annotation.concurrent.GuardedBy;
13 import org.opendaylight.mdsal.binding.generator.api.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 = checkNotNull(moduleInfoRegistry);
41         this.schemaContextProvider = checkNotNull(schemaContextProvider);
42         this.runtimeContext = checkNotNull(runtimeContext);
43     }
44
45     synchronized void updateService() {
46         final SchemaContext context;
47         try {
48             context = schemaContextProvider.getSchemaContext();
49         } catch (final RuntimeException e) {
50             // The ModuleInfoBackedContext throws a RuntimeException if it can't create the schema context.
51             LOG.error("Error updating the schema context", e);
52             return;
53         }
54
55         try {
56             runtimeContext.updateBindingRuntimeContext(context);
57         } catch (final RuntimeException e) {
58             LOG.error("Error updating binding runtime context", e);
59             return;
60         }
61     }
62
63     @Override
64     public ObjectRegistration<YangModuleInfo> registerModuleInfo(final YangModuleInfo yangModuleInfo) {
65         return new ObjectRegistrationWrapper(moduleInfoRegistry.registerModuleInfo(yangModuleInfo));
66     }
67
68     private class ObjectRegistrationWrapper implements ObjectRegistration<YangModuleInfo> {
69         private final ObjectRegistration<YangModuleInfo> inner;
70
71         ObjectRegistrationWrapper(final ObjectRegistration<YangModuleInfo> inner) {
72             this.inner = checkNotNull(inner);
73         }
74
75         @Override
76         public YangModuleInfo getInstance() {
77             return inner.getInstance();
78         }
79
80         @Override
81         public void close() throws Exception {
82             try {
83                 inner.close();
84             } finally {
85                 // send modify event when a bundle disappears
86                 updateService();
87             }
88         }
89
90         @Override
91         public String toString() {
92             return inner.toString();
93         }
94     }
95 }