src/java.desktop/share/classes/com/sun/media/sound/JDK13Services.java
changeset 47216 71c04702a3d5
parent 40444 afabcfc2f3ef
child 50349 b3a654c6fbcc
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package com.sun.media.sound;
       
    27 
       
    28 import java.security.AccessController;
       
    29 import java.security.PrivilegedAction;
       
    30 import java.util.ArrayList;
       
    31 import java.util.Collections;
       
    32 import java.util.List;
       
    33 import java.util.Properties;
       
    34 
       
    35 import javax.sound.midi.Receiver;
       
    36 import javax.sound.midi.Sequencer;
       
    37 import javax.sound.midi.Synthesizer;
       
    38 import javax.sound.midi.Transmitter;
       
    39 import javax.sound.midi.spi.MidiDeviceProvider;
       
    40 import javax.sound.midi.spi.MidiFileReader;
       
    41 import javax.sound.midi.spi.MidiFileWriter;
       
    42 import javax.sound.midi.spi.SoundbankReader;
       
    43 import javax.sound.sampled.Clip;
       
    44 import javax.sound.sampled.Port;
       
    45 import javax.sound.sampled.SourceDataLine;
       
    46 import javax.sound.sampled.TargetDataLine;
       
    47 import javax.sound.sampled.spi.AudioFileReader;
       
    48 import javax.sound.sampled.spi.AudioFileWriter;
       
    49 import javax.sound.sampled.spi.FormatConversionProvider;
       
    50 import javax.sound.sampled.spi.MixerProvider;
       
    51 
       
    52 
       
    53 /**
       
    54  * JDK13Services uses the Service class in JDK 1.3 to discover a list of service
       
    55  * providers installed in the system.
       
    56  * <p>
       
    57  * This class is public because it is called from javax.sound.midi.MidiSystem
       
    58  * and javax.sound.sampled.AudioSystem. The alternative would be to make
       
    59  * JSSecurityManager public, which is considered worse.
       
    60  *
       
    61  * @author Matthias Pfisterer
       
    62  */
       
    63 public final class JDK13Services {
       
    64 
       
    65     /**
       
    66      * Filename of the properties file for default provider properties. This
       
    67      * file is searched in the subdirectory "conf" of the JRE directory (this
       
    68      * behaviour is hardcoded).
       
    69      */
       
    70     private static final String PROPERTIES_FILENAME = "sound.properties";
       
    71 
       
    72     /**
       
    73      * Properties loaded from the properties file for default provider
       
    74      * properties.
       
    75      */
       
    76     private static Properties properties;
       
    77 
       
    78     /**
       
    79      * Private, no-args constructor to ensure against instantiation.
       
    80      */
       
    81     private JDK13Services() {
       
    82     }
       
    83 
       
    84     /**
       
    85      * Obtains a List containing installed instances of the providers for the
       
    86      * requested service. The returned List is immutable.
       
    87      *
       
    88      * @param serviceClass The type of providers requested. This should be one
       
    89      *                     of AudioFileReader.class, AudioFileWriter.class,
       
    90      *                     FormatConversionProvider.class, MixerProvider.class,
       
    91      *                     MidiDeviceProvider.class, MidiFileReader.class,
       
    92      *                     MidiFileWriter.class or SoundbankReader.class.
       
    93      *
       
    94      * @return A List of providers of the requested type. This List is
       
    95      *         immutable.
       
    96      */
       
    97     public static List<?> getProviders(final Class<?> serviceClass) {
       
    98         final List<?> providers;
       
    99         if (!MixerProvider.class.equals(serviceClass)
       
   100                 && !FormatConversionProvider.class.equals(serviceClass)
       
   101                 && !AudioFileReader.class.equals(serviceClass)
       
   102                 && !AudioFileWriter.class.equals(serviceClass)
       
   103                 && !MidiDeviceProvider.class.equals(serviceClass)
       
   104                 && !SoundbankReader.class.equals(serviceClass)
       
   105                 && !MidiFileWriter.class.equals(serviceClass)
       
   106                 && !MidiFileReader.class.equals(serviceClass)) {
       
   107             providers = new ArrayList<>(0);
       
   108         } else {
       
   109             providers = JSSecurityManager.getProviders(serviceClass);
       
   110         }
       
   111         return Collections.unmodifiableList(providers);
       
   112     }
       
   113 
       
   114     /** Obtain the provider class name part of a default provider property.
       
   115         @param typeClass The type of the default provider property. This
       
   116         should be one of Receiver.class, Transmitter.class, Sequencer.class,
       
   117         Synthesizer.class, SourceDataLine.class, TargetDataLine.class,
       
   118         Clip.class or Port.class.
       
   119         @return The value of the provider class name part of the property
       
   120         (the part before the hash sign), if available. If the property is
       
   121         not set or the value has no provider class name part, null is returned.
       
   122      */
       
   123     public static synchronized String getDefaultProviderClassName(Class<?> typeClass) {
       
   124         String value = null;
       
   125         String defaultProviderSpec = getDefaultProvider(typeClass);
       
   126         if (defaultProviderSpec != null) {
       
   127             int hashpos = defaultProviderSpec.indexOf('#');
       
   128             if (hashpos == 0) {
       
   129                 // instance name only; leave value as null
       
   130             } else if (hashpos > 0) {
       
   131                 value = defaultProviderSpec.substring(0, hashpos);
       
   132             } else {
       
   133                 value = defaultProviderSpec;
       
   134             }
       
   135         }
       
   136         return value;
       
   137     }
       
   138 
       
   139     /** Obtain the instance name part of a default provider property.
       
   140         @param typeClass The type of the default provider property. This
       
   141         should be one of Receiver.class, Transmitter.class, Sequencer.class,
       
   142         Synthesizer.class, SourceDataLine.class, TargetDataLine.class,
       
   143         Clip.class or Port.class.
       
   144         @return The value of the instance name part of the property (the
       
   145         part after the hash sign), if available. If the property is not set
       
   146         or the value has no instance name part, null is returned.
       
   147      */
       
   148     public static synchronized String getDefaultInstanceName(Class<?> typeClass) {
       
   149         String value = null;
       
   150         String defaultProviderSpec = getDefaultProvider(typeClass);
       
   151         if (defaultProviderSpec != null) {
       
   152             int hashpos = defaultProviderSpec.indexOf('#');
       
   153             if (hashpos >= 0 && hashpos < defaultProviderSpec.length() - 1) {
       
   154                 value = defaultProviderSpec.substring(hashpos + 1);
       
   155             }
       
   156         }
       
   157         return value;
       
   158     }
       
   159 
       
   160     /** Obtain the value of a default provider property.
       
   161         @param typeClass The type of the default provider property. This
       
   162         should be one of Receiver.class, Transmitter.class, Sequencer.class,
       
   163         Synthesizer.class, SourceDataLine.class, TargetDataLine.class,
       
   164         Clip.class or Port.class.
       
   165         @return The complete value of the property, if available.
       
   166         If the property is not set, null is returned.
       
   167      */
       
   168     private static synchronized String getDefaultProvider(Class<?> typeClass) {
       
   169         if (!SourceDataLine.class.equals(typeClass)
       
   170                 && !TargetDataLine.class.equals(typeClass)
       
   171                 && !Clip.class.equals(typeClass)
       
   172                 && !Port.class.equals(typeClass)
       
   173                 && !Receiver.class.equals(typeClass)
       
   174                 && !Transmitter.class.equals(typeClass)
       
   175                 && !Synthesizer.class.equals(typeClass)
       
   176                 && !Sequencer.class.equals(typeClass)) {
       
   177             return null;
       
   178         }
       
   179         String name = typeClass.getName();
       
   180         String value = AccessController.doPrivileged(
       
   181                 (PrivilegedAction<String>) () -> System.getProperty(name));
       
   182         if (value == null) {
       
   183             value = getProperties().getProperty(name);
       
   184         }
       
   185         if ("".equals(value)) {
       
   186             value = null;
       
   187         }
       
   188         return value;
       
   189     }
       
   190 
       
   191     /** Obtain a properties bundle containing property values from the
       
   192         properties file. If the properties file could not be loaded,
       
   193         the properties bundle is empty.
       
   194     */
       
   195     private static synchronized Properties getProperties() {
       
   196         if (properties == null) {
       
   197             properties = new Properties();
       
   198             JSSecurityManager.loadProperties(properties, PROPERTIES_FILENAME);
       
   199         }
       
   200         return properties;
       
   201     }
       
   202 }