4933700: RFE: Add way to get device from Receiver and Transmitter
Reviewed-by: art
--- a/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java Tue Sep 14 14:09:26 2010 +0400
+++ b/jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java Tue Sep 14 14:14:18 2010 +0400
@@ -474,7 +474,7 @@
This is necessary for Receivers retrieved via MidiSystem.getReceiver()
(which opens the device implicitely).
*/
- protected abstract class AbstractReceiver implements Receiver {
+ protected abstract class AbstractReceiver implements MidiDeviceReceiver {
private boolean open = true;
@@ -508,6 +508,10 @@
AbstractMidiDevice.this.closeInternal(this);
}
+ public MidiDevice getMidiDevice() {
+ return AbstractMidiDevice.this;
+ }
+
protected boolean isOpen() {
return open;
}
@@ -529,7 +533,7 @@
* Also, it has some optimizations regarding sending to the Receivers,
* for known Receivers, and managing itself in the TransmitterList.
*/
- protected class BasicTransmitter implements Transmitter {
+ protected class BasicTransmitter implements MidiDeviceTransmitter {
private Receiver receiver = null;
TransmitterList tlist = null;
@@ -568,6 +572,9 @@
}
}
+ public MidiDevice getMidiDevice() {
+ return AbstractMidiDevice.this;
+ }
} // class BasicTransmitter
--- a/jdk/src/share/classes/com/sun/media/sound/MidiDeviceReceiver.java Tue Sep 14 14:09:26 2010 +0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.media.sound;
-
-import javax.sound.midi.MidiDevice;
-import javax.sound.midi.Receiver;
-
-/**
- * A Receiver with reference to it's MidiDevice object.
- *
- * @author Karl Helgason
- */
-public interface MidiDeviceReceiver extends Receiver {
-
- /** Obtains the MidiDevice object associated with this Receiver.
- */
- public MidiDevice getMidiDevice();
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/MidiDeviceReceiverEnvelope.java Tue Sep 14 14:14:18 2010 +0400
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.*;
+
+
+/**
+ * Helper class which allows to convert {@code Receiver}
+ * to {@code MidiDeviceReceiver}.
+ *
+ * @author Alex Menkov
+ */
+public class MidiDeviceReceiverEnvelope implements MidiDeviceReceiver {
+
+ private final MidiDevice device;
+ private final Receiver receiver;
+
+ /**
+ * Creates a new {@code MidiDeviceReceiverEnvelope} object which
+ * envelops the specified {@code Receiver}
+ * and is owned by the specified {@code MidiDevice}.
+ *
+ * @param device the owner {@code MidiDevice}
+ * @param receiver the {@code Receiver} to be enveloped
+ */
+ public MidiDeviceReceiverEnvelope(MidiDevice device, Receiver receiver) {
+ if (device == null || receiver == null) {
+ throw new NullPointerException();
+ }
+ this.device = device;
+ this.receiver = receiver;
+ }
+
+ // Receiver implementation
+ public void close() {
+ receiver.close();
+ }
+
+ public void send(MidiMessage message, long timeStamp) {
+ receiver.send(message, timeStamp);
+ }
+
+ // MidiDeviceReceiver implementation
+ public MidiDevice getMidiDevice() {
+ return device;
+ }
+
+ /**
+ * Obtains the receiver enveloped
+ * by this {@code MidiDeviceReceiverEnvelope} object.
+ *
+ * @return the enveloped receiver
+ */
+ public Receiver getReceiver() {
+ return receiver;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/media/sound/MidiDeviceTransmitterEnvelope.java Tue Sep 14 14:14:18 2010 +0400
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.*;
+
+
+/**
+ * Helper class which allows to convert {@code Transmitter}
+ * to {@code MidiDeviceTransmitter}.
+ *
+ * @author Alex Menkov
+ */
+public class MidiDeviceTransmitterEnvelope implements MidiDeviceTransmitter {
+
+ private final MidiDevice device;
+ private final Transmitter transmitter;
+
+ /**
+ * Creates a new {@code MidiDeviceTransmitterEnvelope} object which
+ * envelops the specified {@code Transmitter}
+ * and is owned by the specified {@code MidiDevice}.
+ *
+ * @param device the owner {@code MidiDevice}
+ * @param transmitter the {@code Transmitter} to be enveloped
+ */
+ public MidiDeviceTransmitterEnvelope(MidiDevice device, Transmitter transmitter) {
+ if (device == null || transmitter == null) {
+ throw new NullPointerException();
+ }
+ this.device = device;
+ this.transmitter = transmitter;
+ }
+
+ // Transmitter implementation
+ public void setReceiver(Receiver receiver) {
+ transmitter.setReceiver(receiver);
+ }
+
+ public Receiver getReceiver() {
+ return transmitter.getReceiver();
+ }
+
+ public void close() {
+ transmitter.close();
+ }
+
+
+ // MidiDeviceReceiver implementation
+ public MidiDevice getMidiDevice() {
+ return device;
+ }
+
+ /**
+ * Obtains the transmitter enveloped
+ * by this {@code MidiDeviceTransmitterEnvelope} object.
+ *
+ * @return the enveloped transmitter
+ */
+ public Transmitter getTransmitter() {
+ return transmitter;
+ }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java Tue Sep 14 14:09:26 2010 +0400
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java Tue Sep 14 14:14:18 2010 +0400
@@ -27,6 +27,7 @@
import java.util.TreeMap;
import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiDeviceReceiver;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.ShortMessage;
--- a/jdk/src/share/classes/javax/sound/midi/MidiDevice.java Tue Sep 14 14:09:26 2010 +0400
+++ b/jdk/src/share/classes/javax/sound/midi/MidiDevice.java Tue Sep 14 14:14:18 2010 +0400
@@ -204,6 +204,9 @@
* MIDI data. The returned receiver must be closed when the application
* has finished using it.
*
+ * <p>Usually the returned receiver implements
+ * the {@code MidiDeviceReceiver} interface.
+ *
* <p>Obtaining a <code>Receiver</code> with this method does not
* open the device. To be able to use the device, it has to be
* opened explicitly by calling {@link #open}. Also, closing the
@@ -223,6 +226,10 @@
* connected with this MidiDevice.
* A receiver can be removed
* from the device by closing it.
+ *
+ * <p>Usually the returned receivers implement
+ * the {@code MidiDeviceReceiver} interface.
+ *
* @return an unmodifiable list of the open receivers
* @since 1.5
*/
@@ -234,6 +241,9 @@
* MIDI data The returned transmitter must be closed when the application
* has finished using it.
*
+ * <p>Usually the returned transmitter implements
+ * the {@code MidiDeviceTransmitter} interface.
+ *
* <p>Obtaining a <code>Transmitter</code> with this method does not
* open the device. To be able to use the device, it has to be
* opened explicitly by calling {@link #open}. Also, closing the
@@ -253,6 +263,10 @@
* connected with this MidiDevice.
* A transmitter can be removed
* from the device by closing it.
+ *
+ * <p>Usually the returned transmitters implement
+ * the {@code MidiDeviceTransmitter} interface.
+ *
* @return an unmodifiable list of the open transmitters
* @since 1.5
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/sound/midi/MidiDeviceReceiver.java Tue Sep 14 14:14:18 2010 +0400
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.sound.midi;
+
+/**
+ * <p>{@code MidiDeviceReceiver} is a {@code Receiver} which represents
+ * a MIDI input connector of a {@code MidiDevice}
+ * (see {@link MidiDevice#getReceiver()}).
+ *
+ * @since 1.7
+ */
+public interface MidiDeviceReceiver extends Receiver {
+ /** Obtains a MidiDevice object which is an owner of this Receiver.
+ */
+ public MidiDevice getMidiDevice();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/sound/midi/MidiDeviceTransmitter.java Tue Sep 14 14:14:18 2010 +0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.sound.midi;
+
+
+/**
+ * <p>{@code MidiDeviceTransmitter} is a {@code Transmitter} which represents
+ * a MIDI input connector of a {@code MidiDevice}
+ * (see {@link MidiDevice#getTransmitter()}).
+ *
+ * @since 1.7
+ */
+public interface MidiDeviceTransmitter extends Transmitter {
+
+ /** Obtains a MidiDevice object which is an owner of this Transmitter.
+ */
+ public MidiDevice getMidiDevice();
+}
--- a/jdk/src/share/classes/javax/sound/midi/MidiSystem.java Tue Sep 14 14:09:26 2010 +0400
+++ b/jdk/src/share/classes/javax/sound/midi/MidiSystem.java Tue Sep 14 14:14:18 2010 +0400
@@ -47,6 +47,8 @@
import com.sun.media.sound.JDK13Services;
import com.sun.media.sound.ReferenceCountingDevice;
import com.sun.media.sound.AutoConnectSequencer;
+import com.sun.media.sound.MidiDeviceReceiverEnvelope;
+import com.sun.media.sound.MidiDeviceTransmitterEnvelope;
/**
@@ -225,6 +227,8 @@
/**
* Obtains a MIDI receiver from an external MIDI port
* or other default device.
+ * The returned receiver always implements
+ * the {@code MidiDeviceReceiver} interface.
*
* <p>If the system property
* <code>javax.sound.midi.Receiver</code>
@@ -261,6 +265,9 @@
} else {
receiver = device.getReceiver();
}
+ if (!(receiver instanceof MidiDeviceReceiver)) {
+ receiver = new MidiDeviceReceiverEnvelope(device, receiver);
+ }
return receiver;
}
@@ -268,6 +275,8 @@
/**
* Obtains a MIDI transmitter from an external MIDI port
* or other default source.
+ * The returned transmitter always implements
+ * the {@code MidiDeviceTransmitter} interface.
*
* <p>If the system property
* <code>javax.sound.midi.Transmitter</code>
@@ -301,6 +310,9 @@
} else {
transmitter = device.getTransmitter();
}
+ if (!(transmitter instanceof MidiDeviceReceiver)) {
+ transmitter = new MidiDeviceTransmitterEnvelope(device, transmitter);
+ }
return transmitter;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/sound/midi/MidiDeviceConnectors/TestAllDevices.java Tue Sep 14 14:14:18 2010 +0400
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 4933700
+ * @summary Tests that default devices return MidiDeviceTransmitter/Receiver and returned objects return correct MidiDevice
+ * @compile -source 1.7 TestAllDevices.java
+ * @run main TestAllDevices
+ * @author Alex Menkov
+ */
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiDeviceReceiver;
+import javax.sound.midi.MidiDeviceTransmitter;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Transmitter;
+
+
+public class TestAllDevices {
+
+ static boolean failed = false;
+
+ public static void main(String[] args) throws Exception {
+ out("default receiver:");
+ try {
+ Receiver recv = MidiSystem.getReceiver();
+ out(" receiver: " + recv);
+ if (recv instanceof MidiDeviceReceiver) {
+ out(" OK");
+ } else {
+ out(" ERROR: not an instance of MidiDeviceReceiver");
+ failed = true;
+ }
+ } catch (MidiUnavailableException ex) {
+ // this is not an error
+ out(" receiver: MidiUnavailableException (test NOT failed)");
+ }
+
+ out("default transmitter:");
+ try {
+ Transmitter tran = MidiSystem.getTransmitter();
+ out(" transmitter: " + tran);
+ if (tran instanceof MidiDeviceTransmitter) {
+ out(" OK");
+ } else {
+ out(" ERROR: not an instance of MidiDeviceTransmitter");
+ failed = true;
+ }
+ } catch (MidiUnavailableException ex) {
+ // this is not an error
+ out(" transmitter: MidiUnavailableException (test NOT failed)");
+ }
+
+ MidiDevice.Info[] infos = MidiSystem .getMidiDeviceInfo();
+ for (MidiDevice.Info info: infos) {
+ out(info.toString() + ":");
+ try {
+ MidiDevice dev = MidiSystem.getMidiDevice(info);
+ dev.open();
+
+ try {
+ Receiver recv = dev.getReceiver();
+ out(" receiver: " + recv);
+ if (recv instanceof MidiDeviceReceiver) {
+ MidiDeviceReceiver devRecv = (MidiDeviceReceiver)recv;
+ MidiDevice retDev = devRecv.getMidiDevice();
+ if (retDev == dev) {
+ out(" OK");
+ } else {
+ out(" ERROR: getMidiDevice returned incorrect device: " + retDev);
+ failed = true;
+ }
+ } else {
+ out(" ERROR: not an instance of MidiDeviceReceiver");
+ failed = true;
+ }
+ } catch (MidiUnavailableException ex) {
+ // this is not an error
+ out(" receiver: MidiUnavailableException (test NOT failed)");
+ }
+
+ try {
+ Transmitter tran = dev.getTransmitter();
+ out(" transmitter: " + tran);
+ if (tran instanceof MidiDeviceTransmitter) {
+ MidiDeviceTransmitter devTran = (MidiDeviceTransmitter)tran;
+ MidiDevice retDev = devTran.getMidiDevice();
+ if (retDev == dev) {
+ out(" OK");
+ } else {
+ out(" ERROR: getMidiDevice retur4ned incorrect device: " + retDev);
+ failed = true;
+ }
+ } else {
+ out(" ERROR: not an instance of MidiDeviceTransmitter");
+ failed = true;
+ }
+ } catch (MidiUnavailableException ex) {
+ // this is not an error
+ out(" transmitter: MidiUnavailableException (test NOT failed)");
+ }
+
+ dev.close();
+ } catch (MidiUnavailableException ex) {
+ out(" device: MidiUnavailableException (test NOT failed)");
+ }
+ }
+
+ if (failed) {
+ throw new Exception("Test failed.");
+ }
+ }
+
+ static void out(String s) {
+ System.out.println(s);
+ }
+
+}