1 |
|
2 package com.sun.tracing; |
|
3 |
|
4 import java.util.HashSet; |
|
5 import java.io.PrintStream; |
|
6 import java.lang.reflect.Field; |
|
7 import java.security.AccessController; |
|
8 import java.security.PrivilegedAction; |
|
9 import java.security.PrivilegedActionException; |
|
10 import java.security.PrivilegedExceptionAction; |
|
11 |
|
12 import sun.tracing.NullProviderFactory; |
|
13 import sun.tracing.PrintStreamProviderFactory; |
|
14 import sun.tracing.MultiplexProviderFactory; |
|
15 import sun.tracing.dtrace.DTraceProviderFactory; |
|
16 |
|
17 /** |
|
18 * {@code ProviderFactory} is a factory class used to create instances of |
|
19 * providers. |
|
20 * |
|
21 * To enable tracing in an application, this class must be used to create |
|
22 * instances of the provider interfaces defined by users. |
|
23 * The system-defined factory is obtained by using the |
|
24 * {@code getDefaultFactory()} static method. The resulting instance can be |
|
25 * used to create any number of providers. |
|
26 * |
|
27 * @since 1.7 |
|
28 */ |
|
29 public abstract class ProviderFactory { |
|
30 |
|
31 protected ProviderFactory() {} |
|
32 |
|
33 /** |
|
34 * Creates an implementation of a Provider interface. |
|
35 * |
|
36 * @param cls the provider interface to be defined. |
|
37 * @return an implementation of {@code cls}, whose methods, when called, |
|
38 * will trigger tracepoints in the application. |
|
39 * @throws NullPointerException if cls is null |
|
40 * @throws IllegalArgumentException if the class definition contains |
|
41 * non-void methods |
|
42 */ |
|
43 public abstract <T extends Provider> T createProvider(Class<T> cls); |
|
44 |
|
45 /** |
|
46 * Returns an implementation of a {@code ProviderFactory} which |
|
47 * creates instances of Providers. |
|
48 * |
|
49 * The created Provider instances will be linked to all appropriate |
|
50 * and enabled system-defined tracing mechanisms in the JDK. |
|
51 * |
|
52 * @return a {@code ProviderFactory} that is used to create Providers. |
|
53 */ |
|
54 public static ProviderFactory getDefaultFactory() { |
|
55 HashSet<ProviderFactory> factories = new HashSet<ProviderFactory>(); |
|
56 |
|
57 // Try to instantiate a DTraceProviderFactory |
|
58 String prop = AccessController.doPrivileged( |
|
59 (PrivilegedAction<String>) () -> System.getProperty("com.sun.tracing.dtrace")); |
|
60 |
|
61 if ( (prop == null || !prop.equals("disable")) && |
|
62 DTraceProviderFactory.isSupported() ) { |
|
63 factories.add(new DTraceProviderFactory()); |
|
64 } |
|
65 |
|
66 // Try to instantiate an output stream factory |
|
67 prop = AccessController.doPrivileged( |
|
68 (PrivilegedAction<String>) () -> System.getProperty("sun.tracing.stream")); |
|
69 if (prop != null) { |
|
70 for (String spec : prop.split(",")) { |
|
71 PrintStream ps = getPrintStreamFromSpec(spec); |
|
72 if (ps != null) { |
|
73 factories.add(new PrintStreamProviderFactory(ps)); |
|
74 } |
|
75 } |
|
76 } |
|
77 |
|
78 // See how many factories we instantiated, and return an appropriate |
|
79 // factory that encapsulates that. |
|
80 if (factories.size() == 0) { |
|
81 return new NullProviderFactory(); |
|
82 } else if (factories.size() == 1) { |
|
83 return factories.toArray(new ProviderFactory[1])[0]; |
|
84 } else { |
|
85 return new MultiplexProviderFactory(factories); |
|
86 } |
|
87 } |
|
88 |
|
89 private static PrintStream getPrintStreamFromSpec(final String spec) { |
|
90 try { |
|
91 // spec is in the form of <class>.<field>, where <class> is |
|
92 // a fully specified class name, and <field> is a static member |
|
93 // in that class. The <field> must be a 'PrintStream' or subtype |
|
94 // in order to be used. |
|
95 final int fieldpos = spec.lastIndexOf('.'); |
|
96 final Class<?> cls = Class.forName(spec.substring(0, fieldpos)); |
|
97 |
|
98 Field f = AccessController.doPrivileged(new PrivilegedExceptionAction<Field>() { |
|
99 public Field run() throws NoSuchFieldException { |
|
100 return cls.getField(spec.substring(fieldpos + 1)); |
|
101 } |
|
102 }); |
|
103 |
|
104 return (PrintStream)f.get(null); |
|
105 } catch (ClassNotFoundException e) { |
|
106 throw new AssertionError(e); |
|
107 } catch (IllegalAccessException e) { |
|
108 throw new AssertionError(e); |
|
109 } catch (PrivilegedActionException e) { |
|
110 throw new AssertionError(e); |
|
111 } |
|
112 } |
|
113 } |
|
114 |
|