All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.esrf.TangoApi.events.EventConsumer Maven / Gradle / Ivy

There is a newer version: 10.0.0
Show newest version
//+======================================================================
// $Source$
//
// Project:   Tango
//
// Description:  java source code for the TANGO client/server API.
//
// $Author: ingvord $
//
// Copyright (C) :      2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,
//						European Synchrotron Radiation Facility
//                      BP 220, Grenoble 38043
//                      FRANCE
//
// This file is part of Tango.
//
// Tango is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// Tango 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 for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with Tango.  If not, see .
//
// $Revision: 28343 $
//
//-======================================================================


package fr.esrf.TangoApi.events;


import fr.esrf.Tango.*;
import fr.esrf.TangoApi.*;
import fr.esrf.TangoDs.Except;
import fr.esrf.TangoDs.TangoConst;
import org.omg.CosNotifyComm.StructuredPushConsumerPOA;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;


/**
 * @author pascal_verdier
 */
abstract public class EventConsumer extends StructuredPushConsumerPOA
        implements TangoConst, IEventConsumer {

    protected static int subscribe_event_id = 0;
    protected static Hashtable   channel_map        = new Hashtable<>();
    protected static Hashtable               device_channel_map = new Hashtable<>();
    protected static Hashtable  event_callback_map = new Hashtable<>();
    protected static Hashtable  failed_event_callback_map = new Hashtable<>();

    //  Alternate tango hosts
    static List possibleTangoHosts = new ArrayList<>();
    //===============================================================
    //===============================================================
    abstract protected  void checkDeviceConnection(DeviceProxy device,
                        String attribute, DeviceData deviceData, String event_name) throws DevFailed;

    abstract protected void connect_event_channel(ConnectionStructure cs) throws DevFailed;
    abstract protected boolean reSubscribe(EventChannelStruct event_channel_struct,
                                  EventCallBackStruct callback_struct);
    abstract protected void removeFilters(EventCallBackStruct cb_struct) throws DevFailed;

    abstract protected String getEventSubscriptionCommandName();

    abstract protected void checkIfAlreadyConnected(DeviceProxy device,
                                           String attribute,
                                           String event_name,
                                           CallBack callback,
                                           int max_size,
                                           boolean stateless) throws DevFailed;

    abstract protected void setAdditionalInfoToEventCallBackStruct(EventCallBackStruct callback_struct,
                            String device_name, String attribute, String event_name,
                            String[]filters, EventChannelStruct channel_struct)throws DevFailed;

    abstract protected void unsubscribeTheEvent(EventCallBackStruct callbackStruct) throws DevFailed;

    abstract protected void checkIfHeartbeatSkipped(String name, EventChannelStruct eventChannelStruct);
    //===============================================================
    //===============================================================
    protected EventConsumer() throws DevFailed {
        //  Default constructor
        //  Start the KeepAliveThread loop
        KeepAliveThread.getInstance();
    }
    //===============================================================
    //===============================================================
    static Hashtable getChannelMap() {
        return channel_map;
    }
    //===============================================================
    //===============================================================
    static Hashtable  getEventCallbackMap() {
        return event_callback_map;
    }
    //===============================================================
    //===============================================================
    public void disconnect_structured_push_consumer() {
        System.out.println("calling EventConsumer.disconnect_structured_push_consumer()");
    }
    //===============================================================
    //===============================================================
    public void offer_change(org.omg.CosNotification.EventType[] added, org.omg.CosNotification.EventType[] removed)
            throws org.omg.CosNotifyComm.InvalidEventType {
        System.out.println("calling EventConsumer.offer_change()");
    }
    //===============================================================
    //===============================================================
    private EventChannelStruct getEventChannelStruct(String channelName) {
        if (channel_map.containsKey(channelName)) {
            return channel_map.get(channelName);
        }
        //  Check with other TangoHosts using possibleTangoHosts as header
        int index = channelName.indexOf("//");
        if (index>0) {
            index = channelName.indexOf('/', index+2); //  "//".length()
            for (String possibleTangoHost : possibleTangoHosts) {
                String key = possibleTangoHost + channelName.substring(index);
                if (channel_map.containsKey(key))
                    return channel_map.get(key);
            }
        }
        return null;
    }
    //===============================================================
    //===============================================================
    protected void push_structured_event_heartbeat(String channelName) {
        //  ToDo
        try {
            //  If full name try to get structure from channel_map with different tango hosts
            if (channelName.startsWith("tango://")) {
                EventChannelStruct  eventChannelStruct = getEventChannelStruct(channelName);
                if (eventChannelStruct!=null) {
                    eventChannelStruct.last_heartbeat = System.currentTimeMillis();
                    return;
                }
            }

            //  Not Found !
            //	In case of (use_db==false)
            //	domain name is only device name
            //	but key is full name (//host:port/a/b/c....)
            Enumeration keys = channel_map.keys();
            boolean found = false;
            while (keys.hasMoreElements() && !found) {
                String name = (String) keys.nextElement();
                EventChannelStruct eventChannelStruct = channel_map.get(name);
                //  Check with device name for adm device
                String  admDeviceName = eventChannelStruct.adm_device_proxy.name();
                if (admDeviceName.equalsIgnoreCase(channelName)) {
                    eventChannelStruct.last_heartbeat = System.currentTimeMillis();
                    found = true;
                }
            }
            if (!found)
                System.err.println(channelName + " Not found");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //===============================================================
    //===============================================================
    private void callEventSubscriptionAndConnect(DeviceProxy device,
                                                 String attribute,
                                                 String eventType) throws DevFailed {

        String device_name = device.name();
        if (attribute==null) // Interface change event on device.
            attribute = "";
        String[] info = new String[] {
                device_name,
                attribute,
                "subscribe",
                eventType,
                Integer.toString(device.get_idl_version())
        };
        DeviceData argIn = new DeviceData();
        argIn.insert(info);
        String cmdName = getEventSubscriptionCommandName();
        ApiUtil.printTrace(device.get_adm_dev().name() + ".command_inout(\"" +
                    cmdName + "\") for " + device_name + "/" + attribute + "." + eventType);
        DeviceData argOut = device.get_adm_dev().command_inout(cmdName, argIn);
        ApiUtil.printTrace("    command_inout done.");

        //	And then connect to device
        checkDeviceConnection(device, attribute, argOut, eventType);
    }
    //===============================================================
    //===============================================================
    public int subscribe_event(DeviceProxy device,
                               String attribute,
                               int event,
                               CallBack callback,
                               String[] filters,
                               boolean stateless)
            throws DevFailed {
        return subscribe_event(device, attribute, event, callback, -1, filters, stateless);
    }

    //===============================================================
    //===============================================================
    public int subscribe_event(DeviceProxy device,
                               String attribute,
                               int event,
                               int max_size,
                               String[] filters,
                               boolean stateless)
            throws DevFailed {
        return subscribe_event(device, attribute, event, null, max_size, filters, stateless);
    }

    //===============================================================
    //===============================================================
    public int subscribe_event(DeviceProxy device,
                               String attribute,
                               int event,
                               CallBack callback,
                               int max_size,
                               String[] filters,
                               boolean stateless)
            throws DevFailed {
        //	Set the event name;
        String event_name = eventNames[event];
        ApiUtil.printTrace("=============> subscribing for " + device.name() +
                ((attribute==null)? "" : "/" + attribute) + "." +event_name);

        //	Check if already connected
        checkIfAlreadyConnected(device, attribute, event_name, callback, max_size, stateless);

        //	if no callback (null), create EventQueue
        if (callback == null && max_size >= 0) {
            //	Check if already created (in case of reconnection stateless mode)
            if (device.getEventQueue() == null)
                if (max_size > 0)
                    device.setEventQueue(new EventQueue(max_size));
                else
                    device.setEventQueue(new EventQueue());
        }

        String deviceName = device.fullName();
        String callback_key = deviceName.toLowerCase();
        try {
            //  Check idl version
            if (device.get_idl_version()>=5) {
                switch (event_name) {
                    case "intr_change":
                        //  No IDL for interface change
                        callback_key += "." + event_name;
                        break;
                    case "pipe":
                        //    No IDL for pipe
                        callback_key += "/" + attribute + "." + event_name;
                        break;
                    default:
                        callback_key += "/" + attribute + ".idl" + device.get_idl_version() + "_" + event_name;
                        break;
                }
            }
            else
                callback_key += "/" + attribute + "." + event_name;

            //	Inform server that we want to subscribe and try to connect
            ApiUtil.printTrace("calling callEventSubscriptionAndConnect() method");
            String  att = (attribute==null)? null : attribute.toLowerCase();
            callEventSubscriptionAndConnect(device, att, event_name);
            ApiUtil.printTrace("call callEventSubscriptionAndConnect() method done");
        } catch (DevFailed e) {
            //  re throw if not stateless
            if (!stateless || e.errors[0].desc.equals(ZMQutils.SUBSCRIBE_COMMAND_NOT_FOUND)) {
                throw e;
            }
            else {
                //	Build Event CallBack Structure and add it to map
                subscribe_event_id++;
                EventCallBackStruct new_event_callback_struct =
                        new EventCallBackStruct(device,
                                attribute,
                                event_name,
                                "",
                                callback,
                                max_size,
                                subscribe_event_id,
                                event,
//                                "",
//                                -1,
                                filters,
                                false);
                failed_event_callback_map.put(callback_key, new_event_callback_struct);
                return subscribe_event_id;
            }
        }

        //	Prepare filters for heartbeat events on channelName
        String channelName = device_channel_map.get(deviceName);
        if (channelName==null) {
            //  If from notifd, tango host not used.
            int start = deviceName.indexOf('/', "tango:// ".length());
            deviceName = deviceName.substring(start+1);
            channelName = device_channel_map.get(deviceName);
        }
        EventChannelStruct event_channel_struct = channel_map.get(channelName);
        event_channel_struct.last_subscribed = System.currentTimeMillis();

        //	Check if a new event or a re-trying one
        int evnt_id;
        EventCallBackStruct failed_struct = failed_event_callback_map.get(callback_key);
        if (failed_struct == null) {
            //	It is a new one
            subscribe_event_id++;
            evnt_id = subscribe_event_id;
        } else
            evnt_id = failed_struct.id;

        //	Build Event CallBack Structure if any
        EventCallBackStruct new_event_callback_struct =
                new EventCallBackStruct(device,
                        attribute,
                        event_name,
                        channelName,
                        callback,
                        max_size,
                        evnt_id,
                        event,
//                        constraint_expr,
//                        filter_id,
                        filters,
                        true);
        setAdditionalInfoToEventCallBackStruct(new_event_callback_struct,
                deviceName, attribute, event_name, filters, event_channel_struct);
        event_callback_map.put(callback_key, new_event_callback_struct);


        //	Thread to read the attribute by a simple synchronous call and
        //	force callback execution after release monitor.
        //	This is necessary for the first point in "change" mode,
        //	but it is not necessary to be serialized in case of
        //	read attribute or callback execution a little bit long.
        if ((event == CHANGE_EVENT) ||
                (event == PERIODIC_EVENT) ||
                (event == PIPE_EVENT) ||
                (event == ARCHIVE_EVENT) ||
                (event == USER_EVENT) ||
                (event == INTERFACE_CHANGE) ||
                (event == ATT_CONF_EVENT)) {
            new PushAttrValueLater(new_event_callback_struct).start();
        }
        return evnt_id;
    }
    //===============================================================
    /**
     * Try to connect if it failed at subscribe
     */
    //===============================================================
    static void subscribeIfNotDone() {
        Enumeration callbackKeys = failed_event_callback_map.keys();
        while (callbackKeys.hasMoreElements()) {
            String callbackKey = callbackKeys.nextElement();
            EventCallBackStruct eventCallBackStruct = failed_event_callback_map.get(callbackKey);
            if (eventCallBackStruct.consumer!=null) {
                try {
                    subscribeIfNotDone(eventCallBackStruct, callbackKey);
                } catch (DevFailed e) {
                    //	Send error to callback
                    sendErrorToCallback(eventCallBackStruct, callbackKey, e);
                }
            }
            else {
                if (EventConsumerUtil.isZmqLoadable()) {
                    try {
                        //  Try for zmq
                        eventCallBackStruct.consumer = ZmqEventConsumer.getInstance();
                        subscribeIfNotDone(eventCallBackStruct, callbackKey);
                        return;

                    }
                    catch (DevFailed e) {
                        if (e.errors[0].desc.equals(ZMQutils.SUBSCRIBE_COMMAND_NOT_FOUND)) {
                            try {
                                //  Try for notifd
                                eventCallBackStruct.consumer = NotifdEventConsumer.getInstance();
                                subscribeIfNotDone(eventCallBackStruct, callbackKey);
                                return;
                            }
                            catch (DevFailed e2) {
								//TODO use DevFailedUtils#printDevFailed from JTangoCommons
                               System.err.println(e2.errors[0].desc);
                                //  reset if both have failed
                                eventCallBackStruct.consumer = null;
                                //	Send error to callback
                                sendErrorToCallback(eventCallBackStruct, callbackKey, e2);
                            }
                        }
                        else {
                            //	Send error to callback
                            eventCallBackStruct.consumer = null;
                            sendErrorToCallback(eventCallBackStruct, callbackKey, e);
                        }
                    }
                }
                else
                {
                    try {
                        //  Try for notifd
                        eventCallBackStruct.consumer = NotifdEventConsumer.getInstance();
                        subscribeIfNotDone(eventCallBackStruct, callbackKey);
                        return;
                    }
                    catch (DevFailed e) {
						//TODO use DevFailedUtils#printDevFailed from JTangoCommons
                        System.err.println(e.errors[0].desc);
                        //	Send error to callback
                        sendErrorToCallback(eventCallBackStruct, callbackKey, e);
                    }
                }
            }
        }
    }
    //===============================================================
    //===============================================================
    private static void sendErrorToCallback(EventCallBackStruct cs, String callbackKey, DevFailed e) {

        int source = (cs.consumer instanceof NotifdEventConsumer)?
                EventData.NOTIFD_EVENT : EventData.ZMQ_EVENT;
        EventData eventData =
                new EventData(cs.device, callbackKey,
                        cs.event_name, source,
                        cs.event_type, null, null, null, null, null, e.errors);

        if (cs.use_ev_queue) {
            EventQueue ev_queue = cs.device.getEventQueue();
            ev_queue.insert_event(eventData);
        } else
            cs.callback.push_event(eventData);
    }
     //===============================================================
    //===============================================================
    private static void subscribeIfNotDone(EventCallBackStruct eventCallBackStruct,
                                          String callbackKey) throws DevFailed{

        eventCallBackStruct.consumer.subscribe_event(
                eventCallBackStruct.device,
                eventCallBackStruct.attr_name,
                eventCallBackStruct.event_type,
                eventCallBackStruct.callback,
                eventCallBackStruct.max_size,
                eventCallBackStruct.filters,
                false);
        failed_event_callback_map.remove(callbackKey);
    }
    //===============================================================
    //===============================================================
    static EventCallBackStruct getCallBackStruct(Hashtable map, int id) {
        Enumeration keys = map.keys();
        while (keys.hasMoreElements()) {
            String name = (String) keys.nextElement();
            EventCallBackStruct callback_struct =
                    (EventCallBackStruct) map.get(name);
            if (callback_struct.id == id)
                return callback_struct;
        }
        return null;
    }

    //===============================================================
    //===============================================================
    private void removeCallBackStruct(Hashtable map, EventCallBackStruct cb_struct) throws DevFailed {
        removeFilters(cb_struct);
        String callback_key = cb_struct.device.name().toLowerCase() +
                "/" + cb_struct.attr_name + "." + cb_struct.event_name;
        map.remove(callback_key);
    }

    //===============================================================
    //===============================================================
    public void unsubscribe_event(int event_id) throws DevFailed {
        //	Get callback struct for event ID
        EventCallBackStruct callbackStruct =
                getCallBackStruct(event_callback_map, event_id);
        if (callbackStruct != null) {
            removeCallBackStruct(event_callback_map, callbackStruct);
            unsubscribeTheEvent(callbackStruct);
        }
        else {
            //	If not found check if in failed map
            callbackStruct =
                    getCallBackStruct(failed_event_callback_map, event_id);
            if (callbackStruct != null)
                removeCallBackStruct(failed_event_callback_map, callbackStruct);
            else
                Except.throw_event_system_failed("API_EventNotFound",
                        "Failed to unsubscribe event, the event id (" + event_id +
                                ") specified does not correspond with any known one",
                        "EventConsumer.unsubscribe_event()");
        }
    }

    //===============================================================
    /*
     * Re subscribe event selected by name
     */
    //===============================================================
     void reSubscribeByName(EventChannelStruct event_channel_struct, String name) {
        Enumeration callback_structs = event_callback_map.elements();
        while (callback_structs.hasMoreElements()) {
            EventCallBackStruct callback_struct = (EventCallBackStruct) callback_structs.nextElement();
            if (callback_struct.channel_name.equals(name)) {
                reSubscribe(event_channel_struct, callback_struct);
            }
        }
    }
    //===============================================================
    /*
     * Push event containing exception
     */
    //===============================================================
    void pushReceivedException(EventChannelStruct event_channel_struct, EventCallBackStruct callback_struct, DevError error) {
        try {
            if (event_channel_struct != null) {
                if (event_channel_struct.consumer instanceof NotifdEventConsumer) {
                    if (!callback_struct.filter_ok) {
                        callback_struct.filter_id = NotifdEventConsumer.getInstance().add_filter_for_channel(
                                event_channel_struct, callback_struct.filter_constraint);
                        callback_struct.filter_ok = true;
                    }
                }
            } else
                return;

            int eventSource = (event_channel_struct.consumer instanceof NotifdEventConsumer)?
                    EventData.NOTIFD_EVENT : EventData.ZMQ_EVENT;
            DevError[] errors = {error};
            String domain_name = callback_struct.device.name();
            if (callback_struct.attr_name!=null)
                domain_name += "/" + callback_struct.attr_name.toLowerCase();
            EventData event_data =
                    new EventData(event_channel_struct.adm_device_proxy,
                            domain_name, callback_struct.event_name, callback_struct.event_type,
                            eventSource, null, null, null, null, null, errors);

            CallBack callback = callback_struct.callback;
            event_data.device = callback_struct.device;
            event_data.name = callback_struct.device.name();
            event_data.event = callback_struct.event_name;

            if (callback_struct.use_ev_queue) {
                EventQueue ev_queue = callback_struct.device.getEventQueue();
                ev_queue.insert_event(event_data);
            } else
                callback.push_event(event_data);

        } catch (DevFailed e) { /* */ }
    }
    //===============================================================
    /*
     * Read attribute and push result as event.
     */
    //===============================================================
    void readAttributeAndPush(EventChannelStruct eventChannelStruct, EventCallBackStruct callbackStruct) {
        //	Check if known event name
        boolean found = false;
        for (int i = 0; !found && i < eventNames.length; i++)
            found = callbackStruct.event_name.equals(eventNames[i]);
        if (!found)
            return;

        //	Else do the synchronous call
        DeviceAttribute deviceAttribute = null;
        DevicePipe      devicePipe = null;
        AttributeInfoEx info = null;
        DeviceInterface deviceInterface = null;
        DevError[] err = null;
        String domain_name = callbackStruct.device.name() + "/" + callbackStruct.attr_name;
        boolean old_transp = callbackStruct.device.get_transparency_reconnection();
        callbackStruct.device.set_transparency_reconnection(true);
        try {
            callbackStruct.setSynchronousDone(false);
            if (callbackStruct.event_name.equals(eventNames[ATT_CONF_EVENT])) {
                info = callbackStruct.device.get_attribute_info_ex(callbackStruct.attr_name);
            }
            else
            if (callbackStruct.event_name.equals(eventNames[PIPE_EVENT])) {
                devicePipe = callbackStruct.device.readPipe(callbackStruct.attr_name);
            }
            else
            if (callbackStruct.event_name.equals(eventNames[INTERFACE_CHANGE])) {
                deviceInterface = new DeviceInterface(callbackStruct.device);
            }
            else {
                deviceAttribute = callbackStruct.device.read_attribute(callbackStruct.attr_name);
            }
            callbackStruct.setSynchronousDone(true);

            // The reconnection worked fine. The heartbeat should come back now,
            // when the notifd has not closed the connection.
            // Increase the counter to detect when the heartbeat is not coming back.
            eventChannelStruct.has_notifd_closed_the_connection++;
        } catch (DevFailed e) {
            err = e.errors;
        }
        callbackStruct.device.set_transparency_reconnection(old_transp);

        //  Build event data and push it.
        //  ToDo DevIntrChange
        EventData eventData =
                new EventData(callbackStruct.device,
                        domain_name,
                        callbackStruct.event_name,
                        callbackStruct.event_type,
                        getSource(eventChannelStruct.consumer),
                        deviceAttribute, devicePipe,
                        info, null, deviceInterface, err);

        if (callbackStruct.use_ev_queue) {
            EventQueue ev_queue = callbackStruct.device.getEventQueue();
            ev_queue.insert_event(eventData);
        } else {
            callbackStruct.callback.push_event(eventData);
        }
    }



    //===============================================================
    //===============================================================
    private int getSource(EventConsumer consumer) {
        return (consumer instanceof NotifdEventConsumer) ?
            EventData.NOTIFD_EVENT : EventData.ZMQ_EVENT;
    }
    //===============================================================
    /**
     * Thread to read the attribute by a simple synchronous call and
     * force callback execution after release monitor.
     * This is necessary for the first point in "change" mode,
     * but it is not necessary to be serialized in case of
     * read attribute or callback execution a little bit long.
     */
    //===============================================================
    class PushAttrValueLater extends Thread {
        private EventCallBackStruct cb_struct;

        //===============================================================
        PushAttrValueLater(EventCallBackStruct cb_struct) {
            this.cb_struct = cb_struct;
        }

        //===============================================================
        public void run() {
             //	Then read attribute
            DeviceAttribute deviceAttribute = null;
            DevicePipe      devicePipe = null;
            AttributeInfoEx attributeInfo = null;
            DeviceInterface deviceInterface = null;
            DevError[] err = null;
            String eventName = cb_struct.device.name();
            if (cb_struct.event_type!=INTERFACE_CHANGE) {

                eventName += "/" + cb_struct.attr_name.toLowerCase();
            }
            try {
                if (cb_struct.event_type==INTERFACE_CHANGE) {
                    deviceInterface = new DeviceInterface(cb_struct.device);
                }
                else
                if (cb_struct.event_type==PIPE_EVENT) {
                    devicePipe = cb_struct.device.readPipe(cb_struct.attr_name);
                }
                else
                if (cb_struct.event_type==ATT_CONF_EVENT) {
                    attributeInfo = cb_struct.device.get_attribute_info_ex(cb_struct.attr_name);
                }
                else {
                    deviceAttribute = cb_struct.device.read_attribute(cb_struct.attr_name);
                }
            } catch (DevFailed e) {
                err = e.errors;
            }

            //	And push value
            int eventSource = (cb_struct.consumer instanceof NotifdEventConsumer)?
                    EventData.NOTIFD_EVENT : EventData.ZMQ_EVENT;
            EventData event_data =
                    new EventData(cb_struct.device,
                            eventName,
                            cb_struct.event_name,
                            cb_struct.event_type,
                            eventSource,
                            deviceAttribute,
                            devicePipe,
                            attributeInfo, null, deviceInterface, err);
            if (cb_struct.use_ev_queue) {
                EventQueue ev_queue = cb_struct.device.getEventQueue();
                ev_queue.insert_event(event_data);
            } else
                cb_struct.callback.push_event(event_data);
            cb_struct.setSynchronousDone(true);
        }
    }
    //===============================================================
    //===============================================================





    //===============================================================
    //===============================================================
    protected class ConnectionStructure {
        String      tangoHost;
        String      channelName;
        String      attributeName;
        String      deviceName;
        String      eventName;
        Database    database;
        DeviceData  deviceData = null;
        boolean     reconnect = false;
        //===========================================================
        ConnectionStructure(String tangoHost,
                            String channelName,
                            String deviceName,
                            String attributeName,
                            String eventName,
                            Database database,
                            DeviceData deviceData,
                            boolean reconnect) {
            this.tangoHost      = tangoHost;
            this.channelName    = channelName;
            this.deviceName     = deviceName;
            this.attributeName  = attributeName;
            this.eventName      = eventName;
            this.database          = database;
            this.deviceData     = deviceData;
            this.reconnect      = reconnect;
        }
        //===========================================================
        ConnectionStructure(String tangoHost, String name, Database dbase, boolean reconnect) {
            this(tangoHost, name, null, null, null, dbase, null, reconnect);
        }
        //===========================================================
        public String toString() {
            return "channel name: " + channelName +
                 "\ndatabase:     " + database +
                 "\nreconnect:    " + reconnect;
        }
        //===========================================================
    }
    //===============================================================
    //===============================================================
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy