- Timestamp:
- 2014-05-19T13:27:25+12:00 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/OAIPMH.java
r28986 r29067 1 1 /* 2 2 * OAIPMH.java 3 * Copyright (C) 20 02New Zealand Digital Library, http://www.nzdl.org3 * Copyright (C) 2010 New Zealand Digital Library, http://www.nzdl.org 4 4 * 5 5 * This program is free software; you can redistribute it and/or modify … … 43 43 import java.util.Date; 44 44 import java.util.HashMap; 45 import java.util.HashSet; 45 46 import java.util.Map.Entry; 46 47 … … 64 65 protected Element list_sets_response = null; 65 66 67 protected Element meta_formats_definition = null; 68 protected HashMap<String, HashSet<String>> format_elements_map = null; 69 protected HashMap<String, Element> format_response_map = null; 66 70 /** constructor */ 67 71 public OAIPMH() { … … 161 165 } 162 166 167 public boolean configureOAI(Element oai_config_elem) { 168 this.meta_formats_definition = this.desc_doc.createElement(OAIXML.LIST_METADATA_FORMATS); 169 this.format_response_map = new HashMap<String, Element>(); 170 this.format_elements_map = new HashMap<String, HashSet<String>>(); 171 172 // for now, all we want is the metadata prefix description and the mapping list 173 Element main_lmf_elem = (Element) GSXML.getChildByTagName(oai_config_elem, OAIXML.LIST_METADATA_FORMATS); 174 if (main_lmf_elem == null) { 175 logger.error("No listMetadataFormats element found in OAIConfig.xml"); 176 return false; 177 } 178 NodeList meta_formats_list = this.config_info.getElementsByTagName(OAIXML.METADATA_FORMAT); 179 if (meta_formats_list.getLength() == 0) { 180 logger.error("no metadataFormat elements found in OAIPMH serviceRack element"); 181 return false; 182 } 183 boolean found_meta_format = false; 184 for(int i=0; i<meta_formats_list.getLength(); i++) { 185 Element mf = (Element) meta_formats_list.item(i); 186 String prefix = mf.getAttribute(OAIXML.METADATA_PREFIX); 187 if (prefix.equals("")) { 188 logger.error("metadataFormat element had no metadataPrefix attribute"); 189 continue; 190 } 191 // get the right format from OAICOnfig 192 Element meta_format = findNamedMetadataFormat(main_lmf_elem, prefix); 193 if (meta_format == null) { 194 logger.error("Couldn't find metadataFormat named "+prefix+" in OAIConfig.xml"); 195 continue; 196 } 197 // copy the format definition into our stored Element 198 Element collection_version_format = (Element) this.desc_doc.importNode(meta_format, true); 199 collection_version_format.setAttribute(GSXML.NAME_ATT, prefix); // for convenience 200 this.meta_formats_definition.appendChild(collection_version_format); 201 // set up the response element for this format 202 format_response_map.put(prefix, OAIXML.getMetadataFormatShort(this.desc_doc, collection_version_format)); 203 // add in collection specific mappings 204 addCollectionMappings(collection_version_format, mf); 205 // now set up a list of all collection elements for reverse lookup of the mapping 206 format_elements_map.put(prefix, getAllCollectionElements(collection_version_format)); 207 208 } 209 return true; 210 } 211 212 protected Element findNamedMetadataFormat(Element list_meta_formats, String prefix) { 213 NodeList formats = list_meta_formats.getElementsByTagName(OAIXML.METADATA_FORMAT); 214 for (int i=0; i<formats.getLength(); i++) { 215 Element format = (Element)formats.item(i); 216 String meta_name = GSXML.getNodeText((Element)GSXML.getChildByTagName(format, OAIXML.METADATA_PREFIX)); 217 if (prefix.equals(meta_name)) { 218 return format; 219 } 220 } 221 return null; 222 } 223 224 /** goes through the mappings from the collection one, and replaces existing ones in the main one */ 225 protected void addCollectionMappings(Element main_meta_format, Element coll_meta_format) { 226 227 Element element_list = (Element)GSXML.getChildByTagName(main_meta_format, OAIXML.ELEMENT+GSXML.LIST_MODIFIER); 228 Document doc = element_list.getOwnerDocument(); 229 NodeList coll_elements = coll_meta_format.getElementsByTagName(OAIXML.ELEMENT); 230 if (coll_elements.getLength()==0) { 231 // no mappings to include 232 return; 233 } 234 for (int i=0; i<coll_elements.getLength(); i++) { 235 Element e = (Element)coll_elements.item(i); 236 String elem_name = e.getAttribute(GSXML.NAME_ATT); 237 Element main_elem = GSXML.getNamedElement(element_list, OAIXML.ELEMENT, GSXML.NAME_ATT, elem_name); 238 if (main_elem == null) { 239 logger.error(elem_name+" not found in meta format, not using it"); 240 } else { 241 element_list.replaceChild(doc.importNode(e, true),main_elem ); 242 } 243 } 244 } 245 246 /** goes through all the mappings and makes a set of all collection 247 metadata names that could become an oai meta element - acts as 248 a reverse lookup for the mappings */ 249 protected HashSet<String> getAllCollectionElements(Element meta_format) { 250 HashSet<String> meta_name_set = new HashSet<String>(); 251 NodeList elements = meta_format.getElementsByTagName(OAIXML.ELEMENT); 252 for (int i=0; i<elements.getLength(); i++) { 253 Element e = (Element)elements.item(i); 254 Element map = (Element)GSXML.getChildByTagName(e, OAIXML.MAPPING); 255 if (map == null) { 256 // there is no mapping, just use the element name 257 meta_name_set.add(e.getAttribute(GSXML.NAME_ATT)); 258 } else { 259 String list_of_names = map.getAttribute(OAIXML.ELEMENTS); 260 String[] name_array = list_of_names.split(","); 261 for (int j=0; j<name_array.length; j++) { 262 meta_name_set.add(name_array[j]); 263 } 264 } 265 } 266 return meta_name_set; 267 } 268 163 269 /** returns a specific service description */ 164 270 public Element getServiceDescription(Document doc, String service_id, String lang, String subset) { … … 199 305 return null; 200 306 } 201 // /** return the metadata information about this set of the repository */ 202 // protected Element processIdentify(Element req) { 203 // return null; 204 // } 205 /** return the metadata information */ 307 308 /** The list sets service returns all the sets that this collection is/is part of/contains. This is gathered by Receptionist from all collections to answer the OAI ListSets request. */ 206 309 protected Element processListSets(Element req) { 207 310 return list_sets_response; 208 311 } 209 /** return the metadata information*/312 /** returns the actual record element used in the OAI GetRecord response */ 210 313 protected Element processGetRecord(Element req) { 211 314 /** arguments: … … 224 327 } 225 328 226 Element metadata_format = getMetadataFormatElement(prefix);227 if (metadata_format == null) {228 logger.error("metadata prefix is not supported .");329 // check that we support this format 330 if (!format_response_map.containsKey(prefix)) { 331 logger.error("metadata prefix is not supported for collection "+this.coll_name); 229 332 return OAIXML.createErrorResponse(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""); 230 333 } … … 242 345 Document doc = XMLConverter.newDOM(); 243 346 ArrayList<String> keys = new ArrayList<String>(info.getKeys()); 244 String oailastmodified = "";245 if (keys.contains(OAIXML.OAI_LASTMODIFIED)) {246 oailastmodified = info.getInfo(OAIXML.OAI_LASTMODIFIED);347 String oailastmodified = info.getInfo(OAIXML.OAI_LASTMODIFIED); 348 if (!oailastmodified.equals("")) { 349 // format into a string 247 350 oailastmodified = OAIXML.getTime(Long.parseLong(oailastmodified)*1000); // java wants dates in milliseconds 248 351 } … … 255 358 record.appendChild(createHeaderElement(doc, oid, oailastmodified)); 256 359 //compose the metadata element 257 record.appendChild(createMetadataElement(doc, prefix, info , metadata_format));360 record.appendChild(createMetadataElement(doc, prefix, info)); 258 361 get_record.appendChild(record); 259 362 return get_record_response; 260 363 } 261 /** return a list of identifiers */ 364 365 /** return a list of records in specified set, containing metadata from specified prefix*/ 366 protected Element processListRecords(Element req) { 367 return processListIdentifiersOrRecords(req, OAIXML.LIST_RECORDS, true); 368 } 369 370 /** return a list of identifiers in specified set that contain metadata belonging to specified prefix. */ 262 371 protected Element processListIdentifiers(Element req) { 372 return processListIdentifiersOrRecords(req, OAIXML.LIST_IDENTIFIERS, false); 373 } 374 375 // Get a list of records/identifiers that match the parameters. 376 protected Element processListIdentifiersOrRecords(Element req, String response_name, boolean include_metadata) { 263 377 /** arguments: 264 378 metadataPrefix: required … … 303 417 } 304 418 305 Element metadata_format = getMetadataFormatElement(prefix); 306 if(metadata_format == null) { 307 logger.error("metadata prefix is not supported."); 419 if (!format_response_map.containsKey(prefix)) { 420 logger.error(prefix + " metadata prefix is not supported for collection "+this.coll_name); 308 421 return OAIXML.createErrorResponse(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""); 309 422 } … … 315 428 // all validation is done 316 429 430 // get the list of elements that are in this metadata prefix 431 HashSet<String> set_of_elems = format_elements_map.get(prefix); 432 317 433 Document doc = XMLConverter.newDOM(); 318 Element list_i dentifiers_response = doc.createElement(GSXML.RESPONSE_ELEM);319 Element list_i dentifiers = doc.createElement(OAIXML.LIST_IDENTIFIERS);320 list_i dentifiers_response.appendChild(list_identifiers);434 Element list_items_response = doc.createElement(GSXML.RESPONSE_ELEM); 435 Element list_items = doc.createElement(response_name); 436 list_items_response.appendChild(list_items); 321 437 322 438 for(int i=0; i<oid_list.size(); i++) { … … 327 443 continue; 328 444 } 329 ArrayList<String> keys = new ArrayList<String>(info.getKeys());330 String oailastmodified = "";331 if(keys.contains(OAIXML.OAI_LASTMODIFIED)) {332 oailastmodified = info.getInfo(OAIXML.OAI_LASTMODIFIED);333 oailastmodified = OAIXML.getTime(Long.parseLong(oailastmodified)*1000); // java wants dates in milliseconds334 }335 445 336 Date this_date = OAIXML.getDate(oailastmodified); 337 if (from_date != null) { 338 if(this_date.before(from_date)) { 339 continue; 340 } 341 } 342 if (until_date != null) { 343 if (this_date.after(until_date)) { 344 continue; 345 } 346 } 347 //compose the header element and append it 348 list_identifiers.appendChild(createHeaderElement(doc, oid, oailastmodified)); 446 String oailastmodified = info.getInfo(OAIXML.OAI_LASTMODIFIED); 447 long oailastmodifiedmillis = 0; 448 Date this_date = null; 449 if (oailastmodified.equals("")) { 450 if (from_date != null || until_date !=null) { 451 continue; // if this doc doesn't have a date for some reason, and 452 // we are doing a date range, then don't include it. 453 } 454 } else { // check the date against date range from query (if any) 455 oailastmodifiedmillis = Long.parseLong(oailastmodified)*1000; // greenstone dates are in secods, and Java wants dates in milliseconds 456 this_date = new Date(oailastmodifiedmillis); 457 458 if (from_date != null) { 459 if(this_date.before(from_date)) { 460 continue; 461 } 462 } 463 if (until_date != null) { 464 if (this_date.after(until_date)) { 465 continue; 466 } 467 } 468 } 469 //Now check that this id has metadata for the required prefix. 470 if (documentContainsMetadata(info, set_of_elems)) { 471 // YES, it does have some metadata for this prefix 472 if (include_metadata) { 473 // compose a record and add header and metadata 474 Element record = doc.createElement(OAIXML.RECORD); 475 list_items.appendChild(record); 476 //compose the header element 477 record.appendChild(createHeaderElement(doc, oid, OAIXML.getTime(oailastmodifiedmillis))); 478 //compose the metadata element 479 record.appendChild(createMetadataElement(doc, prefix, info)); 480 } else { 481 //compose the header element and append it 482 list_items.appendChild(createHeaderElement(doc, oid, OAIXML.getTime(oailastmodifiedmillis))); 483 } 484 } // otherwise we won't include this oid. 349 485 }//end of for(int i=0; i<oid_list.size(); i++) of doing thru each record 350 486 351 return list_identifiers_response; 352 } 353 /** return a list of records */ 354 protected Element processListRecords(Element req) { 355 /** the request sent here may contain optional 'from', 'untill', 'metadataPrefix', 356 * and 'resumptionToken' params. see doListSets() in OAIReceptionist. 357 * if the request contains 'resumptionToken' then it should have been handled by the 358 * OAIReceptionist. Therefore, the request sent here must not contain 'resumptionToken' 359 * argument but a 'metadataPrefix' param. The OAIReceptionist makes sure of this. 360 */ 361 NodeList params = GSXML.getChildrenByTagName(req, GSXML.PARAM_ELEM); 362 363 if(params.getLength() == 0) { 364 logger.error("must at least have the metadataPrefix parameter, can't be none"); 365 return OAIXML.createErrorResponse(OAIXML.BAD_ARGUMENT, ""); 366 } 367 368 HashMap<String, String> param_map = GSXML.getParamMap(params); 369 370 String prefix = ""; 371 Date from_date = null; 372 Date until_date = null; 373 374 if(param_map.containsKey(OAIXML.METADATA_PREFIX) == false) { 375 //Just a double-check 376 logger.error("A param element containing the metadataPrefix is not present."); 377 return OAIXML.createErrorResponse(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""); 378 } 379 prefix = param_map.get(OAIXML.METADATA_PREFIX); 380 if (prefix == null || prefix.equals("")) { 381 //Just a double-check 382 logger.error("the value of metadataPrefix att is not present in the request."); 383 return OAIXML.createErrorResponse(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""); 384 } 385 386 if(param_map.containsKey(OAIXML.FROM)) { 387 String from = param_map.get(OAIXML.FROM); 388 from_date = OAIXML.getDate(from); 389 } 390 if(param_map.containsKey(OAIXML.UNTIL)) { 391 String until = param_map.get(OAIXML.UNTIL); 392 until_date = OAIXML.getDate(until); 393 } 394 Element metadata_format = getMetadataFormatElement(prefix); 395 if(metadata_format == null) { 396 logger.error("metadata prefix is not supported."); 397 return OAIXML.createErrorResponse(OAIXML.CANNOT_DISSEMINATE_FORMAT, ""); 398 } 399 400 //get a list of identifiers (it contains a list of strings) 401 ArrayList<String> oid_list = getChildrenIds(OAIXML.BROWSELIST); 402 if (oid_list == null) { 403 logger.error("No matched records found in collection: browselist is empty"); 404 return OAIXML.createErrorResponse(OAIXML.NO_RECORDS_MATCH, ""); 405 } 406 // all validation is done 407 408 Document doc = XMLConverter.newDOM(); 409 Element list_records_response = doc.createElement(GSXML.RESPONSE_ELEM); 410 Element list_records = doc.createElement(OAIXML.LIST_RECORDS); 411 list_records_response.appendChild(list_records); 412 for(int i=0; i<oid_list.size(); i++) { 413 String oid = oid_list.get(i); 414 DBInfo info = this.coll_db.getInfo(oid); 415 if (info == null) { 416 logger.error("Database does not contains information about oid: " +oid); 417 continue; 418 } 419 ArrayList<String> keys = new ArrayList<String>(info.getKeys()); 420 String oailastmodified = ""; 421 if(keys.contains(OAIXML.OAI_LASTMODIFIED)) { 422 oailastmodified = info.getInfo(OAIXML.OAI_LASTMODIFIED); 423 oailastmodified = OAIXML.getTime(Long.parseLong(oailastmodified)*1000); // java wants dates in milliseconds 424 } 425 426 Date this_date = OAIXML.getDate(oailastmodified); 427 if (from_date != null) { 428 if(this_date.before(from_date)) { 429 continue; 430 } 431 } 432 if (until_date != null) { 433 if (this_date.after(until_date)) { 434 continue; 435 } 436 } 437 438 Element record = doc.createElement(OAIXML.RECORD); 439 list_records.appendChild(record); 440 //compose the header element 441 record.appendChild(createHeaderElement(doc, oid, oailastmodified)); 442 //compose the metadata element 443 record.appendChild(createMetadataElement(doc, prefix, info, metadata_format)); 444 445 }//end of for(int i=0; i<oid_list.size(); i++) of doing thru each record 446 447 return list_records_response; 448 } 487 return list_items_response; 488 489 } 490 449 491 450 492 // have implemented setDescription as an element, instead of a container containing metadata … … 484 526 return true; 485 527 } 486 /** get the metadataFormat element from the collectionConfig.xml containing the specified metadata prefix. 487 * return null if not found.528 529 /** create the metadata element used when processing ListRecords/GetRecord requests 488 530 */ 489 private Element getMetadataFormatElement(String prefix) { 490 Element list_meta_format = (Element)GSXML.getChildByTagName(this.config_info, OAIXML.LIST_METADATA_FORMATS); 491 Element metadata_format = GSXML.getNamedElement(list_meta_format, OAIXML.METADATA_FORMAT, OAIXML.METADATA_PREFIX, prefix); 492 return metadata_format; 493 } 494 /** create the metadata element used when processing ListRecords/GetRecord requests 495 */ 496 private Element createMetadataElement(Document doc, String prefix, DBInfo info, Element metadata_format) { 497 //the prefix string is in the form: oai_dc, for example. 498 String prfx_str = ""; 499 //the metadata namespace used to retrieve metadata in the repository 500 //For example, if the prefix is like 'oai_ex' then we used 'ex' to get the metadata 501 //Normally we would use 'dc' to find metadata. 502 String meta_ns = ""; 503 if(prefix.equals(OAIXML.OAI_DC)) { 504 if(OAIXML.oai_version.equals(OAIXML.OAI_VERSION2)) { 505 prfx_str = prefix + ":" + OAIXML.DC; 506 } else { 507 prfx_str = OAIXML.DC;//oai version 1 508 } 509 meta_ns = OAIXML.DC; 510 } else { 511 prfx_str = prefix.substring(prefix.indexOf("_") + 1); 512 meta_ns = prfx_str; 513 } 514 //create the <metadata> element 515 //OAIXML.oai_version is read from OAIConfig.xml and its default value is "2.0" 516 Element metadata = doc.createElement(OAIXML.METADATA); 517 Element prfx_str_elem = OAIXML.getMetadataPrefixElement(doc, prfx_str, OAIXML.oai_version); 518 metadata.appendChild(prfx_str_elem); 519 String[] metadata_names = getMetadataNameMapping(metadata_format); 520 HashMap meta_map = getInfoByNames(info, metadata_names); 521 522 // if there's no dc:identifier already after the mapping, we'll add it in 523 if(!meta_map.containsKey(OAIXML.DC+":identifier")) { // dc:identifier OAIXML.IDENTIFIER 524 outputCustomMetadata(meta_map, info, OAIXML.DC+":identifier"); 525 } 526 527 528 if (meta_map == null) { 529 return metadata; 531 protected Element createMetadataElement(Document doc, String prefix, DBInfo info) { 532 // the <metadata> element 533 Element metadata = doc.createElement(OAIXML.METADATA); 534 // the <oai:dc namespace...> element 535 Element prfx_str_elem = OAIXML.getMetadataPrefixElement(doc, prefix, OAIXML.oai_version); 536 metadata.appendChild(prfx_str_elem); 537 538 Element meta_format_element = GSXML.getNamedElement(this.meta_formats_definition, OAIXML.METADATA_FORMAT, GSXML.NAME_ATT, prefix); 539 NodeList elements = meta_format_element.getElementsByTagName(OAIXML.ELEMENT); 540 // for each element in the definition 541 for (int i=0; i<elements.getLength(); i++) { 542 Element e = (Element)elements.item(i); 543 Element map = (Element)GSXML.getChildByTagName(e, OAIXML.MAPPING); 544 if (map == null) { 545 // look up the element name 546 addMetadata(prfx_str_elem, e.getAttribute(GSXML.NAME_ATT), info); 547 } else { 548 // we go though the list of names in the mapping 549 addMetadata(prfx_str_elem, e.getAttribute(GSXML.NAME_ATT), map.getAttribute(OAIXML.SELECT), map.getAttribute(OAIXML.ELEMENTS), info); 550 } 551 } 552 // output any metadata that is not just a simple mapping 553 addCustomMetadata(prfx_str_elem, prefix, info); 554 return metadata; 555 } 556 557 /** a simple addMetadata where we look for meta_name metadata, and add as that name*/ 558 protected void addMetadata(Element meta_list_elem, String meta_name, DBInfo info) { 559 Vector<String> values = info.getMultiInfo(meta_name); 560 for (int i=0; i<values.size(); i++) { 561 addMetadataElement(meta_list_elem, meta_name, values.get(i)); 562 } 563 } 564 565 /** more complicated addMetadata - can add multiple items. */ 566 protected void addMetadata(Element meta_list_elem, String new_meta_name, String select_type, String name_list, DBInfo info) { 567 String[] names = name_list.split(","); 568 for (int i=0; i<names.length; i++) { 569 Vector<String> values = info.getMultiInfo(names[i]); 570 if (values == null || values.size()==0) { 571 continue; 572 } 573 for (int j=0; j<values.size(); j++) { 574 addMetadataElement(meta_list_elem, new_meta_name, values.get(j)); 575 if (select_type.equals(OAIXML.SELECT_SINGLE_VALUE)) { 576 return; // only want to add one value 530 577 } 531 ArrayList meta_list = new ArrayList(meta_map.entrySet()); 532 for (int j=0; j<meta_list.size(); j++) { 533 Entry men = (Entry)meta_list.get(j); 534 String meta_name = (String)men.getKey(); 535 //meta_name = meta_name.replace('.', ':'); // namespace separator should be : for oai 536 String meta_value = (String)men.getValue(); 537 Element e = doc.createElement(meta_name); 538 GSXML.setNodeText(e, meta_value); 539 prfx_str_elem.appendChild(e); 578 } 579 if (select_type.equals(OAIXML.SELECT_FIRST_VALID_META)) { 580 return; // we have added all values of this meta elem 581 } 582 // otherwise, we will keep going through the list and add them all. 583 } 584 } 585 586 // specific metadata formats might need to do some custom metadata that is not 587 //just a standard mapping. eg oai_dc outputting an identifier that is a link 588 protected void addCustomMetadata(Element meta_list_elem, String prefix, DBInfo info) { 589 590 if (prefix.equals(OAIXML.META_FORMAT_DC)) { 591 // we want to add in another dc:identifier element with a link to the resource if possible 592 // try gs.OAIResourceURL first, then srclinkFile, then GS version of documnet 593 String gsURL = info.getInfo(OAIXML.GS_OAI_RESOURCE_URL); 594 if (gsURL.equals("")) { 595 String base_url = OAIXML.getBaseURL(); // e.g. e.g. http://host:port/greenstone3/oaiserver 596 // try srclinkFile 597 gsURL = info.getInfo("srclinkFile"); 598 if (!gsURL.equals("")) { 599 // make up the link to the file 600 gsURL = base_url.replace("oaiserver", "") + "sites/" + this.site_name 601 + "/collect/" + this.coll_name + "/index/assoc/" 602 + info.getInfo("assocfilepath") + "/" + gsURL; 603 } else { 604 // no srclink file, lets provide a link to the greenstone doc 605 gsURL = base_url.replace("oaiserver", "library") + "/collection/" + this.coll_name + "/document/" + info.getInfo("Identifier"); 540 606 } 541 542 return metadata; 543 } 607 } 608 // now we have the url link, add as metadata 609 addMetadataElement(meta_list_elem, "dc:identifier", gsURL); 610 } 611 } 612 613 /** create the actual metadata element for the list */ 614 protected void addMetadataElement(Element meta_list_elem, String name, String value) { 615 616 Element meta = GSXML.createTextElement(meta_list_elem.getOwnerDocument(), name, value); 617 meta_list_elem.appendChild(meta); 618 } 619 620 544 621 /** create a header element used when processing requests like ListRecords/GetRecord/ListIdentifiers 545 622 */ 546 pr ivateElement createHeaderElement(Document doc, String oid, String oailastmodified) {623 protected Element createHeaderElement(Document doc, String oid, String oailastmodified) { 547 624 Element header = doc.createElement(OAIXML.HEADER); 548 625 Element identifier = doc.createElement(OAIXML.IDENTIFIER); 549 //GSXML.setNodeText(identifier, site_name + ":" + coll_name + ":" + oid);550 626 GSXML.setNodeText(identifier, coll_name + ":" + oid); 551 627 header.appendChild(identifier); 552 628 Element set_spec = doc.createElement(OAIXML.SET_SPEC); 553 //GSXML.setNodeText(set_spec, site_name + ":" + coll_name);554 629 GSXML.setNodeText(set_spec, coll_name); 555 630 header.appendChild(set_spec); … … 559 634 return header; 560 635 } 636 561 637 /** return the metadata information */ 562 638 protected Element processListMetadataFormats(Element req) { … … 586 662 } 587 663 588 NodeList meta_list = getMetadataFormatList();589 if (meta_list == null || meta_list.getLength() == 0) {590 logger.error("No metadata format is present in collectionConfig.xml");591 return OAIXML.createErrorResponse(OAIXML.NO_METADATA_FORMATS, "");592 }593 594 664 Document doc = XMLConverter.newDOM(); 595 665 Element list_metadata_formats_response = doc.createElement(GSXML.RESPONSE_ELEM); … … 599 669 boolean has_meta_format = false; 600 670 601 for (int i=0; i<meta_list.getLength(); i++) { 602 Element metadata_format = (Element)meta_list.item(i); 603 String[] metadata_names = getMetadataNameMapping(metadata_format); 604 if (containsMetadata(info, metadata_names) == true) { 605 has_meta_format = true; 606 // TODO, can we do this in an easier way?? 607 Element meta_fmt = doc.createElement(OAIXML.METADATA_FORMAT); 608 GSXML.copyNamedElement(meta_fmt, metadata_format, OAIXML.METADATA_PREFIX); 609 GSXML.copyNamedElement(meta_fmt, metadata_format, OAIXML.METADATA_NAMESPACE); 610 GSXML.copyNamedElement(meta_fmt, metadata_format, OAIXML.SCHEMA); 611 list_metadata_formats.appendChild(meta_fmt); 612 } 613 }//end of for loop 671 // for each format in format_elements_map 672 Iterator<String> it = format_elements_map.keySet().iterator(); 673 while (it.hasNext()) { 674 String format = it.next(); 675 HashSet<String> set_of_elems = format_elements_map.get(format); 676 if (documentContainsMetadata(info, set_of_elems)) { 677 // add this format into the response 678 has_meta_format = true; 679 list_metadata_formats.appendChild(doc.importNode(format_response_map.get(format), true)); 680 } 681 } 682 614 683 if (has_meta_format == false) { 615 684 logger.error("Specified metadata names are not contained in the database."); … … 620 689 } 621 690 622 /** return the ListMetadataFormats element in collectionConfig.xml 623 * Currently, it will only contain one metadata format: oai_dc 624 */ 625 protected NodeList getMetadataFormatList() { 626 Element list_meta_formats = (Element)GSXML.getChildByTagName(this.config_info, OAIXML.LIST_METADATA_FORMATS); 627 return GSXML.getChildrenByTagName(list_meta_formats, OAIXML.METADATA_FORMAT); 628 } 629 /** @param metadata_format - the metadataFormat element in collectionConfig.xml 630 */ 631 protected String[] getMetadataNameMapping(Element metadata_format) { 632 633 String[] names = OAIXML.getMetadataMapping(metadata_format); 634 if (names != null) { 635 return names; 636 } 637 logger.info("No metadata mappings are provided in collectionConfig.xml. Try for global mapping"); 638 names = OAIXML.getGlobalMetadataMapping(metadata_format.getAttribute(OAIXML.METADATA_PREFIX)); 639 return names; 691 protected boolean documentContainsMetadata(DBInfo info, HashSet<String> set_of_elems) { 692 if (set_of_elems.size() == 0) { 693 return false; 694 } 695 Iterator<String> i = set_of_elems.iterator(); 696 while (i.hasNext()) { 697 if (!info.getInfo(i.next()).equals("")) { 698 return true; 699 } 700 } 701 return false; 640 702 } 641 703 … … 677 739 } 678 740 return false; 679 } 680 /** @param keys - contains a list of keys in string format. 681 * Here is a typical record in the collection database, 'keys' contains the values in <...>: 682 *---------------------------------------------------------------------- 683 [HASH01a84acb0f1aad2380493b3a] 684 <doctype>doc 685 <hastxt>1 686 <Language>en 687 <Encoding>windows_1252 688 <Plugin>HTMLPlug 689 <FileSize>205093 690 <Source>wb34te.htm 691 <hascover>1 692 <dls.Organization>World Bank 693 <dls.Title>Development in practice: Toward Gender Equality (wb34te) 694 <dls.Language>English 695 <dls.AZList>A-B-C-D-E-F-G-H-I-J-K-L-M-N-O-P-Q-R-S-T-U-V-W-X-Y-Z 696 <dls.Subject>Women, gender and development, women's organizations 697 <dls.Keyword>achieve gender equality 698 <URL>http://wb34te/wb34te.htm 699 <Title>Development in practice: Toward Gender Equality 700 <lastmodified>1178245194 701 <assocfilepath>HASH01a8.dir 702 <memberof>CL3 703 <archivedir>HASH01a8.dir 704 <thistype>VList 705 <childtype>VList 706 <contains>".1;".2;".3;".4;".5;".6;".7;".8;".9 707 <docnum>349 708 <oailastmodified>1303283795 709 <lastmodifieddate>20110412 710 <oailastmodifieddate>20110420 711 ---------------------------------------------------------------------- 712 */ 713 public String[] getMetadata(DBInfo info, String names) { 714 String[] name_value = new String[2]; 715 ArrayList<String> keys = new ArrayList<String>(info.getKeys()); 716 for (int i=0; i<keys.size(); i++) { 717 String key = keys.get(i); 718 String first_name = ""; 719 String second_name = ""; 720 int index = names.indexOf(","); 721 if(index != -1) { 722 first_name = names.substring(0, index); 723 second_name = names.substring(index + 1); 724 } else { 725 first_name = second_name = names; 726 } 727 if(key.equals(second_name)) { 728 String meta_value = info.getInfo(key); 729 name_value[0] = first_name; 730 name_value[1] = meta_value; 731 return name_value; 732 } 733 } 734 return null; 735 } 736 protected HashMap getInfoByNames(DBInfo info, String[] metadata_names) { 737 738 if (metadata_names == null) { 739 return null; 740 } 741 HashMap<String, String> map = new HashMap<String, String>(); 742 boolean empty_map = true; 743 744 for(int i=0; i<metadata_names.length; i++) { 745 String[] name_value = getMetadata(info, metadata_names[i]); 746 if(name_value != null) { 747 map.put(name_value[0], name_value[1]); 748 empty_map = false; 749 } 750 } 751 return (empty_map == true) ? null : map; 752 } 753 754 // GS3 version of GS2's runtime-src/src/oaiservr/dublincore.cpp function output_custom_metadata 755 protected void outputCustomMetadata(HashMap meta_map, DBInfo info, String dc_identifier) { 756 757 // try gs.OAIResourceURL, else srclinkFile, else the GS version of the document 758 String identifier_value = info.getInfo(OAIXML.GS_OAI_RESOURCE_URL); 759 760 if(identifier_value.equals("")) { 761 String url = OAIXML.getBaseURL(); // e.g. e.g. http://host:port/greenstone3/library/oaiserver 762 763 identifier_value = info.getInfo("srclinkFile"); 764 if(identifier_value.equals("")) 765 { 766 // no source file to link to, so link to the GS version of the document (need to use URL-style slashes) 767 // e.g. http://host:port/greenstone3/library/collection/lucene-jdbm-demo/document/HASH014602ec89e16b7d431c7627 768 769 identifier_value = url.replace("oaiserver", "library") + "collection/" + this.coll_name + "/document/" + info.getInfo("identifier"); // OID 770 } 771 else // use srclinkFile 772 { 773 // e.g. http://host:port/greenstone3/sites/localsite/collect/backdrop/index/assoc/D0.dir/Cat.jpg 774 identifier_value = url.replace("oaiserver", "") + "sites/" + this.site_name 775 + "/collect/" + this.coll_name + "/index/assoc/" 776 + info.getInfo("assocfilepath") + "/" + identifier_value; // srclinkFile 777 } 778 } // else use gs.OAIResourceURL as-is 779 780 //logger.info("**** dc:identifier: " + identifier_value); 781 782 meta_map.put(dc_identifier, identifier_value); 783 } 741 } 742 784 743 } 785 744
Note:
See TracChangeset
for help on using the changeset viewer.