Changeset 37615


Ignore:
Timestamp:
2023-04-06T16:55:52+12:00 (14 months ago)
Author:
kjdon
Message:

this will now ask for format info from each collection in the documentNodeList, and get their format statements for the specified service. it groups these into a xsl:choose statement.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/GeneralDocumentListAction.java

    r37516 r37615  
    55import java.util.HashMap;
    66import java.util.HashSet;
     7import java.util.Map;
    78
    89import javax.xml.parsers.DocumentBuilder;
     
    4243    // assume only one request
    4344    Element request = (Element) GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
    44     logger.debug(" request=" + this.converter.getString(request));
     45    //logger.debug(" request=" + this.converter.getString(request));
    4546
    4647    UserContext userContext = new UserContext(request);
     
    121122    }
    122123
     124    NodeList doc_nodes = result_response.getElementsByTagName(GSXML.DOC_NODE_ELEM);
     125    if (doc_nodes.getLength() == 0) {
     126      // no docs in the result
     127      return result;
     128    }
     129
     130    // lets get format info for each collection
     131    HashSet<String> collections = getCollectionNames(doc_nodes);
     132
     133    //get the format info for the service
     134    Element base_format_elem = getFormatInfo(to, userContext);
     135    // now get any from the collections, and combine into a big if/else block
     136    Element combined_format = getAndCombineFormats(doc, base_format_elem, collections, service_name);
     137
     138    if (combined_format != null) {
     139      // set the format type - what would it be for this??
     140      //format_elem.setAttribute(GSXML.TYPE_ATT, "");
     141      // add to the response
     142      page_response.appendChild(combined_format);
     143    }
     144
    123145    // we need to get metadata for the documents
     146    // which metadata elements do we need?
    124147    HashSet<String> doc_meta_names = new HashSet<String>();
    125148    // always want this one
    126149    doc_meta_names.add("root_assocfilepath");
    127150    // we use extraMetadataList, plus anything that shows up in the service's format statement
    128     //get the format info for the service
    129     Element format_elem = getFormatInfo(to, userContext);
    130     if (format_elem != null) {
    131       // set the format type - what would it be for this??
    132       //format_elem.setAttribute(GSXML.TYPE_ATT, "");
    133       // add to the response
    134       page_response.appendChild(doc.importNode(format_elem, true));
    135     }
     151
    136152    // ... and find any metadata names mentioned in the format, or in extraMetadata
    137     getRequiredMetadataNames(doc_meta_names, format_elem, request);
     153    getRequiredMetadataNames(doc_meta_names, combined_format, request);
    138154
    139155    // TODO, do we want docType and nodeType attributes for each doc Node??
    140     addMetadataToDocNodes(result_response, doc_meta_names);
     156    getAndAddMetadataToDocNodes(result_response, doc_meta_names);
    141157   
    142158    if (response_only)
     
    162178    return result;
    163179  }
    164  
    165   protected void addMetadataToDocNodes(Element result_elem, HashSet<String> meta_names) {
     180
     181  protected HashSet<String> getCollectionNames(NodeList docNodes) {
     182    HashSet<String> coll_names = new HashSet<String>();
     183    for (int i=0; i<docNodes.getLength(); i++) {
     184      String collection = ((Element)docNodes.item(i)).getAttribute(GSXML.COLLECTION_ATT);
     185      if (!collection.equals("")) {
     186        coll_names.add(collection);
     187      }
     188    }
     189    return coll_names;
     190  }
     191
     192  // TODO - store this so don't need to get it each time.
     193  protected Element getAndCombineFormats(Document result_doc, Element base_format, HashSet<String> collections, String service_name)
     194  {
     195    Element combined_format = result_doc.createElement(GSXML.FORMAT_ELEM);
     196
     197    // lets see if the collections are returning any local formats
     198    Document doc = XMLConverter.newDOM();
     199    Element message = doc.createElement(GSXML.MESSAGE_ELEM);
     200
     201    // service_name is an extra attribute
     202    for (String coll : collections) {
     203      Element this_coll_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_FORMAT, coll, new UserContext());
     204      this_coll_request.setAttribute(GSXML.SERVICE_ATT, service_name);
     205      message.appendChild(this_coll_request);
     206    }
     207
     208    // template match:mode is the key->collection->template element
     209    HashMap<String, HashMap<String,Element>> template_map = new HashMap<String, HashMap<String,Element>>();
     210    if (base_format != null) {
     211      // to do - process the defaults differently. any non match tempaltes need to be added as is into hte result, and the options.
     212      addFormatsToMap(template_map, base_format, "default_format", combined_format);
     213    }
     214
     215    //send off the request
     216    boolean has_coll_specific_format = false;
     217    Element mr_response = (Element)this.mr.process(message);
     218    // add all the resulting templates into the map
     219    NodeList colls_responses = mr_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
     220    for (int i=0; i<colls_responses.getLength(); i++) {
     221      Element coll_response = (Element)colls_responses.item(i);
     222      Element format = (Element)GSXML.getChildByTagName(coll_response, GSXML.FORMAT_ELEM);
     223      if (format == null) continue;
     224      String this_coll = coll_response.getAttribute(GSXML.FROM_ATT);
     225      addFormatsToMap(template_map, format, this_coll, null);
     226    }
     227
     228    // ok, now we need to go through the map, and join them up into a big <xsl:choose>
     229    for(Map.Entry<String, HashMap<String, Element>> entry : template_map.entrySet()) {
     230      String id = entry.getKey();
     231      HashMap<String, Element> coll_map = entry.getValue();
     232
     233      Element new_template = result_doc.createElementNS("http://www.w3.org/1999/XSL/Transform", "xsl:template");
     234      String[] id_parts = id.split(":");
     235      String match = id_parts[0];
     236      String mode = "";
     237      if (id_parts.length==2) {
     238        mode = id_parts[1];
     239      }
     240      new_template.setAttribute("match", match);
     241      if (!mode.equals("")) {
     242        new_template.setAttribute("mode", mode);
     243      }
     244      if (coll_map.size()==1 && coll_map.containsKey("default_format")) {
     245        // we only have the default format - can copy it as is
     246        new_template = (Element)result_doc.importNode(coll_map.get("default_format"), true);
     247
     248      } else if (coll_map.size()==1) {
     249        // this is an error
     250        logger.error("no default entry for xsl template!"); // todo better message
     251      } else {
     252        Element choose = result_doc.createElementNS("http://www.w3.org/1999/XSL/Transform", "xsl:choose");
     253        new_template.appendChild(choose);
     254        Element otherwise = null;
     255        for (Map.Entry<String, Element> entry2 : coll_map.entrySet()) {
     256          String coll = entry2.getKey();
     257          Element template = entry2.getValue();
     258          if (coll.equals("default_format")) {
     259            // this is the otherwsie clause
     260            otherwise = GSXML.duplicateWithNewNameNS(result_doc, template, "xsl:otherwise","http://www.w3.org/1999/XSL/Transform", false);
     261           
     262          } else {
     263            // this is a when statement
     264            Element when = GSXML.duplicateWithNewNameNS(result_doc, template, "xsl:when","http://www.w3.org/1999/XSL/Transform", false);
     265            when.setAttribute("test", "@collection='"+coll+"'");
     266            choose.appendChild(when);
     267        }
     268          if (otherwise != null) {
     269            // append otherwise last
     270            choose.appendChild(otherwise);
     271          }
     272          combined_format.appendChild(new_template);
     273       
     274        }
     275       
     276      } // for each entry in template map
     277    }
     278    return combined_format;
     279  }
     280  protected void addFormatsToMap(HashMap<String, HashMap<String, Element>> template_map, Element format_element, String coll_name, Element combined_format) {
     281    Document doc = null;
     282    if (combined_format != null) {
     283      doc = combined_format.getOwnerDocument();
     284    }
     285    NodeList children = format_element.getChildNodes();
     286    for (int j=0; j<children.getLength(); j++) {
     287      Node this_child = children.item(j);
     288      if (this_child instanceof Element) { // lets ignore any other kind of node
     289        if (this_child.getNodeName().equals("xsl:template")) {
     290          Element this_template = (Element)this_child;
     291          String match = this_template.getAttribute("match");
     292          if (match.equals("")) {
     293            if (combined_format != null) {
     294              combined_format.appendChild(doc.importNode(this_template,true));
     295            }
     296          } else {
     297            String mode = this_template.getAttribute("mode");
     298            String id = match+":"+mode;
     299            HashMap<String, Element> coll_map = template_map.get(id);
     300            if (coll_map == null) {
     301              coll_map = new HashMap<String, Element>();
     302              template_map.put(id, coll_map);
     303            }
     304            coll_map.put(coll_name, this_template);
     305          }
     306        } else {
     307        // the node is not xsl:template, add it to combined format, if that has been supplied.
     308          if (combined_format != null) {
     309            combined_format.appendChild(doc.importNode(this_child, true));
     310          }
     311        }
     312      }// if isa Element
     313    } // for each node
     314 
     315
     316  }
     317
     318  protected void getAndAddMetadataToDocNodes(Element result_elem, HashSet<String> meta_names) {
    166319   
    167320    Document doc = XMLConverter.newDOM();
     
    194347    // ok, send off the message
    195348    Element dm_result = (Element)this.mr.process(message);
    196 
    197349    String [] att_names = {GSXML.COLLECTION_ATT, GSXML.NODE_ID_ATT};
    198350    // go throught he original list of doc nodes
Note: See TracChangeset for help on using the changeset viewer.