jdk/src/jdk.runtime/share/classes/com/sun/tracing/ProviderFactory.java
changeset 29034 17c1e9d67f71
parent 29018 7f7b6d9e9461
parent 29033 e70dcf797a33
child 29035 af8778de756a
equal deleted inserted replaced
29018:7f7b6d9e9461 29034:17c1e9d67f71
     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