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

fr.esrf.TangoDs.Util 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: pascal_verdier $
//
// 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: 25482 $
//
//-======================================================================


package fr.esrf.TangoDs;

import fr.esrf.Tango.*;
import fr.esrf.TangoApi.ApiUtil;
import fr.esrf.TangoApi.Database;
import fr.esrf.TangoApi.DbDevImportInfo;
import org.apache.log4j.Level;
import org.omg.CORBA.*;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;

import java.lang.Object;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Iterator;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.regex.Pattern;

import static fr.esrf.TangoDs.TangoConst.*;

/**
 * This class is a used to store TANGO device server process data and to provide
 * the user with a set of utilities method. This class is implemented using the
 * singleton design pattern. Therefore a device server process can have only one
 * instance of this class and its constructor is not public.
 *
 * @deprecated use {@link org.tango.server.ServerManager}
 *
 * @author $Author: pascal_verdier $
 * @version $Revision: 25482 $
 */
@Deprecated
@SuppressWarnings( { "NestedTryStatement" })
public class Util {
    /**
     * The UtilPrint object used for level 1 printing
     */

    static public UtilPrint out1;
    /**
     * The UtilPrint object used for level 2 printing
     */

    static public UtilPrint out2;
    /**
     * The UtilPrint object used for level 3 printing
     */

    static public UtilPrint out3;
    /**
     * The UtilPrint object used for level 4 printing
     */
    static public UtilPrint out4;
    /**
     * The UtilPrint object used for level 5 printing
     */

    static public UtilPrint out5;
    static public boolean _UseDb = true;
    static public boolean _daemon = false;
    static public int _sleep_between_connect = 10;
    static int _tracelevel = 0;
    /**
     * Get the serial model (TangoConst.BY_DEVICE, TangoConst.BY_Class or
     * TangoConst.NO_SYNC)
     */
    // ==========================================================
    static int access_counter = 0;
    private static Util _instance = null;
    static private int serial_model = BY_DEVICE;
    /**
     * returns the POA thread_pool_max value for ORB
     */
    // ==========================================================
    private static int thread_pool_max = 20; // Default value from
    // jacob.property (in jacrob
    // distrib.)
    private static boolean thread_pool_max_done = false;
    private final UtilExt ext;
    private final Vector cmd_line_name_list = new Vector();
    private final Vector class_name_list = new Vector();
    private String ds_exec_name;
    private String ds_instance_name;
    private StringBuffer ds_name;
    private String real_server_name;
    private String db_host;
    private Database db = null;
    private String hostname;
    private String version_str;
    private String pid_str;

    // +----------------------------------------------------------------------------
    //
    // method : instance()
    // 
    // description : static method to retrieve the Util object once it has
    // been initialised
    //
    // -----------------------------------------------------------------------------
    private Vector class_list;

    // +----------------------------------------------------------------------------
    //
    // method : Init()
    // 
    // description : static method to create/retrieve the Util object.
    // This method is the only one which enables a user to
    // create the object
    //
    // in : - argv : The command line argument
    // - class_name : The device server class name
    //
    // -----------------------------------------------------------------------------
    private ORB orb;

    // +----------------------------------------------------------------------------
    //
    // method : Util()
    // 
    // description : Constructor of the Util class.
    //
    // in : - argv : The command line argument
    // - class_name : The device server class name
    //
    // -----------------------------------------------------------------------------
    private POA _poa;

    // +----------------------------------------------------------------------------
    //
    // method : ckeck_args()
    // 
    // description : Check the command line arguments. The first one is
    // mandatory and is the server personal name. A -v option
    // is authorized with an optional argument. The other
    // option should be ORBacus option
    //
    // in : - argv : The command line argument
    //
    // -----------------------------------------------------------------------------

