/*
* This file is part of the openSCADA project
* Copyright (C) 2006-2011 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.vi.ui.draw2d;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.openscada.core.Variant;
import org.openscada.core.connection.provider.ConnectionIdTracker;
import org.openscada.da.client.DataItemValue;
import org.openscada.da.connection.provider.ConnectionService;
public class RegistrationManager
{
private static final long SERVICE_TIMEOUT = Long.getLong ( "org.openscada.vi.ui.draw2d.serviceTimeout", 1000 );
private final SymbolController controller;
private final Map<String, DataItemRegistration> registrations = new LinkedHashMap<String, DataItemRegistration> ();
private final AtomicReference<Map<String, DataValue>> currentValues = new AtomicReference<Map<String, DataValue>> ( Collections.<String, DataValue> emptyMap () );
public RegistrationManager ( final SymbolController symbolController )
{
this.controller = symbolController;
}
public void dispose ()
{
for ( final DataItemRegistration registration : this.registrations.values () )
{
registration.dispose ();
}
this.registrations.clear ();
}
public void unregisterItem ( final String name )
{
final DataItemRegistration registration = this.registrations.remove ( name );
if ( registration != null )
{
registration.dispose ();
}
}
public void registerItem ( final String name, final String itemId, final String connectionId, final boolean ignoreSummary, final boolean nullInvalid )
{
if ( itemId == null )
{
throw new IllegalArgumentException ( String.format ( "'itemId' must not be null" ) );
}
notifyChange ( name, DataItemValue.DISCONNECTED, ignoreSummary, nullInvalid );
final DataItemRegistration oldRegistration = this.registrations.put ( name, new DataItemRegistration ( this, name, itemId, connectionId, ignoreSummary, nullInvalid ) );
if ( oldRegistration != null )
{
oldRegistration.dispose ();
}
}
public void notifyChange ( final String name, final DataItemValue value, final boolean ignoreSummary, final boolean nullInvalid )
{
Map<String, DataValue> currentMap;
Map<String, DataValue> newMap;
do
{
currentMap = this.currentValues.get ();
newMap = new LinkedHashMap<String, DataValue> ( currentMap );
newMap.put ( name, new DataValue ( value, ignoreSummary, nullInvalid ) );
} while ( !this.currentValues.compareAndSet ( currentMap, newMap ) );
this.controller.triggerDataUpdate ();
}
public Map<String, DataValue> getData ()
{
return Collections.unmodifiableMap ( this.currentValues.get () );
}
public void startWrite ( final String connectionId, final String itemId, final Variant value ) throws InterruptedException
{
final ConnectionIdTracker connectionTracker = new ConnectionIdTracker ( Activator.getDefault ().getBundle ().getBundleContext (), connectionId, null, ConnectionService.class );
connectionTracker.open ();
try
{
final ConnectionService service = (ConnectionService)connectionTracker.waitForService ( SERVICE_TIMEOUT );
service.getConnection ().write ( itemId, value, null, null );
}
finally
{
connectionTracker.close ();
}
}
public void startWriteAttributes ( final String connectionId, final String itemId, final Map<String, Variant> attributes ) throws InterruptedException
{
final ConnectionIdTracker connectionTracker = new ConnectionIdTracker ( Activator.getDefault ().getBundle ().getBundleContext (), connectionId, null, ConnectionService.class );
connectionTracker.open ();
try
{
final ConnectionService service = (ConnectionService)connectionTracker.waitForService ( SERVICE_TIMEOUT );
service.getConnection ().writeAttributes ( itemId, attributes, null, null );
}
finally
{
connectionTracker.close ();
}
}
}