4933700: RFE: Add way to get device from Receiver and Transmitter
authoramenkov
Tue, 14 Sep 2010 14:14:18 +0400
changeset 6508 6c00b4789626
parent 6507 34bcd30a8450
child 6509 ea7fb80902b3
4933700: RFE: Add way to get device from Receiver and Transmitter Reviewed-by: art
jdk/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java
jdk/src/share/classes/com/sun/media/sound/MidiDeviceReceiver.java
jdk/src/share/classes/com/sun/media/sound/MidiDeviceReceiverEnvelope.java
jdk/src/share/classes/com/sun/media/sound/MidiDeviceTransmitterEnvelope.java
jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java
jdk/src/share/classes/javax/sound/midi/MidiDevice.java
jdk/src/share/classes/javax/sound/midi/MidiDeviceReceiver.java
jdk/src/share/classes/javax/sound/midi/MidiDeviceTransmitter.java
jdk/src/share/classes/javax/sound/midi/MidiSystem.java
jdk/test/javax/sound/midi/MidiDeviceConnectors/TestAllDevices.java
--- 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);
+    }
+
+}