Showing the changes to java/pkg/com/sun/tracing/ProviderFactory.java (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,114 @@ | |||
| 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.PrivilegedActionException; | ||
| 9 | import java.security.PrivilegedExceptionAction; | ||
| 10 | import sun.security.action.GetPropertyAction; | ||
| 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 | new GetPropertyAction("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 | new GetPropertyAction("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 | |||