1 /* 2 * Copyright (c) 1999, 2013, 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.util.ArrayList; 29 import java.util.Collections; 30 import java.util.List; 31 import java.util.Properties; 32 33 import javax.sound.midi.Receiver; 34 import javax.sound.midi.Sequencer; 35 import javax.sound.midi.Synthesizer; 36 import javax.sound.midi.Transmitter; 37 import javax.sound.midi.spi.MidiDeviceProvider; 38 import javax.sound.midi.spi.MidiFileReader; 39 import javax.sound.midi.spi.MidiFileWriter; 40 import javax.sound.midi.spi.SoundbankReader; 41 import javax.sound.sampled.Clip; 42 import javax.sound.sampled.Port; 43 import javax.sound.sampled.SourceDataLine; 44 import javax.sound.sampled.TargetDataLine; 45 import javax.sound.sampled.spi.AudioFileReader; 46 import javax.sound.sampled.spi.AudioFileWriter; 47 import javax.sound.sampled.spi.FormatConversionProvider; 48 import javax.sound.sampled.spi.MixerProvider; 49 50 51 /** 52 * JDK13Services uses the Service class in JDK 1.3 to discover a list of service 53 * providers installed in the system. 54 * <p> 55 * This class is public because it is called from javax.sound.midi.MidiSystem 56 * and javax.sound.sampled.AudioSystem. The alternative would be to make 57 * JSSecurityManager public, which is considered worse. 58 * 59 * @author Matthias Pfisterer 60 */ 61 public final class JDK13Services { 62 63 /** 64 * Filename of the properties file for default provider properties. This 65 * file is searched in the subdirectory "lib" of the JRE directory (this 66 * behaviour is hardcoded). 67 */ 68 private static final String PROPERTIES_FILENAME = "sound.properties"; 69 70 /** 71 * Properties loaded from the properties file for default provider 72 * properties. 73 */ 74 private static Properties properties; 75 76 /** 77 * Private, no-args constructor to ensure against instantiation. 78 */ 79 private JDK13Services() { 80 } 81 82 /** 83 * Obtains a List containing installed instances of the providers for the 84 * requested service. The returned List is immutable. 85 * 86 * @param serviceClass The type of providers requested. This should be one 87 * of AudioFileReader.class, AudioFileWriter.class, 88 * FormatConversionProvider.class, MixerProvider.class, 89 * MidiDeviceProvider.class, MidiFileReader.class, 90 * MidiFileWriter.class or SoundbankReader.class. 91 * 92 * @return A List of providers of the requested type. This List is 93 * immutable. 94 */ 95 public static List<?> getProviders(final Class<?> serviceClass) { 96 final List<?> providers; 97 if (!MixerProvider.class.equals(serviceClass) 98 && !FormatConversionProvider.class.equals(serviceClass) 99 && !AudioFileReader.class.equals(serviceClass) 100 && !AudioFileWriter.class.equals(serviceClass) 101 && !MidiDeviceProvider.class.equals(serviceClass) 102 && !SoundbankReader.class.equals(serviceClass) 103 && !MidiFileWriter.class.equals(serviceClass) 104 && !MidiFileReader.class.equals(serviceClass)) { 105 providers = new ArrayList<>(0); 106 } else { 107 providers = JSSecurityManager.getProviders(serviceClass); 108 } 109 return Collections.unmodifiableList(providers); 110 } 111 112 /** Obtain the provider class name part of a default provider property. 113 @param typeClass The type of the default provider property. This 114 should be one of Receiver.class, Transmitter.class, Sequencer.class, 115 Synthesizer.class, SourceDataLine.class, TargetDataLine.class, 116 Clip.class or Port.class. 117 @return The value of the provider class name part of the property 118 (the part before the hash sign), if available. If the property is 119 not set or the value has no provider class name part, null is returned. 120 */ 121 public static synchronized String getDefaultProviderClassName(Class<?> typeClass) { 122 String value = null; 123 String defaultProviderSpec = getDefaultProvider(typeClass); 124 if (defaultProviderSpec != null) { 125 int hashpos = defaultProviderSpec.indexOf('#'); 126 if (hashpos == 0) { 127 // instance name only; leave value as null 128 } else if (hashpos > 0) { 129 value = defaultProviderSpec.substring(0, hashpos); 130 } else { 131 value = defaultProviderSpec; 132 } 133 } 134 return value; 135 } 136 137 138 /** Obtain the instance name part of a default provider property. 139 @param typeClass The type of the default provider property. This 140 should be one of Receiver.class, Transmitter.class, Sequencer.class, 141 Synthesizer.class, SourceDataLine.class, TargetDataLine.class, 142 Clip.class or Port.class. 143 @return The value of the instance name part of the property (the 144 part after the hash sign), if available. If the property is not set 145 or the value has no instance name part, null is returned. 146 */ 147 public static synchronized String getDefaultInstanceName(Class<?> typeClass) { 148 String value = null; 149 String defaultProviderSpec = getDefaultProvider(typeClass); 150 if (defaultProviderSpec != null) { 151 int hashpos = defaultProviderSpec.indexOf('#'); 152 if (hashpos >= 0 && hashpos < defaultProviderSpec.length() - 1) { 153 value = defaultProviderSpec.substring(hashpos + 1); 154 } 155 } 156 return value; 157 } 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 value; 180 String propertyName = typeClass.getName(); 181 value = JSSecurityManager.getProperty(propertyName); 182 if (value == null) { 183 value = getProperties().getProperty(propertyName); 184 } 185 if ("".equals(value)) { 186 value = null; 187 } 188 return value; 189 } 190 191 192 /** Obtain a properties bundle containing property values from the 193 properties file. If the properties file could not be loaded, 194 the properties bundle is empty. 195 */ 196 private static synchronized Properties getProperties() { 197 if (properties == null) { 198 properties = new Properties(); 199 JSSecurityManager.loadProperties(properties, PROPERTIES_FILENAME); 200 } 201 return properties; 202 } 203 }