Changeset 24254

Show
Ignore:
Timestamp:
14.07.2011 21:39:43 (8 years ago)
Author:
ak19
Message:

Commits for ticket 770 concerning the display of multiple values for a metadata (like dc.Title) when classified by that metadata. So when the user browses by dc.Title, they no longer merely see a doc listed once for each dc.Title assigned but under the same (first retrieved) dc.Title, but they should now see the doc listed once for each dc.Title assigned to it with a different dc.Title value each time.

Location:
main/trunk/greenstone3
Files:
9 modified

Legend:

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

    r24227 r24254  
    7777    } 
    7878 
    79     protected void extractMetadataNames(Element format, HashSet meta_names) { 
     79    protected void extractMetadataNames(Element format, HashSet meta_names) { 
    8080    //NodeList nodes = format.getElementsByTagNameNS("metadata", "http://www.greenstone.org/configformat"); 
    8181    NodeList metadata_nodes = format.getElementsByTagName("gsf:metadata"); 
     
    9090                metadata.append("all"); 
    9191                metadata.append(GSConstants.META_RELATION_SEP); 
    92             } 
     92            } else if (all.equals("offset")) { // multiple is no longer boolean.  
     93        // Can be "true", "false" or it can be "offset" (when requested to use mdoffset) 
     94                metadata.append("offset"); 
     95                metadata.append(GSConstants.META_RELATION_SEP); 
     96            } // if multiple=false, then get first value for the metadata 
    9397            if (!select.equals("")) { 
    9498                metadata.append(select); 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/GS2BrowseAction.java

    r21928 r24254  
    272272        Element d = this.doc.createElement(GSXML.DOC_NODE_ELEM); 
    273273        d.setAttribute(GSXML.NODE_ID_ATT, ((Element)doc_nodes.item(c)).getAttribute(GSXML.NODE_ID_ATT)); 
     274        if(((Element)doc_nodes.item(c)).hasAttribute(GSXML.NODE_MDOFFSET_ATT)) { 
     275            d.setAttribute(GSXML.NODE_MDOFFSET_ATT, ((Element)doc_nodes.item(c)).getAttribute(GSXML.NODE_MDOFFSET_ATT)); 
     276        } 
    274277        doc_list.appendChild(d); 
    275278        } 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractBrowse.java

    r23050 r24254  
    574574     * <docNode nodeId='xxx' nodeType='leaf' docType='hierarchy'/> 
    575575     */ 
    576     protected Element createDocNode(String node_id) { 
     576    protected Element createDocNode(String node_id, int offset) { 
    577577    Element node = this.doc.createElement(GSXML.DOC_NODE_ELEM); 
    578578    node.setAttribute(GSXML.NODE_ID_ATT, node_id); 
     
    587587    String node_type = getNodeType(node_id, doc_type);   
    588588    node.setAttribute(GSXML.NODE_TYPE_ATT, node_type); 
     589     
     590    // mdoffset information stored in DB determines which of multiple values for 
     591    // a metadata needs to be displayed when a classifier is built on that metadata 
     592    node.setAttribute(GSXML.NODE_MDOFFSET_ATT, Integer.toString(offset)); 
    589593    return node; 
    590594    } 
     
    621625    ArrayList child_ids = getChildrenIds(node_id); 
    622626    if (child_ids==null) return; 
     627     
     628    // get a list of all mdoffsets at this point 
     629    ArrayList child_offsets = getOffsetsForChildrenIds(node_id); 
     630    // make sure that if it's doesn't match up with child_ids in length,  
     631    // it is padded with 0s to make up the length 
     632    if(child_offsets == null) { 
     633        child_offsets = new ArrayList(child_ids.size()); 
     634    }  
     635    if(child_offsets.size() < child_ids.size()) { 
     636        Integer zero = new Integer(0); 
     637        for(int i = child_offsets.size()-1; i < child_ids.size(); i++) { 
     638        child_offsets.add(zero); 
     639        } 
     640    } 
     641 
    623642    for (int i=0; i< child_ids.size(); i++) { 
    624643        String child_id = (String)child_ids.get(i); 
     644        int child_offset = ((Integer)child_offsets.get(i)).intValue(); // counts both docnodes and classnodes at the childlevel, is this right? 
    625645        Element child_elem; 
    626646        if (isDocumentId(child_id)) { 
    627         child_elem = createDocNode(child_id); 
     647        child_elem = createDocNode(child_id, child_offset); 
    628648        } else { 
    629649        child_elem = createClassifierNode(child_id); 
     
    684704    } 
    685705 
     706    /** Override to get a list of mdoffsets of children. Return null if no children or if no mdoffsets for them */ 
     707    protected ArrayList getOffsetsForChildrenIds(String node_id) {  
     708    return null;  
     709    } 
     710 
    686711    /** if id ends in .fc, .pc etc, then translate it to the correct id */ 
    687712    abstract protected String translateId(String node_id); 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractDocumentRetrieve.java

    r22085 r24254  
    241241        Element request_node = (Element) request_nodes.item(i); 
    242242        String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT); 
     243 
     244        // make a custom copy of metadata_names_list for each docID, since mdoffset value varies for each doc 
     245        ArrayList customised_metadata_names_list = new ArrayList(metadata_names_list.size()); 
     246        int mdoffset = 0; 
     247        if(request_node.hasAttribute(GSXML.NODE_MDOFFSET_ATT)) { 
     248        String offset = request_node.getAttribute(GSXML.NODE_MDOFFSET_ATT); 
     249        mdoffset = Integer.parseInt(offset); 
     250         
     251        for(int x = 0; x < metadata_names_list.size(); x++) { 
     252            String metaname = (String)metadata_names_list.get(x); 
     253            if(metaname.indexOf("offset" + GSConstants.META_RELATION_SEP) != -1) { 
     254            // append offset number to the metaname 
     255            metaname = metaname.replace("offset"+GSConstants.META_RELATION_SEP, "offset"+mdoffset+GSConstants.META_RELATION_SEP); 
     256            }  
     257            customised_metadata_names_list.add(x, metaname);             
     258        } 
     259        } 
    243260        
    244261        boolean is_external_link = false; 
     
    272289        if (!is_external_link){ 
    273290        try { 
    274             Element metadata_list = getMetadataList(node_id, all_metadata, metadata_names_list); 
     291            Element metadata_list = getMetadataList(node_id, all_metadata, customised_metadata_names_list); 
    275292            request_node.appendChild(metadata_list); 
    276293        } catch (GSException e) {        
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractGS2DocumentRetrieve.java

    r23792 r24254  
    4141import java.util.Iterator; 
    4242import java.util.ArrayList; 
     43import java.util.regex.Matcher; 
     44import java.util.regex.Pattern; 
    4345 
    4446import org.apache.log4j.*; 
     
    196198         
    197199    } else { 
     200        // prepare regex to work with mdoffset: looking for <offset\d*_> 
     201        Pattern pattern = Pattern.compile("offset[0-9]*" + GSConstants.META_RELATION_SEP); 
     202 
    198203        for (int i=0; i<metadata_names.size(); i++) { 
    199204                String meta_name = (String) metadata_names.get(i); 
    200205        String value = getMetadata(node_id, info, meta_name, lang); 
     206 
     207        // Remove the occurrence (if any) in this metaname of the mdoffset number in the pattern <offset\d*_> 
     208        // Leaving string "offset" in at this point: it will be handled in config_format.xsl's gsf:metadata template match 
     209        Matcher matcher = pattern.matcher(meta_name); 
     210        meta_name = matcher.replaceFirst("offset" + GSConstants.META_RELATION_SEP);  
     211            //replaceFirst(""); // if removing the occurrence (if any) of entire pattern <offset\d*_> in input       
     212 
    201213        GSXML.addMetadata(this.doc, metadata_list, meta_name, value); 
    202214        } 
     
    317329    protected String getMetadata(String node_id, DBInfo info,  
    318330                 String metadata, String lang) { 
    319     boolean multiple = false; 
     331    String multiple = "false"; // multiple can now be "true", "false" or "offset<number>". It's no longer a boolean 
    320332    String relation = ""; 
    321333    String separator = ", "; 
     
    346358    metadata = metadata.substring(pos+1); 
    347359    // check for all on the front 
    348     if (temp.equals("all")) { 
    349         multiple=true;       
     360    if (temp.equals("all") || temp.startsWith("offset")) { // multiple can now be "true", "false" or "offset" 
     361        multiple = temp; // multiple=true; 
    350362        pos = metadata.indexOf(GSConstants.META_RELATION_SEP); 
    351363        if (pos ==-1) { 
     
    399411    StringBuffer result = new StringBuffer(); 
    400412 
    401     if (!multiple) { 
     413    if (multiple.equals("false")) { 
    402414        result.append(this.macro_resolver.resolve(relation_info.getInfo(metadata), lang, MacroResolver.SCOPE_META, relation_id)); 
    403     } else { 
    404         // we have multiple meta 
     415    } else if(multiple.startsWith("offset")) { // multiple = offset 
     416        String offset = multiple.substring("offset".length(), multiple.length()); 
     417        int offsetVal = offset.equals("") ? 0 : Integer.parseInt(offset); 
     418        String value = relation_info.getInfoOffset(metadata, offsetVal); // what if this metadata is not the one we need to get the offset for? MDTYPE! 
     419           // at the moment, do we assume the user will specify retrieving the offset only for such metadata as has an offset?  
     420           // At least, getInfoOffset will return the firstelement if the offset exceeds the bounds of the values for this metadata key 
     421 
     422        result.append(this.macro_resolver.resolve(value, lang, MacroResolver.SCOPE_META, relation_id)); 
     423         
     424    } else { // multiple = true, we have multiple meta       
    405425        Vector values = relation_info.getMultiInfo(metadata); 
    406         if (values != null) { 
     426        if (values != null) { 
    407427        boolean first = true; 
    408428        for (int i=0; i<values.size(); i++) { 
     
    415435        } 
    416436        } 
    417           logger.info(result);  
     437        logger.info(result); 
    418438    } 
    419439    // if not ancestors, then this is all we do 
     
    428448        relation_info = this.coll_db.getInfo(relation_id); 
    429449        if (relation_info == null) return result.toString(); 
    430         if (!multiple) { 
     450        if (multiple.equals("false")) { //if (!multiple) 
    431451        result.insert(0, separator); 
    432452        result.insert(0, this.macro_resolver.resolve(relation_info.getInfo(metadata), lang, MacroResolver.SCOPE_META, relation_id)); 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/GS2Browse.java

    r22974 r24254  
    175175 
    176176    } 
     177    /** returns a list of the mdoffset values in order for the children, null is  
     178      * returned if there are no children or if the mdoffset field is empty */ 
     179    protected ArrayList getOffsetsForChildrenIds(String node_id) {  
     180    DBInfo info = this.coll_db.getInfo(node_id); 
     181    if (info == null) { 
     182        return null; 
     183    } 
     184     
     185    ArrayList childrenOffsets = new ArrayList(); 
     186     
     187    String offset = info.getInfo("mdoffset").trim(); 
     188    if(offset.equals("")) { 
     189        return null; 
     190    } 
     191    StringTokenizer st = new StringTokenizer(offset, ";"); 
     192    while (st.hasMoreTokens()) { 
     193        String val = st.nextToken().trim(); 
     194        childrenOffsets.add(Integer.valueOf(val)); 
     195    } 
     196    return childrenOffsets; 
     197    } 
     198 
    177199    /** returns the node id of the parent node, null if no parent */ 
    178200    protected String getParentId(String node_id){ 
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/DBInfo.java

    r16869 r24254  
    5353    } 
    5454 
     55    /** get the value for the key at offset. If offset out of bounds, 
     56     * just return the first one. */ 
     57    public String getInfoOffset(String key, int offset) { 
     58    Vector items = (Vector)info_map_.get(key); 
     59    if (items==null) { 
     60        return ""; 
     61    } 
     62    if(offset >= 0 && offset < items.size()) { 
     63        return (String)items.get(offset); 
     64    } // else 
     65    return (String)items.firstElement(); 
     66    } 
     67 
     68 
    5569    // methods for keys that can have multiple values 
    5670     
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java

    r24221 r24254  
    157157  public static final String NODE_TYPE_INTERNAL = "internal"; 
    158158  public static final String NODE_TYPE_LEAF = "leaf"; 
     159  public static final String NODE_MDOFFSET_ATT = "mdoffset"; 
    159160   
    160161  public static final String DOC_TYPE_SIMPLE = "simple"; 
     
    10391040      StringWriter sw = new StringWriter(); 
    10401041      trans.transform(new DOMSource(e), new StreamResult(sw)); 
    1041       System.err.println( sw.toString() ); 
     1042      System.err.println( sw.toString() ); // logger.info( sw.toString() ); 
    10421043    } catch( Exception ex ) { 
    10431044      System.err.println( "couldn't write " + e + " to log" ); 
  • main/trunk/greenstone3/web/interfaces/default/transform/config_format.xsl

    r24227 r24254  
    3434    <a><xslt:attribute name='href'><xslt:value-of select='$library_name'/>?a=b&amp;rt=r&amp;s=<xslt:value-of select='$serviceName'/>&amp;c=<xslt:value-of select='$collName'/>&amp;cl=<xslt:value-of select='@nodeID'/><xslt:if test="classifierNode|documentNode">.pr</xslt:if><xslt:if test="parent::node()[@orientation='horizontal']">&amp;sib=1</xslt:if></xslt:attribute> 
    3535      <xsl:apply-templates/> 
    36     </a> 
     36    </a>     
    3737      </xsl:when> 
    3838      <xsl:when test="@type='source'"> 
     
    112112 
    113113  <xsl:template match="gsf:metadata" mode="get-metadata-name"> 
    114     <xsl:if test="@multiple='true'">all_</xsl:if><xsl:if test='@select'><xsl:value-of select='@select'/>_</xsl:if><xsl:if test="@separator">*<xsl:value-of select='@separator'/>*_</xsl:if><xsl:value-of select="@name"/> 
     114    <xsl:if test="@multiple='true'">all_</xsl:if><xsl:if test="starts-with(@multiple,'offset')"><xsl:value-of select='@multiple'/>_</xsl:if><xsl:if test='@select'><xsl:value-of select='@select'/>_</xsl:if><xsl:if test="@separator">*<xsl:value-of select='@separator'/>*_</xsl:if><xsl:value-of select="@name"/> 
    115115  </xsl:template> 
    116116