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

fr.esrf.TangoApi.Group.Group 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: 25296 $
//
//-======================================================================


package fr.esrf.TangoApi.Group;

//- Import Java stuffs

import fr.esrf.Tango.DevFailed;
import fr.esrf.TangoApi.Database;
import fr.esrf.TangoApi.DeviceAttribute;
import fr.esrf.TangoApi.DeviceData;
import fr.esrf.TangoApi.DeviceProxy;
import fr.esrf.TangoDs.Except;

import java.util.Iterator;
import java.util.TreeMap;
import java.util.Vector;

/**
 * TANGO group abstraction main class
 */

public class Group extends GroupElement implements java.io.Serializable {

    /**
     * Group's elements repository
     */
    private final Vector elements;

    // -- PUBLIC INTERFACE -----------------------------------------------------
    // -------------------------------------------------------------------------
    /**
     * Group element factory
     */
    private final GroupElementFactory factory;
    /**
     * Asynch request repository
     */
    private final TreeMap arp;
    /**
     * Pseudo asynch. request id generator
     */
    private int asynch_req_id;

    /** Creates a new instance of Group */
    public Group(final String name) {
	super(name);
	asynch_req_id = 0;
	elements = new Vector();
	factory = new GroupElementFactory();
	arp = new TreeMap();
    }

    /** Dump group */
    public void dump() {
	synchronized (this) {
	    dump_i(0);
	}
    }

    /** Ping the group returns true if all device alive, false otherwise */
    public boolean ping(final boolean fwd) {
	synchronized (this) {
	    return ping_i(fwd);
	}
    }

    /** Returns the group's device list */
    public String[] get_device_list(final boolean fwd) {
	return get_device_name_list(fwd);
    }

    /** Returns the first group named  in the hierarchy */
    public Group get_group(final String n) {
	synchronized (this) {
	    return get_group_i(n, true);
	}
    }

    /** Returns the device named  in the hierarchy */
    public DeviceProxy get_device(final String n) {
	synchronized (this) {
	    return get_device_i(n);
	}
    }

    /** Returns the th device in the hierarchy */
    public DeviceProxy get_device(final int i) {
	synchronized (this) {
	    return get_device_i(i);
	}
    }

    /** Returns the group's size */
    @Override
    public int get_size(final boolean fwd) {
	synchronized (this) {
	    return get_size_i(fwd);
	}
    }

    /** Adds a group to the group */
    public void add(final Group g) {
	if (g == null) {
	    return;
	}
	synchronized (this) {
	    add_i(g);
	}
    }

