Adds AliasModel and AliasEvent and support for conversion from legacy

playlist format.

Renames PlaylistEditor to ChannelController
This commit is contained in:
denny
2016-01-24 13:45:29 -05:00
parent da924e8b3a
commit 15edcdebe6
14 changed files with 526 additions and 93 deletions

View File

@@ -24,12 +24,14 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import alias.Alias;
import alias.AliasDirectory;
import controller.channel.Channel;
import controller.channel.map.ChannelMapList;
import controller.system.SystemList;
@XmlSeeAlso( { AliasDirectory.class,
Alias.class,
Channel.class,
ChannelMapList.class,
SystemList.class } )
@@ -40,12 +42,24 @@ public class Playlist
private AliasDirectory mAliasDirectory = new AliasDirectory();
private ChannelMapList mChannelMapList = new ChannelMapList();
private SystemList mSystemList = new SystemList();
private List<Alias> mAliases = new ArrayList<>();
private List<Channel> mChannels = new ArrayList<>();
public Playlist()
{
}
@XmlElement( name = "alias" )
public List<Alias> getAliases()
{
return mAliases;
}
public void setAliases( List<Alias> aliases )
{
mAliases = aliases;
}
@XmlElement( name = "channel" )
public List<Channel> getChannels()
{
@@ -70,6 +84,13 @@ public class Playlist
mAliasDirectory = directory;
}
public boolean hasAliasDirectory()
{
return mAliasDirectory != null &&
mAliasDirectory.getAliasList() != null &&
!mAliasDirectory.getAliasList().isEmpty();
}
@XmlElement( name = "system_list" )
public SystemList getSystemList()
{

View File

@@ -1,222 +0,0 @@
package playlist;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import net.coderazzi.filters.gui.AutoChoices;
import net.coderazzi.filters.gui.TableFilterHeader;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import source.SourceManager;
import com.jidesoft.swing.JideSplitPane;
import controller.channel.Channel;
import controller.channel.ChannelEditor;
import controller.channel.ChannelModel;
public class PlaylistEditor extends JPanel
implements ActionListener, ListSelectionListener
{
private static final long serialVersionUID = 1L;
private final static Logger mLog = LoggerFactory.getLogger( PlaylistEditor.class );
private ChannelModel mChannelModel;
private JTable mChannelTable;
private TableFilterHeader mTableFilterHeader;
private ChannelEditor mEditor;
private static final String NEW_CHANNEL = "New";
private static final String COPY_CHANNEL = "Copy";
private static final String DELETE_CHANNEL = "Delete";
private JButton mNewChannelButton = new JButton( NEW_CHANNEL );
private JButton mCopyChannelButton = new JButton( COPY_CHANNEL );
private JButton mDeleteChannelButton = new JButton( DELETE_CHANNEL );
public PlaylistEditor( ChannelModel channelModel,
PlaylistManager playlistManager,
SourceManager sourceManager )
{
mChannelModel = channelModel;
mEditor = new ChannelEditor( channelModel, playlistManager, sourceManager );
mChannelModel.addListener( mEditor );
init();
}
private void init()
{
setLayout( new MigLayout( "insets 0 0 0 0",
"[grow,fill]",
"[grow,fill]") );
//System Configuration View and Editor
mChannelTable = new JTable( mChannelModel );
mChannelTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
mChannelTable.getSelectionModel().addListSelectionListener( this );
mChannelTable.setAutoCreateRowSorter( true );
mTableFilterHeader = new TableFilterHeader( mChannelTable, AutoChoices.ENABLED );
mTableFilterHeader.setFilterOnUpdates( true );
JScrollPane channelScroller = new JScrollPane( mChannelTable );
JPanel buttonsPanel = new JPanel();
buttonsPanel.setLayout(
new MigLayout( "insets 0 0 0 0", "[grow,fill][grow,fill][grow,fill]", "[]") );
mNewChannelButton.addActionListener( this );
mNewChannelButton.setToolTipText( "Adds a new default channel" );
buttonsPanel.add( mNewChannelButton );
mCopyChannelButton.addActionListener( this );
mCopyChannelButton.setEnabled( false );
mCopyChannelButton.setToolTipText( "Creates a copy of the currently selected channel and adds it" );
buttonsPanel.add( mCopyChannelButton );
mDeleteChannelButton.addActionListener( this );
mDeleteChannelButton.setEnabled( false );
mDeleteChannelButton.setToolTipText( "Deletes the currently selected channel" );
buttonsPanel.add( mDeleteChannelButton );
JPanel listAndButtonsPanel = new JPanel();
listAndButtonsPanel.setLayout(
new MigLayout( "insets 0 0 0 0", "[grow,fill]", "[grow,fill][]") );
listAndButtonsPanel.add( channelScroller, "wrap" );
listAndButtonsPanel.add( buttonsPanel );
JideSplitPane splitPane = new JideSplitPane( JideSplitPane.HORIZONTAL_SPLIT );
splitPane.setDividerSize( 5 );
splitPane.setShowGripper( true );
splitPane.add( listAndButtonsPanel );
splitPane.add( mEditor );
add( splitPane );
}
@Override
public void valueChanged( ListSelectionEvent event )
{
//This limits event firing to only when selection is complete
if( !event.getValueIsAdjusting() )
{
int selectedRow = mChannelTable.getSelectedRow();
if( selectedRow != -1 )
{
int index = mChannelTable.convertRowIndexToModel( mChannelTable.getSelectedRow() );
Channel channel = mChannelModel.getChannelAtIndex( index );
if( channel != null )
{
mEditor.setChannel( channel );
mCopyChannelButton.setEnabled( true );
mDeleteChannelButton.setEnabled( true );
}
}
else
{
mEditor.setChannel( null );
mCopyChannelButton.setEnabled( false );
mDeleteChannelButton.setEnabled( false );
}
}
}
/**
* Selects the channel's table row and scrolls the table's viewport to show it
*/
private void addChannel( Channel channel )
{
//HACK: when inserting a row to the model, the JTable gets
//notified and attempts to tell the coderazzi table filter
//adaptive choices filter to refresh before the table filter is
//notified of the row additions, causing an index out of bounds
//exception. We turn off adaptive choices temporarily, add the
//channel, and turn on adaptive choices again.
mTableFilterHeader.setAdaptiveChoices( false );
int index = mChannelModel.addChannel( channel );
mTableFilterHeader.setAdaptiveChoices( true );
if( index >= 0 )
{
int translatedIndex = mChannelTable.convertRowIndexToView( index );
mChannelTable.setRowSelectionInterval( translatedIndex, translatedIndex );
mChannelTable.scrollRectToVisible(
new Rectangle( mChannelTable.getCellRect( translatedIndex, 0, true ) ) );
}
}
private Channel getSelectedChannel()
{
int index = mChannelTable.getSelectedRow();
if( index >= 0 )
{
return mChannelModel.getChannelAtIndex(
mChannelTable.convertRowIndexToModel( index ) );
}
return null;
}
/**
* Responds to New, Copy and Delete Channel button invocations
*/
@Override
public void actionPerformed( ActionEvent event )
{
switch( event.getActionCommand() )
{
case NEW_CHANNEL:
addChannel( new Channel( "New Channel" ) );
break;
case COPY_CHANNEL:
Channel selected = getSelectedChannel();
if( selected != null )
{
addChannel( selected.copyOf() );
}
break;
case DELETE_CHANNEL:
Channel toDelete = getSelectedChannel();
if( toDelete != null )
{
int choice = JOptionPane.showConfirmDialog( PlaylistEditor.this,
"Do you want to delete this channel?", "Delete Channel?",
JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE );
if( choice == JOptionPane.YES_OPTION )
{
mChannelModel.removeChannel( toDelete );
}
}
break;
default:
break;
}
}
}

View File

@@ -37,10 +37,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import properties.SystemProperties;
import controller.channel.Channel;
import controller.channel.ChannelModel;
import controller.site.Site;
import controller.system.SystemList;
import alias.Alias;
import alias.AliasDirectory;
import alias.AliasList;
import alias.AliasModel;
import alias.Group;
import controller.ThreadPoolManager;
import controller.channel.Channel;
import controller.channel.Channel.ChannelType;
@@ -57,10 +58,8 @@ public class PlaylistManager implements ChannelEventListener
private Playlist mPlaylist = new Playlist();
private ChannelModel mChannelModel;
public PlaylistManager( ChannelModel channelModel )
private ThreadPoolManager mThreadPoolManager;
private AliasModel mAliasModel;
private ChannelModel mChannelModel;
private AtomicBoolean mPlaylistSavePending = new AtomicBoolean();
@@ -76,10 +75,12 @@ public class PlaylistManager implements ChannelEventListener
* @param threadPoolManager
* @param channelModel
*/
public PlaylistManager( ThreadPoolManager threadPoolManager,
public PlaylistManager( ThreadPoolManager threadPoolManager,
AliasModel aliasModel,
ChannelModel channelModel )
{
mThreadPoolManager = threadPoolManager;
mAliasModel = aliasModel;
mChannelModel = channelModel;
//Register for channel events so that we can save the playlist when
@@ -101,7 +102,8 @@ public class PlaylistManager implements ChannelEventListener
//all of the data
mPlaylistLoading = true;
mAliasModel.addAliases( mPlaylist.getAliases() );
mChannelModel.addChannels( mPlaylist.getChannels() );
mPlaylistLoading = false;
@@ -168,11 +170,57 @@ public class PlaylistManager implements ChannelEventListener
}
}
/**
* Channel event listener method. Monitors channel events for events that
* indicate that the playlist has changed and queues automatic playlist
* saving.
*/
@Override
public void channelChanged( ChannelEvent event )
{
//Only save playlist for changes to standard channels (not traffic)
if( event.getChannel().getChannelType() == ChannelType.STANDARD )
{
switch( event.getEvent() )
{
case NOTIFICATION_ADD:
case NOTIFICATION_CONFIGURATION_CHANGE:
case NOTIFICATION_DELETE:
case NOTIFICATION_PROCESSING_START:
case NOTIFICATION_PROCESSING_STOP:
schedulePlaylistSave();
break;
case NOTIFICATION_ENABLE_REJECTED:
case NOTIFICATION_SELECTION_CHANGE:
case NOTIFICATION_STATE_RESET:
case REQUEST_DELETE:
case REQUEST_DESELECT:
case REQUEST_DISABLE:
case REQUEST_ENABLE:
case REQUEST_SELECT:
//Do nothing for these event types
break;
default:
//When a new event enum entry is added and received, throw an
//exception here to ensure developer adds support for the
//use case
throw new IllegalArgumentException( "Unrecognized Channel "
+ "Event [" + event.getEvent().name() + "]" );
}
}
}
public void save()
{
//TODO: recreate the playlist and load values from each of the models
mLog.debug( "Aliases in model:" + mAliasModel.getAliases().size() );
mPlaylist.setAliases( mAliasModel.getAliases() );
mLog.debug( "Aliases in playlist:" + mPlaylist.getAliases().size() );
mLog.debug( "Channels in model:" + mChannelModel.getChannels().size() );
mPlaylist.setChannels( mChannelModel.getChannels() );
mLog.debug( "Channels in playlist:" + mPlaylist.getChannels().size() );
JAXBContext context = null;
@@ -370,16 +418,27 @@ public class PlaylistManager implements ChannelEventListener
playlistPath.toString() + "]" );
}
boolean saveRequired = false;
if( mPlaylist == null )
{
mPlaylist = new Playlist();
save();
saveRequired = true;
}
//Check for and convert from legacy play list format
if( mPlaylist.hasSystemList() )
if( mPlaylist.hasSystemList() || mPlaylist.hasAliasDirectory() )
{
convertPlaylistFormat();
saveRequired = true;
}
transferPlaylistToModels();
if( saveRequired )
{
save();
}
}
@@ -388,35 +447,60 @@ public class PlaylistManager implements ChannelEventListener
*/
private void convertPlaylistFormat()
{
mLog.info( "Legacy playlist format detected - converting ..." );
mLog.info( "Legacy playlist format detected - converting" );
createBackupPlaylist();
//Playlist version 1 to version 2 format conversion. In order to keep
//backwards compatibility, transfer all of the System-Site-Channel
//objects over to the new channel list format
SystemList systemList = mPlaylist.getSystemList();
for( controller.system.System system: systemList.getSystem() )
if( mPlaylist.hasSystemList() )
{
for( Site site: system.getSite() )
SystemList systemList = mPlaylist.getSystemList();
for( controller.system.System system: systemList.getSystem() )
{
for( Channel channel: site.getChannel() )
for( Site site: system.getSite() )
{
channel.setSystem( system.getName() );
channel.setSite( site.getName() );
mPlaylist.getChannels().add( channel );
for( Channel channel: site.getChannel() )
{
channel.setSystem( system.getName() );
channel.setSite( site.getName() );
mPlaylist.getChannels().add( channel );
}
}
}
mPlaylist.getSystemList().clearSystems();
mLog.info( "Converted [" + mPlaylist.getChannels().size() +
"] channels to new playlist format" );
}
if( mPlaylist.hasAliasDirectory() )
{
AliasDirectory aliasDirectory = mPlaylist.getAliasDirectory();
for( AliasList list: aliasDirectory.getAliasList() )
{
for( Group group: list.getGroup() )
{
for( Alias alias: group.getAlias() )
{
alias.setList( list.getName() );
alias.setGroup( group.getName() );
mPlaylist.getAliases().add( alias );
}
}
}
mPlaylist.getAliasDirectory().clearAliasLists();
mLog.info( "Converted [" + mPlaylist.getAliases().size() +
"] aliases to new playlist format" );
}
mPlaylist.getSystemList().clearSystems();
mLog.info( "Converted [" + mPlaylist.getChannels().size() +
"] channels to new playlist format" );
save();
}
/**
@@ -448,46 +532,5 @@ public class PlaylistManager implements ChannelEventListener
mPlaylistSavePending.set( false );
}
//Check for and convert from legacy play list format
if( mPlaylist.hasSystemList() )
{
convertPlaylistFormat();
}
}
/**
* Converts playlist data over to new format
*/
private void convertPlaylistFormat()
{
mLog.info( "Legacy playlist format detected - converting ..." );
createBackupPlaylist();
//Playlist version 1 to version 2 format conversion. In order to keep
//backwards compatibility, transfer all of the System-Site-Channel
//objects over to the new channel list format
SystemList systemList = mPlaylist.getSystemList();
for( controller.system.System system: systemList.getSystem() )
{
for( Site site: system.getSite() )
{
for( Channel channel: site.getChannel() )
{
channel.setSystem( system.getName() );
channel.setSite( site.getName() );
mPlaylist.getChannels().add( channel );
}
}
}
mPlaylist.getSystemList().clearSystems();
mLog.info( "Converted [" + mPlaylist.getChannels().size() + "] channels to new playlist format" );
save();
}
}