Changeset 29067 for main


Ignore:
Timestamp:
2014-05-19T13:27:25+12:00 (10 years ago)
Author:
kjdon
Message:

changed metadataFormat stuff. service uses some info from main OAIConfig.xml. Format for elements and mappings has changed. a lot of code tidy up.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/OAIPMH.java

    r28986 r29067  
    11/*
    22 *    OAIPMH.java
    3  *    Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
     3 *    Copyright (C) 2010 New Zealand Digital Library, http://www.nzdl.org
    44 *
    55 *    This program is free software; you can redistribute it and/or modify
     
    4343import java.util.Date;
    4444import java.util.HashMap;
     45import java.util.HashSet;
    4546import java.util.Map.Entry;
    4647
     
    6465  protected Element list_sets_response = null;
    6566 
     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;
    6670  /** constructor */
    6771  public OAIPMH() {
     
    161165  }
    162166
     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   
    163269  /** returns a specific service description */
    164270  public Element getServiceDescription(Document doc, String service_id, String lang, String subset) {
     
    199305    return null;
    200306  }
    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.  */
    206309  protected Element processListSets(Element req) {
    207310    return list_sets_response;
    208311  }
    209   /** return the metadata information */
     312  /** returns the actual record element used in the OAI GetRecord response */
    210313  protected Element processGetRecord(Element req) {
    211314    /** arguments:
     
    224327    }
    225328   
    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);
    229332      return OAIXML.createErrorResponse(OAIXML.CANNOT_DISSEMINATE_FORMAT, "");
    230333    }
     
    242345    Document doc = XMLConverter.newDOM();
    243346    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
    247350      oailastmodified = OAIXML.getTime(Long.parseLong(oailastmodified)*1000); // java wants dates in milliseconds
    248351    }
     
    255358    record.appendChild(createHeaderElement(doc, oid, oailastmodified));     
    256359    //compose the metadata element
    257     record.appendChild(createMetadataElement(doc, prefix, info, metadata_format));
     360    record.appendChild(createMetadataElement(doc, prefix, info));
    258361    get_record.appendChild(record);
    259362    return get_record_response;
    260363  }
    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. */
    262371  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) {
    263377    /** arguments:
    264378        metadataPrefix: required
     
    303417    }   
    304418
    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);
    308421      return OAIXML.createErrorResponse(OAIXML.CANNOT_DISSEMINATE_FORMAT, "");
    309422    }
     
    315428    // all validation is done
    316429
     430    // get the list of elements that are in this metadata prefix
     431    HashSet<String> set_of_elems = format_elements_map.get(prefix);
     432
    317433    Document doc = XMLConverter.newDOM();
    318     Element list_identifiers_response = doc.createElement(GSXML.RESPONSE_ELEM);
    319     Element list_identifiers = doc.createElement(OAIXML.LIST_IDENTIFIERS);
    320     list_identifiers_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);
    321437
    322438    for(int i=0; i<oid_list.size(); i++) {
     
    327443        continue;
    328444      }
    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 milliseconds
    334       }
    335445     
    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.
    349485    }//end of for(int i=0; i<oid_list.size(); i++) of doing thru each record
    350486   
    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
    449491 
    450492  // have implemented setDescription as an element, instead of a container containing metadata
     
    484526    return true;
    485527  }
    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
    488530   */
    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
    530577    }
    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");
    540606    }
    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
    544621  /** create a header element used when processing requests like ListRecords/GetRecord/ListIdentifiers
    545622   */
    546   private Element createHeaderElement(Document doc, String oid, String oailastmodified) {   
     623  protected Element createHeaderElement(Document doc, String oid, String oailastmodified) {   
    547624        Element header = doc.createElement(OAIXML.HEADER);
    548625        Element identifier = doc.createElement(OAIXML.IDENTIFIER);
    549         //GSXML.setNodeText(identifier, site_name + ":" + coll_name + ":" + oid);
    550626    GSXML.setNodeText(identifier, coll_name + ":" + oid);
    551627        header.appendChild(identifier);
    552628        Element set_spec = doc.createElement(OAIXML.SET_SPEC);
    553         //GSXML.setNodeText(set_spec, site_name + ":" + coll_name);
    554629    GSXML.setNodeText(set_spec, coll_name);
    555630        header.appendChild(set_spec);
     
    559634        return header;
    560635  }
     636
    561637  /** return the metadata information  */
    562638  protected Element processListMetadataFormats(Element req) {
     
    586662    }
    587663   
    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 
    594664    Document doc = XMLConverter.newDOM();
    595665    Element list_metadata_formats_response = doc.createElement(GSXML.RESPONSE_ELEM);
     
    599669    boolean has_meta_format = false;
    600670   
    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
    614683    if (has_meta_format == false) {
    615684      logger.error("Specified metadata names are not contained in the database.");
     
    620689  }
    621690
    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;
    640702  }
    641703
     
    677739    }
    678740    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
    784743}
    785744
Note: See TracChangeset for help on using the changeset viewer.