    /**
     * Adds devices matching pattern
     * 

* to the group * * @throws DevFailed */ public void add(final String p) throws DevFailed { synchronized (this) { final Vector v = factory.instanciate(p); final Iterator it = v.iterator(); while (it.hasNext()) { add_i((GroupElement) it.next()); } } } /** * Adds devices matching patterns to the group * * @throws DevFailed */ public void add(final String[] pl) throws DevFailed { synchronized (this) { for (final String element : pl) { if (element != null) { final Vector v = factory.instanciate(element); final Iterator it = v.iterator(); while (it.hasNext()) { add_i((GroupElement) it.next()); } } } } } /** * Remove elements matching pattern *

* from the group */ public void remove(final String p, final boolean fwd) { synchronized (this) { remove_i(p, fwd); } } /** Remove elements matching patterns from the group */ public void remove(final String[] pl, final boolean fwd) { synchronized (this) { for (final String element : pl) { remove_i(element, fwd); } } } /** Remove all elements from the group */ public void remove_all() { synchronized (this) { elements.removeAllElements(); } } /** Returns true if the group contains an element named , false otherwise */ public boolean contains(final String n, final boolean fwd) { synchronized (this) { return find_i(n, fwd) != null ? true : false; } } /** set_timeout_millis */ @Override public void set_timeout_millis(final int timeout, final boolean fwd) throws DevFailed { synchronized (this) { final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e instanceof GroupDeviceElement || fwd) { e.set_timeout_millis(timeout, fwd); } } } } /** command_inout */ public GroupCmdReplyList command_inout(final String c, final boolean fwd) throws DevFailed { synchronized (this) { final int rid = command_inout_asynch_i(c, false, fwd, next_req_id()); return command_inout_reply_i(rid, 0, fwd); } } /** command_inout */ public GroupCmdReplyList command_inout(final String c, final DeviceData dd, final boolean fwd) throws DevFailed { synchronized (this) { final int rid = command_inout_asynch_i(c, dd, false, fwd, next_req_id()); return command_inout_reply_i(rid, 0, fwd); } } /** get_command_argument_list */ public DeviceData[] get_command_specific_argument_list(final boolean fwd) throws DevFailed { final int al_size = get_size(fwd); final DeviceData[] al = new DeviceData[al_size]; for (int i = 0; i < al_size; i++) { al[i] = new DeviceData(); } return al; } /** command_inout */ public GroupCmdReplyList command_inout(final String c, final DeviceData[] dd, final boolean fwd) throws DevFailed { synchronized (this) { final int rid = command_inout_asynch_i(c, dd, false, fwd, next_req_id()); return command_inout_reply_i(rid, 0, fwd); } } /** command_inout_asynch */ public int command_inout_asynch(final String c, final boolean fgt, final boolean fwd) throws DevFailed { final int rid = command_inout_asynch_i(c, fgt, fwd, next_req_id()); if (fgt == false) { arp.put(new Integer(rid), new Boolean(fwd)); } return rid; } /** command_inout_asynch */ public int command_inout_asynch(final String c, final DeviceData dd, final boolean fgt, final boolean fwd) throws DevFailed { final int rid = command_inout_asynch_i(c, dd, fgt, fwd, next_req_id()); if (fgt == false) { arp.put(new Integer(rid), new Boolean(fwd)); } return rid; } /** command_inout_asynch */ public int command_inout_asynch(final String c, final DeviceData[] dd, final boolean fgt, final boolean fwd) throws DevFailed { final int rid = command_inout_asynch_i(c, dd, fgt, fwd, next_req_id()); if (fgt == false) { arp.put(new Integer(rid), new Boolean(fwd)); } return rid; } /** command_inout_reply */ public GroupCmdReplyList command_inout_reply(final int rid, final int tmo) throws DevFailed { final Integer rid_obj = new Integer(rid); final Boolean fwd = (Boolean) arp.get(rid_obj); if (fwd == null) { Except.throw_exception("API_BadAsynPollId", "Invalid asynch. request identifier specified", "Group.command_inout_reply"); } arp.remove(rid_obj); return command_inout_reply_i(rid, tmo, fwd.booleanValue()); } /** read_attribute */ public GroupAttrReplyList read_attribute(final String a, final boolean fwd) throws DevFailed { synchronized (this) { final int rid = read_attribute_asynch_i(a, fwd, next_req_id()); return read_attribute_reply_i(rid, 0, fwd); } } /** read_attribute_asynch */ public int read_attribute_asynch(final String a, final boolean fwd) throws DevFailed { final int rid = read_attribute_asynch_i(a, fwd, next_req_id()); arp.put(new Integer(rid), new Boolean(fwd)); return rid; } /** read_attribute_reply */ public GroupAttrReplyList read_attribute_reply(final int rid, final int tmo) throws DevFailed { final Integer rid_obj = new Integer(rid); final Boolean fwd = (Boolean) arp.get(rid_obj); if (fwd == null) { Except.throw_exception("API_BadAsynPollId", "Invalid asynch. request identifier specified", "Group.read_inout_reply"); } arp.remove(rid_obj); return read_attribute_reply_i(rid, tmo, fwd.booleanValue()); } /** write_attribute */ public GroupReplyList write_attribute(final DeviceAttribute da, final boolean fwd) throws DevFailed { synchronized (this) { final int rid = write_attribute_asynch_i(da, fwd, next_req_id()); return write_attribute_reply_i(rid, 0, fwd); } } /** get_command_argument_list */ public DeviceAttribute[] get_attribute_specific_value_list(final boolean fwd) { synchronized (this) { int i = 0; final int av_size = get_size_i(fwd); final DeviceAttribute[] av = new DeviceAttribute[av_size]; Iterator it; if (fwd) { final Vector h = get_hierarchy(); it = h.iterator(); while (it.hasNext()) { av[i++] = new DeviceAttribute(((GroupDeviceElement) it.next()).get_name()); } } else { it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e instanceof GroupDeviceElement) { av[i++] = new DeviceAttribute(e.get_name()); } } } return av; } } /** write_attribute */ public GroupReplyList write_attribute(final DeviceAttribute[] da, final boolean fwd) throws DevFailed { synchronized (this) { final int rid = write_attribute_asynch_i(da, fwd, next_req_id()); return write_attribute_reply_i(rid, 0, fwd); } } // -- PRIVATE INTERFACE ---------------------------------------------------- // ------------------------------------------------------------------------- /** write_attribute_asynch */ public int write_attribute_asynch(final DeviceAttribute da, final boolean fwd) throws DevFailed { final int rid = write_attribute_asynch_i(da, fwd, next_req_id()); arp.put(new Integer(rid), new Boolean(fwd)); return rid; } /** write_attribute_asynch */ public int write_attribute_asynch(final DeviceAttribute[] da, final boolean fwd) throws DevFailed { final int rid = write_attribute_asynch_i(da, fwd, next_req_id()); arp.put(new Integer(rid), new Boolean(fwd)); return rid; } /** write_attribute_reply */ public GroupReplyList write_attribute_reply(final int rid, final int tmo) throws DevFailed { final Integer rid_obj = new Integer(rid); final Boolean fwd = (Boolean) arp.get(rid_obj); if (fwd == null) { Except.throw_exception("API_BadAsynPollId", "Invalid asynch. request identifier specified", "Group.write_attribute_reply"); } arp.remove(rid_obj); return write_attribute_reply_i(rid, tmo, fwd.booleanValue()); } /** Returns the group's device list - access limited to package Group */ @Override String[] get_device_name_list(final boolean fwd) { synchronized (this) { int i = 0; final String[] dl = new String[get_size_i(fwd)]; final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e instanceof GroupDeviceElement || fwd) { final String[] sub_dl = e.get_device_name_list(fwd); for (int j = 0; j < sub_dl.length; j++, i++) { dl[i] = sub_dl[j]; } } } return dl; } } /** Returns the group's hierarchy */ private Vector get_hierarchy() { synchronized (this) { final Vector h = new Vector(); final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e instanceof GroupDeviceElement) { h.add(e); } else { h.add(((Group) e).get_hierarchy()); } } return h; } } /** Returns the group's size - internal impl */ private int get_size_i(final boolean fwd) { int size = 0; final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e instanceof GroupDeviceElement || fwd) { size += e.get_size(true); } } return size; } /** Returns the group named or null if no such group - internal impl */ private Group get_group_i(final String n, final boolean fwd) { final GroupElement e = find_i(n, fwd); return e != null && e instanceof Group ? (Group) e : null; } /** Returns the first element named or null if no such element */ @Override GroupElement find(final String n, final boolean fwd) { synchronized (this) { return find_i(n, fwd); } } /** Returns the element named or null if no such element - internal impl */ private GroupElement find_i(final String n, final boolean fwd) { if (name_equals(n)) { return this; } GroupElement e = null; Iterator it = elements.iterator(); while (it.hasNext()) { e = (GroupElement) it.next(); if (e.name_equals(n)) { return e; } } if (fwd) { it = elements.iterator(); while (it.hasNext()) { e = ((GroupElement) it.next()).find(n, fwd); if (e != null) { return e; } } } return null; } /** Adds an element to the group */ private boolean add_i(final GroupElement e) { if (e == null || e == this) { // -DEBUG System.out.println("Group::add_i::failed to add " + e.get_name() + " (null or self)"); return false; } final GroupElement ge = find_i(e.get_name(), e instanceof Group ? false : true); if (ge != null && ge != this) { // -DEBUG System.out.println("Group::add_i::failed to add " + e.get_name() + " (already attached)"); return false; } elements.add(e); e.set_parent(this); return true; } /** * Remove elements matching pattern *

