- Timestamp:
- 2000-05-17T14:57:06+12:00 (24 years ago)
- Location:
- branches/z3950-branch/gsdl/src/recpt
- Files:
-
- 2 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/z3950-branch/gsdl/src/recpt/Makefile.in
r1168 r1174 77 77 RECEPTHEADERS = 78 78 79 LIBRARYHEADERS = nullproto.h z3950proto.h 79 LIBRARYHEADERS = nullproto.h z3950proto.h z3950server.h 80 80 81 81 HEADERS = $(COMMONHEADERS) $(RECPTHEADERS) $(LIBRARYHEADERS) … … 95 95 RECPTSOURCES = recptmain.cpp 96 96 97 LIBRARYSOURCES = nullproto.cpp z3950proto.cpp librarymain.cpp97 LIBRARYSOURCES = nullproto.cpp z3950proto.cpp z3950server.cpp librarymain.cpp 98 98 99 99 SOURCES = $(COMMONSOURCES) $(RECPTSOURCES) $(LIBRARYSOURCES) … … 113 113 RECPTOBJECTS = recptmain.o 114 114 115 LIBRARYOBJECTS = nullproto.o z3950proto.o librarymain.o zparse.tab.o 115 LIBRARYOBJECTS = nullproto.o z3950proto.o z3950server.o \ 116 librarymain.o zparse.tab.o parse.yy.o 116 117 117 118 OBJECTS = $(COMMONOBJECTS) $(RECPTOBJECTS) $(LIBRARYOBJECTS) -
branches/z3950-branch/gsdl/src/recpt/TODO
r1169 r1174 21 21 Needs updating for all added files (z*, parse.fl) 22 22 23 yaz 24 --- 25 Maybe put libyaz.a in $GSDLHOME/lib ? 26 27 28 DESIGN ISSUES 29 for z39.50 (and eventually nullproto when corba allows recept. and 30 coll server to be physically separate), if the server is unavailable, 31 should this be determined at: 32 * "home page" creation time, in which case the recept. must ping and 33 test each collection it knows about, which may cause unacceptable delay, or 34 * "about page" creation time (ie individual collection), in which case 35 the collection can not customise the page layout by modifying macros. 36 37 Eg currently, the z39.50 collection will not create a TCP connection to the 38 "target" (ie z39.50 server somewhere around the world) until it tries to 39 get the "About this collection" information for that collection. 40 If the connection fails, the protocol can not change _queryform_ part of 41 the page. 42 43 44 MULTI-LINGUAL SUPPORT 45 Multi-lingual - eg macros - want to set _collectionextra_ using 46 metadata["collectionextra"] based on the chosen interface language. 47 Should be done by OIDtools.cpp:get_info() and any action that calls 48 proto->filter(). 49 queryaction.cpp (c. line 1097): 50 // add the requested language as an option to the query 51 if (!args["l"].empty()) { 52 OptionValue_t option; 53 option.name="Language"; 54 option.value=args["l"]; 55 request.filterOptions.push_back(option); 56 } 57 -
branches/z3950-branch/gsdl/src/recpt/parse.fl
r1168 r1174 26 26 %% 27 27 char *string; 28 int string_ size;28 int string_len; 29 29 30 30 {COMMENT} lineno++;yylval.string=yytext; … … 40 40 Languages return(LANGUAGES); 41 41 About return(ABOUT); 42 en return(EN);43 fr return(FR);44 mi return(MI);45 zh return(ZH);46 de return(DE);47 42 Browse return(BROWSE); 48 43 Date[lL]ist return(DATELIST); … … 67 62 ^document return (DOCUMENT); 68 63 ^section return (SECTION); 69 \"[^\" ]*\" { /* for single word strings */70 if ((string=strdup(yytext+1))==NULL)71 {72 fprintf(stderr,"malloc failed\n");73 exit(1);74 }75 string[strlen(string)-1]='\0'; /* chomp " */76 /* yylval=yytext; */77 yylval.string=string;78 return(STRING);79 }80 \"[^\"]* {81 BEGIN(STRINGCOND);82 /* the +1 is to skip the leading " */83 if ((string=strdup(yytext+1))==NULL)84 {85 fprintf(stderr,"malloc failed\n");86 exit(1);87 }88 else string_size=strlen(yytext)-1;89 }90 64 [iI]con return (ICON); 91 65 [sS]mall[iI]con return (SMALLICON); 66 \" {string=NULL;BEGIN(STRINGCOND);} 92 67 <STRINGCOND>{ 93 ([^\"\\])* { 94 if (strlen(string)+strlen(yytext)>string_size) 95 { /* what if strlen(yytext) > 40 !!!!!! */ 96 if ((string=realloc(string,string_size+40))==NULL) 97 { 98 fprintf(stderr,"realloc failed\n"); 99 exit(1); 100 } 101 else string_size+=40; 102 } 103 strcat(string,yytext); 68 ([^\"\\])* {/* append this to our current string */ 69 if (string==NULL) string_len=0; else 70 string_len=strlen(string); 71 string=realloc(string,string_len+strlen(yytext)+1); 72 /* +1 is for trailing \0 */ 73 strcpy(string+string_len,yytext); 104 74 } 105 "\\"\" | 106 \"\" { /* replace with a single " */ 107 /* yes, this is dodgy for now... */ 108 strcat(string,"\""); 75 "\\"\" | 76 \"\" { /*replace quoted quote with one quote*/ 77 string_len=strlen(string); 78 string=realloc(string,string_len+2); 79 string[string_len]='\"'; 80 string[string_len+1]='\0'; 109 81 } 110 111 112 113 82 \" { 83 BEGIN(INITIAL); 84 yylval.string=string; 85 return(STRING); 114 86 /* note that the string may have long bits of 115 whitespace in it that could be removed. */87 whitespace in it that we could remove. */ 116 88 } 117 89 } … … 120 92 (\n|\r) lineno++; 121 93 %% 94 /******** deleted rules: ******* 95 en return(EN); 96 fr return(FR); 97 mi return(MI); 98 zh return(ZH); 99 de return(DE); 100 ***************/ 122 101 123 102 124 103 125 104 126 -
branches/z3950-branch/gsdl/src/recpt/queryaction.cpp
r962 r1174 28 28 /* 29 29 $Log$ 30 Revision 1.36.6.1 2000/05/17 02:57:00 johnmcp 31 checkpoint - can now connect and get status information from a z39.50 server. 32 Still need to get queries and data retrieval working. 33 30 34 Revision 1.36 2000/02/21 21:57:48 sjboddie 31 35 actions are now configured with gsdlhome … … 1095 1099 args["q"]=formattedstring; 1096 1100 } 1101 1097 1102 format_querystring (formattedstring, args.getintarg("b")); 1098 1103 set_queryfilter_options (request, formattedstring, args); -
branches/z3950-branch/gsdl/src/recpt/z3950proto.cpp
r1168 r1174 6 6 #include "comtypes.h" 7 7 #include <stdio.h> 8 // z39.50 yaz stuff 9 8 10 9 11 // config file parsing stuff … … 11 13 // defines "struct z3950cfg *zserver_list" as the head of the list. 12 14 extern FILE *yyin; 13 // for some reason, adding the following line screws up the linking... 14 //extern int zconfigparse(); 15 16 /*** 17 We will use the "collection" argument as the name of the database 18 to query on the z3950 server. 19 ***/ 20 21 22 z3950_server::z3950_server() { 23 count=0; 24 info=NULL; 25 meta["iconcollection"]="/~johnmcp/gsdl/images/zserver.png"; 26 // meta["collectionextra"]="Extra collection information"; 27 // meta["collectionname"]="overwritten"; 28 } 29 void z3950_server::setMeta(const text_t &key, const text_t &value) { 30 meta[key]=value; 31 } 32 void z3950_server::setName(const text_t &newname) { 33 title=newname; 34 meta["collectionname"]=newname; 35 // cout << "Have set server name\n"; 36 } 37 38 39 40 41 // z3950 Protocol functions 15 extern "C" { 16 extern int zconfigparse(); 17 } 18 42 19 z3950proto::z3950proto() { 43 20 zserver_count=0; 21 } 22 23 z3950proto::~z3950proto() { 44 24 } 45 25 … … 53 33 void z3950proto::read_config_file(const text_t &filename) { 54 34 struct z3950cfg *here; 35 struct z3950cfg *oldhere; 55 36 z3950_server *zserver; 56 37 ShortColInfo_t *tempinfo; 57 38 58 cerr << "attempting to read config file: " << filename.getcstr() << "\n";59 39 // zconfigparse() is defined in zparse.tab.c, 60 40 // which is the bison output of zparse.y … … 94 74 } 95 75 96 // and about list .... later. 76 // About list 77 if (here->about!=NULL) { 78 struct z3950aboutlist *about_here=here->about; 79 struct z3950aboutlist *oldabout; 80 81 while (about_here!=NULL) { 82 // problem with default lang (null): 83 if (about_here->lang==NULL) 84 zserver->addAbout("en",about_here->text); 85 else 86 zserver->addAbout(about_here->lang, about_here->text); 87 oldabout=about_here; 88 about_here=about_here->next; 89 free(oldabout->lang); 90 free(oldabout->text); 91 free(oldabout); 92 } 93 } 94 95 oldhere=here; 96 here=here->next; 97 free(oldhere->shortname); 98 free(oldhere->hostname); 99 free(oldhere->dbname); 100 free(oldhere->longname); 101 free(oldhere->icon); 102 free(oldhere->smallicon); 103 free(oldhere); 104 97 105 98 106 add_server(*zserver); 99 here=here->next;100 }101 102 // finally, delete all unneeded allocated memory in server_list107 /* assume that the push_back operator creates a copy. 108 BUT: doesn't create copies of structures pointed to... only 109 creates a copy of the pointer (to the same location!) */ 110 } // end of while loop. 103 111 104 112 } … … 200 208 } 201 209 202 /* collectinfo.shortInfo.name="sdfg";203 collectinfo.shortInfo.host="localhost";204 collectinfo.shortInfo.port=0; */205 210 const ShortColInfo_t *colinfo=here->getInfo(); 206 211 collectinfo.shortInfo.name=colinfo->name; … … 214 219 // leave ccsCols empty (no cross-coll. searching - for now) 215 220 /*collectinfo.ccsCols=(text_tarray);*/ //not like this!!! 221 // This info is available from the config file -- johnmcp */ 216 222 collectinfo.languages.push_back("en"); 217 223 collectinfo.languages.push_back("fr"); … … 221 227 // copy the text maps over. 222 228 // collectinfo.collectionmeta; // text_tmap 223 // delete collectinfo.collectionmeta;224 229 collectinfo.collectionmeta=*(here->getMeta()); 225 230 /* collectinfo.format; //text_tmap … … 243 248 FilterResponse_t &response, 244 249 comerror_t &err, ostream &logout) { 245 246 250 // this function is called when: 247 251 // * creating the title page,(looking for iconcoll* & collectname metadata) 248 252 // * creating the about page (looking for "Title" metadata) 253 // * doing the query - (note that a request for metadata comes first, then 254 // filterOptions = FRmetadata | FROID | FRtermFreq (64+4+1) 255 256 // metadata-only requests have filterName="NullFilter", else "QueryFilter". 249 257 // For the title page, we should not create a connection to the target 250 258 // (target means the actual z39.50 server, origin means us), but … … 255 263 // cerr now goes to errout.txt in etc directory 256 264 257 response.numDocs=0; 258 response.isApprox=Approximate; // Exact | Approximate | MoreThan 265 // get relevant "collection" 266 z3950_server_array::iterator zserver = zservers.begin(); 267 z3950_server_array::iterator zend = zservers.end(); 268 while (zserver != zend) { 269 if(zserver->getName()==collection) { 270 break; 271 } 272 zserver++; 273 } 274 // now have collection in zserver. 275 276 // ColInfoResponse_t *info = new ColInfoResponse_t; 277 ColInfoResponse_t info; 278 ResultDocInfo_t *docInfo=new ResultDocInfo_t; 279 280 259 281 // leave response.termInfo empty 260 282 // leave response.docInfo empty … … 269 291 270 292 293 // See if this is for a query action 294 /*** johnmcp ********** 295 this is not enough, as FROID is set for the about action, 296 and furthermore, the number of docInfo's (+1?) seems to imply the number 297 of search methods. 298 ** ABOUT ACTION 299 * OIDtools.get_children() 300 . FRmetadata, FilterOptions ParentNode='' 301 * OIDtools.get_info() 302 . FRmetadata 303 ** QUERY ACTION 304 * OIDtools.get_info() <- receptionist.define_general_macros() 305 . FRmetadata, no OptionValues 306 * queryaction.search_single_collection 307 . FRmetadata | FROID | FRtermFreq, fltrOps Term/QueryType/Casefold/.. 308 */ 309 if (request.filterResultOptions & /*FROID*/FRtermFreq) { 310 // Pretty bad hack: this is assuming 311 // FRtermFreq is only set for query action, not about action. 312 313 // what about: 314 // OptionValue_tarray filterOptions 315 // docSet 316 // requestParams 317 // refParams 318 // fields -- requested metadata fields. 319 /* 320 if (!request.requestParams.empty()) 321 cout << "RequestParams: " << request.requestParams.getcstr() << "\n"; 322 if (!request.refParams.empty()) 323 cout << "RefParams: " << request.refParams.getcstr() << "\n"; 324 */ OptionValue_tarray::iterator ov_here=request.filterOptions.begin(); 325 OptionValue_tarray::iterator ov_end=request.filterOptions.end(); 326 while (ov_here != ov_end) { 327 cout << "OV pair: `" << ov_here->name.getcstr() << "'=`" 328 << ov_here->value.getcstr() << "'\n"; 329 ov_here++; 330 }/* 331 cout << "end\n\n"; 332 */ 333 334 /* Sample OptionValue pairs 335 `StartResults'=`1' 336 `EndResults'=`20' 337 `Term'=`firstword secondword' (term is just whatever the user typed in) 338 `QueryType'=`ranked' => 'OR' (cgiarg t=1) 339 `QueryType' = `boolean' => 'AND' (cgiarg t=0) 340 `Casefold'=`true' 341 `Stem'=`false' 342 `Maxdocs'=`50' 343 */ 344 docInfo->metadata["Title"].values.push_back("dummy title"); 345 docInfo->result_num=1; 346 347 if (request.filterResultOptions & FRtermFreq) { 348 response.numDocs=2; 349 response.isApprox=Exact; // Exact | Approximate | MoreThan 350 } 351 352 response.docInfo.push_back(*docInfo); 353 // create a 2nd dummy record 354 docInfo=new ResultDocInfo_t; 355 docInfo->metadata["Title"].values.push_back("another title"); 356 docInfo->result_num=2; 357 response.docInfo.push_back(*docInfo); 358 359 } // end of if (... & FROID) 360 else { 361 // this wasn't a query action 362 363 if (request.filterOptions.size()>0 && 364 request.filterOptions[0].name=="ParentNode") { 365 // don't want to return anything 366 //delete (docInfo); 367 } else { 368 // in case we need to return only metadata 369 response.docInfo.push_back(*docInfo); 370 } 371 } 372 373 // Fill in metadata for each response.docInfo (if wanted) 271 374 if (request.filterResultOptions & FRmetadata) { 272 273 ColInfoResponse_t *info = new ColInfoResponse_t; 274 get_collectinfo (collection, *info, err, logout); 375 get_collectinfo (collection, info, err, logout); 275 376 // should check err returned here.... 276 277 ////////// cerr << "Filter.\n";278 279 ResultDocInfo_t *docInfo=new ResultDocInfo_t;280 281 377 /* In the absence of any other information, (eg commented code), 282 378 assuming that if the request.fields is empty, then we should return 283 379 all metadata, otherwise return only the requested fields */ 380 /**** comtypes.h has: "text_tset fields; // empty if not used" ****/ 284 381 285 382 if (!request.fields.empty()) { 286 // loop on all the metadata fields in request.fields (type text_tset) 287 text_tset::iterator fields_here=request.fields.begin(); 288 text_tset::iterator fields_end=request.fields.end(); 289 text_tmap::iterator it; 290 while (fields_here!=fields_end) { 291 it=info->collectionmeta.find(*fields_here); 292 ////////// cerr << "filter: getting " << (*fields_here).getcstr(); 293 if (it!=info->collectionmeta.end()) 294 docInfo->metadata[*fields_here].values.push_back((*it).second); 295 else { 296 docInfo->metadata[*fields_here].values.push_back(""); 297 /////// cerr << " (not found)"; 298 } 299 ////////cerr << "\n"; 300 fields_here++; 301 } // end of while loop 383 // loop on each document being returned 384 ResultDocInfo_tarray::iterator docs_here=response.docInfo.begin(); 385 ResultDocInfo_tarray::iterator docs_end=response.docInfo.end(); 386 while (docs_here!=docs_end) { 387 388 // loop on all the metadata fields in request.fields (type text_tset) 389 text_tset::iterator fields_here=request.fields.begin(); 390 text_tset::iterator fields_end=request.fields.end(); 391 text_tmap::iterator it; 392 while (fields_here!=fields_end) { 393 it=info.collectionmeta.find(*fields_here); 394 ////////// cerr << "filter: getting " << (*fields_here).getcstr(); 395 if (it!=info.collectionmeta.end()) 396 docs_here->metadata[*fields_here].values.push_back((*it).second); 397 else { 398 docs_here->metadata[*fields_here].values.push_back(""); 399 /////// cerr << " (not found)"; 400 } 401 ////////cerr << "\n"; 402 fields_here++; 403 } // end of inner while loop 404 docs_here++; 405 } // end of outer while loop 302 406 } // end of if (!request.fields.empty()) 303 else { 304 // return all metadata for about page or query 305 text_tmap::iterator colmeta_here=info->collectionmeta.begin(); 306 text_tmap::iterator colmeta_end=info->collectionmeta.end(); 407 408 else { // request.fields empty: return all metadata for about page or query 409 // we'll only put it in the first docInfo. 410 text_tmap::iterator colmeta_here=info.collectionmeta.begin(); 411 text_tmap::iterator colmeta_end=info.collectionmeta.end(); 307 412 while (colmeta_here!=colmeta_end) { 308 docInfo->metadata[(*colmeta_here).first].413 response.docInfo[0].metadata[(*colmeta_here).first]. 309 414 values.push_back((*colmeta_here).second); 310 415 /////cerr << "\t" << (*colmeta_here).first.getcstr() << "\n"; … … 312 417 } 313 418 // get data from target. 314 z3950_server_array::iterator zserver = zservers.begin();315 z3950_server_array::iterator zend = zservers.end();316 while (zserver != zend) {317 if(zserver->getName()==collection) {318 break;319 }320 zserver++;321 }322 // now have collection in zserver.323 419 // check if "collectionextra" metadata is set. If it isn't, we should 324 420 // create connection to target to get it. 325 if (info ->collectionmeta.find("collectionextra")==colmeta_end) {421 if (info.collectionmeta.find("collectionextra")==colmeta_end) { 326 422 // it doesn't exist. 327 zserver->setMeta("collectionextra","This is some extra info."); 328 docInfo->metadata["collectionextra"].values.push_back("This is extra"); 423 text_t *abouttext; 424 // this gets the server's name and id, plus MOTD, etc. 425 abouttext=zserver->connect_getAbout(); 426 // add in the text we read in from config file. 427 // how do we incorporate multi-lingual metadata? 428 (*abouttext)+="<P>\n"; 429 (*abouttext)+=zserver->getAbout("en"); 430 zserver->setMeta("collectionextra",*abouttext); 431 response.docInfo[0].metadata["collectionextra"].values.push_back(*abouttext); 432 delete (abouttext); 329 433 } 330 331 434 } // end of else 332 333 response.docInfo.push_back(*docInfo); 435 334 436 } //end of if (... & FRmetadata) ... 437 438 439 335 440 err=noError; 336 441 } -
branches/z3950-branch/gsdl/src/recpt/z3950proto.h
r1168 r1174 4 4 5 5 #include "recptproto.h" 6 7 // each "server" (ie collection) consists of a {z39.50 server + database} pair. 8 class z3950_server { 9 protected: 10 text_t title; // Descriptive name 11 text_t hostname; // network name (IP or host+domain name) 12 text_tmap meta; // metadata for this collection (ie server/database pair) 13 // this is currently only iconcollection (and iconcollectionsmall) 14 int count; 15 // z3950_DB_array* db; 16 ShortColInfo_t *info; // has (database) name, host and port 17 18 public: 19 z3950_server(); 20 const text_t getName() {return title;} 21 void setMeta(const text_t &key, const text_t &value); 22 void setName(const text_t &newname); 23 void setInfo(ShortColInfo_t *newinfo) {info=newinfo;} 24 const ShortColInfo_t *getInfo() {return info;} 25 const text_tmap *getMeta() {return &meta;} 26 }; 27 28 typedef vector<z3950_server> z3950_server_array; 29 30 31 6 #include "z3950server.h" 32 7 33 8 class z3950proto : public recptproto { … … 37 12 public: 38 13 z3950proto(); 39 virtual ~z3950proto() {}14 virtual ~z3950proto(); 40 15 41 16 int getServerCount() { return zserver_count;} … … 88 63 }; 89 64 90 91 65 #endif -
branches/z3950-branch/gsdl/src/recpt/zparse.y
r1168 r1174 72 72 %type <cfg> zserver zserverlist 73 73 %type <number> port 74 %type <string> icon smallicon 75 %type <about> about 74 %type <string> icon smallicon lang 75 %type <about> about aboutLang aboutList 76 76 %% 77 77 /* grammar */ … … 82 82 | {fprintf(stderr,"No version - not GSDL config file?\n");exit(1);} 83 83 84 zserverlist : zserverlist zserver { $2->next=$1;$$=$2;}84 zserverlist : zserverlist zserver {if ($2!=NULL) {$2->next=$1;$$=$2;}} 85 85 | zserver ; 86 86 … … 97 97 $$->about=$8; 98 98 } 99 | error {$$=NULL;} 99 100 ; 100 101 … … 107 108 errormsg("Icon must be enclosed in quotes"); 108 109 yylex();yylex();} 109 | { ;}110 | {$$=NULL;} 110 111 smallicon : SMALLICON STRING {$$=$2;} 111 112 | SMALLICON DATA {$$=$2; … … 114 115 yylex();yylex(); 115 116 } 116 | { ;}117 | {$$=NULL;} 117 118 118 119 about : aboutList {;} 119 | { ;}120 | {$$=NULL;} 120 121 121 122 aboutList : aboutLang {;} 122 | aboutList aboutLang {;} 123 124 aboutLang : ABOUT lang STRING {/*printf("string is <%s>\n",$3)*/;} 125 | ABOUT STRING { 126 if (defLanguage) 123 /* note this action reverses the order of the list */ 124 | aboutList aboutLang {$$=$2;$2->next=$1;} 125 126 127 aboutLang : ABOUT lang STRING 128 { 129 if(($$=malloc(sizeof(struct z3950aboutlist))) 130 ==NULL) { 131 fprintf(stderr,"Malloc failed\n"); 132 exit(1); 133 } 134 $$->lang=$2; 135 $$->text=$3; 136 $$->next=NULL; 137 } 138 | ABOUT STRING 139 { 140 if (defLanguage) 127 141 { 128 142 fprintf(stderr,"warning: (line %d): already have a default language in config file\n",lineno); 129 143 } 130 144 else defLanguage=1; 131 } 132 /* this can only happen once (default lang) */ 145 146 if(($$=malloc(sizeof(struct z3950aboutlist))) 147 ==NULL) { 148 fprintf(stderr,"Malloc failed\n"); 149 exit(1); 150 } 151 $$->lang=NULL; /* default lang... */ 152 $$->text=$2; 153 $$->next=NULL; 154 } 155 /* this can only happen once (default lang) */ 156 133 157 134 158 /* languages should be done using a lookup, rather than hard-coding 135 them as tokens like this. Eg '_' token for en_BR */ 136 lang : lang '_' DATA {;} 137 | EN {;} 138 | FR {;} 139 | MI {;} 140 | ZH {;} 141 | DE {;} 142 | DATA {errormsg("unknown language");} 159 them as tokens. Also '_' token for en_BR */ 160 lang : DATA '_' DATA 161 { 162 $$=malloc(strlen($1)+strlen($3)+1); 163 strncpy($$,$1,strlen($1)); 164 $$[strlen($1)]='_'; 165 strncpy($$+strlen($1)+1,$3,strlen($3)); 166 free($1);free($3); 167 } 168 | DATA {;} 169 /*lang '_' DATA {;} */ 170 /* | EN {;} 171 | FR {;} 172 | MI {;} 173 | ZH {;} 174 | DE {;} 175 | DATA {errormsg("unknown language");}*/ 143 176 | error {errormsg("missing language");} 144 177
Note:
See TracChangeset
for help on using the changeset viewer.