/*
* This file is part of the OpenSCADA project
* Copyright (C) 2006-2010 TH4 SYSTEMS GmbH (http://th4-systems.com)
*
* OpenSCADA is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* only, as published by the Free Software Foundation.
*
* OpenSCADA 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 Lesser General Public License version 3 for more details
* (a copy is included in the LICENSE file that accompanied this code).
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with OpenSCADA. If not, see
* <http://opensource.org/licenses/lgpl-3.0.html> for a copy of the LGPLv3 License.
*/
package org.openscada.da.ui.widgets.realtime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import org.openscada.da.ui.connection.data.Item;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ListData implements Observer
{
private final static Logger logger = LoggerFactory.getLogger ( ListData.class );
private List<ListEntry> items = new CopyOnWriteArrayList<ListEntry> ();
private final Set<Listener> listeners = new CopyOnWriteArraySet<Listener> ();
public List<ListEntry> getItems ()
{
return new ArrayList<ListEntry> ( this.items );
}
synchronized public void setItems ( final List<ListEntry> items )
{
clear ();
this.items = items;
fireAdded ( this.items.toArray ( new ListEntry[this.items.size ()] ) );
for ( final ListEntry entry : items )
{
entry.addObserver ( this );
}
}
public void add ( final ListEntry entry )
{
if ( this.items.add ( entry ) )
{
fireAdded ( new ListEntry[] { entry } );
entry.addObserver ( this );
}
}
public void add ( final Item item )
{
final ListEntry entry = new ListEntry ();
entry.setDataItem ( item );
add ( entry );
}
public void remove ( final ListEntry entry )
{
if ( this.items.remove ( entry ) )
{
entry.deleteObserver ( this );
entry.clear ();
fireRemoved ( new ListEntry[] { entry } );
}
}
public void removeAll ( final Collection<ListEntry> entries )
{
this.items.removeAll ( entries );
for ( final ListEntry entry : entries )
{
entry.deleteObserver ( this );
entry.clear ();
}
fireRemoved ( entries.toArray ( new ListEntry[entries.size ()] ) );
}
synchronized public void clear ()
{
for ( final ListEntry entry : this.items )
{
entry.deleteObserver ( this );
}
this.items.clear ();
fireRemoved ( this.items.toArray ( new ListEntry[this.items.size ()] ) );
}
public void addListener ( final Listener listener )
{
this.listeners.add ( listener );
// now fill the new listener with what we already have
if ( !this.items.isEmpty () )
{
listener.added ( this.items.toArray ( new ListEntry[this.items.size ()] ) );
}
}
public void removeListener ( final Listener listener )
{
this.listeners.remove ( listener );
}
protected void fireAdded ( final ListEntry[] entries )
{
logger.debug ( String.format ( "Fire add for %d items", entries.length ) ); //$NON-NLS-1$
for ( final Listener listener : this.listeners )
{
try
{
listener.added ( entries );
}
catch ( final Exception e )
{
logger.warn ( "Failed while sending add notification", e ); //$NON-NLS-1$
}
}
}
protected void fireRemoved ( final ListEntry[] entries )
{
for ( final Listener listener : this.listeners )
{
try
{
listener.removed ( entries );
}
catch ( final Exception e )
{
logger.warn ( "Failed while sending remove notification", e ); //$NON-NLS-1$
}
}
}
protected void fireUpdated ( final ListEntry[] entries )
{
logger.debug ( "Updating items: " + entries.length ); //$NON-NLS-1$
for ( final Listener listener : this.listeners )
{
try
{
listener.updated ( entries );
}
catch ( final Exception e )
{
logger.warn ( "Failed while sending update notification", e ); //$NON-NLS-1$
}
}
}
public void update ( final Observable o, final Object arg )
{
if ( o instanceof ListEntry && this.items.contains ( o ) )
{
fireUpdated ( new ListEntry[] { (ListEntry)o } );
}
}
}