/* * Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program 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. * * This program 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 at /legal/license.txt). * * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */ package com.sun.amms; import javax.microedition.amms.Module; import javax.microedition.media.Player; import javax.microedition.media.MediaException; import java.util.Hashtable; import java.util.Enumeration; abstract class BasicDirectModule extends AbstractDirectControllable implements Module { private class PlayerConnectionInfo { private int _channels_mask; private boolean _added_wholly; PlayerConnectionInfo() { _added_wholly = true; _channels_mask = 0; } PlayerConnectionInfo( int channel ) { _added_wholly = false; _channels_mask = ( 1 << channel ); } boolean canAddMIDIChannel( int channel ) { return ( ( _added_wholly == false ) && ( ( _channels_mask & ( 1 << channel ) ) == 0 ) ); } boolean allChannelsRemoved() { return ( _added_wholly == false && _channels_mask == 0 ); } void addMIDIChannel( int channel ) { _channels_mask |= ( 1 << channel ); } boolean canRemoveMIDIChannel( int channel ) { return ( _added_wholly == false && ( _channels_mask & ( 1 << channel ) ) != 0 ); } boolean isAddedWholly() { return _added_wholly; } void removeMIDIChannel( int channel ) { _channels_mask &= ~( 1 << channel ); } } private Hashtable _players; BasicDirectModule() { _players = new Hashtable(); } private static void checkChannelNumberRange( int channel_number ) { if( channel_number < 0 || channel_number > 15 ) { throw new IllegalArgumentException( "The MIDI channel number should be from 0 to 15" ); } } private static boolean isPlayerMIDI( Player p ) { return p.getContentType().toLowerCase().indexOf( "midi" ) != -1; } private static void checkIfPlayerIsMIDI( Player p ) { if( !isPlayerMIDI( p ) ) { throw new IllegalArgumentException( "JSR-234 Module: Cannot add/remove a MIDI channel of a " + "Player that is not a MIDI Player" ); } } private static void checkIfPlayerIsNull( Player player ) { if( player == null ) { throw new IllegalArgumentException( "JSR-234 Module: Cannot add/remove a null player" ); } } private static boolean isPlayerStateAcceptable( Player p ) { return ( p.getState() != Player.PREFETCHED && p.getState() != Player.STARTED ); } private void checkPlayerStates( Player playerToAddOrRemove ) { if( !isPlayerStateAcceptable( playerToAddOrRemove ) ) { throw new IllegalStateException( "JSR-234 Module: Cannot add/remove a Player in PREFETCHED or STARTED state" ); } Enumeration e = _players.keys(); while( e.hasMoreElements() ) { if( !isPlayerStateAcceptable( ( Player )e.nextElement() ) ) { throw new IllegalStateException( "JSR-234 Module: Cannot add/remove a Player when connected " + "with any other Player in PREFETCHED or STARTED state" ); } } } protected abstract void doAddMIDIChannel( Player player, int channel ) throws MediaException; public void addMIDIChannel( Player player, int channel ) throws MediaException { checkChannelNumberRange( channel ); checkIfPlayerIsNull( player ); checkIfPlayerIsMIDI( player ); checkPlayerStates( player ); PlayerConnectionInfo conn = ( PlayerConnectionInfo )_players.get( player ); if( conn != null ) { if( !conn.canAddMIDIChannel( channel ) ) { throw new IllegalArgumentException( "Cannot add a MIDI channel to a Module if either the channel or the whole " + "Player is already part of the Module" ); } } doAddMIDIChannel( player, channel ); if( conn != null ) { conn.addMIDIChannel( channel ); } else { conn = new PlayerConnectionInfo( channel ); _players.put( player, conn ); } } protected abstract void doAddPlayer( Player player ) throws MediaException; public void addPlayer( Player player ) throws MediaException { checkIfPlayerIsNull( player ); checkPlayerStates( player ); if( _players.containsKey( player ) ) { throw new IllegalArgumentException( "Cannot add a Player to a Module if either the Player or one " + "of its MIDI channels is already part of the Module" ); } doAddPlayer( player ); _players.put( player, new PlayerConnectionInfo() ); } protected abstract void doRemoveMIDIChannel( Player player, int channel ); public void removeMIDIChannel( Player player, int channel ) { checkChannelNumberRange( channel ); checkIfPlayerIsNull( player ); checkIfPlayerIsMIDI( player ); checkPlayerStates( player ); PlayerConnectionInfo conn = ( PlayerConnectionInfo )_players.get( player ); if( conn == null ) { throw new IllegalArgumentException( "Cannot remove a MIDI channel that is not a part of the Module" ); } if( !conn.canRemoveMIDIChannel( channel ) ) { throw new IllegalArgumentException( "Cannot remove a MIDI channel that is not a part of the Module" ); } doRemoveMIDIChannel( player, channel ); conn.removeMIDIChannel( channel ); if( conn.allChannelsRemoved() ) { _players.remove( player ); } } protected abstract void doRemovePlayer( Player player ); public void removePlayer( Player player ) { checkIfPlayerIsNull( player ); checkPlayerStates( player ); if( !isAddedWholly( player ) ) { throw new IllegalArgumentException( "Cannot remove the Player because it is not a part of the Module" ); } doRemovePlayer( player ); _players.remove( player ); } protected boolean isAddedWholly( Player p ) { boolean added = false; PlayerConnectionInfo conn = ( PlayerConnectionInfo )_players.get( p ); if( conn != null ) { added = conn.isAddedWholly(); } return added; } }