Changeset 2119


Ignore:
Timestamp:
2001-03-05T19:25:43+13:00 (23 years ago)
Author:
say1
Message:

updated for new idl file. extra documenation. a little more PTP work

Location:
trunk/java-client
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/java-client/Makefile

    r2109 r2119  
    11
     2
     3.PHONY: docs clean all distclean test
    24
    35# find the top-level directory of the java-client tree
     
    3234
    3335docs :
     36    rm -rf docs
    3437    mkdir docs
    35     javadoc -private -version -author -d docs -header "Documentation for the <a href=\"http://www.corba.org/\">CORBA</a> interface to the <a href=\"http://www.nzdl.org/\">NZDL</a>\'s Greenstone Digital Library software." -footer "This software is distributed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\">GPL</a>" */*/*.java */*/*/*.java */*/*/*/*.java
     38    javadoc -private -version -author -use -d docs -header "Documentation for the <a href=\"http://www.corba.org/\">CORBA</a> interface to the <a href=\"http://www.nzdl.org/\">NZDL</a>\'s Greenstone Digital Library software." -footer "This software is distributed under the <a href=\"http://www.gnu.org/copyleft/gpl.html\">GPL</a>" -windowtitle  "Greenstone Digital Library Software from the NZDL" -link "http://www.scms.waikato.ac.nz/help/reference/jdk1.2/docs/api/" gnu.getopt org.nzdl.gsdl org.nzdl.gsdl.service org.nzdl.gsdl.util org.nzdl.gsdl.corba.gsdlInterface org.nzdl.gsdl.ptp
     39
    3640
    3741clean :
  • trunk/java-client/corbaiface.idl

    r2055 r2119  
    201201interface corbaiface
    202202{
    203   boolean   initialise();
    204   void      configure(in corbatext_t key, in corbatext_tarray cfgline);
    205   void      collectionList(inout corbatext_tarray collist);
     203  boolean   initialise(inout corbaComError error);
     204  void      configure(in corbatext_t key, in corbatext_tarray cfgline,
     205              inout corbaComError error);
     206  void      collectionList(inout corbatext_tarray collist,
     207               inout corbaComError error);
    206208  void      hasCollection(in corbatext_t corbaCollection, inout boolean has,
    207209               inout corbaComError error);
  • trunk/java-client/org/nzdl/gsdl/SearchAllCollections.java

    r2103 r2119  
    7171 * @see org.nzdl.gsdl.service.NzdlService
    7272 * @see org.nzdl.gsdl.service.NzdlServiceClient
    73  * @see gnu.getopt.Getopt;
    74  * @see gnu.getopt.LongOpt;
     73 * @see gnu.getopt.Getopt
     74 * @see gnu.getopt.LongOpt
    7575 */
    7676
  • trunk/java-client/org/nzdl/gsdl/SimpleClient.java

    r2116 r2119  
    6464 * @author Gordon Paynter ([email protected])
    6565 * @version $Revision$
     66 * @see org.nzdl.gsdl.SimpleServer
    6667 * @see org.nzdl.gsdl.service.NzdlCollectionInfo
    6768 * @see org.nzdl.gsdl.service.NzdlQuery
     
    7071 * @see org.nzdl.gsdl.service.NzdlResultSet
    7172 * @see org.nzdl.gsdl.service.NzdlService
    72  * @see org.nzdl.gsdl.service.NzdlServiceImpl
    73  * @see gnu.getopt.Getopt;
    74  * @see gnu.getopt.LongOpt;
     73 * @see org.nzdl.gsdl.service.NzdlServiceClient
     74 * @see gnu.getopt.Getopt
     75 * @see gnu.getopt.LongOpt
     76 * @see <a href="http://www.nzdl.org/">The New Zealand Digital Library Project</a>
     77 * @see <a href="http://www.nzdl.org/fast-cgi-bin/library?&a=p&p=gsdl">Greenstone Digital Library Software</a>
    7578 */
    7679
     
    102105  int verbosity = 2;
    103106
    104   SimpleClient() {
     107  /**
     108   * Basic no-args constructor. Not recommended for normal use,
     109   * but necessary if we want to create beans ...
     110   */
     111  protected SimpleClient() {
    105112    init(null);
    106113  }
    107 
     114 
     115  /**
     116   * Normal constructor. the args are passed into the orb
     117   * initialisation code so they can extract obscure args ...
     118   */
    108119  SimpleClient(String [] args) {
    109120    parseArgs(args);
     
    111122  }
    112123
    113   void init(String [] args)  {
     124  /**
     125   *
     126   */
     127  protected void init(String [] args)  {
    114128
    115129    // read our prevously seed IORs ...
  • trunk/java-client/org/nzdl/gsdl/SimpleServer.java

    r2098 r2119  
    2222
    2323// java standard library classes used
    24 import java.io.IOException;
    2524import java.io.Serializable;
    26 import java.lang.Cloneable;
    27 import java.util.*;
     25//import java.util.*;
    2826
    29 // HelloServer will use the naming service.
    3027import org.omg.CosNaming.*;
    31 // The package containing special exceptions thrown by the name service.
    32 //import org.omg.CosNaming.NamingContextPackage.*;
    33 // All CORBA applications need these classes.
    3428import org.omg.CORBA.ORB;
    3529
     
    4842
    4943/**
    50  * SimpleServer
    51  *
    52  * Based on algorithms in ...
     44 * SimpleServer A very basic Greenstoen server (not yet complete).
    5345 *
    5446 * @author stuart yeates ([email protected])
    5547 * @version $Revision$
    56  * @see
    57  * @see
    58  * @see
    59  *
     48 * @see org.nzdl.gsdl.SimpleClient
     49 * @see org.nzdl.gsdl.service.NzdlServiceServer
     50 * @see org.omg.CORBA.ORB
     51 * @see <a href="http://www.nzdl.org/">The New Zealand Digital Library Project</a>
     52 * @see <a href="http://www.nzdl.org/fast-cgi-bin/library?&a=p&p=gsdl">Greenstone Digital Library Software</a>
    6053 */
    6154
    6255
    63 public class SimpleServer
     56public class SimpleServer implements Serializable, Cloneable
    6457{
    6558  /**
    66    * Tests...
     59   * Starts up a trivial server.
    6760   *
    68    *
    69    * @exception java.io.IOException when ...
    70    * @param args the arguments ...
     61   * @param args the arguments passed through to the orb initialisation code...
    7162   */
    7263  public static void main(String args[])
     
    10192  }
    10293}
    103 
    104   /**
    105    * Tests...
    106    *
    107    *
    108    * @exception java.io.IOException when ...
    109    * @param args the arguments ...
    110    */
  • trunk/java-client/org/nzdl/gsdl/ptp/Makefile

    r2111 r2119  
    1818  Poller.class \
    1919  Connection.class \
     20  Listener.class \
    2021  Node.class
    2122
  • trunk/java-client/org/nzdl/gsdl/ptp/Node.java

    r2109 r2119  
    3636
    3737/**
    38  * Class ...
     38 * Class representing a Node in a Peer-To-Peer (PTP) network.
    3939 *
    40  * Based on algorithms in ...
     40 * Does very little actual work, but maintains a number of important
     41 * statics and contains the command-line parsing and initialisation
     42 * code (or it will).
     43 *
     44 * Unlike PTP networks as Napster and Gnutella queries are not
     45 * propogated, only knowledge about servers.
    4146 *
    4247 * @author stuart yeates ([email protected])
    4348 * @version $Revision$
    44  * @see
    45  * @see
    46  * @see
     49 * @see Poller
     50 * @see <a href="http://www.napster.com/">Napster</a>
     51 * @see <a href="http://gnutella.wego.com/">Gnutella</a>
    4752 *
    4853 */
     
    5055public class Node {
    5156
     57  /** A list of Locators which we know. */
    5258  static Properties knownList = new Properties();
    5359 
     60  /** Our IOR string*/
    5461  static String identityIOR = "IOR:123456789012345678901234567890123456789012345678901234567890";
    5562 
     63  /** Our HTTP string */
    5664  static String identityHTTP = "http://www.nzdl.org";
    5765
     66  /** The port we listen on */
    5867  static int identityPort = 4567;
     68  /** Our host name */
    5969  static String identityHost = null; //= InetAddress.getLocalHost().getHostName();
    60   static String identityP2P = identityHost + ":" + identityPort;
     70  /** Our PTP object ...*/
     71  static String identityPTP = identityHost + ":" + identityPort;
    6172
     73  /** Initialise the static variables  */
    6274  void init(){
    6375    if (identityHost == null) {
    6476      try {
    6577    identityHost = InetAddress.getLocalHost().getHostName();
    66     identityP2P = identityHost + ":" + identityPort;
     78    identityPTP = identityHost + ":" + identityPort;
    6779      } catch (Exception exception) {
    6880    System.err.println("caught exception: "+exception);
     
    7284  }
    7385 
    74  
    75   Node() {
     86  /**
     87   * Construct and rung a Node ...
     88   */
     89  public Node() {
    7690   
    7791    init();
    7892
    79 
    8093    // start the server ...
    81    
     94    Listener listener = new Listener();
     95    listener.run();
    8296   
    8397    // start the poller ...
    8498    Poller poller = new Poller();
    85     poller.run();
     99    poller.run();   
    86100 
    87101  }
    88 
    89  
    90 
    91 
    92102
    93103
     
    102112  public static void main(String args[]) throws IOException
    103113  {
    104 
     114    Node node = new Node();
    105115  }
    106116}
    107117
     118
  • trunk/java-client/org/nzdl/gsdl/ptp/PTP.java

    r2110 r2119  
    3535
    3636/**
    37  * Class ...
     37 * Class PTP represents a URL-like connection information to a remote Peer
    3838 *
    39  * Based on algorithms in ...
     39 * PTP's and connections initiated based on them form the backbone
     40 * of the Peer-To-Peer network.
    4041 *
    4142 * @author stuart yeates ([email protected])
    4243 * @version $Revision$
    43  * @see
    44  * @see
    45  * @see
     44 * @see org.nzdl.gsdl.ptp.Connection
     45 * @see Locator
     46 * @see HTTP
     47 * @see IOR
    4648 *
    4749 */
    4850
    49 public class PTP extends Locator{
     51public class PTP extends Locator {
     52  /** The remote port at which the peer is listening */
    5053  int port;
     54  /** The host on which the peer is resident */
    5155  String host;
    5256 
     57  /** The basic constructor */
    5358  PTP(String host, int port) {
    5459    this.host = host;
    5560    this.port = port;
    5661  }
     62  /** the no-arguments constructor */
     63  protected PTP() {
     64    this.host = "";
     65    this.port = 0;
     66  }
     67
     68  /** convert the PTP to a string suitable for parsing later on ...*/
    5769  public String toString() {
    5870    return "PTP:" + host + ":" + port;
    59   }
    60 
    61 
    62   /**
    63    * Tests...
    64    *
    65    *
    66    * @exception java.io.IOException when ...
    67    * @param args the arguments ...
    68    */
    69 
    70   public static void main(String args[]) throws IOException
    71   {
    72 
    7371  }
    7472
  • trunk/java-client/org/nzdl/gsdl/ptp/Poller.java

    r2110 r2119  
    3535
    3636/**
    37  * Class ...
     37 * Class Poller polls a group of peers periodically.
    3838 *
    39  * Based on algorithms in ...
     39 * Poller exists in it's  own Thread so it is asynchronous with
     40 * the rest of the program. The Connections to peers are also in
     41 * seperate Threads, but only one run at once.
     42 *
     43 * The static Node.knownList is consulted about which peers to
     44 * poll.
    4045 *
    4146 * @author stuart yeates ([email protected])
    4247 * @version $Revision$
    43  * @see
    44  * @see
    45  * @see
    46  *
     48 * @see org.nzdl.gsdl.ptp.PTP
     49 * @see org.nzdl.gsdl.ptp.Connection
     50 * @see org.nzdl.gsdl.ptp.Node
     51 * @see org.nzdl.gsdl.ptp.Node#knownList
     52 * @see java.lang.Thread
    4753 */
    4854
    4955public class Poller extends Thread {
     56  /** How often should we poll our peers? */
    5057  int secondsBetweenPollCycles = 60;
    5158 
     59  /** The no-args constructor */
    5260  public Poller() {
    5361
    5462  }
    5563
     64  /**
     65   * Start the poller.
     66   *
     67   * Only returns if interrupted or an Error is thrown.
     68   */
    5669  public void run() {
    5770    while (true) {
     
    6679  }
    6780
    68   void poll() {
     81  /**
     82   * Poll each peer once, waiting for the Connections to terminate
     83   * between each.
     84   *
     85   * Returns when all peer has been polled.
     86   */
     87 void poll() {
    6988    Enumeration e = Node.knownList.propertyNames();
    7089    while (e.hasMoreElements()) {
     
    88107  }
    89108 
    90   /**
    91    * Tests...
    92    *
    93    *
    94    * @exception java.io.IOException when ...
    95    * @param args the arguments ...
    96    */
    97 
    98   public static void main(String args[]) throws IOException
    99   {
    100 
    101   }
    102109
    103110}
  • trunk/java-client/org/nzdl/gsdl/service/NzdlServiceClient.java

    r2098 r2119  
    1717
    1818  public NzdlServiceClient( String [] _args, Properties _props, String _IOR) {
     19    corbaComErrorHolder error = new corbaComErrorHolder();
    1920    try {
    2021      System.err.println("before ORB.init");
     
    2930      m_nzdlServer = corbaifaceHelper.narrow(obj);
    3031      System.err.println("after .narrow");
     32     
    3133      // basic setup
    32       if (m_nzdlServer.initialise()) {
     34      if (m_nzdlServer.initialise(error)) {
    3335    System.err.println("Nzdl init ... YES");
    3436      }
     
    4446      System.exit(1);
    4547    }
     48    if (error.value.value() != corbaComError._corbaNoError) {
     49      System.err.println("CORBA error:" + error.value.value());
     50    }
    4651   
    4752    System.err.println("Service init ... YES");
     
    4954 
    5055  public void configure( String _key, Set _values ) {
     56    corbaComErrorHolder error = new corbaComErrorHolder();
    5157    m_nzdlServer.configure( NzdlCorbaFactory.toCorbaText( _key ),
    52                 NzdlCorbaFactory.toCorbaTextArray( _values ));
     58                NzdlCorbaFactory.toCorbaTextArray( _values ),
     59                error);
     60    if (error.value.value() != corbaComError._corbaNoError) {
     61      System.err.println("CORBA error:" + error.value.value());
     62    }
    5363  }
    5464 
    5565  public Set getCollectionSet( ) {
     66    corbaComErrorHolder error = new corbaComErrorHolder();
    5667    corbatext_tarrayHolder c_collSet = NzdlCorbaFactory.createCorbaTextArrayHolder();
    57     m_nzdlServer.collectionList(c_collSet);
     68    m_nzdlServer.collectionList(c_collSet, error);
    5869    Set collSet = new HashSet();
    5970    for (int i=0; i<c_collSet.value.length; i++) {
    6071      collSet.add( NzdlCorbaFactory.toString( c_collSet.value[i] ) );
     72    }
     73    if (error.value.value() != corbaComError._corbaNoError) {
     74      System.err.println("CORBA error:" + error.value.value());
    6175    }
    6276    return collSet ;
  • trunk/java-client/org/nzdl/gsdl/service/NzdlServiceServer.java

    r2108 r2119  
    6969  }
    7070
    71   public boolean initialise () {
     71  public boolean initialise (corbaComErrorHolder error) {
    7272    // TODO should map the anything in NzdlService?
    7373    if (nzdl == null)
    7474      throw new Error ("NzdlServer needs a NzdlService to foward calls to ...");
     75    error.value = corbaComError.from_int(corbaComError._corbaNoError);
    7576    return true;
    7677  }
    7778  public void configure (corbatext_t key,
    78           corbatext_t[] cfgline) {
    79 //      m_nzdlServer.configure( NzdlCorbaFactory.toCorbaText( _key ),
    80 //                  NzdlCorbaFactory.toCorbaTextArray( _values ));
     79             corbatext_t[] cfgline,
     80             corbaComErrorHolder error) {
     81    //      m_nzdlServer.configure( NzdlCorbaFactory.toCorbaText( _key ),
     82    //                  NzdlCorbaFactory.toCorbaTextArray( _values ));
    8183
    8284    nzdl.configure( NzdlCorbaFactory.toString(key),
    8385            NzdlCorbaFactory.toSet(cfgline));
    84   }
    85 
    86   public void collectionList (corbatext_tarrayHolder collist) {
     86    error.value = corbaComError.from_int(corbaComError._corbaNoError);
     87  }
     88
     89  public void collectionList (corbatext_tarrayHolder collist,
     90                  corbaComErrorHolder error) {
    8791    //corbatext_tarrayHolder c_collSet = NzdlCorbaFactory.createCorbaTextArrayHolder();
    8892    //m_nzdlServer.collectionList(c_collSet);
     
    98102    while (itr.hasNext()) {
    99103      String s = (String) itr.next();
    100        collist.value[i++] = NzdlCorbaFactory.toCorbaText(s);
     104      collist.value[i++] = NzdlCorbaFactory.toCorbaText(s);
    101105    }
     106    error.value = corbaComError.from_int(corbaComError._corbaNoError);
    102107
    103108    return;
    104109  }
    105110  public void hasCollection (corbatext_t corbaCollection,
    106               org.omg.CORBA.BooleanHolder has,
    107               corbaComErrorHolder error) {
    108 //      corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
    109 //      org.omg.CORBA.BooleanHolder c_has = new org.omg.CORBA.BooleanHolder();
    110 //      m_nzdlServer.hasCollection( NzdlCorbaFactory.toCorbaText(_name), c_has, c_err );
    111 //      if (c_err.value.value() != 0)
    112 //        System.err.println("hasCollection error " + c_err.value.value());
    113 //      return c_has.value;
     111                 org.omg.CORBA.BooleanHolder has,
     112                 corbaComErrorHolder error) {
     113    //      corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
     114    //      org.omg.CORBA.BooleanHolder c_has = new org.omg.CORBA.BooleanHolder();
     115    //      m_nzdlServer.hasCollection( NzdlCorbaFactory.toCorbaText(_name), c_has, c_err );
     116    //      if (c_err.value.value() != 0)
     117    //        System.err.println("hasCollection error " + c_err.value.value());
     118    //      return c_has.value;
    114119    String name = NzdlCorbaFactory.toString(corbaCollection);
    115120    has.value  = nzdl.hasCollection(name);
     121    error.value = corbaComError.from_int(corbaComError._corbaNoError);
    116122    return;
    117123  }
    118124  public boolean ping (corbatext_t collection,
    119         corbaComErrorHolder error) {
     125               corbaComErrorHolder error) {
    120126    String name = NzdlCorbaFactory.toString(collection);
    121127    return  nzdl.hasCollection(name);
    122128  }
    123129  public void getDocument (corbatext_t collection,
    124             corbaDocRequestHolder request,
    125             corbaDocResponseHolder response,
    126             corbaComErrorHolder error) {
    127 //      corbatext_t c_name = NzdlCorbaFactory.toCorbaText( _name );
    128 //      corbaDocRequestHolder c_request = NzdlCorbaFactory.createDocRequestHolder( _docID );
    129 //      corbaDocResponseHolder c_response = NzdlCorbaFactory.createDocResponseHolder( );
    130 //      corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
    131 //      m_nzdlServer.getDocument( c_name, c_request, c_response, c_err );
    132 //      if (c_err.value.value() != 0)
    133 //        System.err.println("getDocument() error " + c_err.value.value());
    134 //      return NzdlCorbaFactory.toString( c_response.value.doc );
     130               corbaDocRequestHolder request,
     131               corbaDocResponseHolder response,
     132               corbaComErrorHolder error) {
     133    //      corbatext_t c_name = NzdlCorbaFactory.toCorbaText( _name );
     134    //      corbaDocRequestHolder c_request = NzdlCorbaFactory.createDocRequestHolder( _docID );
     135    //      corbaDocResponseHolder c_response = NzdlCorbaFactory.createDocResponseHolder( );
     136    //      corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
     137    //      m_nzdlServer.getDocument( c_name, c_request, c_response, c_err );
     138    //      if (c_err.value.value() != 0)
     139    //        System.err.println("getDocument() error " + c_err.value.value());
     140    //      return NzdlCorbaFactory.toString( c_response.value.doc );
    135141    String collectionName = NzdlCorbaFactory.toString(collection);
    136142    String documentID = NzdlCorbaFactory.toString(request.value.OID);
    137143    String doc = nzdl.getDocument( collectionName, documentID );
    138144    response.value.doc = NzdlCorbaFactory.toCorbaText(doc);
     145    error.value = corbaComError.from_int(corbaComError._corbaNoError);
    139146    return;
    140147  }
    141148  public void getCollectInfo (corbatext_t collection,
    142                corbaColInfoResponseHolder response,
    143                corbaComErrorHolder error) {
    144 //      corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
    145 //      corbaColInfoResponseHolder c_info = NzdlCorbaFactory.createColInfoResponseHolder();
    146 //      m_nzdlServer.getCollectInfo( NzdlCorbaFactory.toCorbaText(_name), c_info, c_err );
    147 //      if (c_err.value.value() != 0)
    148 //        System.err.println("getCollectionInfo() error " + c_err.value.value());
    149 //      return new NzdlCollectionInfo( c_info.value );
     149                  corbaColInfoResponseHolder response,
     150                  corbaComErrorHolder error) {
     151    //      corbaComErrorHolder c_err = NzdlCorbaFactory.createComErrorHolder();
     152    //      corbaColInfoResponseHolder c_info = NzdlCorbaFactory.createColInfoResponseHolder();
     153    //      m_nzdlServer.getCollectInfo( NzdlCorbaFactory.toCorbaText(_name), c_info, c_err );
     154    //      if (c_err.value.value() != 0)
     155    //        System.err.println("getCollectionInfo() error " + c_err.value.value());
     156    //      return new NzdlCollectionInfo( c_info.value );
    150157    String collectionName = NzdlCorbaFactory.toString(collection);
    151158    NzdlCollectionInfo info = nzdl.getCollectionInfo( collectionName );
    152159    response.value = info.getInfo();
     160    error.value = corbaComError.from_int(corbaComError._corbaNoError);
    153161    return;
    154162  }
    155163  public void getFilterInfo (corbatext_t collection,
    156               corbatext_tarrayHolder filterNames,
    157               corbaComErrorHolder error) {
     164                 corbatext_tarrayHolder filterNames,
     165                 corbaComErrorHolder error) {
    158166    String collectionName = NzdlCorbaFactory.toString(collection);
    159167 
     
    164172    while (itr.hasNext()) {
    165173      String s = (String) itr.next();
    166        filterNames.value[i++] = NzdlCorbaFactory.toCorbaText(s);
     174      filterNames.value[i++] = NzdlCorbaFactory.toCorbaText(s);
    167175    }
    168176
     177    error.value = corbaComError.from_int(corbaComError._corbaNoError);
    169178    return;
    170179  }
    171180  public void getFilterOptions (corbatext_t collection,
    172              corbatext_t option,
    173              corbaFilterOptionsResponseHolder response,
    174              corbaComErrorHolder error) {
    175     String collectionName = NzdlCorbaFactory.toString(collection);
    176         System.err.println("TO BE IMPLEMENTED: DON'T KNOW HOW YET !!!");
    177 
    178     return;
    179       }
     181                corbatext_t option,
     182                corbaFilterOptionsResponseHolder response,
     183                corbaComErrorHolder error) {
     184    String collectionName = NzdlCorbaFactory.toString(collection);
     185    System.err.println("TO BE IMPLEMENTED: DON'T KNOW HOW YET !!!");
     186
     187    error.value = corbaComError.from_int(corbaComError._corbaProtocolError);
     188    return;
     189  }
    180190  public  void filter (corbatext_t collection,
    181            corbaFilterRequest request,
    182            corbaFilterResponseHolder response,
    183            corbaComErrorHolder error) {
     191               corbaFilterRequest request,
     192               corbaFilterResponseHolder response,
     193               corbaComErrorHolder error) {
    184194    String collectionName = NzdlCorbaFactory.toString(collection);
    185195    System.err.println("TO BE IMPLEMENTED: DON'T KNOW HOW YET !!!");
     196    error.value = corbaComError.from_int(corbaComError. _corbaProtocolError);
    186197    return;
    187198  }
Note: See TracChangeset for help on using the changeset viewer.