* from the group */ private void remove_i(final String p, final boolean fwd) { if (name_equals(p)) { System.out.println("Group::remove_i::failed to remove " + p + " (can't remove self)"); return; } if (p.indexOf('*') == -1) { final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e.name_equals(p)) { elements.remove(e); break; } } } else { final Vector remove_list = new Vector(); Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e.name_matches(p)) { remove_list.add(e); } } it = remove_list.iterator(); while (it.hasNext()) { elements.remove(it.next()); } } if (fwd == true) { final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e instanceof Group) { ((Group) e).remove(p, fwd); } } } } /** * Returns the th device in the hierarchy - access limited to package * Group */ @Override DeviceProxy get_device_i(int i) { synchronized (this) { DeviceProxy dp = null; final Iterator it = elements.iterator(); while (dp == null && it.hasNext()) { final GroupElement e = (GroupElement) it.next(); dp = e.get_device_i(i--); } return dp; } } /** Returns device in the hierarchy - access limited to package Group */ @Override DeviceProxy get_device_i(final String n) { DeviceProxy dp = null; final Iterator it = elements.iterator(); while (dp == null && it.hasNext()) { final GroupElement e = (GroupElement) it.next(); dp = e.get_device_i(n); } return dp; } /** Dump group - access limited to package Group */ @Override void dump_i(final int indent_level) { for (int i = 0; i < indent_level; i++) { System.out.print(" "); } System.out.println("|- Group: " + get_name() + " [" + get_size_i(true) + ":" + get_size_i(false) + "]"); final Iterator it = elements.iterator(); while (it.hasNext()) { ((GroupElement) it.next()).dump_i(indent_level + 1); } } /** Ping the group - access limited to package Group */ @Override boolean ping_i(final boolean fwd) { boolean all_alive = true; final Iterator it = elements.iterator(); while (it.hasNext() && all_alive) { final GroupElement e = (GroupElement) it.next(); if (e instanceof GroupDeviceElement || fwd) { all_alive = e.ping_i(fwd) ? all_alive : false; } } return all_alive; } /** command_inout_asynch_i - access limited to package Group */ @Override int command_inout_asynch_i(final String c, final boolean fgt, final boolean fwd, final int rid) throws DevFailed { synchronized (this) { final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e instanceof GroupDeviceElement || fwd) { e.command_inout_asynch_i(c, fgt, fwd, rid); } } return rid; } } /** command_inout_i - access limited to package Group */ @Override int command_inout_asynch_i(final String c, final DeviceData dd, final boolean fgt, final boolean fwd, final int rid) throws DevFailed { synchronized (this) { final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e instanceof GroupDeviceElement || fwd) { e.command_inout_asynch_i(c, dd, fgt, fwd, rid); } } return rid; } } /** command_inout_asynch_i - access limited to package Group */ private int command_inout_asynch_i(final String c, final DeviceData[] dd, final boolean fgt, final boolean fwd, final int rid) throws DevFailed { synchronized (this) { final int gsize = get_size_i(fwd); if (gsize != dd.length) { final String desc = "the size of the input argument list must equal the number of device in the group" + " [expected:" + gsize + " - got:" + dd.length + "]"; Except.throw_exception("API_MethodArgument", desc, "Group.command_inout_asynch"); } int i = 0; Iterator it; if (fwd) { final Vector h = get_hierarchy(); it = h.iterator(); while (it.hasNext()) { ((GroupDeviceElement) it.next()).command_inout_asynch_i(c, dd[i++], fgt, fwd, rid); } } else { it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e instanceof GroupDeviceElement) { e.command_inout_asynch_i(c, dd[i++], fgt, fwd, rid); } } } return rid; } } /** command_inout_reply_i - access limited to package Group */ @Override GroupCmdReplyList command_inout_reply_i(final int rid, final int tmo, final boolean fwd) throws DevFailed { synchronized (this) { final GroupCmdReplyList reply = new GroupCmdReplyList(); GroupCmdReplyList sub_reply; final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement ge = (GroupElement) it.next(); if (ge instanceof GroupDeviceElement || fwd) { sub_reply = ge.command_inout_reply_i(rid, tmo, fwd); if (sub_reply.isEmpty() == false) { reply.addAll(sub_reply); } if (sub_reply.has_failed()) { reply.has_failed = true; } } } return reply; } } /** read_attribute_asynch_i - access limited to package Group */ @Override int read_attribute_asynch_i(final String a, final boolean fwd, final int rid) throws DevFailed { synchronized (this) { final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e instanceof GroupDeviceElement || fwd) { e.read_attribute_asynch_i(a, fwd, rid); } } return rid; } } /** read_attribute_reply_i - access limited to package Group */ @Override GroupAttrReplyList read_attribute_reply_i(final int rid, final int tmo, final boolean fwd) throws DevFailed { synchronized (this) { final GroupAttrReplyList reply = new GroupAttrReplyList(); GroupAttrReplyList sub_reply; final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement ge = (GroupElement) it.next(); if (ge instanceof GroupDeviceElement || fwd) { sub_reply = ge.read_attribute_reply_i(rid, tmo, fwd); if (sub_reply.isEmpty() == false) { reply.addAll(sub_reply); } if (sub_reply.has_failed()) { reply.has_failed = true; } } } return reply; } } /** write_attribute_asynch_i - access limited to package Group */ @Override int write_attribute_asynch_i(final DeviceAttribute da, final boolean fwd, final int rid) throws DevFailed { synchronized (this) { final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e instanceof GroupDeviceElement || fwd) { e.write_attribute_asynch_i(da, fwd, rid); } } return rid; } } /** write_attribute_asynch_i - access limited to package Group */ private int write_attribute_asynch_i(final DeviceAttribute da[], final boolean fwd, final int rid) throws DevFailed { synchronized (this) { final int gsize = get_size_i(fwd); if (gsize != da.length) { final String desc = "the size of the input argument list must equal the number of device in the group" + " [expected:" + gsize + " - got:" + da.length + "]"; Except.throw_exception("API_MethodArgument", desc, "Group.write_attribute_asynch"); } int i = 0; Iterator it; if (fwd) { final Vector h = get_hierarchy(); it = h.iterator(); while (it.hasNext()) { ((GroupDeviceElement) it.next()).write_attribute_asynch_i(da[i++], fwd, rid); } } else { it = elements.iterator(); while (it.hasNext()) { final GroupElement e = (GroupElement) it.next(); if (e instanceof GroupDeviceElement) { e.write_attribute_asynch_i(da[i++], fwd, rid); } } } return rid; } } /** write_attribute_reply_i - access limited to package Group */ @Override GroupReplyList write_attribute_reply_i(final int rid, final int tmo, final boolean fwd) throws DevFailed { synchronized (this) { final GroupReplyList reply = new GroupReplyList(); GroupReplyList sub_reply; final Iterator it = elements.iterator(); while (it.hasNext()) { final GroupElement ge = (GroupElement) it.next(); if (ge instanceof GroupDeviceElement || fwd) { sub_reply = ge.write_attribute_reply_i(rid, tmo, fwd); if (sub_reply.isEmpty() == false) { reply.addAll(sub_reply); } if (sub_reply.has_failed()) { reply.has_failed = true; } } } return reply; } } /** Pseudo asynch. request generator */ private int next_req_id() { asynch_req_id = asynch_req_id++ % java.lang.Integer.MAX_VALUE; return asynch_req_id; } @Override int read_attribute_asynch_i(final String[] a, final boolean fwd, final int rid) throws DevFailed { return 0; } // -- PRIVATE INNER CLASS: GroupElementFactory ----------------------------- // ------------------------------------------------------------------------- private final class GroupElementFactory { // ====================================================================== /** * Instanciate the TangoElements which name matches the pattern p * * @param device name pattern (wild card). * @return a vector of GroupElement. */ // ====================================================================== public Vector instanciate(final String p) throws DevFailed { // - a vector to store GroupElement String[] dnl = null; // - is

a device name or a device name pattern ? if (p.indexOf('*') == -1) { // -

is a pure device name dnl = new String[1]; dnl[0] = p; } else { // - ask the db the list of device matching pattern p final Database db = new Database(); dnl = db.get_device_exported(p); } if (dnl.length == 0) { return null; } final Vector ge = new Vector(); for (final String element : dnl) { ge.add(new GroupDeviceElement(element)); } return ge; } } }