package de.desy.tine.queryUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import de.desy.tine.addrUtils.*;
import de.desy.tine.bitfieldUtils.*;
import de.desy.tine.client.TLink;
import de.desy.tine.client.TLinkFactory;
import de.desy.tine.client.TLinkFactory.AccessLockType;
import de.desy.tine.csvUtils.RowHandler;
import de.desy.tine.csvUtils.csv;
import de.desy.tine.csvUtils.csvColumn;
import de.desy.tine.csvUtils.csvHandler;
import de.desy.tine.dataUtils.TDataType;
import de.desy.tine.definitions.*;
import de.desy.tine.server.TServerSettings;
import de.desy.tine.server.connections.*;
import de.desy.tine.server.equipment.TWriteAccessInfo;
import de.desy.tine.server.logger.*;
import de.desy.tine.server.properties.*;
import de.desy.tine.structUtils.*;
import de.desy.tine.types.*;
/**
* TQuery: Utility with many standard query routines
*
* This is a static class which can be used to make system queries without
* the need for instantiating a TQuery object.
*/
/**
* @author duval
*
*/
public final class TQuery
{
public static final int nicePropertyQuerySize = 10;
public static final int niceContextsQuerySize = 100;
private static int maxQueryBufferSize = 256000;
private static byte[] hByteBlobX = new byte[nicePropertyQuerySize * XPropertyQuery.sizeInBytes];
private static byte[] hByteBlobL = new byte[nicePropertyQuerySize * PropertyQueryLegacy.sizeInBytes];
private static byte[] hByteBlob = new byte[nicePropertyQuerySize * TPropertyQuery.sizeInBytes];
private static byte[] hLegacyByteBlob;
private static String lastQueriedContext = null;
private static String lastQueriedServer = null;
private static String lastQueriedDevice = null;
private static TSrvEntry srvAddr = null;
public static boolean properties_have_query_function = false;
public static boolean devices_have_query_function = false;
/**
* @param property is the targeted property
* @return true if the input property represents a stock property of the server
*/
public static boolean isStockProperty(String property)
{
return TStockProperties.isStockProperty(property);
}
public static boolean isMetaProperty(String property)
{
return TMetaProperties.isMetaProperty(property);
}
public static String getModuleAddressInfo()
{ // not thread-safe
if (srvAddr == null) srvAddr = new TSrvEntry();
return srvAddr.toString(lastQueriedServer,lastQueriedContext);
}
public static String getModuleAddressInfo(String server,String context)
{
srvAddr = new TSrvEntry(server,context);
if (srvAddr.eqmName == null) return "server /"+context+"/"+server+ " unavailable";
String inf = srvAddr.toString(server,context);
FECInfo fi = getServerInformation(srvAddr.fecName);
inf += "\nLocation : " + fi.getLocation();
inf += "\nOS : " + fi.getOs();
inf += "\nDescription : " + fi.getDescription();
inf += "\nResponsible : " + fi.getResponsible();
return inf;
}
public static TSrvEntry getModuleAddress(String server,String context)
{
return new TSrvEntry(server,context);
}
private static String[] getTagList(String context,String tagtype)
{
return getTagList(context,tagtype,null);
}
private static String[] getTagList(String context,String tagtype,String subsys)
{
return getTagList(context,tagtype,subsys,TLink.defaultTimeout);
}
private static String[] getTagList(String context,String tagtype,String subsys,int timeout)
{
int cc,n,i;
TDataType dout;
TDataType din;
TLink tl;
StringBuffer host = new StringBuffer(32);
StringBuffer query = new StringBuffer(32);
short[] numout = new short[1];
TDataType numoutData = new TDataType(numout);
NAME16[] taglist16;
NAME32[] taglist32;
String[] strlist;
if (subsys == null || subsys.compareTo("ALL") == 0)
{
din = new TDataType();
}
else
{
din = new TDataType(subsys);
}
host.delete(0,31); query.delete(0,31);
if (context != null && context.length() != 0)
{
host.insert(0,"ENS/" + context);
}
else
{
host.insert(0,"ENS");
}
query.insert(0,"N" + tagtype);
try
{
tl = new TLink(host.toString(),query.toString(),numoutData,din,TAccess.CA_READ);
cc = tl.execute(timeout,true);
srvAddr = tl.srvAddr;
tl.close();
}
catch (Exception e)
{ // if the host name cannot be resolved -> runtime exception
MsgLog.log("getTagList", e.getMessage(),TErrorList.non_existent_elem,e,0);
cc = TErrorList.non_existent_elem;
}
if (cc != 0) return null;
if (numout[0] == 0 && subsys != null && subsys.length() > 0) numout[0] = 100;
query.delete(0,31);
query.insert(0,tagtype);
n = numout[0];
taglist32 = new NAME32[n];
for (i=0; i<n; i++) taglist32[i] = new NAME32();
if (taglist32.length == 0) return null;
if (numout[0] > taglist32.length) numout[0] = (short)taglist32.length;
dout = new TDataType(taglist32);
tl = new TLink(host.toString(),query.toString(),dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,true);
if (dout.getCompletionLength() < n) n = dout.getCompletionLength();
tl.close();
if (cc == 0)
{ // this worked, so we're finished
strlist = new String[n];
for (i=0; i<n; i++) strlist[i] = taglist32[i].name;
return strlist;
}
if (cc == TErrorList.illegal_format)
{ // old ENS ? -> try with reduced lengths ...
taglist16 = new NAME16[n];
for (i=0; i<n; i++) taglist16[i] = new NAME16();
if (taglist16.length == 0) return null;
if (numout[0] > taglist16.length) numout[0] = (short)taglist16.length;
dout = new TDataType(taglist16);
tl = new TLink(host.toString(),query.toString(),dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,true);
tl.close();
if (cc != 0) return null;
strlist = new String[n];
for (i=0; i<n; i++) strlist[i] = taglist16[i].name;
return strlist;
}
return null;
}
private static int getNumberOf(String property,String target) throws IOException
{
return getNumberOf(property,target,TLink.defaultTimeout);
}
private static int getNumberOf(String property,String target,int timeout) throws IOException
{
int cc = TErrorList.non_existent_elem;
short[] n = new short[1];
TDataType dout;
TLink tl;
String propertyq;
if (property == null || target == null) return -TErrorList.argument_list_error;
dout = new TDataType(n);
propertyq = new String("N" + property);
try
{
tl = new TLink(target,propertyq,dout,null,TAccess.CA_READ);
cc = tl.execute(timeout,true);
srvAddr = tl.srvAddr;
tl.close();
}
catch (Exception e)
{
cc = TErrorList.host_not_resolved;
}
if (cc == TErrorList.link_not_open ||
cc == TErrorList.connection_timeout ||
cc == TErrorList.tcp_connect_error)
throw new IOException("timeout getting information from " + target);
return cc > 0 ? -cc : (int)n[0];
}
/**
* Sets the maximum size for use in tine queries.
*
* @param size is the size in bytes of the buffer used to hold the query
* information (65000 bytes is the default)
*
* @return 0 if successful
*/
public static short setMaximumQueryBufferSize(int size)
{
if (size < 4000 || size > 256000) return TErrorList.out_of_range;
maxQueryBufferSize = size;
return 0;
}
/**
* Returns a list of Contexts (obtained from the name services)
*
* @return A string array containing a list of available contexts as
* obtained from the Equipment Name Server (ENS) or a null pointer if the call could
* not complete successfully. If no contexts were found a
* string array of zero length is returned.
*/
public static String[] getContexts()
{
if (!TLinkFactory.getInstance().isRunningStandAlone())
{
String[] lst = getTagList(null,"CONTEXTS");
if (lst != null) return lst;
}
// then try static cache ...
return DBQuery.getContextsFromFileCache(null);
}
/**
* Returns a list of Contexts (obtained from the name services)
* which offer a server with the name specified
*
* @param serverName is the targeted server name
*
* @return A string array containing a list of available contexts
* which have the named server or a null pointer if the call could
* not complete successfully. If no contexts were found a
* string array of zero length is returned.
*/
public static String[] getContexts(String serverName)
{
return getContexts(serverName,null);
}
/**
* Returns a list of Contexts (obtained from the name services)
* which offer a server with the name and importance specified
*
* @param serverName is the targeted server name
* @param imporance is the desired server importance
* (one of "ALL", "IMPORTANT", "CRITICAL", "ESSENTIAL")
*
* @return A string array containing a list of available contexts
* which have the named server or a null pointer if the call could
* not complete successfully. If no contexts were found a
* string array of zero length is returned.
*/
public static String[] getContexts(String serverName,String importance)
{
if (!TLinkFactory.getInstance().isRunningStandAlone())
{
int cc,n,i;
TDataType dout;
TDataType din;
TLink tl;
NAME32[] taglist32;
String[] strlist;
if (serverName == null || serverName.compareToIgnoreCase("ALL") == 0)
{
din = new TDataType();
}
else if (importance == null)
{
din = new TDataType(serverName);
}
else
{
if (importance.length() == 0) importance = "ALL";
NAME32[] n32a = new NAME32[2];
n32a[0] = new NAME32(serverName);
n32a[1] = new NAME32(importance);
din = new TDataType(n32a);
}
taglist32 = new NAME32[niceContextsQuerySize];
for (i=0; i<niceContextsQuerySize; i++) taglist32[i] = new NAME32();
if (taglist32.length == 0) return null;
dout = new TDataType(taglist32);
tl = new TLink("/SITE/ENS","CONTEXTS",dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,true);
tl.close();
n = dout.getCompletionLength();
if (cc == 0)
{ // this worked, so we're finished
strlist = new String[n];
for (i=0; i<n; i++) strlist[i] = taglist32[i].name;
return strlist;
}
}
// try static cache
return DBQuery.getContextsFromFileCache(serverName);
}
public static String[] getDeviceServerReport(String context,String server,String device)
{
return getDeviceServerReport(context,server,device,-1);
}
public static String[] getDeviceServerReport(String context,String server)
{
return getDeviceServerReport(context,server,null,-1);
}
public static String[] getDeviceServerReport(String context,String server,String device,int limit)
{
ArrayList<String>al = new ArrayList<String>(100);
String tgt = "/"+context+"/"+server;
String tgtdev = device; //"#0";
TSrvEntry se = new TSrvEntry(server,context);
al.add("server /"+context+"/"+server);
FECInfo inf = se.getFecAddr().info;
if (inf == null) inf = TQuery.getServerInformation(se.getFecName());
al.add("OS : "+inf.getOs());
al.add("ver : "+inf.getVer());
al.add("fec : "+ se.getFecName());
String ip = se.getFecAddr().fecHost.getHostAddress().toString();
al.add("ip : "+ ip);
al.add("host: "+ se.getFecAddr().fecHost.getHostName());
TServerSettings tsrvs = TQuery.getServerSettings(tgt);
//al.add(tsrvs.toString());
if (tsrvs != null)
{
al.add("settings :");
al.add("\tserver working area: "+tsrvs.getSrvWorkArea());
al.add("\tcontract table capacity: "+tsrvs.getConTblCapacity());
al.add("\tclient table capacity: "+tsrvs.getClnTblCapacity());
al.add("\tserver sck recv buffers: "+tsrvs.getSrvRecvBuffers());
al.add("\tminimum polling interval: "+tsrvs.getMinPollInterval());
al.add("\tclient-side link capacity: "+tsrvs.getLnkTblCapacity());
al.add("\tclient-side sck recv buffers: "+tsrvs.getClnRecvBuffers());
}
int rc;
boolean isOffline = false;
TLink lnk;
TDataType tdt;
NAME32[] n32 = new NAME32[100];
al.add("security :");
tdt = new TDataType(n32);
lnk = new TLink(tgt,"USERS",tdt,null,TAccess.CA_READ);
rc = lnk.executeAndClose();
if (rc == TErrorList.link_timeout || rc == TErrorList.connection_timeout)
isOffline = true;
if (rc == 0 && tdt.getCompletionLength() > 0)
{
al.add("WRITE access open to Users : ");
for (int i=0; i<tdt.getCompletionLength(); i++)
al.add("\t"+n32[i].name);
}
else
{
if (!isOffline) al.add("WRITE access open to : ALL users");
}
lnk = new TLink(tgt,"IPNETS",tdt,null,TAccess.CA_READ);
rc = isOffline ? TErrorList.connection_timeout : lnk.executeAndClose();
if (rc == 0 && tdt.getCompletionLength() > 0)
{
al.add("WRITE access open to Network Addresses : ");
for (int i=0; i<tdt.getCompletionLength(); i++)
al.add("\t"+n32[i].name);
}
else
{
if (!isOffline) al.add("WRITE access open to : ALL network addresses");
}
al.add("servers running on same host :");
ServerQuery[] sqhst = TQuery.getDeviceServersEx(context, ip,"ALL");
for (ServerQuery sq : sqhst) al.add("\t"+sq.getName());
String[] alst = ENSTools.getServerAliasList(tgt);
if (alst != null && alst.length > 0)
{
al.add("aliases for "+tgt+":");
for (String s : alst) al.add("\t"+s+ " -> "+tgt);
}
if (!isOffline)
{
String[] devs = TQuery.getDeviceNames(context, server);
if (devs != null)
{
al.add(tgt+" has "+devs.length+" devices");
if (TQuery.devices_have_query_function)
{
al.add(tgt+" has property query precedence (classic property server model)");
tgtdev = "#0";
}
if (devs.length > 0 && tgtdev == null) tgtdev = devs[0];
//for (String s: devs) al.add(s);
}
String[] prps = TQuery.getDeviceProperties(context, server, tgtdev);
if (prps != null)
{
al.add(tgt+" has "+prps.length+" properties");
if (TQuery.properties_have_query_function)
{
al.add(tgt+" has device query precedence (classic device server model)");
}
if (devs.length > 0 && tgtdev == null) tgtdev = devs[0];
//for (String s: prps) al.add(s);
}
TPropertyQuery pztpq[] = null;
long t0;
String rdr = null, lclhststr = null;
int callsOK = 0;
int callsErr = 0;
int callsNA = 0;
int len = prps.length;
if (limit > 0 && limit < len) len = limit;
for (int i=0; prps != null && i<len; i++)
{
pztpq = TQuery.getPropertyInformation(context, server, tgtdev, prps[i]);
if (pztpq == null)
{
callsErr++;
continue;
}
for (TPropertyQuery p: pztpq)
{
if (TAccess.isRead(p.prpAccess))
{
al.add("read "+p.prpName+" : "+p.prpDescription);
lclhststr = p.prpHistoryDepthShort == 0 ? "none" :
p.prpHistoryDepthShort < 0 ? "redirected" :
p.prpHistoryDepthLong > 0 ? ""+p.prpHistoryDepthLong+" month(s)" :
""+p.prpHistoryDepthShort+" entries in ring buffer";
al.add("\tlocal history : "+lclhststr);
al.add("\tarray type : "+TArrayType.toString(p.prpArrayType));
if (p.prpRedirection.length() > 0)
al.add("\tis redirected to "+p.prpRedirection);
if (p.prpSizeIn > 0) al.add("\ttakes input: "+p.prpSizeIn+" "+TFormat.toString(p.prpFormatIn)+" elements");
al.add("\tresults:");
if (p.prpFormat == TFormat.CF_STRUCT)
{
int ssiz = 0;
if ((ssiz=TStructRegistry.getSizeInBytes(p.prpTag)) <= 0)
{
TQuery.AcquireAndRegisterStructInfo(context, server, p.prpTag);
ssiz = TStructRegistry.getSizeInBytes(p.prpTag,context,server);
}
if (ssiz > 0) tdt = new TDataType(new byte[ssiz],p.prpTag);
else
{
al.add("\tunable to acquire and register structure tag "+p.prpTag);
tdt = new TDataType(p.prpSize,p.prpFormat);
}
}
else if (p.prpFormat == TFormat.CF_AIMAGE || p.prpFormat == TFormat.CF_ASPECTRUM)
{
al.add("\t"+lnk.getFullDeviceNameAndProperty()+" adjustable format not accessed");
callsNA++;
continue;
}
else
{
tdt = new TDataType(p.prpSize,p.prpFormat);
}
lnk = new TLink(tgt+"/"+tgtdev,p.prpName,tdt,null,TAccess.CA_READ);
t0 = System.currentTimeMillis();
rc = lnk.executeAndClose();
if (rc == TErrorList.illegal_read_write && p.prpSizeIn > 0)
{
al.add("\t"+lnk.getFullDeviceNameAndProperty()+" not accessed: requires input data");
callsNA++;
}
else
{
al.add("\t"+lnk.getFullDeviceNameAndProperty()+" "+p.prpSize+" "+
TFormat.toString(p.prpFormat)+" value(s) in "+
(System.currentTimeMillis()-t0)+" ms : "+lnk.getLastError());
TDataType dout = lnk.getOutputDataObject();
switch (dout.dFormat)
{
case TFormat.CF_STRUCT:
al.add("\tStructure type "+dout.getTag());
break;
case TFormat.CF_BITFIELD8:
case TFormat.CF_BITFIELD16:
case TFormat.CF_BITFIELD32:
case TFormat.CF_BITFIELD64:
al.add("\tBitfield type "+dout.getTag());
break;
case TFormat.CF_IMAGE:
IMAGE img = (IMAGE)dout.getDataObject();
al.add("\tImage; Frame size "+img.getFrameHeader().appendedFrameSize+" bytes");
break;
default:
if (dout.dCompletionLength <= 10)
{
dout.setArrayDelimiter(" ");
al.add("\tvalues: "+dout.toString());
}
else
{
al.add("\treceived "+dout.dCompletionLength+" values");
}
break;
}
if (TErrorList.hasData(rc)) callsOK++; else callsErr++;
}
if ((rdr=lnk.getRedirectionKey()) != null && rdr.length() > 0)
{
al.add("\t"+"redirected to "+rdr);
}
}
else
{
al.add("write "+p.prpName+" : "+p.prpDescription);
if (p.prpRedirection.length() > 0)
al.add("\tis redirected to "+p.prpRedirection);
al.add("\tresults:");
al.add("\t not accessed: is a command!");
callsNA++;
}
}
}
al.add("total calls : "+(callsOK+callsErr+callsNA));
al.add("total succeeded : "+callsOK);
al.add("total failed : "+callsErr);
al.add("total not accessed : "+callsNA);
}
else
{
al.add("server appears to be offline");
}
return al.toArray(new String[0]);
}
/**
* Returns a list of device servers associated with the specified
* context (obtained from the name services)
*
* @param context Is the context for which the device server name list is
* desired
*
* @return A string array containing a list of device servers associated
* with the given context as obtained from the Equipment Name Server (ENS)
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getDeviceServers(String context)
{
String[] lst = getTagList(context,"TAGS");
if (lst != null) return lst;
// then try static cache:
return DBQuery.getServersFromFileCache(context,null);
}
/**
* Returns a list of device servers associated with the specified
* context and subsystem (obtained from the name services)
*
* @param context Is the context for which the device server name list is
* desired
* @param subsys Is the subsystem for which the device server name list is
* desired
*
* @return A string array containing a list of device servers associated
* with the given context and subsystem as obtained from the Equipment Name Server (ENS)
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getDeviceServers(String context,String subsys)
{
if (!TLinkFactory.getInstance().isRunningStandAlone())
{
String[] lst = getTagList(context,"TAGS",subsys);
if (lst != null) return lst;
}
// then try static cache:
return DBQuery.getServersFromFileCache(context,subsys);
}
/**
* Returns a list of device servers associated with the specified
* context, subsystem, and importance level (obtained from the name services)
*
* @param context Is the context for which the device server name list is
* desired
* @param subsys Is the subsystem for which the device server name list is
* desired
* @param imporance Is the importance level for which the device server name list is
* desired (one of "ALL", "IMPORTANT", "ESSENTIAL", or "CRITICAL")
*
* @return A ServerQuery array containing a list of device servers associated
* with the given context, subsystem, and importance as obtained from the
* Equipment Name Server (ENS)
* A null pointer is returned if the call fails for any reason.
*/
public static ServerQuery[] getDeviceServersEx(String context,String subsys,String importance)
{
return getDeviceServersEx(context,subsys,importance,TLink.defaultTimeout);
}
/**
* Returns a list of device servers associated with the specified
* context, subsystem, and importance level (obtained from the name services)
*
* @param context Is the context for which the device server name list is
* desired
* @param subsys Is the subsystem for which the device server name list is
* desired
* @param imporance Is the importance level for which the device server name list is
* desired (one of "ALL", "IMPORTANT", "ESSENTIAL", or "CRITICAL")
* @param timeout is the time in milliseconds to wait for the call to complete
*
* @return A ServerQuery array containing a list of device servers associated
* with the given context, subsystem, and importance as obtained from the
* Equipment Name Server (ENS)
* A null pointer is returned if the call fails for any reason.
*/
public static ServerQuery[] getDeviceServersEx(String context,String subsys,String importance,int timeout)
{
return getXTagList(context,"TAGS",subsys,importance,timeout);
}
/**
* Returns a list of registered subsystems
* (obtained from the name services)
*
* @return A string array containing a list of subsystems.
* The subsystem is itself not part of the TINE name space,
* but can be used to refine queries to the Equipment Name
* Servers (ENS).
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getDeviceSubsystems()
{
String[] lst = getTagList(null,"SUBSYSTEMS");
if (lst != null) return lst;
return DBQuery.getSubsystemsFromFileCache(null);
}
/**
* Returns a list of registered subsystems in a given context
* (obtained from the name services)
*
* @param context Is the context for which the subsystem list is desired
*
* @return A string array containing a list of available subsystems in the given context.
* The subsystem is itself not part of the name space,
* but can be used to refine queries to the Equipment Name
* Servers (ENS).
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getDeviceSubsystems(String context)
{
if (!TLinkFactory.getInstance().isRunningStandAlone())
{
String[] lst = getTagList(context,"SUBSYSTEMS");
if (lst != null) return lst;
}
return DBQuery.getSubsystemsFromFileCache(context);
}
/**
* Returns a list of front end computers (FECs) associated with the specified
* context (obtained from the name services)
*
* @param context Is the context for which the FEC name list is
* desired
*
* @return A string array containing a list of front end computers associated
* with the given context as obtained from the Equipment Name Server (ENS)
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getServers(String context)
{
return getTagList(context,"FECS");
}
/**
* Returns a list of front end computers (FECs) associated with the specified
* context and sub system (obtained from the name services)
*
* @param context Is the context for which the FEC name list is
* desired
* @param subsys Is the subsystem for which the device server name list is
* desired
*
* @return A string array containing a list of front end computers associated
* with the given context and subsystem as obtained from the Equipment Name Server (ENS)
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getServers(String context,String subsys)
{
return getTagList(context,"FECS",subsys);
}
public static String[] getServersOnFec(String fecname)
{
return getTagList("DEFAULT","TAGS",fecname);
}
/**
* Returns a list of front end computers (FECs) associated with the specified
* context, subsystem, and importance level (obtained from the name services)
*
* @param context Is the context for which the device server name list is
* desired
* @param subsys Is the subsystem for which the device server name list is
* desired
* @param imporance Is the importance level for which the device server name list is
* desired (one of "ALL", "IMPORTANT", "ESSENTIAL", or "CRITICAL")
*
* @return A ServerQuery array containing a list of device servers associated
* with the given context, subsystem, and importance as obtained from the
* Equipment Name Server (ENS)
* A null pointer is returned if the call fails for any reason.
*/
public static ServerQuery[] getServersEx(String context,String subsys,String importance)
{
return getServersEx(context,subsys,importance,TLink.defaultTimeout);
}
/**
* Returns a list of front end computers (FECs) associated with the specified
* context, subsystem, and importance level (obtained from the name services)
*
* @param context Is the context for which the device server name list is
* desired
* @param subsys Is the subsystem for which the device server name list is
* desired
* @param imporance Is the importance level for which the device server name list is
* desired (one of "ALL", "IMPORTANT", "ESSENTIAL", or "CRITICAL")
* @param timeout is the time in milliseconds to wait for completion.
*
* @return A ServerQuery array containing a list of device servers associated
* with the given context, subsystem, and importance as obtained from the
* Equipment Name Server (ENS)
* A null pointer is returned if the call fails for any reason.
*/
public static ServerQuery[] getServersEx(String context,String subsys,String importance,int timeout)
{
return getXTagList(context,"FECS",subsys,importance,timeout);
}
/**
* @param fullServerName is the fully specified device server for which the
* information is requested (/<context>/<server>).
*
* @return an array of TClientStruct objects containing information
* about each of the clients attached to the targeted server.
* Returns null if the information cannot be obtained.
*/
public static TClientStruct[] getServerClients(String fullServerName)
{
if (fullServerName == null) return null;
TClientStruct[] tcs = new TClientStruct[100];
for (int i=0; i<100; i++) tcs[i] = new TClientStruct();
TDataType tcsd = new TDataType(tcs);
TLink tl = new TLink(fullServerName,"CLIENTS",tcsd,null,TAccess.CA_READ);
if (tl.executeAndClose(TLink.defaultTimeout) == 0)
{
int len;
for (len=0; len<100 && tcs[len].getProtocol()[0] != (short)0; len++);
if (len < 100)
{
TClientStruct[] tcss = new TClientStruct[len];
System.arraycopy(tcs,0,tcss,0,len);
return tcss;
}
return tcs;
}
DbgLog.log("getServerClients","error : " + tl.linkStatus);
return null;
}
public static TContractStruct[] getServerContracts(String fullServerName)
{
if (fullServerName == null) return null;
TContractStruct[] tcs = new TContractStruct[100];
for (int i=0; i<100; i++) tcs[i] = new TContractStruct();
TDataType tcsd = new TDataType(tcs);
TLink tl = new TLink(fullServerName,"CONTRACTS",tcsd,null,TAccess.CA_READ);
if (tl.executeAndClose(TLink.defaultTimeout) == 0)
{
int len;
for (len=0; len<100 && tcs[len].getEqpProperty()[0] != (char)0; len++);
if (len < 100)
{
TContractStruct[] tcss = new TContractStruct[len];
System.arraycopy(tcs,0,tcss,0,len);
return tcss;
}
return tcs;
}
DbgLog.log("getServerContracts","error : " + tl.linkStatus);
return null;
}
public static TServerSettings getServerSettings(String fullServerName)
{
if (fullServerName == null) return null;
TServerSettings[] tss = new TServerSettings[1];
tss[0] = new TServerSettings();
TDataType tssd = new TDataType(tss);
TLink tl = new TLink(fullServerName,"SRVSETTINGS",tssd,null,TAccess.CA_READ);
if (tl.executeAndClose(TLink.defaultTimeout) == 0)
{
return tss[0];
}
DbgLog.log("getServerSettings","error : " + tl.linkStatus);
return null;
}
public static TWriteAccessInfo[] getServerCommandList(String fullServerName)
{
if (fullServerName == null) return null;
TWriteAccessInfo[] twai = new TWriteAccessInfo[100];
for (int i=0; i<100; i++) twai[i] = new TWriteAccessInfo();
TDataType d = new TDataType(twai);
TLink tl = new TLink(fullServerName,"SRVCOMMANDS",d,null,TAccess.CA_READ);
if (tl.executeAndClose(TLink.defaultTimeout) == 0)
{
int len = d.getCompletionLength();
TWriteAccessInfo[] ra = (len < 100) ? Arrays.copyOf(twai, len) : twai;
return ra;
}
DbgLog.log("getServerCommandList","error : " + tl.linkStatus);
return null;
}
private static final int FECINFO_BASESIZE = 208;
/**
* Retrieves information about the specified front-end computer.
* @param frontEndComputer
* @return a FECInfo object containing the front end computer information.
* If the information cannot be obtained for what ever reason, the FECInfo
* object will contain nothing but "unknown" strings.
*/
public static FECInfo getServerInformation(String frontEndComputer)
{
TFecEntry fec;
FECInfo info;
if (frontEndComputer == null) return null;
if ((fec=TSrvEntry.getFecEntry(frontEndComputer)) != null)
{
if (fec.info != null) return fec.info;
}
String os, desc, loc, hdw, ver, resp;
char[] fi = new char[FECINFO_BASESIZE];
TDataType fid = new TDataType(fi);
if (frontEndComputer.startsWith("ENS#")) frontEndComputer = "ENS";
TLink tl = new TLink("ENS/FEC.EXT",frontEndComputer,fid,null,TAccess.CA_READ);
if (tl.executeAndClose(TLink.defaultTimeout) == 0)
{
int off = 0;
os = new String(fi,off,TStrings.FEC_OS_SIZE); off += TStrings.FEC_OS_SIZE;
desc = new String(fi,off,TStrings.FEC_DESC_SIZE); off += TStrings.FEC_DESC_SIZE;
loc = new String(fi,off,TStrings.FEC_LOCATION_SIZE); off += TStrings.FEC_LOCATION_SIZE;
ver = new String(fi,off,TStrings.FEC_VERSION_SIZE); off += TStrings.FEC_VERSION_SIZE;
hdw = new String(fi,off,TStrings.FEC_HDW_SIZE); off += TStrings.FEC_HDW_SIZE;
resp = new String(fi,off,TStrings.FEC_RESP_SIZE); off += TStrings.FEC_RESP_SIZE;
// parse away legacy description info
if (desc.startsWith("["))
{
int p = desc.indexOf(']');
if (p != -1)
{
desc = desc.substring(p+1);
}
}
}
else
{
os = "unknown"; desc = "unknown"; loc = "unknown";
hdw = "unknown"; ver = "unknown"; resp = "unknown";
}
info = new FECInfo(os,desc,loc,hdw,ver,resp);
if (fec != null) fec.info = info;
return info;
}
/**
* Returns a list of properties associated with the specified
* context and device server and device (obtained from the device server)
*
* @param context Is the context of the device server for which the property list is
* desired.
* @param server Is the device server for which the property list is
* desired.
* @param device Is the device name (module name) for which the property list
* is desired.
*
* @return A string array containing a list of properties
* as obtained from the given device server
*/
public static String[] getDeviceProperties(String context,String server,String device)
{
return getDeviceProperties(context,server,device,TLink.defaultTimeout);
}
public static String[] getDeviceProperties(String context,String server,String device,int timeout)
{
return getDeviceProperties(context,server,device,null,timeout);
}
/**
* Returns a list of properties associated with the specified
* context and device server, device, and property (sub)string
* (obtained from the device server)
*
* @param context Is the context of the device server for which the property list is
* desired.
* @param server Is the device server for which the property list is
* desired.
* @param device Is the device name (module name) for which the property list
* is desired.
* @param property Can be a queriable string with wildcard
* parameter '*'. e.g. property = 'P*' will return all properties whose
* first letter begins with 'P'.
*
* @return A string array containing a list of properties
* as obtained from the given device server
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getDeviceProperties(String context,String server,String device,String property)
{
return getDeviceProperties(context,server,device,property,TLink.defaultTimeout);
}
/**
* Returns a list of properties associated with the specified
* context and device server, device, and property (sub)string
* (obtained from the device server)
*
* @param context Is the context of the device server for which the property list is
* desired.
* @param server Is the device server for which the property list is
* desired.
* @param device Is the device name (module name) for which the property list
* is desired.
* @param property Can be a queriable string with wildcard
* parameter '*'. e.g. property = 'P*' will return all properties whose
* first letter begins with 'P'.
* @param timeout is the time in milliseconds to allow the call to complete
*
* @return A string array containing a list of properties
* as obtained from the given device server
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getDeviceProperties(String context,String server,String device,String property,int timeout)
{
String[] prps = null;
try
{
prps = getDeviceProperties64(context,server,device,property,timeout);
if (prps != null) return prps;
prps = getDeviceProperties16(context,server,device,property,timeout);
}
catch (IOException e)
{
return null;
}
return prps;
}
private static String[] getDeviceProperties16(String context,String server,String device,String property,int timeout) throws IOException
{
String tgt = getNamesQueryTarget(context,server,device);
if (tgt == null) return null;
TLink tl;
TDataType dout;
TDataType din;
int cc = 0,n,i,j;
NAME32[] properties;
String[] strprops;
n = getNumberOf("PROPS",tgt);
if (n <= 0) return null;
if (n*32 > maxQueryBufferSize) n = maxQueryBufferSize/32;
properties = new NAME32[n];
for (i=0; i<n; i++) properties[i] = new NAME32();
if (properties.length <= 0) return null;
dout = new TDataType(properties);
if (property != null) din = new TDataType(property); else din = null;
properties_have_query_function = false;
try
{
tl = new TLink(tgt,"PROPS",dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,true);
tl.close();
if ((cc & TErrorList.CE_SENDDATA) == TErrorList.CE_SENDDATA)
{
if ((cc & TErrorList.has_query_function) == TErrorList.has_query_function)
{
properties_have_query_function = true;
}
cc = 0;
}
}
catch (Exception e)
{
MsgLog.log("getDeviceProperties16", e.getMessage(),TErrorList.non_existent_elem,e,0);
cc = TErrorList.host_not_resolved;
}
if (cc == 0)
{
for (i=0,n=0; i<properties.length; i++) if (properties[i].name.length() > 0) n++;
strprops = new String[n];
for (i=0,j=0; j<n && i<properties.length; i++)
{
if (properties[i].name.length() == 0) continue;
strprops[j++] = properties[i].name;
}
return strprops;
}
else if (cc != TErrorList.link_not_open)
{
if (lastQueriedContext == context && lastQueriedServer == server &&
lastQueriedDevice == device && lastQueriedServer != null)
{
cc = 0;
}
else
{
hLegacyByteBlob = new byte[n * PropertyQuery.sizeInBytes];
dout = new TDataType(hLegacyByteBlob,"");
tl = new TLink(tgt,"PROPS",dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,false);
tl.close();
}
if (cc == 0)
{
lastQueriedContext = context;
lastQueriedServer = server;
lastQueriedDevice = device;
strprops = new String[n];
PropertyQuery[] pq = new PropertyQuery[n];
byte b[];
if (hLegacyByteBlob == null) return null;
for (i=0; i<n; i++)
{
pq[i] = new PropertyQuery();
b = pq[i].toByteArray();
System.arraycopy(hLegacyByteBlob,i*PropertyQuery.sizeInBytes,b,0,PropertyQuery.sizeInBytes);
pq[i].toStruct();
strprops[i] = pq[i].name;
}
return strprops;
}
}
throw new IOException("Could not acquire property information for " + server + " (" + TErrorList.getErrorString(cc) + ")");
}
/**
* Returns an array of properties matching the pattern input
*
* @param context is the desired server context
* @param server is the targeted device server
* @param device is the targeted device name
* @param propertyPattern is the property pattern (using the wild card character '*')
* for which a match is desired.
* @param timeout is the time in milliseconds to allow the call to complete.
* @return a string array containing those properties which match the pattern given.
* @throws IOException
*/
public static String[] getPropertiesWithPattern(String context,String server,String device,String propertyPattern,int timeout) throws IOException
{
String tgt = getNamesQueryTarget(context,server,device);
if (tgt == null || propertyPattern == null) return null;
TLink tl;
TDataType dout;
int cc = 0,n = 64,i,j;
NAME64[] properties;
String[] strprops;
properties = new NAME64[n];
for (i=0; i<n; i++) properties[i] = new NAME64();
dout = new TDataType(properties);
try
{
tl = new TLink(tgt,propertyPattern,dout,null,TAccess.CA_READ);
cc = tl.execute(timeout,true);
tl.close();
if ((cc & TErrorList.CE_SENDDATA) == TErrorList.CE_SENDDATA)
{
cc = 0;
}
}
catch (Exception e)
{
MsgLog.log("getPropertiesWithPattern", e.getMessage(),TErrorList.non_existent_elem,e,0);
cc = TErrorList.non_existent_elem;
}
if (cc == TErrorList.illegal_format) return null; // legacy server
if (cc == 0)
{
n = dout.getCompletionLength();
strprops = new String[n];
for (i=0,j=0; j<n && i<properties.length; i++)
{
if (properties[i].name.length() == 0) continue;
strprops[j++] = properties[i].name;
}
return strprops;
}
throw new IOException("Could not acquire property information for " + server + " (" + TErrorList.getErrorString(cc) + ")");
}
private static String[] getDeviceProperties64(String context,String server,String device,String property,int timeout) throws IOException
{
String tgt = getNamesQueryTarget(context,server,device);
if (tgt == null) return null;
TLink tl;
TDataType dout;
TDataType din;
int cc = 0,n,i,j;
NAME64[] properties;
String[] strprops;
n = getNumberOf("PROPS",tgt);
if (n == -TErrorList.illegal_device_number)
{ // a Steve special ...
strprops = new String[1];
strprops[0] = "INVALID";
properties_have_query_function = true;
return strprops;
}
if (n <= 0) return null;
if (n < 128) n = 256; else n += 100; // room for aliases
if (n*32 > maxQueryBufferSize) n = maxQueryBufferSize/64;
properties = new NAME64[n];
for (i=0; i<n; i++) properties[i] = new NAME64();
if (properties.length <= 0) return null;
dout = new TDataType(properties);
if (property != null) din = new TDataType(property); else din = null;
properties_have_query_function = false;
try
{
tl = new TLink(tgt,"PROPS",dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,true);
tl.close();
if ((cc & TErrorList.CE_SENDDATA) == TErrorList.CE_SENDDATA)
{
if ((cc & TErrorList.has_query_function) == TErrorList.has_query_function)
{
properties_have_query_function = true;
}
cc = 0;
}
if (cc == TErrorList.illegal_device_number)
{ // try this
properties_have_query_function = true;
}
}
catch (Exception e)
{
MsgLog.log("getDeviceProperties64", e.getMessage(),TErrorList.non_existent_elem,e,0);
cc = TErrorList.host_not_resolved;
}
if (cc == TErrorList.illegal_format ||
cc == TErrorList.invalid_transport_size) return null; // legacy server
if (cc == 0)
{
if (properties[0].name.length() == 0) return null; // release 3.3 java problem
for (i=0,n=0; i<properties.length; i++) if (properties[i].name.length() > 0) n++;
strprops = new String[n];
for (i=0,j=0; j<n && i<properties.length; i++)
{
if (properties[i].name.length() == 0) continue;
strprops[j++] = properties[i].name;
}
return strprops;
}
throw new IOException("Could not acquire property information for " + server + " (" + TErrorList.getErrorString(cc) + ")");
}
private static String getTineStockString(String context,String server,String property,String text)
{
TLink tl;
TDataType dout;
String tgt;
int cc = 0;
StringBuffer ver = new StringBuffer(32);
tgt = new String("/" + context + "/" + server + "/#0");
dout = new TDataType(ver);
try
{
tl = new TLink(tgt,property,dout,null,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,true);
tl.close();
}
catch (Exception e)
{
MsgLog.log("getTineStockString", e.getMessage(),TErrorList.non_existent_elem,e,0);
cc = TErrorList.non_existent_elem;
}
if (cc == 0)
{
return text + " : " + ver.toString().trim();
}
return text + " : unavailable";
}
/**
* Retrieves the TINE version of the input server
*
* @param context is the desired context
* @param server is the targeted server
* @return the current TINE version of the specified server
*/
public static String getTineVersion(String context,String server)
{
return getTineStockString(context,server,"SRVVERSION","tine version");
}
/**
* Retrieves the application version of the input server
*
* @param context is the desired context
* @param server is the targeted server
* @return the current application version of the specified server.
* If this information is not supplied by the server developer,
* then "1.0.0" will be the likely result.
*/
public static String getAppVersion(String context,String server)
{
return getTineStockString(context,server,"APPVERSION","Appl version");
}
/**
* Retrieves the application compile date
*
* @param context is the desired context
* @param server is the targeted server
* @return the current application compile data of the specified server.
* If this information is not supplied by the server developer,
* then "January 1, 1970" will be the likely result.
*/
public static String getAppDate(String context,String server)
{
return getTineStockString(context,server,"APPDATE","Appl date");
}
/**
* Returns a list of stock properties associated with the specified
* context and device server (obtained from the device server).
*
* @param context Is the context of the device server for which the property list is
* desired.
* @param server Is the device server for which the property list is
* desired.
*
* @return A string array containing a list of stock properties
* as obtained from the given device server
*/
public static String[] getStockProperties(String context,String server)
{
return getStockProperties(context,server,"#0",null);
}
/**
* Returns a list of stock properties associated with the specified
* context and device server, device, and property (sub)string
* (obtained from the device server). Typically, the device parameter does not
* play a role in this query.
*
* @param context Is the context of the device server for which the property list is
* desired.
* @param server Is the device server for which the property list is
* desired.
* @param device Is the device name (module name) for which the property list
* is desired.
* @param property Can be a queriable string with wildcard
* parameter '*'. e.g. property = 'P*' will return all stock properties whose
* first letter begins with 'P'.
*
* @return A string array containing a list of stock properties
* as obtained from the given device server
*/
public static String[] getStockProperties(String context,String server,String device,String property)
{
TLink tl;
TDataType dout;
TDataType din;
String tgt;
int cc = 0,n = 0,i,j;
NAME32[] properties;
String[] strprops;
tgt = new String("/" + context + "/" + server + "/" + device);
try
{
n = getNumberOf("STOCKPROPS",tgt);
}
catch (IOException e)
{
return null;
}
if (n <= 0) return null;
if (n*32 > maxQueryBufferSize) n = maxQueryBufferSize/32;
properties = new NAME32[n];
for (i=0; i<n; i++) properties[i] = new NAME32();
dout = new TDataType(properties);
if (property != null) din = new TDataType(property); else din = null;
properties_have_query_function = false;
tl = new TLink(tgt,"STOCKPROPS",dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,true);
if ((cc & TErrorList.CE_SENDDATA) == TErrorList.CE_SENDDATA)
{
if ((cc & TErrorList.has_query_function) == TErrorList.has_query_function)
{
properties_have_query_function = true;
}
cc = 0;
}
tl.close();
if (cc == 0)
{
for (i=0,n=0; i<properties.length; i++) if (properties[i].name.length() > 0) n++;
strprops = new String[n];
for (i=0,j=0; j<n && i<properties.length; i++)
{
if (properties[i].name.length() == 0) continue;
strprops[j++] = properties[i].name;
}
return strprops;
}
else if (cc != TErrorList.link_not_open)
{
if (lastQueriedContext == context && lastQueriedServer == server &&
lastQueriedDevice == device && lastQueriedServer != null)
{
cc = 0;
}
else
{
hLegacyByteBlob = new byte[n * PropertyQuery.sizeInBytes];
dout = new TDataType(hLegacyByteBlob,"");
tl = new TLink(tgt,"STOCKPROPS",dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,false);
tl.close();
}
if (cc == 0)
{
lastQueriedContext = context;
lastQueriedServer = server;
lastQueriedDevice = device;
strprops = new String[n];
PropertyQuery[] pq = new PropertyQuery[n];
byte b[];
if (hLegacyByteBlob == null) return null;
for (i=0; i<n; i++)
{
pq[i] = new PropertyQuery();
b = pq[i].toByteArray();
System.arraycopy(hLegacyByteBlob,i*PropertyQuery.sizeInBytes,b,0,PropertyQuery.sizeInBytes);
pq[i].toStruct();
strprops[i] = pq[i].name;
}
return strprops;
}
}
MsgLog.log("TQuery.getStockProperties", "Could not acquire property information for " + server,cc,null,0);
return null;
}
/**
* Returns a list of meta properties associated with the specified
* context and device server (obtained from the device server).
*
* @param context Is the context of the device server for which the property list is
* desired.
* @param server Is the device server for which the property list is
* desired.
*
* @return A string array containing a list of meta properties
* as obtained from the given device server
*/
public static String[] getMetaProperties(String context,String server)
{
return getMetaProperties(context,server,"#0",null);
}
/**
* Returns a list of meta properties associated with the specified
* context and device server, device, and property (sub)string
* (obtained from the device server). Typically, the device parameter does not
* play a role in this query.
*
* @param context Is the context of the device server for which the property list is
* desired.
* @param server Is the device server for which the property list is
* desired.
* @param device Is the device name (module name) for which the property list
* is desired.
* @param property Can be a queriable string with wildcard
* parameter '*'. e.g. property = 'P*' will return all stock properties whose
* first letter begins with 'P'.
*
* @return A string array containing a list of meta properties
* as obtained from the given device server
*/
public static String[] getMetaProperties(String context,String server,String device,String property)
{
TLink tl;
TDataType dout;
TDataType din;
String tgt;
int cc = 0,n = 0,i,j;
NAME64[] properties;
String[] strprops;
tgt = new String("/" + context + "/" + server + "/" + device);
try
{
TPropertyQuery[] pq = getStockPropertyInformation(context,server,device,"METAPROPS");
if (pq != null) {
n = pq[0].prpSize;
}
}
catch (Exception e)
{
return null;
}
if (n <= 0) return null;
if (n*32 > maxQueryBufferSize) n = maxQueryBufferSize/32;
properties = new NAME64[n];
for (i=0; i<n; i++) properties[i] = new NAME64();
dout = new TDataType(properties);
if (property != null) din = new TDataType(property); else din = null;
properties_have_query_function = false;
tl = new TLink(tgt,"METAPROPS",dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,true);
if ((cc & TErrorList.CE_SENDDATA) == TErrorList.CE_SENDDATA)
{
if ((cc & TErrorList.has_query_function) == TErrorList.has_query_function)
{
properties_have_query_function = true;
}
cc = 0;
}
tl.close();
if (cc == 0)
{
for (i=0,n=0; i<properties.length; i++) if (properties[i].name.length() > 0) n++;
strprops = new String[n];
for (i=0,j=0; j<n && i<properties.length; i++)
{
if (properties[i].name.length() == 0) continue;
strprops[j++] = properties[i].name;
}
return strprops;
}
else if (cc != TErrorList.link_not_open)
{
if (lastQueriedContext == context && lastQueriedServer == server &&
lastQueriedDevice == device && lastQueriedServer != null)
{
cc = 0;
}
else
{
hLegacyByteBlob = new byte[n * PropertyQuery.sizeInBytes];
dout = new TDataType(hLegacyByteBlob,"");
tl = new TLink(tgt,"METAPROPS",dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,false);
tl.close();
}
if (cc == 0)
{
lastQueriedContext = context;
lastQueriedServer = server;
lastQueriedDevice = device;
strprops = new String[n];
PropertyQuery[] pq = new PropertyQuery[n];
byte b[];
if (hLegacyByteBlob == null) return null;
for (i=0; i<n; i++)
{
pq[i] = new PropertyQuery();
b = pq[i].toByteArray();
System.arraycopy(hLegacyByteBlob,i*PropertyQuery.sizeInBytes,b,0,PropertyQuery.sizeInBytes);
pq[i].toStruct();
strprops[i] = pq[i].name;
}
return strprops;
}
}
MsgLog.log("TQuery.getMetaProperties", "Could not acquire property information for " + server,cc,null,0);
return null;
}
/**
* Returns a list of device names associated with the specified
* context and device server
* (obtained from the device server)
*
* As the call is directed to the device server, it assumes the return
* list applies to all properties
*
* @param context Is the context of the device server for which the property list is
* desired.
* @param server Is the device server for which the property list is
* desired.
*
* @return A string array containing a list of devices
* as obtained from the given device server.
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getDeviceNames(String context,String server)
{
return getDeviceNames(context,server,null);
}
/**
* Returns a list of device names associated with the specified
* context, device server and property
* (obtained from the device server)
*
* @param context Is the context of the device server for which the device list is
* desired.
* @param server Is the device server for which the device list is
* desired.
* @param property Is the property for which the device list is
* desired.
*
* @return A string array containing a list of devices
* as obtained from the given device server
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getDeviceNames(String context,String server,String property)
{
return getDeviceNames(context,server,property,TLink.defaultTimeout);
}
/**
* Returns a list of device names associated with the specified
* context, device server and property
* (obtained from the device server)
*
* @param context Is the context of the device server for which the device list is
* desired.
* @param server Is the device server for which the device list is
* desired.
* @param property Is the property for which the device list is
* desired.
* @param filter is a device name filter containing the wildcard character '*'
*
* @return A string array containing a list of devices
* as obtained from the given device server
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getDeviceNames(String context,String server,String property,String filter)
{
return getDeviceNames(context,server,property,filter,TLink.defaultTimeout);
}
/**
* Returns a list of device names associated with the specified
* context, device server and property
* (obtained from the device server)
*
* @param context is the context of the device server for which the device list is
* desired.
* @param server is the device server for which the device list is
* desired.
* @param property is the property for which the device list is
* desired.
* @param timeout is the time in milliseconds to wait for the call to complete
*
* @return A string array containing a list of devices
* as obtained from the given device server
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getDeviceNames(String context,String server,String property,int timeout)
{
return getDeviceNames(context,server,property,null,timeout);
}
/**
* Returns a list of device names associated with the specified
* context, device server and property
* (obtained from the device server)
*
* @param context is the context of the device server for which the device list is
* desired.
* @param server is the device server for which the device list is
* desired.
* @param property is the property for which the device list is
* desired.
* @param filter is a device name filter containing the wildcard character '*'
* @param timeout is the time in milliseconds to wait for the call to complete
*
* @return A string array containing a list of devices
* as obtained from the given device server
* A null pointer is returned if the call fails for any reason.
*/
public static String[] getDeviceNames(String context,String server,String property,String filter,int timeout)
{
String[] devs = null;
try
{
devs = getDeviceNames64(context,server,property,filter,timeout);
if (devs != null) return devs;
devs = getDeviceNames16(context,server,property,timeout);
}
catch (IOException e)
{
return null;
}
return devs;
}
private static String[] getDeviceNames16(String context,String server,String property,int timeout) throws IOException
{
DeviceNamesQueryParams dnqp = getDeviceNamesQueryProperty(context,server,property,null,timeout);
if (dnqp == null) return null;
int n = dnqp.size;
TLink tl;
TDataType dout;
int cc = 0,i,j;
String tmp;
NAME16[] devices;
String[] strdevs;
//if (n*16 > maxQueryBufferSize) n = maxQueryBufferSize/16;
devices = new NAME16[n];
for (i=0; i<n; i++) devices[i] = new NAME16();
if (devices.length == 0) return null;
if (n == 1)
{ // server claimed not to have device names ?
devices[0].name = "#0";
}
dout = new TDataType(devices);
tl = new TLink(dnqp.target,dnqp.property,dout,null,TAccess.CA_READ);
cc = tl.execute(timeout,true);
tl.close();
if ((cc & TErrorList.CE_SENDDATA) == TErrorList.CE_SENDDATA)
{
if ((cc & TErrorList.has_query_function) == TErrorList.has_query_function)
{
devices_have_query_function = true;
}
cc = 0;
}
if (cc != 0) return null;
// check for long names (the Channel Access kluge)
for (i=0,n=0; i<devices.length; i++)
if (devices[i].name.length() > 0 && !devices[i].name.endsWith("&")) n++;
strdevs = new String[n];
for (i=0,j=0; i<devices.length && j<n; i++)
{
tmp = devices[i].name;
if (tmp.length() == 0) continue;
if (tmp.endsWith("&"))
{
i++;
tmp = tmp.substring(0, tmp.length() - 1) + devices[i].name;
}
strdevs[j++] = tmp;
}
return strdevs;
}
private static String getNamesQueryTarget(String context,String server,String device)
{
String tgt, dev;
if (server == null || server.length() == 0) return null;
dev = (device == null) ? "#0" : device; // a '*' here is lethal at the moment !
if (context == null || context.length() == 0)
tgt = new String("/DEFAULT/" + server + "/" + dev);
else
tgt = new String("/" + context + "/" + server + "/" + dev);
return tgt;
}
private class DeviceNamesQueryParams
{
String target;
String property;
int size;
}
private static TQuery tQueryInstance = new TQuery();
private static TQuery getInstance()
{
if (tQueryInstance == null) tQueryInstance = new TQuery();
return tQueryInstance;
}
private static DeviceNamesQueryParams getDeviceNamesQueryProperty(String context,String server,String property,String filter,int timeout) throws IOException
{
if (property != null) filter = null;
TQuery tq = getInstance();
String tgt = getNamesQueryTarget(context,server,filter);
if (tgt == null) return null;
DeviceNamesQueryParams dnqp = tq.new DeviceNamesQueryParams();
int n = 0;
String prp=null;
TPropertyQuery[] tpq;
n = getNumberOf("DEVICES",tgt,timeout);
if (property != null)
{
if (property.length() > 0 && !isStockProperty(property))
{
devices_have_query_function = false;
if ((tpq=getPropertyInformation(context,server,"#0",property,timeout)) != null)
{ // this should always work
if (tpq[0].prpFormat != TFormat.CF_TEXT)
{
if (TArrayType.isChannel(tpq[0].prpArrayType) || tpq[0].prpSize > n) n = tpq[0].prpSize;
}
else
{
if (n < 100) n = 100;
}
//if (tpq[0].prpFormat == TFormat.CF_TEXT) n = 1;
prp = property + ".NAM";
}
else if (property.contains(".DMASK.") || property.endsWith(".ONLINE"))
{
prp = property + ".NAM";
}
if (TLinkFactory.isRedirected(context, server, "#0", "PROPS"))
{ // keep the device list from the original target
prp = null;
}
}
}
if (prp == null)
{ // fallback :
devices_have_query_function = false;
if (n < 0) return null;
if (n == 0) n++;
prp = "DEVICES";
}
dnqp.target = tgt;
dnqp.property = prp;
dnqp.size = n;
return dnqp;
}
/**
* Returns the number of registered devices for the server and context
* (and property if non null) given.
*
* @param context is the requested context
* @param server is the requested device server
* @param property is the desired property (if null or an empty string) the
* call returns the number of registered devices, else it returns the number
* of property-specific devices.
* @param timeout in milliseconds
* @return the number of devices
* @throws IOException
*/
public static int getNumberOfDevices(String context,String server,String property,int timeout) throws IOException
{
DeviceNamesQueryParams dnqp = getDeviceNamesQueryProperty(context,server,property,null,timeout);
return dnqp == null ? 0 : dnqp.size;
}
/**
* Returns the number of registered devices for the server and context
* (and property if non null) given.
*
* @param context is the requested context
* @param server is the requested device server
* @param property is the desired property (if null or an empty string) the
* call returns the number of registered devices, else it returns the number
* of property-specific devices.
* @param filter is a device name filter containing a wildcard character '*'
* @param timeout in milliseconds
* @return the number of devices
* @throws IOException
*/
public static int getNumberOfDevices(String context,String server,String property,String filter,int timeout) throws IOException
{
DeviceNamesQueryParams dnqp = getDeviceNamesQueryProperty(context,server,property,filter,timeout);
return dnqp == null ? 0 : dnqp.size;
}
private static String[] getDeviceNames64(String context,String server,String property,String filter,int timeout) throws IOException
{
DeviceNamesQueryParams dnqp = getDeviceNamesQueryProperty(context,server,property,filter,timeout);
if (dnqp == null) return null;
TLink tl;
TDataType dout;
int cc = 0,i;
NAME64[] devices;
String[] strdevs;
int n = dnqp.size;
//if (n*64 > maxQueryBufferSize) n = maxQueryBufferSize/64;
devices = new NAME64[n];
for (i=0; i<n; i++) devices[i] = new NAME64();
if (devices.length == 0) return null;
dout = new TDataType(devices);
tl = new TLink(dnqp.target,dnqp.property,dout,null,TAccess.CA_READ);
cc = tl.executeAndClose(timeout);
if ((cc & TErrorList.CE_SENDDATA) == TErrorList.CE_SENDDATA)
{
if ((cc & TErrorList.has_query_function) == TErrorList.has_query_function)
{
devices_have_query_function = true;
}
cc = 0;
}
if (cc != 0)
{
if (cc == TErrorList.link_not_open || cc == TErrorList.connection_timeout)
{
throw new IOException("/"+context+"/"+server+" timed out getting device names");
}
return null;
}
// check for empty names (java pre-release 4.0 specialty)
if (devices[0].name.length() == 0) return null;
// int ndevs = devices.length;
// for (n=ndevs; n > 0; n--)
// { // find the last one in the list with names
// if (devices[n-1].name.length() > 0) break;
// }
for (i=0,n=0; i<devices.length; i++)
{ // recount the returned list
if (devices[i].name.length() > 0) n++;
}
strdevs = new String[n];
for (i=0; i<n; i++)
{
if (devices[i].name.length() == 0) continue;
strdevs[i] = devices[i].name;
}
return strdevs;
}
/**
* @deprecated
* @see getPropertyInformation
*
* Returns a list of extended property query information objects associated
* with the specified context, device server, device. and target property
* (obtained from the device server).
*
* Usually a call to getDeviceProperties() returns a property list
* A secondary call to getDevicePropertyInformation() returns a list of
* all property information pertaining to the specified property including
* all property overloads (maximum 10). If 'property' is null then the
* call returns information for the first 10 items.
*
* @param context Is the context of the device server for which the property
* information is desired.
* @param server Is the device server for which the property information is
* desired.
* @param device Is the device name (module name) for which the property
* information is desired.
* @param property Is the property for which the property information is
* desired.
*
* @return An array of PropertyQueryEx (extended Property Query) objects,
* as obtained from the given device server
*/
public static PropertyQueryEx[] getDevicePropertyInformation(String context,String server,String device,String property)
{
return getDevicePropertyInformation(context,server,device,property,TLink.defaultTimeout);
}
/**
* @deprecated
* @see getPropertyInformation
*
*/
public static synchronized PropertyQueryEx[] getDevicePropertyInformation(String context,String server,String device,String property,int timeout)
{
XPropertyQuery[] xpq = getDevicePropertyInformationX(context, server, device, property, timeout);
if (xpq == null) return null;
PropertyQueryEx[] pqx = new PropertyQueryEx[xpq.length];
for (int i=0; i<pqx.length; i++) pqx[i] = new PropertyQueryEx(xpq[i]);
return pqx;
}
public static synchronized int AcquireAndRegisterBitfieldInfo(String context,String server,String tag,short format)
{
if (TBitfieldRegistry.getBitfield(context,server,tag) != null) return 0; // already registered
String tgt;
if (context == null || context.length() == 0) context = "DEFAULT";
tgt = new String("/" + context + "/" + server);
TBitfield bf = new TBitfield(tgt,tag,format);
return bf.acquireAndRegisterFields(tgt);
}
public static synchronized int AcquireAndRegisterStructInfo(String context,String server,String tag)
{
//if (TStructRegistry.contains(tag)) return 0; // already registered
boolean doOnce = TStructRegistry.acquireOnce(tag);
if (!doOnce && TStructRegistry.contains(tag,context,server)) return 0; // already registered
int cc = 0, fmt, siz;
NAME64DBLDBL[] sf = new NAME64DBLDBL[64];
TDataType din = new TDataType(tag);
TDataType dout = new TDataType(sf);
String tgt;
if (context == null || context.length() == 0) context = "DEFAULT";
tgt = new String("/"+context+"/"+server+"/#0");
TLink tl = new TLink(tgt,"STRUCTFORMAT",dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,true);
if ((cc & TErrorList.CE_SENDDATA) == TErrorList.CE_SENDDATA) cc = 0;
tl.close();
if (cc == 0)
{
TStructDescription sd = new TStructDescription(tag);
sd.beginDefinition();
for (int i=0; i<64; i++)
{
fmt = (int)(sf[i].d2val)%512;
siz = (int)sf[i].d1val;
if (fmt == TFormat.CF_NULL) break;
if (fmt == TFormat.CF_STRUCT)
{
String stag = sf[i].name.substring(1, sf[i].name.indexOf('>'));
AcquireAndRegisterStructInfo(context,server,stag);
}
if (doOnce) TStructRegistry.fill(tag,sf[i].name,(short)fmt,siz);
sd.addField(sf[i].name, (short)fmt, siz);
}
if (doOnce) TStructRegistry.fill(tag,(short)TFormat.CF_NULL,100);
sd.setArraySize(100);
sd.endDefinition();
if (doOnce)
{
TStructRegistry.acquiredOnce(tag);
return 0;
}
//TStructRegistry.assignServerKey(tag, "/"+context+"/"+server);
TStructRegistry.assignServerKey(sd,"/"+context+"/"+server);
}
else if (cc == TErrorList.illegal_format)
{
cc = AcquireAndRegisterStructInfoLegacy(context,server,tag);
}
return cc;
}
private static int AcquireAndRegisterStructInfoLegacy(String context,String server,String tag)
{
if (TStructRegistry.contains(tag)) return 0; // already registered
int cc = 0;
INTINT[] sf = new INTINT[64];
TDataType din = new TDataType(tag);
TDataType dout = new TDataType(sf);
String tgt;
if (context == null || context.length() == 0) context = "DEFAULT";
tgt = new String("/"+context+"/"+server+"/#0");
TLink tl = new TLink(tgt,"STRUCTFORMAT",dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,true);
if ((cc & TErrorList.CE_SENDDATA) == TErrorList.CE_SENDDATA) cc = 0;
tl.close();
if (cc == 0)
{
TStructDescription sd = new TStructDescription(tag);
sd.beginDefinition();
for (int i=0; i<64; i++)
{
if ((sf[i].i2val%512) == TFormat.CF_NULL) break;
//TStructRegistry.fill(tag,(short)sf[i].i2val,sf[i].i1val);
sd.addField((short)sf[i].i2val,sf[i].i1val);
}
//TStructRegistry.fill(tag,(short)TFormat.CF_NULL,100);
sd.setArraySize(100);
sd.endDefinition();
//TStructRegistry.assignServerKey(tag, "/"+context+"/"+server);
TStructRegistry.assignServerKey(sd,"/"+context+"/"+server);
}
return cc;
}
/**
* @deprecated
* @see getPropertyInformation
*
* Returns a list of extended property query information objects associated
* with the specified context, device server, device. and target property
* (obtained from the device server).
*
* Usually a call to getDeviceProperties() returns a property list
* A secondary call to getDevicePropertyInformationX() returns a list of
* all property information pertaining to the specified property including
* all property overloads (maximum 10). If 'property' is null then the
* call returns information for the first 10 items. This is an extended
* method call which returns information as to the array 'type' if the
* property returns an array, as well as the horizontal axis engineering
* units and range if the property returns a spectrum and the row size
* and number or rows if the property returns a double array (matrix).
*
* @param context Is the context of the device server for which the property
* information is desired.
* @param server Is the device server for which the property information is
* desired.
* @param device Is the device name (module name) for which the property
* information is desired.
* @param property Is the property for which the property information is
* desired.
*
* @return An array of XPropertyQuery (extended Property Query) objects,
* as obtained from the given device server
*
*/
public static XPropertyQuery[] getDevicePropertyInformationX(String context,String server,String device,String property)
{
return getDevicePropertyInformationX(context,server,device,property,TLink.defaultTimeout);
}
/**
* @deprecated
* @see getPropertyInformation
*/
public static XPropertyQuery[] getDevicePropertyInformationX(String context,String server,String device,String property,int timeout)
{
return getDevicePropertyInformationX("PROPS", context,server,device,property,timeout);
}
private static synchronized XPropertyQuery[] getDevicePropertyInformationX(String stockprop, String context,String server,String device,String property,int timeout)
{
TLink tl;
TDataType dout, din;
int cc = 0,i;
String tgt, dev;
XPropertyQuery[] xpq = null;
XPropertyQuery xpq1 = new XPropertyQuery();
byte[] blob = hByteBlobX;
boolean hasTarget = true;
if (server == null || server.length() == 0) return null;
if (device == null || device.length() == 0)
dev = new String("#0");
else
dev = device;
if (context == null || context.length() == 0)
tgt = new String("/DEFAULT/" + server + "/" + dev);
else
tgt = new String("/" + context + "/" + server + "/" + dev);
int np = nicePropertyQuerySize;
if (property == null || property.compareTo("*") == 0)
{
din = new TDataType();
String target = "/" + context + "/" + server;
try
{
np = getNumberOf("PROPERTIES", target, timeout);
}
catch (IOException e)
{
throw new RuntimeException("Could not acquire property information for " + server + " (" + TErrorList.getErrorString(cc) + ")");
}
int fudge_factor = np > 150 ? 1 : 2;
blob = new byte[fudge_factor * np * XPropertyQuery.sizeInBytes]; // allow room for overloads
hasTarget = false;
}
else
{
din = new TDataType(property);
}
dout = new TDataType(blob,"XPQS");
while (np > 0)
{
try
{
tl = new TLink(tgt,stockprop,dout,din,TAccess.CA_READ);
cc = tl.execute(timeout,true);
srvAddr = tl.srvAddr;
if ((cc & TErrorList.CE_SENDDATA) == TErrorList.CE_SENDDATA) cc = 0;
tl.close();
}
catch (Exception e)
{
MsgLog.log("getDevicePropertyInformationX", e.getMessage(),TErrorList.non_existent_elem,e,0);
cc = TErrorList.non_existent_elem;
}
if (cc == TErrorList.invalid_transport_size)
{
np /= 2;
blob = new byte[np * XPropertyQuery.sizeInBytes]; // allow room for overloads
dout = new TDataType(blob,"XPQS");
}
else
{
break;
}
}
if (cc == 0) // it's at lease a 3.31 server
{
try
{
TStructIo.bytesToStruct(xpq1, blob,0,XPropertyQuery.sizeInBytes);
}
catch (IOException e1) { e1.printStackTrace(); }
int nxpq = dout.dCompletionLength;
if (hasTarget)
{
if (xpq1.prpNumOverloads < 1) xpq1.prpNumOverloads = 1; // can't be less than 1 !
nxpq = xpq1.prpNumOverloads;
if (nxpq > nicePropertyQuerySize) nxpq = nicePropertyQuerySize;
}
if (nxpq == 0) return null;
if (xpq1.prpNumOverloads < 1) xpq1.prpNumOverloads = 1; // can't be less than 1 !
if (nxpq > np) nxpq = np;
xpq = new XPropertyQuery[nxpq];
xpq[0] = xpq1;
for (i=1; i<nxpq; i++)
{
xpq[i] = new XPropertyQuery();
try {
TStructIo.bytesToStruct(xpq[i],blob,i*XPropertyQuery.sizeInBytes,XPropertyQuery.sizeInBytes);
} catch (Exception e) {
e.printStackTrace();
}
}
return xpq;
}
if (cc == TErrorList.link_not_open)
{
throw new RuntimeException("Could not acquire property information for " + server + " (" + TErrorList.getErrorString(cc) + ")");
}
if (cc == TErrorList.non_existent) return null;
PropertyQueryLegacy[] pqx = null;
PropertyQueryLegacy pqx1 = new PropertyQueryLegacy();
dout = new TDataType(hByteBlobL,"PQSX");
tl = new TLink(tgt,stockprop,dout,din,TAccess.CA_READ);
cc = tl.execute(timeout,true);
tl.close();
if (cc == 0) // it's at lease a 3.20 server
{
byte b[] = pqx1.toByteArray();
System.arraycopy(hByteBlobL,0,b,0,PropertyQueryLegacy.sizeInBytes);
pqx1.toStruct();
int npqx = np;
if (hasTarget)
{
if (pqx1.prpNumOverloads < 1) pqx1.prpNumOverloads = 1; // can't be less than 1 !
npqx = pqx1.prpNumOverloads;
}
if (npqx > nicePropertyQuerySize) npqx = nicePropertyQuerySize;
pqx = new PropertyQueryLegacy[npqx];
xpq = new XPropertyQuery[npqx];
pqx[0] = pqx1;
for (i=1; i<npqx; i++)
{
pqx[i] = new PropertyQueryLegacy();
b = pqx[i].toByteArray();
System.arraycopy(hByteBlobL,i*PropertyQueryLegacy.sizeInBytes,b,0,PropertyQueryLegacy.sizeInBytes);
pqx[i].toStruct();
}
for (i=0; i<npqx; i++)
{
xpq[i] = new XPropertyQuery();
xpq[i].prpFormat = pqx[i].prpFormat;
xpq[i].prpFormatIn = pqx[i].prpFormatIn;
xpq[i].prpSize = pqx[i].prpSize;
xpq[i].prpSizeIn = pqx[i].prpSizeIn;
xpq[i].prpAccess = pqx[i].prpAccess;
xpq[i].prpDescription = pqx[i].prpDescription;
xpq[i].prpName = pqx[i].prpName;
xpq[i].prpNumOverloads = pqx[i].prpNumOverloads;
xpq[i].prpTag = pqx[i].prpTag;
xpq[i].prpTagIn = pqx[i].prpTagIn;
xpq[i].prpRedirection = pqx[i].prpRedirection;
xpq[i].prpHistoryDepthLong = pqx[i].prpHistoryDepthLong;
xpq[i].prpHistoryDepthShort = pqx[i].prpHistoryDepthShort;
xpq[i].prpUnits = pqx[i].prpUnits;
xpq[i].prpMaxValue = pqx[i].prpMaxValue;
xpq[i].prpMinValue = pqx[i].prpMinValue;
xpq[i].prpGraphType = pqx[i].prpGraphType;
}
return xpq;
}
if (cc == TErrorList.link_not_open)
{
throw new RuntimeException("Could not acquire property information for " + server + " (" + TErrorList.getErrorString(cc) + ")");
}
// legacy server
hLegacyByteBlob = null;
String[] prps = getDeviceProperties(context,server,device);
if (prps == null || prps.length == 0) return null;
PropertyQuery[] pq = new PropertyQuery[prps.length];
xpq = new XPropertyQuery[1];
byte b[];
if (hLegacyByteBlob == null) return null;
for (i=0; i<prps.length; i++)
{
pq[i] = new PropertyQuery();
b = pq[i].toByteArray();
System.arraycopy(hLegacyByteBlob,i*PropertyQuery.sizeInBytes,b,0,PropertyQuery.sizeInBytes);
pq[i].toStruct();
if (pq[i].name.compareTo(property) != 0) continue;
xpq[0] = new XPropertyQuery();
xpq[0].prpFormat = pq[i].prpFormat;
xpq[0].prpSize = pq[i].prpSize;
xpq[0].prpAccess = pq[i].prpAccess;
xpq[0].prpDescription = pq[i].prpDesc;
xpq[0].prpName = pq[i].name;
xpq[0].prpNumOverloads = 1;
if ((pq[0].prpAccess & TAccess.CA_WRITE) == TAccess.CA_WRITE)
{
xpq[0].prpFormatIn = pq[i].prpFormat;
xpq[0].prpSizeIn = pq[i].prpSize;
}
else
{
xpq[0].prpFormatIn = (byte)TFormat.CF_NULL;
xpq[0].prpSizeIn = 0;
}
USTRING[] egu = new USTRING[1];
egu[0] = new USTRING();
dout = new TDataType(egu);
din = new TDataType();
String prpegu = new String(property + ".EGU");
tl = new TLink(tgt,prpegu,dout,din,TAccess.CA_READ);
cc = tl.execute(timeout,false);
tl.close();
if (cc == 0)
{
xpq[0].prpMinValue = egu[0].f1val;
xpq[0].prpMaxValue = egu[0].f2val;
xpq[0].prpUnits = egu[0].str;
xpq[0].prpGraphType = (byte)egu[0].ival;
}
break;
}
return xpq;
}
/**
* Returns a list of property query information objects associated
* with the specified context, device server, device. and target property
* (obtained from the device server).
*
* Usually a call to getDeviceProperties() returns a property list
* A secondary call to getPropertyInformation() returns a list of
* all property information pertaining to the specified property including
* all property overloads (maximum 10). If 'property' is null then the
* call returns information for the first 10 items. This is an extended
* method call which returns information as to the array 'type' if the
* property returns an array, as well as the horizontal axis engineering
* units and range if the property returns a spectrum and the row size
* and number or rows if the property returns a double array (matrix).
*
* @param context is the context of the device server for which the property
* information is desired.
* @param server is the device server for which the property information is
* desired.
* @param device is the device name (module name) for which the property
* information is desired.
* @param property is the property for which the property information is
* desired.
*
* @return An array of TPropertyQuery objects, as obtained from the given device server
* A null pointer is returned if the call fails for any reason.
*
*/
public static TPropertyQuery[] getPropertyInformation(String context,String server,String device,String property)
{
return getPropertyInformation(context,server,device,property,500);
}
/**
* Returns a list of property query information objects associated
* with the specified context, device server, device. and target property
* (obtained from the device server).
*
* Usually a call to getDeviceProperties() returns a property list
* A secondary call to getPropertyInformation() returns a list of
* all property information pertaining to the specified property including
* all property overloads (maximum 10). If 'property' is null then the
* call returns information for the first 10 items. This is an extended
* method call which returns information as to the array 'type' if the
* property returns an array, as well as the horizontal axis engineering
* units and range if the property returns a spectrum and the row size
* and number or rows if the property returns a double array (matrix).
*
* @param context is the context of the device server for which the property
* information is desired.
* @param server is the device server for which the property information is
* desired.
* @param device is the device name (module name) for which the property
* information is desired.
* @param property Is the property for which the property information is
* desired.
* @param timeout is the time in milliseconds to wait for the call to complete
*
* @return An array of TPropertyQuery objects, as obtained from the given device server.
* A null pointer is returned if the call fails for any reason.
*/
public static TPropertyQuery[] getPropertyInformation(String context,String server,String device,String property,int timeout)
{
try
{
return getPropertyInformation("PROPS",context,server,device,property,timeout);
}
catch (IOException e)
{
return null;
}
}
public static int pingServer(String context,String server,int timeout)
{
return pingServer(context,server,timeout,false);
}
public static int pingServer(String context,String server,int timeout,boolean output)
{
if (context == null || server == null)
{
if (output) System.out.println("error: parameter list error");
return TErrorList.argument_list_error;
}
String target = "/"+context+"/"+server;
char[] st = new char[32];
TDataType dout = new TDataType(st);
int cc = TErrorList.address_unknown;
try
{
TLink tl = new TLink(target,"SRVSTARTTIME",dout,null,TAccess.CA_READ);
cc = tl.execute(timeout,true);
tl.close();
if (output && cc == 0) System.out.println("running since "+new String(st));
}
catch (Exception e)
{
// just swallow it ...
}
if (output && cc != 0) System.out.println("error: "+TErrorList.getErrorString(cc));
return cc;
}
public static boolean isValidServer(String context,String server)
{
srvAddr = new TSrvEntry(server,context);
if (srvAddr.eqmName == null) return false;
return true;
}
/**
* Returns the number of registered properties for the give server and context
*
* @param context is the requested context
* @param server is the requested device server
* @param timeout in milliseconds
* @return the number of properties
* @throws IOException
*/
public static int getNumberOfProperties(String context,String server,int timeout) throws IOException
{
if (context == null || server == null) return 0;
return getNumberOf("PROPERTIES", "/"+context+"/"+server, timeout);
}
private static synchronized TPropertyQuery[] getPropertyInformation(String stockprop,String context,String server,String device,String property,int timeout) throws IOException
{
TLink tl = null;
TDataType dout, din;
int cc = 0, i;
String tgt, dev;
TPropertyQuery[] tpq = null;
TPropertyQuery tpq0 = new TPropertyQuery();
boolean hasTarget = true;
byte[] blob = hByteBlob;
if (server == null || server.length() == 0)
{
MsgLog.log("getPropertyInformation", "argument list error",TErrorList.argument_list_error,null,0);
return null;
}
if (device == null || device.length() == 0)
dev = new String("#0");
else
dev = device;
if (context == null || context.length() == 0)
tgt = new String("/DEFAULT/" + server + "/" + dev);
else
tgt = new String("/" + context + "/" + server + "/" + dev);
if (property == null || property.compareTo("*") == 0)
{
hasTarget = false;
din = new TDataType();
//String target = "/" + context + "/" + server;
int np = nicePropertyQuerySize;
try
{
np = getNumberOf("PROPERTIES", tgt, timeout);
}
catch (Exception e)
{
MsgLog.log("getPropertyInformation",e.toString(),TErrorList.connection_timeout,e,0);
throw new IOException("Could not acquire property information for " + server + " (" + e.toString() + ")");
}
blob = new byte[2 * np * TPropertyQuery.sizeInBytes]; // allow room for overloads
}
else
{
if (TQuery.isStockProperty(property))
{
stockprop = "STOCKPROPS";
}
din = new TDataType(property);
}
dout = new TDataType(blob,"PRPQSr4");
try
{
tl = new TLink(tgt,stockprop,dout,din,TAccess.CA_READ);
cc = tl.execute(timeout,true);
srvAddr = tl.srvAddr;
if ((cc & TErrorList.CE_SENDDATA) == TErrorList.CE_SENDDATA) cc = 0;
tl.close();
}
catch (Exception e)
{
MsgLog.log("getPropertyInformation", e.toString(),cc,e,0);
cc = TErrorList.address_unknown;
if (tl != null) tl.close();
}
if (cc == 0) // it's at lease a 4.0 server
{
try
{
TStructIo.bytesToStruct(tpq0, blob,0,TPropertyQuery.sizeInBytes);
}
catch (IOException e1)
{
e1.printStackTrace();
cc = TErrorList.code_failure;
MsgLog.log("getPropertyInformation", e1.toString(),cc,e1,0);
}
int ntpq = dout.dCompletionLength;
if (hasTarget)
{
if (tpq0.prpNumOverloads < 1) tpq0.prpNumOverloads = 1; // can't be less than 1 !
ntpq = tpq0.prpNumOverloads;
if (ntpq > nicePropertyQuerySize) ntpq = nicePropertyQuerySize;
}
if (ntpq == 0) return null;
tpq = new TPropertyQuery[ntpq];
tpq[0] = tpq0;
for (i=1; i<ntpq; i++)
{
tpq[i] = new TPropertyQuery();
try
{
TStructIo.bytesToStruct(tpq[i],blob,i*TPropertyQuery.sizeInBytes,TPropertyQuery.sizeInBytes);
}
catch (Exception e)
{
cc = TErrorList.code_failure;
MsgLog.log("getPropertyInformation", e.toString(),cc,e,0);
}
}
return tpq;
}
if (cc == TErrorList.link_not_open)
{
MsgLog.log("getPropertyInformation", TErrorList.getErrorString(cc),cc,null,0);
throw new IOException("Could not acquire property information for " + server + " (" + TErrorList.getErrorString(cc) + ")");
}
if (cc == TErrorList.non_existent ||
cc == TErrorList.non_existent_property) return null;
// try the old way :
XPropertyQuery[] xpq = getDevicePropertyInformationX(stockprop,context,server,device,property,timeout);
if (xpq == null || xpq.length == 0) return null;
tpq = new TPropertyQuery[xpq.length];
for (i=0; i<xpq.length; i++)
{
tpq[i] = new TPropertyQuery();
tpq[i].prpFormat = xpq[i].prpFormat;
tpq[i].prpFormatIn = xpq[i].prpFormatIn;
tpq[i].prpSize = xpq[i].prpSize;
tpq[i].prpSizeIn = xpq[i].prpSizeIn;
tpq[i].prpAccess = xpq[i].prpAccess;
tpq[i].prpDescription = xpq[i].prpDescription;
tpq[i].prpName = xpq[i].prpName;
tpq[i].prpNumOverloads = xpq[i].prpNumOverloads;
tpq[i].prpTag = xpq[i].prpTag;
tpq[i].prpTagIn = xpq[i].prpTagIn;
tpq[i].prpRedirection = xpq[i].prpRedirection;
tpq[i].prpHistoryDepthLong = xpq[i].prpHistoryDepthLong;
tpq[i].prpHistoryDepthShort = xpq[i].prpHistoryDepthShort;
tpq[i].prpUnits = xpq[i].prpUnits;
tpq[i].prpMaxValue = xpq[i].prpMaxValue;
tpq[i].prpMinValue = xpq[i].prpMinValue;
tpq[i].prpGraphType = xpq[i].prpGraphType;
tpq[i].numRows = xpq[i].numRows;
tpq[i].rowSize = xpq[i].rowSize;
tpq[i].rngMaxValue = xpq[i].rngMaxValue;
tpq[i].rngMinValue = xpq[i].rngMinValue;
tpq[i].rngUnits = xpq[i].rngUnits;
}
return tpq;
}
/**
* Returns a list of extended property query information objects associated
* with the specified context, device server, device. and target property
* (obtained from the device server). Typically, the device name is ignored
* in this query.
*
* Usually a call to getStockProperties() returns a property list
* A secondary call to getStockPropertyInformationX() returns a list of
* all property information pertaining to the specified property including
* all property overloads (maximum 10). If 'property' is null then the
* call returns information for the first 10 items. This is an extended
* method call which returns information as to the array 'type' if the
* property returns an array, as well as the horizontal axis engineering
* units and range if the property returns a spectrum and the row size
* and number or rows if the property returns a double array (matrix).
*
* @param context Is the context of the device server for which the property
* information is desired.
* @param server Is the device server for which the property information is
* desired.
* @param device Is the device name (module name) for which the property
* information is desired.
* @param property Is the property for which the property information is
* desired.
*
* @return An array of XPropertyQuery (extended Property Query) objects,
* as obtained from the given device server
* A null pointer is returned if the call fails for any reason.
*/
public static TPropertyQuery[] getStockPropertyInformation(String context,String server,String device,String property)
{
return getStockPropertyInformation(context,server,device,property,500);
}
/**
* Returns a list of extended property query information objects associated
* with the specified context, device server, device. and target property
* (obtained from the device server). Typically, the device name is ignored
* in this query.
*
* Usually a call to getStockProperties() returns a property list
* A secondary call to getStockPropertyInformationX() returns a list of
* all property information pertaining to the specified property including
* all property overloads (maximum 10). If 'property' is null then the
* call returns information for the first 10 items. This is an extended
* method call which returns information as to the array 'type' if the
* property returns an array, as well as the horizontal axis engineering
* units and range if the property returns a spectrum and the row size
* and number or rows if the property returns a double array (matrix).
*
* @param context is the context of the device server for which the property
* information is desired.
* @param server is the device server for which the property information is
* desired.
* @param device is the device name (module name) for which the property
* information is desired.
* @param property is the property for which the property information is
* desired.
* @param timeout is the amount of time in milliseconds to wait for the call to
* complete
*
* @return An array of XPropertyQuery (extended Property Query) objects,
* as obtained from the given device server
* A null pointer is returned if the call fails for any reason.
*/
public static TPropertyQuery[] getStockPropertyInformation(String context,String server,String device,String property,int timeout)
{
try
{
return getPropertyInformation("STOCKPROPS",context,server,device,property,timeout);
}
catch (IOException e)
{
return null;
}
}
/**
* @deprecated
* @see getStockPropertyInformation
*/
public static synchronized XPropertyQuery[] getStockPropertyInformationX(String context,String server,String device,String property)
{
return getDevicePropertyInformationX("STOCKPROPS", context,server,device,property,TLink.defaultTimeout);
}
private static ServerQuery[] getXTagList(String context,String tagtype,String subsys,String importance,int timeout)
{
int cc,n,i;
TDataType dout;
TDataType din;
TLink tl;
StringBuffer host = new StringBuffer(32);
StringBuffer query = new StringBuffer(32);
short[] numout = new short[1];
TDataType numoutData = new TDataType(numout);
NAME16[] inplist = new NAME16[2];
USTRING[] taglist;
ServerQuery[] strlist;
boolean isFecRequest = tagtype.compareToIgnoreCase("FECS") == 0;
if (subsys == null || subsys.length() == 0)
{
inplist[0] = new NAME16("ALL");
}
else
{
inplist[0] = new NAME16(subsys);
}
if (importance == null || importance.length() == 0)
{
inplist[1] = new NAME16("ALL");
}
else
{
inplist[1] = new NAME16(importance);
}
din = new TDataType(inplist);
host.delete(0,31); query.delete(0,31);
if (context != null && context.length() != 0)
{
host.insert(0,"ENS/" + context);
}
else
{
host.insert(0,"ENS");
}
query.insert(0,"N" + tagtype);
try
{
tl = new TLink(host.toString(),query.toString(),numoutData,din,TAccess.CA_READ);
cc = tl.execute(timeout,true);
srvAddr = tl.srvAddr;
tl.close();
}
catch (Exception e)
{
MsgLog.log("getXTagList", e.getMessage(),TErrorList.non_existent_elem,e,0);
cc = TErrorList.non_existent_elem;
}
if (cc != 0) return null;
if (numout[0] == 0 && subsys != null && subsys.length() > 0) numout[0] = 100;
// Get Tags from name server (synchronous call)
query.delete(0,31);
query.insert(0,tagtype);
n = numout[0];
taglist = new USTRING[n];
for (i=0; i<n; i++) taglist[i] = new USTRING();
if (taglist.length == 0) return null;
if (numout[0] > taglist.length) numout[0] = (short)taglist.length;
dout = new TDataType(taglist);
tl = new TLink(host.toString(),query.toString(),dout,din,TAccess.CA_READ);
cc = tl.execute(TLink.defaultTimeout,true);
tl.close();
if (cc != 0) return null;
strlist = new ServerQuery[n];
int zidx, cntr=0;
String srv;
for (i=0; i<n; i++)
{
String s = taglist[i].getString();
if (s.length() < 64) continue;
strlist[i] = new ServerQuery();
srv = s.substring(0,16).trim();
if (!isFecRequest && srv.endsWith("&"))
{
srv = srv.substring(0, 15) + s.substring(48,64).trim();
}
strlist[i].setName(srv);
strlist[i].setOs(s.substring(16,24).trim());
strlist[i].setSubsystem(s.substring(24,32).trim());
zidx = s.indexOf(0, 32);
strlist[i].setXref(s.substring(32,zidx).trim());
if (isFecRequest)
{
strlist[i].setContext(s.substring(zidx+1).trim());
}
else
{
strlist[i].setContext(context);
}
strlist[i].setImportance(taglist[i].tm);
strlist[i].setAddress(taglist[i].ival);
strlist[i].setXRefIsFec(!isFecRequest);
cntr++;
}
if (cntr < n) strlist = Arrays.copyOf(strlist, cntr);
return strlist;
}
private static int tryAccessLock(String context, String server, AccessLockType lockType)
{
short[] lvals = new short[2];
lvals[0] = (short)lockType.ordinal();
lvals[1] = (short)1;
TDataType din = new TDataType(lvals);
TLink lnk = new TLink("/"+context+"/"+server,"ACCESSLOCK",null,din,TAccess.CA_WRITE|TAccess.CA_RETRY);
int rc = lnk.execute(TLink.defaultTimeout,true);
lnk.close();
return rc;
}
/**
* Establishes an access lock on the device server specified
*
* @param context is the context containing the device server
* @param server is the targeted device server
* @param lockType is the lock type requested
* @param lockDuration is the duration of the access lock (in seconds)
* @return 0 upon success or a TINE error code.
*
* @include eg_SetAccessLock.java
*/
public static int setAccessLock(String context, String server, AccessLockType lockType, int lockDuration)
{
int rc = tryAccessLock(context, server, lockType);
if (rc != 0) return rc;
return TLinkFactory.setAccessLock(context, server, lockType, lockDuration);
}
/**
* Retrieves the access lock information on the device server specified
*
* @param context is the context containing the device server
* @param server is the targeted device server
* @return a string array containing the user and address of the owner of
* the current access lock. If there is no access lock, the strings are empty.
*
* @include eg_GetAccessLock.java
*/
public static String[] getAccessLockInformation(String context, String server)
{
NAME32[] n32 = new NAME32[3];
TDataType dout = new TDataType(n32);
TLink lnk = new TLink("/"+context+"/"+server,"ACCESSLOCK",dout,null,TAccess.CA_READ);
int rc = lnk.execute(TLink.defaultTimeout);
lnk.close();
if (rc != 0) return null;
String[] rs = new String[3];
rs[0] = n32[0].getName();
rs[1] = n32[1].getName();
rs[2] = n32[2].getName();
return rs;
}
/**
* Removes an access lock on the server specified.
*
* @param context is the targeted context of the server
* @param server is the targeted device server
* @return a tine return code
*/
public static void removeAccessLock(String context, String server)
{
TLinkFactory.removeAccessLock(context, server);
}
public static synchronized int getThresholds(String context,String server, String property,float[] tmax,float[] tmin)
{
if (tmax == null || tmin == null) return TErrorList.invalid_parameter;
if (tmax.length == 0 || tmin.length == 0) return TErrorList.dimension_error;
TDataType dt = new TDataType(tmax);
TLink tl = new TLink("/"+context+"/"+server+"/#0",property+".TMAX",dt,null,TAccess.CA_READ);
int cc = tl.execute();
tl.close();
int dlen = dt.getCompletionLength();
boolean pifDone = false;
TPropertyQuery[] tpq = null;
switch (cc)
{
default:
return cc;
case TErrorList.link_blacklisted:
case TErrorList.illegal_property:
tpq = getPropertyInformation(context,server,"#0",property);
if (tpq == null) return TErrorList.io_error;
tmax[0] = tpq[0].prpMaxValue;
tmin[0] = tpq[0].prpMinValue;
cc = 0; dlen = 1;
pifDone = true;
case TErrorList.success:
break;
}
if (dlen == 1)
{ // one threshold applies to all elements
for (int i=1; i<tmax.length; i++)
{ // so fill them in ...
tmax[i] = tmax[0];
}
}
dt = new TDataType(tmin);
tl = new TLink("/"+context+"/"+server+"/#0",property+".TMIN",dt,null,TAccess.CA_READ);
cc = tl.execute();
tl.close();
dlen = dt.getCompletionLength();
switch (cc)
{
default:
case TErrorList.illegal_property:
if (!pifDone)
{ // had success with TMAX but not here!
tpq = getPropertyInformation(context,server,"#0",property);
if (tpq == null) return TErrorList.io_error;
tmin[0] = tpq[0].prpMinValue;
}
cc = 0; dlen = 1;
case TErrorList.success:
break;
}
if (dlen == 1)
{ // one threshold applies to all elements
for (int i=1; i<tmin.length; i++)
{ // so fill them in ...
tmin[i] = tmin[0];
}
}
for (int i=0; i<tmax.length && i<tmin.length; i++)
{
if (tmin[i] >= tmax[i])
{ // doesn't make sense
if (!pifDone)
{ // had success with TMAX but not here!
tpq = getPropertyInformation(context,server,"#0",property);
if (tpq == null) return TErrorList.io_error;
}
if (tmax[i] < tpq[0].prpMinValue) tmax[i] = tpq[0].prpMaxValue;
tmin[i] = tpq[0].prpMinValue;
}
}
return 0;
}
class stRowHndlr implements RowHandler
{ // the Row Handler will be called when all columns have been read in
String prp;
public void setProperty(String p) { prp = p; }
String dev;
public void setDevice(String d) { dev = d; }
int sizOut;
public void setSizeOut(int siz) { sizOut = siz; }
int fmtOut;
public void setFormatOut(int fmt) { fmtOut = fmt; }
int sizIn;
public void setSizeIn(int siz) { sizIn = siz; }
int fmtIn;
public void setFormatIn(int fmt) { fmtIn = fmt; }
int acc;
public void setAccess(int access) { acc = access; }
int mod;
public void setMode(int mode) { mod = mode; }
float tolAbs;
float tolRel;
String tolStr;
public void setToleranceString(String tol) { tolStr = tol; }
String tagOut;
public void setTagOut(String tag) { tagOut = tag; }
String tagIn;
public void setTagIn(String tag) { tagIn = tag; }
int tmr;
public void setTimer(int timer) { tmr = timer; }
String req;
public void setRequiredState(String reqState) { req = reqState; }
int msk;
public void setMask(int mask) { msk = mask; }
String tgt;
public void setTgt(String target) { tgt = target; }
String inpt;
public void setInput(String input) { inpt = input; }
LinkedList<SelfTestItem> lst = new LinkedList<SelfTestItem>();
stRowHndlr()
{
}
public int process(int index)
{
SelfTestItem sti = new SelfTestItem(dev,prp,new TDataType(sizOut,(short)fmtOut),new TDataType(sizIn,(short)fmtIn),acc,0,0,req);
sti.setTgt(tgt);
sti.setMask(msk);
sti.setInpt(inpt);
lst.add(sti);
return 0;
}
}
class prpHndlr implements csvHandler
{
private stRowHndlr rHndlr;
prpHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
rHndlr.setProperty(strValue);
return 0;
}
}
class devHndlr implements csvHandler
{
private stRowHndlr rHndlr;
devHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
rHndlr.setDevice(strValue);
return 0;
}
}
class sizOutHndlr implements csvHandler
{
private stRowHndlr rHndlr;
sizOutHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
int siz = 0;
try { siz = Integer.parseInt(strValue); } catch (Exception e) {};
rHndlr.setSizeOut(siz);
return 0;
}
}
class sizInHndlr implements csvHandler
{
private stRowHndlr rHndlr;
sizInHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
int siz = 0;
try { siz = Integer.parseInt(strValue); } catch (Exception e) {};
rHndlr.setSizeIn(siz);
return 0;
}
}
class fmtOutHndlr implements csvHandler
{
private stRowHndlr rHndlr;
fmtOutHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
int fmt = TFormat.getFormatCode(strValue);
rHndlr.setFormatOut(fmt);
return 0;
}
}
class fmtInHndlr implements csvHandler
{
private stRowHndlr rHndlr;
fmtInHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
int fmt = TFormat.getFormatCode(strValue);
rHndlr.setFormatIn(fmt);
return 0;
}
}
class datTgtHndlr implements csvHandler
{
private stRowHndlr rHndlr;
datTgtHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
rHndlr.setTgt(strValue);
return 0;
}
}
class datMskHndlr implements csvHandler
{
private stRowHndlr rHndlr;
datMskHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
int msk = 0;
try { msk = Integer.parseInt(strValue); } catch (Exception e) {};
rHndlr.setMask(msk);
return 0;
}
}
class datInHndlr implements csvHandler
{
private stRowHndlr rHndlr;
datInHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
rHndlr.setInput(strValue);
return 0;
}
}
class tmrHndlr implements csvHandler
{
private stRowHndlr rHndlr;
tmrHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
float tmr = 0;
try { tmr = Float.parseFloat(strValue); } catch (Exception e) {};
int itmr = (int)(tmr * 1000);
rHndlr.setTimer(itmr);
return 0;
}
}
class accHndlr implements csvHandler
{
private stRowHndlr rHndlr;
accHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
int acc = TAccess.CA_READ;
int mod = TMode.CM_SINGLE;
if (strValue.compareToIgnoreCase("WRITE") == 0) acc = TAccess.CA_WRITE;
rHndlr.setAccess(acc);
if (strValue.compareToIgnoreCase("MONITOR") == 0) mod = TMode.CM_TIMER;
if (strValue.compareToIgnoreCase("TIMER") == 0) mod = TMode.CM_TIMER;
rHndlr.setMode(mod);
return 0;
}
}
class tolHndlr implements csvHandler
{
private stRowHndlr rHndlr;
tolHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
rHndlr.setToleranceString(strValue);
return 0;
}
}
class reqHndlr implements csvHandler
{
private stRowHndlr rHndlr;
reqHndlr(stRowHndlr rowHndlr)
{
rHndlr = rowHndlr;
}
public int process(String strValue,int index)
{
if (strValue == null || strValue.length() == 0) return 0;
rHndlr.setRequiredState(strValue);
return 0;
}
}
public static SelfTestItem[] getServerSelfTest(String context, String server)
{
char[] stChars = new char[32000];
TDataType dout = new TDataType(stChars);
TLink lnk = new TLink("/"+context+"/"+server,"SRVSELFTEST",dout,null,TAccess.CA_READ);
int rc = lnk.executeAndClose(TLink.defaultTimeout);
if (rc != 0) return null;
int p = dout.getCompletionLength();
String stString = new String(stChars,0,p);
csvColumn[] stCols = new csvColumn[26];
stRowHndlr stRows = new TQuery().new stRowHndlr();
stCols[0] = new csvColumn("PROPERTY","",new TQuery().new prpHndlr(stRows));
stCols[1] = new csvColumn("DEVICE","",new TQuery().new devHndlr(stRows));
stCols[2] = new csvColumn("SIZE_OUT","",new TQuery().new sizOutHndlr(stRows));
stCols[3] = new csvColumn("FORMAT_OUT","",new TQuery().new fmtOutHndlr(stRows));
stCols[4] = new csvColumn("SIZE_IN","",new TQuery().new sizInHndlr(stRows));
stCols[5] = new csvColumn("FORMAT_IN","",new TQuery().new fmtInHndlr(stRows));
stCols[6] = new csvColumn("DATA_TGT","",new TQuery().new datTgtHndlr(stRows));
stCols[7] = new csvColumn("DATA_MASK","",new TQuery().new datMskHndlr(stRows));
stCols[8] = new csvColumn("DATA_IN","",new TQuery().new datInHndlr(stRows));
stCols[9] = new csvColumn("WAIT","",new TQuery().new tmrHndlr(stRows));
stCols[10] = new csvColumn("ACCESS","",new TQuery().new accHndlr(stRows));
stCols[11] = new csvColumn("TOLERANCE","",new TQuery().new tolHndlr(stRows));
stCols[12] = new csvColumn("REQUIRED","",new TQuery().new reqHndlr(stRows));
// open it
csv expFile = new csv(stString.toCharArray());
// read it
rc = expFile.readFile(stCols,stRows);
// close it
if (rc != TErrorList.no_such_file)
TFecLog.log("get registered exports and properties from exports.csv : " + TErrorList.errorString[rc]);
return stRows.lst.toArray(new SelfTestItem[0]);
//return stString;
}
}