1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 package org.spf4j.base;
33
34 import com.google.common.cache.CacheBuilder;
35 import com.google.common.cache.CacheLoader;
36 import com.google.common.cache.LoadingCache;
37 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
38 import java.net.URL;
39 import java.security.CodeSource;
40 import javax.annotation.Nonnull;
41 import javax.annotation.Nullable;
42
43
44
45
46 @SuppressFBWarnings("FCCD_FIND_CLASS_CIRCULAR_DEPENDENCY")
47 public final class PackageInfo {
48
49 public static final org.spf4j.base.avro.PackageInfo NONE = new org.spf4j.base.avro.PackageInfo("", "");
50
51 private static final LoadingCache<String, org.spf4j.base.avro.PackageInfo> CACHE = CacheBuilder.newBuilder()
52 .weakKeys().weakValues().build(new CacheLoader<String, org.spf4j.base.avro.PackageInfo>() {
53
54 @Override
55 public org.spf4j.base.avro.PackageInfo load(final String key) {
56 return getPackageInfoDirect(key);
57 }
58 });
59
60
61 private PackageInfo() {
62 }
63
64
65 @SuppressWarnings("checkstyle:regexp")
66 public static void errorNoPackageDetail(final String message, final Throwable t) {
67 if (Boolean.getBoolean("spf4j.reportPackageDetailIssues")) {
68 System.err.println(message);
69 Throwables.writeTo(t, System.err, Throwables.PackageDetail.NONE);
70 }
71 }
72
73 @Nonnull
74 public static org.spf4j.base.avro.PackageInfo getPackageInfoDirect(@Nonnull final String className) {
75 Class<?> aClass;
76 try {
77 aClass = Class.forName(className);
78 } catch (Throwable ex) {
79 errorNoPackageDetail("Error getting package detail for " + className, ex);
80 return NONE;
81 }
82 return getPackageInfoDirect(aClass);
83 }
84
85 @Nonnull
86 public static org.spf4j.base.avro.PackageInfo getPackageInfoDirect(@Nonnull final Class<?> aClass) {
87 URL jarSourceUrl = getJarSourceUrl(aClass);
88 final Package aPackage = aClass.getPackage();
89 if (aPackage == null) {
90 return NONE;
91 }
92 String version = aPackage.getImplementationVersion();
93 return new org.spf4j.base.avro.PackageInfo(jarSourceUrl == null ? "" : jarSourceUrl.toString(),
94 version == null ? "" : version);
95 }
96
97 @Nonnull
98 public static org.spf4j.base.avro.PackageInfo getPackageInfo(@Nonnull final String className) {
99 return CACHE.getUnchecked(className);
100 }
101
102
103
104
105
106
107 @Nullable
108 public static URL getJarSourceUrl(final Class<?> clasz) {
109 final CodeSource codeSource = clasz.getProtectionDomain().getCodeSource();
110 if (codeSource == null) {
111 return null;
112 } else {
113 return codeSource.getLocation();
114 }
115 }
116
117
118
119 }