Bump versions to 14.0.3-SNAPSHOT
[mdsal.git] / dom / mdsal-dom-schema-osgi / src / main / java / org / opendaylight / mdsal / dom / schema / osgi / impl / KarafFeaturesSupport.java
1 /*
2  * Copyright (c) 2020 PANTHEON.tech, 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.dom.schema.osgi.impl;
9
10 import org.apache.karaf.features.FeaturesService;
11 import org.eclipse.jdt.annotation.NonNullByDefault;
12 import org.osgi.framework.BundleContext;
13 import org.osgi.framework.ServiceReference;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16
17 /**
18  * Optional support for Karaf's FeaturesService. This class centralizes wrapping based on bundle resolution state. If
19  * FeaturesService interface is not resolved, this class ends up reusing RegularYangModuleInfoRegistry. If the interface
20  * is resolved, we use it to locate the appropriate service whenever we are asked to activate.
21  */
22 @NonNullByDefault
23 final class KarafFeaturesSupport {
24     @FunctionalInterface
25     private interface WrapperFunction {
26         YangModuleInfoRegistry wrap(BundleContext ctx, RegularYangModuleInfoRegistry delegate);
27     }
28
29     private static final class NoopWrapperFunction implements WrapperFunction {
30         @Override
31         public YangModuleInfoRegistry wrap(final BundleContext ctx, final RegularYangModuleInfoRegistry delegate) {
32             return delegate;
33         }
34     }
35
36     private static final class KarafWrapperFunction implements WrapperFunction {
37         // Forces FeaturesService to be resolved
38         private static final Class<FeaturesService> FEATURES_SERVICE = FeaturesService.class;
39
40         @Override
41         public YangModuleInfoRegistry wrap(final BundleContext ctx, final RegularYangModuleInfoRegistry delegate) {
42             final ServiceReference<FeaturesService> ref = ctx.getServiceReference(FEATURES_SERVICE);
43             if (ref != null) {
44                 final FeaturesService features = ctx.getService(ref);
45                 if (features != null) {
46                     LOG.debug("Integrating with Karaf's FeaturesService");
47                     return KarafYangModuleInfoRegistry.create(features, delegate);
48                 }
49             }
50
51             return delegate;
52         }
53     }
54
55     private static final Logger LOG = LoggerFactory.getLogger(KarafFeaturesSupport.class);
56     private static final WrapperFunction WRAPPER = staticInit();
57
58     private KarafFeaturesSupport() {
59         // Hidden on purpose
60     }
61
62     static YangModuleInfoRegistry wrap(final BundleContext ctx, final RegularYangModuleInfoRegistry regular) {
63         return WRAPPER.wrap(ctx, regular);
64     }
65
66     private static WrapperFunction staticInit() {
67         try {
68             final WrapperFunction karaf = new KarafWrapperFunction();
69             LOG.info("Will attempt to integrate with Karaf FeaturesService");
70             return karaf;
71         } catch (NoClassDefFoundError e) {
72             LOG.trace("Failed to initialize Karaf support", e);
73             LOG.info("Karaf FeaturesService integration disabled");
74             return new NoopWrapperFunction();
75         }
76     }
77 }