View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.logging.log4j.core.osgi;
19  
20  import java.util.concurrent.atomic.AtomicReference;
21  
22  import org.apache.logging.log4j.Logger;
23  import org.apache.logging.log4j.core.config.plugins.util.PluginManager;
24  import org.apache.logging.log4j.core.util.BundleResourceLoader;
25  import org.apache.logging.log4j.status.StatusLogger;
26  import org.osgi.framework.Bundle;
27  import org.osgi.framework.BundleActivator;
28  import org.osgi.framework.BundleContext;
29  import org.osgi.framework.BundleEvent;
30  import org.osgi.framework.SynchronousBundleListener;
31  
32  /**
33   * OSGi BundleActivator.
34   */
35  public final class Activator implements BundleActivator, SynchronousBundleListener {
36  
37      private static final Logger LOGGER = StatusLogger.getLogger();
38  
39      private final AtomicReference<BundleContext> context = new AtomicReference<BundleContext>();
40  
41      @Override
42      public void start(final BundleContext context) throws Exception {
43          if (this.context.compareAndSet(null, context)) {
44              context.addBundleListener(this);
45              // done after the BundleListener as to not miss any new bundle installs in the interim
46              scanInstalledBundlesForPlugins(context);
47          }
48      }
49  
50      private static void scanInstalledBundlesForPlugins(final BundleContext context) {
51          final Bundle[] bundles = context.getBundles();
52          for (final Bundle bundle : bundles) {
53              if (bundle.getState() == Bundle.ACTIVE) {
54                  // TODO: bundle state can change during this
55                  scanBundleForPlugins(bundle);
56              }
57          }
58      }
59  
60      private static void scanBundleForPlugins(final Bundle bundle) {
61          LOGGER.trace("Scanning bundle [{}] for plugins.", bundle.getSymbolicName());
62          PluginManager.loadPlugins(new BundleResourceLoader(bundle));
63      }
64  
65      @Override
66      public void stop(final BundleContext context) throws Exception {
67          // not much can be done that isn't already automated by the framework
68          this.context.compareAndSet(context, null);
69      }
70  
71      @Override
72      public void bundleChanged(BundleEvent event) {
73          switch (event.getType()) {
74              case BundleEvent.STARTED:
75                  scanBundleForPlugins(event.getBundle());
76                  break;
77  
78              default:
79                  break;
80          }
81      }
82  }