Ignore:
Timestamp:
2009-09-11T11:54:17+12:00 (15 years ago)
Author:
mdewsnip
Message:

Completely rewrote the resumption token support, as its buginess finally tipped the "I can't stand it any more" scale...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • gsdl/trunk/runtime-src/src/oaiservr/resumptiontoken.cpp

    r15380 r20590  
    11#include "resumptiontoken.h"
    2 #include "oaitools.h"
    32
    4 /**
    5  *  Generate an initial resumption token from some basic details.
    6  *
    7  *  TODO: add optional argument to set the server name.
    8  */
    9 ResumptionToken::ResumptionToken(const text_t &collection, const text_t &node,
    10                  const text_t &buildDate)
    11 { this->collection = collection;
    12   this->browseNode = node;
    13   this->buildDate  = buildDate;
    14   this->startItem  = 0;
     3
     4ResumptionToken::ResumptionToken(const text_t &build_date, const text_t &set, const text_t &metadata_prefix,
     5                 const text_t &from, const text_t &until, const text_t &position)
     6{
     7  this->build_date = build_date;
     8  this->set = set;
     9  this->metadata_prefix = metadata_prefix;
     10  this->from = from;
     11  this->until = until;
     12  this->position = position;
     13  this->valid = true;
    1514}
    1615
    17 /**
    18  *  Generate a resumption token from a URN-style format.
    19  *
    20  *  See getToken() for details of the format.
    21  *
    22  *  TODO: support inclusion of an optional server name.
    23  */
    24 ResumptionToken::ResumptionToken(const text_t &URN)
    25 { text_t::const_iterator first = URN.begin();
    26   text_t::const_iterator last = URN.end();
    27   text_t::const_iterator second;
    2816
    29   this->collection = "";
    30   this->browseNode = "";
    31   this->startItem  = -1;
    32  
    33   text_t::const_iterator here = findchar(first, last, ':');
    34   if (here == first) {
    35     return;
     17ResumptionToken::ResumptionToken(const text_t &resumption_token_string)
     18{
     19  this->build_date = "";
     20  this->set = "";
     21  this->metadata_prefix = "";
     22  this->from = "";
     23  this->until = "";
     24  this->position = "";
     25
     26  // This uses custom code into of the text_t splitchar() function because that is buggy
     27  text_tarray resumption_token_string_parts;
     28  text_t resumption_token_string_part;
     29  text_t::const_iterator resumption_token_string_iterator = resumption_token_string.begin();
     30  while (resumption_token_string_iterator != resumption_token_string.end())
     31  {
     32    if (*resumption_token_string_iterator == ',')
     33    {
     34      resumption_token_string_parts.push_back(resumption_token_string_part);
     35      resumption_token_string_part.clear();
     36    }
     37    else
     38    {
     39      resumption_token_string_part.push_back(*resumption_token_string_iterator);
     40    }
     41
     42    resumption_token_string_iterator++;
    3643  }
    37  
    38   text_t oainamespace = substr(first, here);
    39   if (oainamespace != "gsdloai") {
     44  resumption_token_string_parts.push_back(resumption_token_string_part);
     45
     46  if (resumption_token_string_parts.size() != 6)
     47  {
     48    // The resumption token is invalid -- there should be exactly 6 parts
     49    this->valid = false;
    4050    return;
    4151  }
    4252
    43   // increment past the first colon to get the location
    44   first = ++here; 
    45 
    46   // get the collection, browseNode
    47   here = findchar(first, last, ',');
    48   if (here == last) {
    49     return;
    50   }
    51 
    52   second = findchar(first, here,'.');
    53   this->collection = substr(first, second);
    54 
    55   //  cerr << "Collection " << this->collection << endl;
    56 
    57   if (second != here) {
    58     // get past the '.'
    59     ++second;
    60     this->browseNode = substr(second, here);
    61   }
    62   else {
    63     first = here;
    64   }
    65   // get past the ','
    66   first = ++here;
    67 
    68   // find the second ',' to delimit the position stack
    69   second = findchar(first, last, ',');
    70 
    71   // if not found, then get build and start item
    72   if (second != first) {
    73     // extract list and step past it
    74     text_t offsetList = substr(first, second);
    75     first = ++second;
    76    
    77     do {
    78       second = findchar(offsetList.begin(), offsetList.end(), '.');
    79       if (second == offsetList.end())
    80     break;
    81      
    82       // extract and push the next position
    83       text_t thisPos = substr(offsetList.begin(), second);
    84       this->browsePosition.push_back(thisPos.getint());
    85 
    86       // pop the position from the list
    87       offsetList = substr(++second, offsetList.end());
    88     } while (true);   
    89     this->browsePosition.push_back(offsetList.getint());
    90   }
    91   else {
    92     first ++;
    93   }
    94 
    95   // now find the build date marker
    96   here = findchar(first, last, '-');
    97   if (here == first) {
    98     this->startItem = substr(first, last).getint();
    99   }
    100   else {
    101     this->startItem = substr(first, here).getint();
    102     this->buildDate = substr(++here, last);
    103   }
     53  this->build_date = resumption_token_string_parts[0];
     54  this->set = resumption_token_string_parts[1];
     55  this->metadata_prefix = resumption_token_string_parts[2];
     56  this->from = resumption_token_string_parts[3];
     57  this->until = resumption_token_string_parts[4];
     58  this->position = resumption_token_string_parts[5];
     59  this->valid = true;
    10460}
    10561
    106 /**
    107  *  Get a resumption token in text_t format.
    108  *
    109  *  Resumption tokens are in the format:
    110  *
    111  *    gsdloai:<serverName>:collectionname.browseNode,startItem-BuildDate
    112  *
    113  *  The resumption token format does not currently implement the use of
    114  *  the optional <serverName> item; it is taken to default to the name of
    115  *  the receiving server.
    116  *
    117  *  TODO: add server identity as an optional argument; also change
    118  *        ResumptionToken(text_t &) accordingly.
    119  */
    120 text_t ResumptionToken::getToken()
    121 { text_t reply = "gsdloai:";
    122   reply = reply + this->collection;
    123   if (this->browseNode != "") {
    124     reply = reply + "." + this->browseNode;
    125   }
    126   reply = reply + ",";
    127   for (int i = 0; i < this->browsePosition.size(); i++) {
    128     if (i != 0) {
    129       reply.append(".");
    130     }
    131     reply.appendint(i);
    132   }
    133   reply = reply + ",";
    134   reply.append(this->startItem);
    135   reply = reply + "-" + buildDate;
    13662
    137   return reply;
     63text_t ResumptionToken::getResumptionTokenString()
     64{
     65  return this->build_date + "," + this->set + "," + this->metadata_prefix + "," + this->from + "," + this->until + "," + this->position;
    13866}
    13967
    140 /**
    141  *  Update the position of an existing resumption token
    142  */
    143 void ResumptionToken::setPosition(const text_t &node, int startItem)
    144 { this->browseNode = node;
    145   this->startItem  = startItem;
     68
     69bool ResumptionToken::isValid()
     70{
     71  return this->valid;
    14672}
    147 
    148 /**
    149  *  Check if the resumption token is valid - only a very primitive
    150  *  check is done here; one ought to check for an existing collection
    151  *  and valid browse Node, build date and startItem
    152  *
    153  *  TODO: implement improved validation checking.
    154  */
    155 bool ResumptionToken::isValid()
    156 { return this->collection != "";
    157 }
Note: See TracChangeset for help on using the changeset viewer.