1 package com.atlassian.plugin.spring.scanner.runtime.impl.util;
2
3 import com.atlassian.plugin.spring.scanner.ProductFilter;
4 import com.google.common.annotations.VisibleForTesting;
5 import com.google.common.collect.ImmutableMap;
6 import org.osgi.framework.BundleContext;
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9
10 import javax.annotation.Nullable;
11 import java.util.Map;
12 import java.util.concurrent.atomic.AtomicReference;
13
14
15
16
17 public class ProductFilterUtil {
18 private static ProductFilterUtil INSTANCE;
19
20 @VisibleForTesting
21 static final String CLASS_ON_BAMBOO_CLASSPATH = "com.atlassian.bamboo.build.BuildExecutionManager";
22 @VisibleForTesting
23 static final String CLASS_ON_BITBUCKET_CLASSPATH = "com.atlassian.bitbucket.repository.RepositoryService";
24 @VisibleForTesting
25 static final String CLASS_ON_CONFLUENCE_CLASSPATH = "com.atlassian.confluence.core.ContentEntityManager";
26 @VisibleForTesting
27 static final String CLASS_ON_FECRU_CLASSPATH = "com.atlassian.fisheye.spi.services.RepositoryService";
28 @VisibleForTesting
29 static final String CLASS_ON_JIRA_CLASSPATH = "com.atlassian.jira.bc.issue.IssueService";
30 @VisibleForTesting
31 static final String CLASS_ON_REFAPP_CLASSPATH = "com.atlassian.refapp.api.ConnectionProvider";
32 @VisibleForTesting
33 static final String CLASS_ON_STASH_CLASSPATH = "com.atlassian.stash.repository.RepositoryService";
34
35 private static final Logger log = LoggerFactory.getLogger(ProductFilterUtil.class);
36
37 private AtomicReference<ProductFilter> filterForProduct = new AtomicReference<ProductFilter>();
38
39 private ProductFilterUtil() {
40 }
41
42
43
44
45
46 public static ProductFilter getFilterForCurrentProduct(@Nullable BundleContext bundleContext) {
47 return getInstance().getFilterForProduct(bundleContext);
48 }
49
50 public ProductFilter getFilterForProduct(@Nullable final BundleContext bundleContext) {
51
52 ProductFilter productFilter = filterForProduct.get();
53 if (productFilter == null) {
54 filterForProduct.compareAndSet(productFilter, detectProduct(bundleContext));
55 productFilter = filterForProduct.get();
56 }
57 return productFilter;
58 }
59
60
61
62
63
64
65 private final static Map<String, ProductFilter> PRODUCTS_TO_HOSTCLASSES = ImmutableMap.<String, ProductFilter>builder()
66 .put(CLASS_ON_BAMBOO_CLASSPATH, ProductFilter.BAMBOO)
67 .put(CLASS_ON_BITBUCKET_CLASSPATH, ProductFilter.BITBUCKET)
68 .put(CLASS_ON_CONFLUENCE_CLASSPATH, ProductFilter.CONFLUENCE)
69 .put(CLASS_ON_FECRU_CLASSPATH, ProductFilter.FECRU)
70 .put(CLASS_ON_JIRA_CLASSPATH, ProductFilter.JIRA)
71 .put(CLASS_ON_REFAPP_CLASSPATH, ProductFilter.REFAPP)
72 .put(CLASS_ON_STASH_CLASSPATH, ProductFilter.STASH)
73
74 .build();
75
76 private ProductFilter detectProduct(final BundleContext bundleContext) {
77 if (bundleContext == null) {
78 log.warn("Couldn't detect product due to null bundleContext: will use ProductFilter.ALL");
79 return ProductFilter.ALL;
80 }
81
82 for (Map.Entry<String, ProductFilter> entry : PRODUCTS_TO_HOSTCLASSES.entrySet()) {
83 if (detectService(bundleContext, entry.getKey())) {
84 log.debug("Detected product: " + entry.getValue().name());
85 return entry.getValue();
86 }
87 }
88
89 log.warn("Couldn't detect product, no known services found: will use ProductFilter.ALL");
90 return ProductFilter.ALL;
91 }
92
93 private boolean detectService(final BundleContext bundleContext, final String serviceClassName) {
94
95 return null != bundleContext.getServiceReference(serviceClassName);
96 }
97
98 private static ProductFilterUtil getInstance() {
99 if (null == INSTANCE) {
100 INSTANCE = new ProductFilterUtil();
101 }
102
103 return INSTANCE;
104 }
105
106 }