    /**
     * Constructs a newly allocated Util object.
     *
     * This constructor is protected following the singleton pattern
     *
     * @param argv
     *            The device server command line argument
     * @param class_name
     *            The TANGO device class name
     *
     */
    protected Util(final String[] argv, final String class_name) {

	//
	// Init ds executable name
	//

	ds_exec_name = class_name;

	//
	// Check server option
	//

	if (argv.length < 1) {
	    print_usage();
	    System.exit(-1);
	}

	//
	// Manage command line option (instance name and -v option)
	//

	check_args(argv);

	//
	// Build the four print objects
	//

	out1 = new UtilPrint(Level.INFO);
	out2 = new UtilPrint(Level.INFO);
	out3 = new UtilPrint(Level.DEBUG);
	out4 = new UtilPrint(Level.DEBUG);
	out5 = new UtilPrint(Level.DEBUG);

	//
	// Get Tango_host property
	//
	if (_UseDb == true) {
	    read_env();
	}

	org.omg.PortableServer.POA root_poa = null;
	try {
	    // Initialise CORBA
	    ApiUtil.set_in_server(true);
	    orb = ApiUtil.get_orb();

	    root_poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
	    // boot_manager =
	    // BootManagerHelper.narrow(orb.resolve_initial_references("BootManager"));
	} catch (final InvalidName ex) {
	    System.err.println("Can't intialise CORBA ORB !!!");
	    System.err.println("Failed when trying to get root POA reference");
	    System.exit(-1);
	} catch (final DevFailed ex) {
	    System.err.println("Can't intialise CORBA ORB !!!");
	    System.err.println("Failed when trying to get root POA reference");
	    System.exit(-1);
	}

	//
	// If the database is not used, create a POA with the USER_ID policy
	//

	org.omg.PortableServer.POA nodb_poa = null;
	try {
	    if (Util._UseDb == false) {
		final org.omg.PortableServer.IdAssignmentPolicy pol = root_poa
			.create_id_assignment_policy(org.omg.PortableServer.IdAssignmentPolicyValue.USER_ID);

		final org.omg.CORBA.Policy[] policy_list = new org.omg.CORBA.Policy[2];
		policy_list[0] = pol;
		policy_list[1] = root_poa
			.create_lifespan_policy(org.omg.PortableServer.LifespanPolicyValue.PERSISTENT);

		final org.omg.PortableServer.POAManager manager = root_poa.the_POAManager();
		nodb_poa = root_poa.create_POA("nodb_poa", manager, policy_list);
	    }
	} catch (final org.omg.PortableServer.POAPackage.AdapterAlreadyExists ex) {
	    System.err.println("Can't create CORBA POA !!!");
	    System.err.println("POA already exists");
	    System.exit(-1);
	} catch (final org.omg.PortableServer.POAPackage.InvalidPolicy ex) {
	    System.err.println("Can't create CORBA POA !!!");
	    System.err.println("Invalid policy");
	    System.exit(-1);
	}

	//
	// Store POA
	//

	if (_UseDb == true) {
	    _poa = root_poa;
	} else {
	    _poa = nodb_poa;
	}

	if (_UseDb == true) {

	    //
	    // Connect to the database
	    //

	    connect_db();
	}

	//
	// Connect to the database
	//
	Logging.init(ds_name.toString(), _tracelevel, db);

	if (_UseDb == true) {
	    //
	    // check if the server is not already running somewhere else
	    //

	    server_already_running();

	}

	//
	// create UtilExt class
	//
	ext = new UtilExt();
	//
	// Create the polling thread and start it
	//

	ext.poll_th = new PollThread(ext.shared_data, ext.poll_mon);
	ext.poll_th.start();

	//
	// Get process PID, host name and Tango version
	//

	misc_init();

	Util.out4.println("Util object singleton constructed");
    }

    // +----------------------------------------------------------------------------
    //
    // method : Tango::print_usage()
    // 
    // description : Print device server command line syntax
    //
    // in : - serv_name : The server name
    //
    // -----------------------------------------------------------------------------

