#ifndef CIPRES_IDL_SENTRY #define CIPRES_IDL_SENTRY /* This module defines types that are used by Cipres interfaces. $Id$ */ module CipresIDL_api1 { typedef unsigned short Size; typedef string NewickString; const NewickString EMPTY_NEWICK = ""; /* Caller needs to know context of the score inorder to interpret/compare scores. For example, is < or > better? I had to change TreeScoreType from an enum to integer constants to work around an apparent jacorb bug. Using the enum version, when a Tree is put into an Any and passed as a parameter jacorb gives a "BAD_PARAM Duplicate union case label ..." error. */ const long INT_SCORE_TYPE = 0; const long DOUBLE_SCORE_TYPE = 1; const long NO_SCORE_TYPE = 2; union TreeScore switch(long) { case INT_SCORE_TYPE: long intScore; case DOUBLE_SCORE_TYPE: double doubleScore; case NO_SCORE_TYPE: double noScore; }; // ReadNexus interface requires taxa labels for taxa block typedef string TaxonInfo; // eventually this will need to be struct with label and possibly unique ID, now it is just the ID typedef sequence TaxonInfoSeq; // for use in decomposing tree into taxa subsets. typedef long Taxon; typedef sequence TaxonSeq; typedef sequence TaxonSeqSeq; /* Todo: both trees and matrices will sometimes be too large to pass as parameters. Can pass ref to object that has iterator, but that requires clients to act as servers and objects and returned objects must stick around until caller destroys them. */ struct Tree { NewickString m_newick; TreeScore m_score; TaxonSeq m_leafSet; string m_name; }; typedef sequence TreeSeq; /* Recidcm3 deals with subsets of taxa. Have taxa names in the matrix? Somewhere else? I guess for recidcm3, if the tree uses names we need to specify taxa sets using names, and if the tree uses indices we need to specify taxa subsets using indices. Are Newick trees using indices instead of names OK? Does Usman's code need the list of taxa names? It's not in the treedecompose interface currently. */ // this is the lookup table typedef sequence StateSet; typedef sequence CharStateLookup; // used to decode elements of the matrix into sets of character states // this is the data matrix. Each cell is an index into the lookup table. typedef short Character; typedef sequence Characters; typedef sequence RawMatrix; enum DiscreteDatatypes {DNA_DATATYPE, RNA_DATATYPE, AA_DATATYPE, CODON_DATATYPE, GENERIC_DATATYPE} ; struct DataMatrix { string m_symbols; // this is the string I build as I see characters in the nexus datda unsigned long m_numStates; // this is '4' for dna unsigned long m_numCharacters; // length of data matrix row. CharStateLookup m_charStateLookup; RawMatrix m_matrix; DiscreteDatatypes m_datatype; // have list of taxa names here too? }; typedef string Xml; /* Catch all for application errors. Note that the java mapping for exceptions is a little confusing, especially when we define a string member as we do here because the underlying java Exception also has a string member. We define an additional string member here for languages that don't use a base class with its own message. If you throw new ApplicationException("", "here's what happened") and you explictly catch this type of exception and print its "msg" member you'll probably be happy. The ctor shown above puts "CipresIDL/ApplicationException" + "" into the underlying Exception's message field and "here's what happened" into our msg field. When the exception is unmarshaled on the client side jacorb always puts the exception type "CipresIDL/ApplicationException" into the message field and "here's what happened" into msg. It looks like a bug in jacorb that you can put extra stuff (the first parameter in the ctor above) into the message on the server side and it isn't unmarshaled on the client side. I ran into problems when I used throw new ApplicationException("here's what happened") and expected to see "here's what happened" when I called Exception.getMessage() or printStackTrace(), since this ctor sets message to the exception type and msg to the string supplied. */ exception ApplicationException { string msg; }; // Catch all for arguments that do not conform to the API exception BadArgException { string msg; }; exception TreeParseException { string msg; }; exception InsufficientPrivilegeException { string msg; string filename; }; enum TargetType {IOR_TARGET_TYPE, REGISTRY_TARGET_TYPE }; union TargetReference switch(TargetType) { /* stringified version of the IOR */ case IOR_TARGET_TYPE: string ior; /* comma separated serialization of an RegistryEntryInfo struct: registryInstanceID,repositoryID,applicationName,description */ case REGISTRY_TARGET_TYPE: string registryInfo; }; struct Target { TargetReference reference; string uiId; }; typedef sequence CommandSequence; /* Forward decl of structure generates bad code in jacorb 2.2 - it generates an empty class for the forward decl'd structure. There's a bug report in their database. Omniorb on the other hand, issues a warning if there's an anonymous sequence within CommandObject so we have to fwd declare CommandObject and typedef the sequence for use within CommandObject. */ #if defined(JACORB_HAS_BROKEN_FORWARD_DECL) struct CommandObject { Target commandTarget; CommandSequence commands; sequence children; }; #else struct CommandObject; typedef sequence CommandObjectSequence; struct CommandObject { Target commandTarget; CommandSequence commands; CommandObjectSequence children; }; #endif interface Scriptable { // Returns an empty string if there isn't anything to script. // todo: add a string parameter to specify a context? Xml getUIXml(); // Returns true if "succesful", false otherwise. // Sets output parameter display to a string that may be shown // to the user. boolean execute(in string command, out string display); }; interface RecursiveScriptable : Scriptable { boolean executeRecursive(in CommandObject commandObjectParam, out string display); }; // todo: Use the standard lifecycle service interface? interface LifeCycle { void remove(); }; interface ObjectFactory { Object build(in string repositoryID, in string appName) raises (ApplicationException); }; /* This is a simple idea really: clients for the AsyncTreeInfer interface will want to be able to disconnect and reconnect to the service. If you call AsyncTreeInfer.disconnect you'll get a receipt back (free format up to the server, for now), and a RegistryEntryInfo (as per Registry.idl, but reproduced below). With the rei (as defined by the service), you should be able to i) find the registry again; ii) find the implementation of the AsyncTreeInfer that gave out the receipt It is then up to the service to reconstruct its state based on the receipt it gave out. */ struct RegistryEntryInfo { string registryInstanceID; string repositoryID; string applicationName; string description; }; typedef sequence RegistryEntryInfoSeq; interface TreeIterator : Scriptable, LifeCycle { /* accessors */ Tree getFirstTree(); Tree getLastTree(); Tree getNextTree(); Tree getPreviousTree(); Tree getTreeByIndex(in long whichTree); // zero-based /* stack operations */ Tree pop(); // removes and returns last item on stack void push(in Tree treeParam); // adds another item to the end of the stack Tree shift(); // removes and returns first item on stack void unshift(in Tree treeParam); // adds another item to the front of the stack /* long i; for ( i = 0; i < TreeIterator.getNumTrees(); i++ ) { Tree t = TreeIterator.getTreeByIndex(i); } */ long getNumTrees(); /* i = 0; while ( TreeIterator.exists(i) ) { Tree t = TreeIterator.getTreeByIndex(i); i++; } */ boolean exists(in long whichTree); }; interface RendezVous { RegistryEntryInfo disconnect(out string receipt); boolean reconnect(in RegistryEntryInfo rei, in string receipt); }; }; #endif