    /**
     * Get the singleton object reference.
     * 

* This method returns a reference to the object of the Util class. If the * class has not been initialised with it's init method, this method print a * message and abort the device server process * * @return The Util object reference */ public static Util instance() { if (_instance == null) { System.err.println("Util is not initialised !!!"); System.err.println("Exiting"); System.exit(-1); } return _instance; } /** * Create and get the singleton object reference. *

* This method returns a reference to the object of the Util class. If the * class singleton object has not been created, it will be instanciated * * @param argv The process argument String array * @param exec_name The device server executable name * @return The Util object reference */ public static Util init(final String[] argv, final String exec_name) { if (_instance == null) { _instance = new Util(argv, exec_name); } return _instance; } // +---------------------------------------------------------------------------- // // method : read_env() // // description : Get the TANGO_HOST system property and extract the // database server host and port for it. // This system property should be set when the java // interpreter is started with its -D option // // ----------------------------------------------------------------------------- /** * Create and return an empty CORBA Any object. *

* Create an empty CORBA Any object. Could be used by command which does not * return anything to the client. This method also prints a message on * screen (level 4) before it returns * * @param cmd The cmd name which use this empty Any. Only used to create the * thrown exception (in case of) and in the displayed message * @return The empty CORBA Any * @throws DevFailed If the Any object creation failed. Click here to read DevFailed exception specification */ public static Any return_empty_any(final String cmd) throws DevFailed { Any ret = null; // noinspection ErrorNotRethrown try { ret = Util.instance().get_orb().create_any(); } catch (final OutOfMemoryError ex) { final StringBuffer o = new StringBuffer(cmd); o.append(".execute"); Util.out3.println("Bad allocation while in " + cmd + ".execute()"); Except.throw_exception("API_MemoryAllocation", "Can't allocate memory in server", o .toString()); } Util.out4.println("Leaving " + cmd + ".execute()"); return ret; } // +---------------------------------------------------------------------------- // // method : misc_init() // // description : This method initialises miscellaneous variable which // are needed later in the device server startup // sequence. These variables are : // The process ID // The host name // The Tango version // // ----------------------------------------------------------------------------- /** * idem fabs in c libraray. */ // =============================================================== public static double fabs(final double d) { if (d >= 0.0) { return d; } else { return -1.0 * d; } } // +---------------------------------------------------------------------------- // // method : connect_db() // // description : This method builds a connection to the Tango database // servant. It uses the db_host and db_port object // variables. The Tango database server implements its // CORBA object as named servant. // // ----------------------------------------------------------------------------- static int getPoaThreadPoolMax() { if (!thread_pool_max_done) { final String str = System.getProperty("jacorb.poa.thread_pool_max"); int value; try { value = Integer.parseInt(str); if (value > 0) { thread_pool_max = value; } } catch (final NumberFormatException e) { } thread_pool_max_done = true; } return thread_pool_max; } // +---------------------------------------------------------------------------- // // method : server_already_running() // // description : Check if the same device server is not already running // somewhere else and refuse to start in this case // // ----------------------------------------------------------------------------- /** * Get the serial model (TangoConst.BY_DEVICE, TangoConst.BY_Class or * TangoConst.NO_SYNC) */ // ========================================================== static public int get_serial_model() { return serial_model; } // +---------------------------------------------------------------------------- // // method : server_init() // // description : To initialise all classes in the device server process // // ----------------------------------------------------------------------------- /** * Set the serial model. The default is TangoConst.BY_DEVICE * * @param model the specified model (TangoConst.BY_DEVICE, TangoConst.BY_Class * or TangoConst.NO_SYNC) */ // ========================================================== static public void set_serial_model(final int model) { serial_model = model; } // +---------------------------------------------------------------------------- // // method : server_run() // // description : To start a device server // // ----------------------------------------------------------------------------- static synchronized void increaseAccessConter() { access_counter++; } // +---------------------------------------------------------------------------- // // method : get_device_list() // // description : To return a list of device reference which name match the // specified pattern // // in : - pattern : The device name pattern // // ----------------------------------------------------------------------------- static synchronized void decreaseAccessConter() { access_counter--; } // +---------------------------------------------------------------------------- // // method : get_device_list_by_class() // // description : To return a reference to the vector of device for a // specific class // // in : - class_name : The class name // // ----------------------------------------------------------------------------- static synchronized int getAccessConter() { return access_counter; } // +---------------------------------------------------------------------------- // // method : get_device_by_name() // // description : To return a reference to the device object from its // name // // in : - dev_name : The device name // // ----------------------------------------------------------------------------- private void check_args(final String argv[]) { if (argv[0].charAt(0) == '-') { if (argv[0].equals("-?")) { print_usage(); printInstanceNames(); System.exit(0); } else { print_usage(); System.exit(-1); } } ds_instance_name = argv[0]; if (argv.length > 1) { int ind = 1; String dlist; while (ind < argv.length) { if (argv[ind].charAt(0) == '-') { switch (argv[ind].charAt(1)) { // // The verbose option // case 'v': if (argv[ind].length() == 2) { if (argv.length - 1 > ind) { if (argv[ind + 1].charAt(0) == '-') { set_trace_level(4); } else { print_usage(); System.exit(-1); } } else { set_trace_level(4); } ind++; } else { final String level_str = argv[ind].substring(2); int level = 0; try { level = Integer.parseInt(level_str); } catch (final NumberFormatException ex) { print_usage(); System.exit(-1); } set_trace_level(level); ind++; } break; // // Device server without database // case 'n': if (argv[ind].equals("-nodb") == false) { print_usage(); System.exit(-1); } else { _UseDb = false; ind++; } break; // // Device list (for device server without database) // case 'd': if (argv[ind].equals("-dlist") == false) { print_usage(); System.exit(-1); } else { if (_UseDb == true) { print_usage(); System.exit(-1); } ind++; if (ind == argv.length) { print_usage(); System.exit(-1); } else { dlist = argv[ind].toLowerCase(); // // Extract each device name // String str; int start = 0; int pos; while ((pos = dlist.indexOf(',', start)) != -1) { str = dlist.substring(start, pos); start = pos + 1; cmd_line_name_list.addElement(str); } if (start != dlist.length()) { str = dlist.substring(start); cmd_line_name_list.addElement(str); } // // Check that the same device name is not used // twice // int i, j; for (i = 0; i < cmd_line_name_list.size(); i++) { for (j = 0; j < cmd_line_name_list.size(); j++) { if (i != j) { if (cmd_line_name_list.elementAt(i).equals( cmd_line_name_list.elementAt(j))) { System.err .println("Each device name must have different name"); System.exit(-1); } } } } } } break; default: ind++; break; } } else { if (argv[ind - 1].substring(0, 2).equals("-v")) { print_usage(); System.exit(-1); } ind++; } } } // // Build server name in lower-case letters // real_server_name = ds_exec_name + "/" + ds_instance_name; ds_exec_name = ds_exec_name.toLowerCase(); ds_instance_name = ds_instance_name.toLowerCase(); ds_name = new StringBuffer(ds_exec_name); ds_name.append("/"); ds_name.append(ds_instance_name); // // Check that the server name is not too long // if (ds_name.length() > Tango_MaxServerNameLength) { System.err.println("The device server name is too long! Max length is " + Tango_MaxServerNameLength + " characters."); System.exit(-1); } } // +---------------------------------------------------------------------------- // // method : get_dserver_device() // // description : To return a reference to the dserver device automatically // attached to each device server process // // ----------------------------------------------------------------------------- private void print_usage() { System.err.print("usage : java -DTANGO_HOST=$TANGO_HOST " + ds_exec_name + " instance_name [-v[trace level]]"); System.err.println(" [-nodb [-dlist ]]"); } // +---------------------------------------------------------------------------- // // method : unregister_server() // // description : Unregister the server from the database // // ----------------------------------------------------------------------------- // +---------------------------------------------------------------------------- // // method : printInstanceNames // // description : Print server instances found in database // // in : - serv_name : The server name // // +---------------------------------------------------------------------------- private void printInstanceNames() { try { System.out.println("Instance name defined in database for server PowerSupply :"); final String[] instnames = ApiUtil.get_db_obj().get_instance_name_list(ds_exec_name); for (final String instname : instnames) { System.out.println("\t" + instname); } } catch (final DevFailed e) { Except.print_exception(e); } } // +------------------------------------------------------------------------- // // method : return_empty_any // // description : Build and return one emty any for all commands which // returns an empty any (obvious no!) // // arguments : in : - cmd : The command name // // -------------------------------------------------------------------------- private void read_env() { String env; try { if ((env = System.getProperty("TANGO_HOST")) == null) { if ((env = System.getenv("TANGO_HOST")) == null) { Except.throw_connection_failed("TangoApi_TANGO_HOST_NOT_SET", "Property \"TANGO_HOST\" not exported", "TangoDs.Util.read_env()"); } } assert env != null; if (env.indexOf(":") < 0) { Except.throw_connection_failed("TangoApi_TANGO_HOST_NOT_SET", "Unknown \"TANGO_HOST\" property " + env, "TangoDs.Util.read_env()"); } final String[] array = ApiUtil.parseTangoHost(env); db_host = array[0]; } catch (final DevFailed e) { Except.print_exception(e); System.exit(-1); } } // // Miscellaneous basic methods // private void misc_init() { // // Get PID // pid_str = String.valueOf(0); // // Get hostname // try { final String tmp_host1 = InetAddress.getLocalHost().toString(); int pos = tmp_host1.indexOf('/'); final String tmp_host2 = tmp_host1.substring(0, pos); pos = tmp_host2.indexOf('.'); if (pos == -1) { hostname = tmp_host2; } else { hostname = tmp_host2.substring(0, pos); } } catch (final UnknownHostException ex) { System.err.println("Cant retrieve server host name"); System.exit(1); } Util.out4.println("Hostname = " + hostname); // // Convert Tango version number to string (for device export) // version_str = String.valueOf(Tango_DevVersion); } /** * Connect the process to the TANGO database. * * If the connection to the database failed, a message is displayed on the * screen and the process is aborted */ public synchronized void connect_db() { // // Try to connect to the database // if (_daemon == true) { boolean connected = false; while (connected == false) { try { db = ApiUtil.get_db_obj(); if (db == null) { Util.out4.println("Can't contact db server, will try later"); try { wait(_sleep_between_connect * 1000); } catch (final InterruptedException ex) { } } else { connected = true; } } catch (final Exception e) { Util.out4.println("Can't contact db server, will try later"); try { wait(_sleep_between_connect * 1000); } catch (final InterruptedException ex) { } } } } else { try { db = ApiUtil.get_db_obj(); if (db == null) { System.err.println("Can't build connection to TANGO database server, exiting"); System.err.println("DB server host = " + db_host); System.exit(-1); } } catch (final Exception ex) { System.err.println("Can't build connection to TANGO database server, exiting"); System.err.println("DB server host = " + db_host); System.exit(-1); } } Util.out4.println("Connected to database"); } private synchronized void server_already_running() { Util.out4.println("Entering Tango::server_already_running method"); // // First, sleep a while in order to solve race condition for two // servers started at the "same time" and a schedulling happens between // the database check and the export device. This system is inherited // from what has been implemented for the TACO control system // final Random rand = new Random(); final int sl = rand.nextInt(1000); Util.out4.println("Waiting " + sl + " ms...."); try { wait(sl); } catch (final InterruptedException ex) { } // // Build device name and try to import it from database // final StringBuffer dev_name = new StringBuffer(Tango_DSDeviceDomain); dev_name.append('/'); dev_name.append(ds_name); final String dev_name_str = new String(dev_name); Device dev = null; try { final DbDevImportInfo db_dev = db.import_device(dev_name_str); Util.out4.println("db.import_device(" + dev_name_str + "); DONE "); Util.out4.println("db_dev.exported ==" + db_dev.exported); // // If the device is not imported, leave function // if (db_dev.exported == false) { Util.out4.println("Leaving Tango::server_already_running method"); return; } final org.omg.CORBA.Object obj = orb.string_to_object(db_dev.ior); Util.out4.println("orb.string_to_object(db_dev.ior); DONE "); // // Try to narrow the reference to a Tango_Device object // dev = DeviceHelper.narrow(obj); Util.out4.println("dev = DeviceHelper.narrow(obj); DONE "); } catch (final DevFailed e) { if (e.errors[0].reason.equals("DB_DeviceNotDefined") == true) { System.err.println("This device server is not defined in database. Exiting!"); System.exit(-1); } } catch (final org.omg.CORBA.TIMEOUT e) { // Receive a Timeout exception ---> It is not running !!!! // System.err.println("org.omg.CORBA.TIMEOUT"); } catch (final BAD_OPERATION e) { System.err.println("Can't pack/unpack data sent to/from database in/to Any object"); System.exit(-1); } catch (final TRANSIENT e) { Util.out4.println("Leaving Tango::server_already_running method"); return; } catch (final OBJECT_NOT_EXIST e) { Util.out4.println("Leaving Tango::server_already_running method"); return; } catch (final COMM_FAILURE e) { Util.out4.println("Leaving Tango::server_already_running method"); return; } catch (final Exception e) { System.err.println(e); e.printStackTrace(); System.exit(-1); } if (dev == null) { Util.out4.println("Leaving Tango::server_already_running method"); return; } // Now, get the device name from the server try { final String n = dev.name(); if (n.equals(dev_name_str) == true) { System.err.println("This server is already running, exiting!"); System.exit(-1); } } catch (final NO_RESPONSE e) { System.err.println("This server is already running but is blocked!"); System.exit(-1); } catch (final SystemException e) { } Util.out4.println("Leaving Tango::server_already_running method"); } /** * Initialise all the device server pattern(s) embedded in a device server * process. * * @exception DevFailed * If the device pattern initialistaion failed Click here to read DevFailed exception specification */ public void server_init() throws DevFailed { // Initialise main class DServerClass.init(); // Configure polling from the polling properties polling_configure(); } /** * Ask a device server to listen for incoming request. * * This method does not return. */ public void server_run() { orb.run(); } /** * Get the list of device references which name name match the specified * pattern Returns a null vector in case there is no device matching the * pattern * * @param pattern * The device name pattern */ public Vector get_device_list(String pattern) { // - The returned list final Vector dl = new Vector(); // ------------------------------------------------------------------ // CASE I: pattern does not contain any '*' char - it's a device name if (pattern.indexOf('*') == -1) { DeviceImpl dev = null; try { dev = get_device_by_name(pattern); } catch (final DevFailed df) { // - Ignore exception } if (dev != null) { dl.add(dev); return dl; } } // - For the two remaining cases, we need the list of all DeviceClasses. final Vector dcl = get_class_list(); // - A temp vector to store a given class' devices Vector temp_dl; // ------------------------------------------------------------------ // CASE II: pattern == "*" - return a list containing all devices if (pattern.equals("*")) { for (int i = 0; i < dcl.size(); i++) { temp_dl = ((DeviceClass) dcl.elementAt(i)).get_device_list(); for (final Object aTemp_dl : temp_dl) { final DeviceImpl dev = (DeviceImpl) aTemp_dl; dl.add(dev); } } return dl; } // ------------------------------------------------------------------ // CASE III: pattern contains at least one '*' char Iterator dl_it; String dev_name; DeviceImpl dev; final Iterator dcl_it = dcl.iterator(); // - Compile the pattern pattern = pattern.replace('*', '.'); final Pattern p = Pattern.compile(pattern); // - For each DeviceClass... while (dcl_it.hasNext()) { // ...get device list temp_dl = ((DeviceClass) dcl_it.next()).get_device_list(); // for each device in in list... dl_it = temp_dl.iterator(); while (dl_it.hasNext()) { // ...get device ... dev = (DeviceImpl) dl_it.next(); // ...and device name dev_name = dev.get_name().toLowerCase(); // then look for token(s) in device name if (p.matcher(dev_name).matches()) { dl.add(dev); } } } return dl; } /** * Get the list of device references for a given TANGO class. * * Return the list of references for all devices served by one * implementation of the TANGO device pattern implemented in the process * * @param class_name * The TANGO device class name * @return The device reference list * @exception DevFailed * If in the device server process there is no TANGO device * pattern implemented the TANGO device class given as * parameter Click here to read DevFailed exception specification */ public Vector get_device_list_by_class(final String class_name) throws DevFailed { // // Retrieve class list. Don't use the get_dserver_device() method // followed by // the get_class_list(). In case of several classes embedded within // the same server and the use of this method in the object creation, it // will fail because the end of the dserver object creation is after the // end of the last server device creation. // final Vector cl_list = class_list; // // Check if the wanted class really exists // final int nb_class = cl_list.size(); int i; for (i = 0; i < nb_class; i++) { if (((DeviceClass) cl_list.elementAt(i)).get_name().equals(class_name) == true) { break; } } // // Throw exception if the class is not found // if (i == nb_class) { final StringBuffer o = new StringBuffer("Class "); o.append(class_name); o.append(" not found"); Except.throw_exception("API_ClassNotFound", o.toString(), "Util::get_device_list_by_class()"); } return ((DeviceClass) cl_list.elementAt(i)).get_device_list(); } /** * Get a device reference from its name * * @param dev_name * The TANGO device name * @return The device reference * @exception DevFailed * If in the device is not served by one device pattern * implemented in this process. Click here to read DevFailed exception specification */ public DeviceImpl get_device_by_name(String dev_name) throws DevFailed { // // Retrieve class list. Don't use the get_dserver_device() method // followed by // the get_class_list(). In case of several classes embedded within // the same server and the use of this method in the object creation, it // will fail because the end of the dserver object creation is after the // end of the last server device creation. // final Vector cl_list = class_list; // // Check if the wanted device exists in each class // dev_name = dev_name.toLowerCase(); Vector dev_list = get_device_list_by_class(((DeviceClass) cl_list.elementAt(0)).get_name()); final int nb_class = cl_list.size(); int i, j, nb_dev; j = nb_dev = 0; boolean found = false; for (i = 0; i < nb_class; i++) { dev_list = get_device_list_by_class(((DeviceClass) cl_list.elementAt(i)).get_name()); nb_dev = dev_list.size(); for (j = 0; j < nb_dev; j++) { if (((DeviceImpl) dev_list.elementAt(j)).get_name().toLowerCase().equals(dev_name) == true) { found = true; break; } } if (found == true) { break; } } // // Check also the dserver device // if (found == false) { final DServerClass ds_class = DServerClass.instance(); dev_list = ds_class.get_device_list(); final String name = ((DeviceImpl) dev_list.elementAt(0)).get_name(); if (name.compareToIgnoreCase(dev_name) == 0) { j = 0; } } // // Throw exception if the class is not found // if (i == nb_class && j == nb_dev) { final StringBuffer o = new StringBuffer("Device "); o.append(dev_name); o.append(" not found"); Except .throw_exception("API_DeviceNotFound", o.toString(), "Util::get_device_by_name()"); } return (DeviceImpl) dev_list.elementAt(j); } /** * Get a reference to the dserver device attached to the device server * process * * @return A reference to the dserver device */ public DServer get_dserver_device() { return (DServer) DServerClass.instance().get_device_list().elementAt(0); } /** * Unregister a device server process from the TANGO database. * * If the database call fails, a message is displayed on the screen and the * process is aborted */ public void unregister_server() { Util.out4.println("Entering Tango::unregister_server method"); if (Util._UseDb == true) { // // Mark all the devices belonging to this server as unexported // try { db.unexport_server(ds_name.toString()); } catch (final SystemException e) { Except.print_exception(e); System.exit(-1); } catch (final DevFailed e) { Except.print_exception(e); System.exit(-1); } catch (final UserException e) { Except.print_exception(e); System.exit(-1); } } Util.out4.println("Leaving Tango::unregister_server method"); } /** * Get the process trace level. * * @return The process trace level */ public int get_trace_level() { return _tracelevel; } /** * Get a reference to the CORBA Boot Manager * * @return The CORBA boot manager public BootManager get_boot_manager() { * return boot_manager; } */ /** * Set the process trace level. * * @param level * The new process level */ public void set_trace_level(final int level) { _tracelevel = level; } /** * Get the device server instance name. * * @return The device server instance name */ public String get_ds_inst_name() { return ds_instance_name; } /** * Get the device server executable name. * * @return The device server executable name */ public String get_ds_exec_name() { return ds_exec_name; } /** * Get the device server name. * * The device server name is the device server executable name/the device * server instance name * * @return The device server name */ public String get_ds_name() { return new String(ds_name); } /** * Get the real (not only lowercase) server name. * * The device server name is the device server executable name/the device * server instance name * * @return The real server name */ public String get_ds_real_name() { return real_server_name; } /** * Get the host name where the device server process is running. * * @return The host name */ public String get_host_name() { return hostname; } /** * Get the device server TANGO version. * * @return The device server version */ public String get_version_str() { return version_str; } // =============================================================== /** * Get the TANGO database object reference * * @return The database reference */ public Database get_database() { return db; } // ========================================================== /** * Get a reference to the CORBA ORB * * @return The CORBA ORB */ public ORB get_orb() { return orb; } /** * Get a reference to the CORBA Portable Object Adapter (POA). * * For classical device server, this is the root POA. For no database device * server, this is a specific POA with the USER_ID policy. * * @return The CORBA POA */ public POA get_poa() { return _poa; } /** * Get the device server process identifier as a String * * Return 0 as process identifer. Is ther any way to know process identifier * in a PURE java class ? */ public String get_pid_str() { return pid_str; } /** * Get the DeviceClass list vector * * @return The DeviceClass vector reference */ Vector get_class_list() { return class_list; } /** * Set the DeviceClass list vector * * @param list * The DeviceClass vector reference */ public void set_class_list(final Vector list) { class_list = list; } // ========================================================== /** * Get the commnd line device name list (for device server without database) * * @return The command line device name list */ Vector get_cmd_line_name_list() { return cmd_line_name_list; } // ========================================================== /** * Add a new class in this device server (For no database device server) * * @param name * The class name */ public void add_class(final String name) { class_name_list.addElement(name); } // ========================================================== /** * Get the class name list (For no database device server) * * @return A string vector. Each element is a class name */ public Vector get_class_name_list() { return class_name_list; } // ========================================================== // ========================================================== // ========================================================== /** * WARNING: The following code is JacORB specific. The jacorb.jar must have * been modified by adding org.jacorb.orb.ORB.putObjectKeyMap method. public * void putObjectKeyMap(String s, String t) { objectKeyMap.put(s, t); } * * Add device name in HashTable used for JacORB objectKeyMap if * _UseDb==false. * * @param name * The device's name. */ void registerDeviceForJacorb(final String name) { // Get the 3 fields of device name final StringTokenizer st = new StringTokenizer(name, "/"); final String[] field = new String[3]; for (int i = 0; i < 3 && st.countTokens() > 0; i++) { field[i] = st.nextToken(); } // After a header used by JacORB, in the device name // the '/' char must be replaced by another separator final String separator = "&%25"; final String targetname = "StandardImplName/nodb_poa/" + field[0] + separator + field[1] + separator + field[2]; // And set the JacORB objectKeyMap HashMap final org.jacorb.orb.ORB jacorb = (org.jacorb.orb.ORB) orb; // Method added by PV for server without database. // in org/jacorb/orb/ORB.java jacorb.addObjectKey(name, targetname); } /** * This method sends command to the polling thread for all cmd/attr with * polling configuration stored in db. */ // ========================================================== void polling_configure() { // Send a stop polling command to thread in order not to poll devices final DServer adm_dev = get_dserver_device(); try { adm_dev.stop_polling(); } catch (final DevFailed e) { Except.print_exception(e); } final Vector tmp_cl_list = adm_dev.get_class_list();// DeviceClass int upd; // Create the structure used to send data to the polling thread final DevVarLongStringArray send = new DevVarLongStringArray(); send.lvalue = new int[1]; send.svalue = new String[3]; // A loop on each class and each device in class for (int i = 0; i < tmp_cl_list.size(); i++) { final DeviceClass dc = (DeviceClass) tmp_cl_list.elementAt(i); final Vector dev_list = dc.get_device_list(); // id() == * dev_mon.get_locking_thread_id()) { cout4 << * "Possible deadlock detected!" << endl; deadlock = true; * dev_mon.rel_monitor(); dev_mon.rel_monitor(); } */ interupted = mon.wait_it(Tango_DEFAULT_TIMEOUT); /* * if (deadlock == true) { dev_mon.get_monitor(); * dev_mon.get_monitor(); } */ if (shared_cmd.trigger == true && interupted == false) { out4.println("TIME OUT"); Except.throw_exception("API_CommandTimedOut", "Polling thread blocked !!!", "Util.trigger_attr_polling"); } } mon.rel_monitor(); out4.println("Thread cmd normally executed"); } /** * This method fills the polling buffer for one polled attribute registered * with an update period defined as "externally triggerred" (polling period * set to 0) * * @param dev * The TANGO device * @param att_name * The attribute name which must be polled * @param data * The data stack with one element for each history element * * @throws DevFailed * If the call failed */ // ========================================================== public void fill_attr_polling_buffer(final DeviceImpl dev, final String att_name, final TimedAttrData[] data) throws DevFailed { // Check that the device is polled if (dev.is_polled() == false) { Except.throw_exception("API_DeviceNotPolled", "Device " + dev.get_name() + " is not polled", "Util.fill_attr_polling_buffer()"); } // Attribute name in lower case letters and check that it is marked as // polled final String obj_name = att_name.toLowerCase(); dev.get_polled_obj_by_type_name(Tango_POLL_ATTR, obj_name); // Get a reference on the Attribute object final Attribute att = dev.get_device_attr().get_attr_by_name(att_name); // Check that it is a READ only attribute final AttrWriteType w_type = att.get_writable(); if (w_type != AttrWriteType.READ) { final String desc = "Attribute " + att_name + " of device " + dev.get_name() + " is not READ only"; Except.throw_exception("API_DeviceNotPolled", desc, "Util.fill_attr_polling_buffer()"); } // Check that history is not larger than polling buffer final int nb_elt = data.length; final int nb_poll = dev.get_poll_ring_depth(); if (nb_elt > nb_poll) { final String desc = "The polling buffer depth for attribute " + att_name + " for device " + dev.get_name() + " is only " + nb_poll + " which is less than " + nb_elt + " !"; Except.throw_exception("API_DeviceNotPolled", desc, "Util.fill_attr_polling_buffer()"); } // A loop on each record DevFailed save_except = null; AttributeValue back = null; final TimeVal zero = new TimeVal(0, 0, 0); for (int i = 0; i < nb_elt; i++) { // Check if read attr has failed boolean attr_failed = false; if (data[i].err != null && data[i].err.length > 0) { attr_failed = true; save_except = new DevFailed(data[i].err); } else { // Allocate memory for the AttributeValueList sequence back = new AttributeValue(); // Init name,date and quality factor back.time = new TimeVal(0, 0, 0); back.time.tv_sec = data[i].t_val.tv_sec; back.time.tv_usec = data[i].t_val.tv_usec; back.time.tv_nsec = 0; back.quality = data[i].qual; back.name = att_name; back.dim_x = 0; back.dim_y = 0; if (data[i].qual == AttrQuality.ATTR_VALID || data[i].qual == AttrQuality.ATTR_ALARM || data[i].qual == AttrQuality.ATTR_CHANGING) { // Set Attribute object value att.wanted_date(false); att.set_date(data[i].t_val); att.set_quality(data[i].qual); // Init remaining fields in AttributeValueList final Any any = ApiUtil.get_orb().create_any(); switch (att.get_data_type()) { case Tango_DEV_BOOLEAN: att.set_value(data[i].bool_ptr, data[i].x, data[i].y); DevVarBooleanArrayHelper.insert(any, att.get_boolean_value()); break; case Tango_DEV_SHORT: att.set_value(data[i].sh_ptr, data[i].x, data[i].y); DevVarShortArrayHelper.insert(any, att.get_short_value()); break; case Tango_DEV_LONG: att.set_value(data[i].lg_ptr, data[i].x, data[i].y); DevVarLongArrayHelper.insert(any, att.get_long_value()); break; case Tango_DEV_LONG64: att.set_value(data[i].lg64_ptr, data[i].x, data[i].y); DevVarLong64ArrayHelper.insert(any, att.get_long64_value()); break; case Tango_DEV_FLOAT: att.set_value(data[i].fl_ptr, data[i].x, data[i].y); DevVarFloatArrayHelper.insert(any, att.get_float_value()); break; case Tango_DEV_DOUBLE: att.set_value(data[i].db_ptr, data[i].x, data[i].y); DevVarDoubleArrayHelper.insert(any, att.get_double_value()); break; case Tango_DEV_STRING: att.set_value(data[i].str_ptr, data[i].x, data[i].y); DevVarStringArrayHelper.insert(any, att.get_string_value()); break; /* * case Tango_DEV_USHORT : * DevVarUShortArrayHelper.insert(any, * att.get_ushort_value()); break; * * case Tango_DEV_UCHAR : DevVarUCharArrayHelper.insert(any, * att.get_uchar_value()); break; */ default: Except .throw_exception("Api_DataTypeNotSupported", "att.get_data_type() returns " + att.get_data_type() + "\nType NOT supported", "Util.fill_attr_polling_buffer()"); } back.value = any; back.dim_x = data[i].x; back.dim_y = data[i].y; } } // Fill one slot of polling buffer try { get_poll_monitor().get_monitor(); final PollObj item = dev.get_polled_obj_by_type_name(Tango_POLL_ATTR, obj_name); final TimeVal when = new TimeVal(0, 0, 0); if (attr_failed == false) { when.tv_sec = back.time.tv_sec - Tango_DELTA_T; when.tv_usec = back.time.tv_usec; item.insert_data(back, when, zero); } else { when.tv_sec = data[i].t_val.tv_sec - Tango_DELTA_T; when.tv_usec = data[i].t_val.tv_usec; item.insert_except(save_except, when, zero); } get_poll_monitor().rel_monitor(); } catch (final DevFailed e) { get_poll_monitor().rel_monitor(); } } } /** * This class is used for polling */ // ========================================================== class UtilExt { Vector cmd_line_name_list; /** * The polling thread object */ PollThread poll_th; /** * The shared buffer */ PollThCmd shared_data; /** * The monitor */ TangoMonitor poll_mon; /** * Polling on flag */ boolean poll_on; UtilExt() { shared_data = new PollThCmd(); shared_data.cmd_pending = false; poll_mon = new TangoMonitor(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy