Changeset 24990

Show
Ignore:
Timestamp:
26.01.2012 11:37:58 (8 years ago)
Author:
sjm84
Message:

Reformatting this file ahead of some changes

Files:
1 modified

Legend:

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

    r24889 r24990  
    44import org.greenstone.gsdl3.util.*; 
    55// XML classes 
    6 import org.w3c.dom.Node;  
    7 import org.w3c.dom.NodeList;  
    8 import org.w3c.dom.Document;  
    9 import org.w3c.dom.Element;  
     6import org.w3c.dom.Node; 
     7import org.w3c.dom.NodeList; 
     8import org.w3c.dom.Document; 
     9import org.w3c.dom.Element; 
    1010 
    1111import java.util.HashMap; 
     
    1717 
    1818/** action for GS2 style classifier browsing */ 
    19 public class GS2BrowseAction extends Action { 
    20      
    21     public static final String CLASSIFIER_ARG = "cl"; 
    22  
    23     static Logger logger = Logger.getLogger(org.greenstone.gsdl3.action.GS2BrowseAction.class.getName());     
    24  
    25     /** process the request */ 
    26     public Node process (Node message_node) { 
    27  
    28     Element message = this.converter.nodeToElement(message_node); 
    29  
    30     // get the request - assume only one 
    31     Element request = (Element)GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM); 
    32  
    33     // the result 
    34     Element result = this.doc.createElement(GSXML.MESSAGE_ELEM); 
    35     Element response = classifierBrowse(request); 
    36     result.appendChild(response); 
    37     return result; 
    38     } 
    39      
    40  
    41     protected Element classifierBrowse(Element request) { 
    42  
    43     Element page_response = this.doc.createElement(GSXML.RESPONSE_ELEM); 
    44  
    45     // extract the params from the cgi-request, and check that we have a coll specified 
    46     Element cgi_paramList = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER); 
    47     HashMap params = GSXML.extractParams(cgi_paramList, false); 
    48      
    49     String service_name = (String)params.get(GSParams.SERVICE); 
    50     String collection = (String)params.get(GSParams.COLLECTION); 
    51     if (collection == null || collection.equals("")) { 
    52         logger.error("classifierBrowse, need to specify a collection!"); 
    53         return page_response; 
    54         
     19public class GS2BrowseAction extends Action 
     20{ 
     21 
     22    public static final String CLASSIFIER_ARG = "cl"; 
     23 
     24    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.action.GS2BrowseAction.class.getName()); 
     25 
     26    /** process the request */ 
     27    public Node process(Node message_node) 
     28    { 
     29 
     30        Element message = this.converter.nodeToElement(message_node); 
     31 
     32        // get the request - assume only one 
     33        Element request = (Element) GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM); 
     34 
     35        // the result 
     36        Element result = this.doc.createElement(GSXML.MESSAGE_ELEM); 
     37        Element response = classifierBrowse(request); 
     38        result.appendChild(response); 
     39        return result; 
    5540    } 
    56      
    57     String lang = request.getAttribute(GSXML.LANG_ATT); 
    58     String uid = request.getAttribute(GSXML.USER_ID_ATT); 
    59     String to = GSPath.appendLink(collection, service_name); 
    60      
    61     // the first part of the response is the service description  
    62     // for now get this again from the service.  
    63     // this should be cached somehow later on.  
    64      
    65     Element info_message = this.doc.createElement(GSXML.MESSAGE_ELEM); 
    66     Element info_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, to, lang, uid);  
    67     info_message.appendChild(info_request); 
    68      
    69     // also get the format stuff now if there is some 
    70     Element format_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_FORMAT, to, lang, uid); 
    71     info_message.appendChild(format_request); 
    72     // process the requests 
    73  
    74     Element info_response = (Element) this.mr.process(info_message); 
    75  
    76     // the two responses 
    77     NodeList responses = info_response.getElementsByTagName(GSXML.RESPONSE_ELEM); 
    78     Element service_response = (Element)responses.item(0); 
    79     Element format_response = (Element)responses.item(1); 
    80  
    81     Element service_description = (Element)GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM); 
    82     page_response.appendChild(this.doc.importNode(service_description, true)); 
    83      
    84     //append site metadata 
    85     addSiteMetadata( page_response, lang, uid); 
    86  
    87     // if rt=d, then we are just displaying the service 
    88     String request_type = (String)params.get(GSParams.REQUEST_TYPE); 
    89     if (request_type.equals("d")) { 
    90         //return the page that we have so far 
    91         return page_response; 
     41 
     42    protected Element classifierBrowse(Element request) 
     43    { 
     44 
     45        Element page_response = this.doc.createElement(GSXML.RESPONSE_ELEM); 
     46 
     47        // extract the params from the cgi-request, and check that we have a coll specified 
     48        Element cgi_paramList = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER); 
     49        HashMap params = GSXML.extractParams(cgi_paramList, false); 
     50 
     51        String service_name = (String) params.get(GSParams.SERVICE); 
     52        String collection = (String) params.get(GSParams.COLLECTION); 
     53        if (collection == null || collection.equals("")) 
     54        { 
     55            logger.error("classifierBrowse, need to specify a collection!"); 
     56            return page_response; 
     57 
     58        } 
     59 
     60        String lang = request.getAttribute(GSXML.LANG_ATT); 
     61        String uid = request.getAttribute(GSXML.USER_ID_ATT); 
     62        String to = GSPath.appendLink(collection, service_name); 
     63 
     64        // the first part of the response is the service description  
     65        // for now get this again from the service.  
     66        // this should be cached somehow later on.  
     67 
     68        Element info_message = this.doc.createElement(GSXML.MESSAGE_ELEM); 
     69        Element info_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, to, lang, uid); 
     70        info_message.appendChild(info_request); 
     71 
     72        // also get the format stuff now if there is some 
     73        Element format_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_FORMAT, to, lang, uid); 
     74        info_message.appendChild(format_request); 
     75        // process the requests 
     76 
     77        Element info_response = (Element) this.mr.process(info_message); 
     78 
     79        // the two responses 
     80        NodeList responses = info_response.getElementsByTagName(GSXML.RESPONSE_ELEM); 
     81        Element service_response = (Element) responses.item(0); 
     82        Element format_response = (Element) responses.item(1); 
     83 
     84        Element service_description = (Element) GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM); 
     85        page_response.appendChild(this.doc.importNode(service_description, true)); 
     86 
     87        //append site metadata 
     88        addSiteMetadata(page_response, lang, uid); 
     89 
     90        // if rt=d, then we are just displaying the service 
     91        String request_type = (String) params.get(GSParams.REQUEST_TYPE); 
     92        if (request_type.equals("d")) 
     93        { 
     94            //return the page that we have so far 
     95            return page_response; 
     96        } 
     97 
     98        // get the node that the user has clicked on 
     99        String classifier_node = (String) params.get(CLASSIFIER_ARG); 
     100 
     101        // if the node is not defined, return the page that we have so far 
     102        if (classifier_node == null || classifier_node.equals("")) 
     103        { 
     104            return page_response; 
     105        } 
     106 
     107        // the id of the classifier is the top id of the selected node 
     108        String top_id = OID.getTop(classifier_node); 
     109        HashSet doc_meta_names = new HashSet(); 
     110        HashSet class_meta_names = new HashSet(); 
     111        // add in the defaults 
     112        doc_meta_names.add("Title"); 
     113        class_meta_names.add("Title"); 
     114 
     115        // add the format info into the response 
     116        Element format_elem = (Element) GSXML.getChildByTagName(format_response, GSXML.FORMAT_ELEM); 
     117        if (format_elem != null) 
     118        { 
     119 
     120            // find the one for the classifier we are in 
     121            Element this_format = GSXML.getNamedElement(format_elem, GSXML.CLASSIFIER_ELEM, GSXML.NAME_ATT, top_id); 
     122            if (this_format == null) 
     123            { 
     124                this_format = (Element) GSXML.getChildByTagName(format_elem, GSXML.DEFAULT_ELEM); 
     125            } 
     126 
     127            if (this_format != null) 
     128            { 
     129                Element new_format = GSXML.duplicateWithNewName(this.doc, this_format, GSXML.FORMAT_ELEM, false); 
     130                extractMetadataNames(new_format, doc_meta_names, class_meta_names); 
     131                // set the format type 
     132                new_format.setAttribute(GSXML.TYPE_ATT, "browse"); 
     133 
     134                page_response.appendChild(new_format); 
     135            } 
     136        } 
     137 
     138        // find out if this classifier is horizontal at top 
     139        Element class_list = (Element) GSXML.getChildByTagName(service_description, GSXML.CLASSIFIER_ELEM + GSXML.LIST_MODIFIER); 
     140        Element this_classifier = GSXML.getNamedElement(class_list, GSXML.CLASSIFIER_ELEM, GSXML.NAME_ATT, top_id); 
     141        boolean horizontal_at_top = false; 
     142        if (!this_classifier.getAttribute("horizontalAtTop").equals("")) 
     143        { 
     144            horizontal_at_top = true; 
     145        } 
     146        if (top_id.equals(classifier_node) && horizontal_at_top) 
     147        { 
     148            // we have asked for a top node - if the first list is horizontal, we will select the first element of that list 
     149            // this is a hack. also it craps out if the classifier really isn't horizontalAtTop. -  
     150            classifier_node = classifier_node + ".1"; 
     151 
     152        } 
     153 
     154        // get the browse structure for the selected node 
     155        Element classify_message = this.doc.createElement(GSXML.MESSAGE_ELEM); 
     156        Element classify_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid); 
     157        classify_message.appendChild(classify_request); 
     158 
     159        //Create a parameter list to specify the required structure information 
     160        // for now, always get ancestors and children 
     161        Element param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER); 
     162        classify_request.appendChild(param_list); 
     163        Element param = this.doc.createElement(GSXML.PARAM_ELEM); 
     164        param_list.appendChild(param); 
     165        param.setAttribute(GSXML.NAME_ATT, "structure"); 
     166        param.setAttribute(GSXML.VALUE_ATT, "ancestors"); 
     167        param = this.doc.createElement(GSXML.PARAM_ELEM); 
     168        param_list.appendChild(param); 
     169        param.setAttribute(GSXML.NAME_ATT, "structure"); 
     170        param.setAttribute(GSXML.VALUE_ATT, "children"); 
     171 
     172        // put the classifier node into a classifier node list 
     173        Element classifier_list = this.doc.createElement(GSXML.CLASS_NODE_ELEM + GSXML.LIST_MODIFIER); 
     174        Element classifier = this.doc.createElement(GSXML.CLASS_NODE_ELEM); 
     175        classifier.setAttribute(GSXML.NODE_ID_ATT, classifier_node); 
     176        classifier_list.appendChild(classifier); 
     177        classify_request.appendChild(classifier_list); 
     178 
     179        if (horizontal_at_top && !classifier_node.equals(top_id)) 
     180        { 
     181            // also put the top id in, to get the persistant horizontal info 
     182            classifier = this.doc.createElement(GSXML.CLASS_NODE_ELEM); 
     183            classifier.setAttribute(GSXML.NODE_ID_ATT, top_id); 
     184            classifier_list.appendChild(classifier); 
     185        } 
     186        // process the request 
     187        Element classify_response = (Element) this.mr.process(classify_message); 
     188        String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.CLASS_NODE_ELEM + GSXML.LIST_MODIFIER); 
     189        Element class_node_list = (Element) GSXML.getNodeByPath(classify_response, path); 
     190 
     191        path = GSPath.appendLink(GSXML.CLASS_NODE_ELEM, GSXML.NODE_STRUCTURE_ELEM); 
     192        // assume that we always get back the top level CL1 node - this becomes the page_classifier node 
     193        path = GSPath.appendLink(path, GSXML.CLASS_NODE_ELEM); 
     194        Element cl_structure = (Element) GSXML.getNodeByPath(class_node_list, path); 
     195        if (cl_structure == null) 
     196        { 
     197            logger.error("classifier structure request returned no structure"); 
     198            return page_response; 
     199        } 
     200 
     201        Element page_classifier = null; 
     202        if (horizontal_at_top && !classifier_node.equals(top_id)) 
     203        { 
     204            // get the info for the top node 
     205            Element top_node = GSXML.getNamedElement(class_node_list, GSXML.CLASS_NODE_ELEM, GSXML.NODE_ID_ATT, top_id); 
     206            if (top_node != null) 
     207            { 
     208                path = GSPath.appendLink(GSXML.NODE_STRUCTURE_ELEM, GSXML.CLASS_NODE_ELEM); 
     209                Element top_structure = (Element) GSXML.getNodeByPath(top_node, path); 
     210                // add this as the classifier elem 
     211                page_classifier = GSXML.duplicateWithNewName(this.doc, top_structure, GSXML.CLASSIFIER_ELEM, true); 
     212                page_response.appendChild(page_classifier); 
     213                // now replace the child with the structure from the other request 
     214                Element new_classifier = (Element) GSXML.getChildByTagName(cl_structure, GSXML.CLASS_NODE_ELEM); 
     215                String replace_name = new_classifier.getAttribute(GSXML.NODE_ID_ATT); 
     216 
     217                // find the appropriate child 
     218                Element old_classifier = GSXML.getNamedElement(page_classifier, GSXML.CLASS_NODE_ELEM, GSXML.NODE_ID_ATT, replace_name); 
     219                page_classifier.replaceChild(this.doc.importNode(new_classifier, true), old_classifier); 
     220                page_classifier.setAttribute(GSXML.NAME_ATT, top_id); 
     221            } 
     222            else 
     223            { 
     224                // add the single classifier node as the page classifier  
     225                page_classifier = GSXML.duplicateWithNewName(this.doc, cl_structure, GSXML.CLASSIFIER_ELEM, true); 
     226                page_response.appendChild(page_classifier); 
     227                page_classifier.setAttribute(GSXML.NAME_ATT, top_id); 
     228            } 
     229 
     230        } 
     231        else 
     232        { 
     233            // add the single classifier node as the page classifier  
     234            page_classifier = GSXML.duplicateWithNewName(this.doc, cl_structure, GSXML.CLASSIFIER_ELEM, true); 
     235            page_response.appendChild(page_classifier); 
     236            page_classifier.setAttribute(GSXML.NAME_ATT, top_id); 
     237        } 
     238        // get the metadata for each classifier node,  
     239        // then for each document node 
     240 
     241        Element metadata_message = this.doc.createElement(GSXML.MESSAGE_ELEM); 
     242 
     243        boolean did_classifier = false; 
     244        boolean did_documents = false; 
     245 
     246        // if there are classifier nodes  
     247        // create a metadata request for the classifier, and add it to  
     248        // the the message 
     249        NodeList cl_nodes = page_classifier.getElementsByTagName(GSXML.CLASS_NODE_ELEM); 
     250 
     251        if (cl_nodes.getLength() > 0) 
     252        { 
     253            did_classifier = true; 
     254            Element cl_meta_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to + "MetadataRetrieve", lang, uid); 
     255            metadata_message.appendChild(cl_meta_request); 
     256 
     257            Element new_cl_nodes_list = this.doc.createElement(GSXML.CLASS_NODE_ELEM + GSXML.LIST_MODIFIER); 
     258            cl_meta_request.appendChild(new_cl_nodes_list); 
     259 
     260            for (int c = 0; c < cl_nodes.getLength(); c++) 
     261            { 
     262 
     263                Element cl = this.doc.createElement(GSXML.CLASS_NODE_ELEM); 
     264                cl.setAttribute(GSXML.NODE_ID_ATT, ((Element) cl_nodes.item(c)).getAttribute(GSXML.NODE_ID_ATT)); 
     265                new_cl_nodes_list.appendChild(cl); 
     266            } 
     267 
     268            // create and add in the param list - for now get all the metadata 
     269            // should be based on info sent in from the recept, and the  
     270            // format stuff 
     271            Element cl_param_list = createMetadataParamList(class_meta_names); 
     272            cl_meta_request.appendChild(cl_param_list); 
     273 
     274        } 
     275 
     276        // if there are document nodes in the classification (happens  
     277        // sometimes), create a second request for document metadata and  
     278        // append to the message 
     279        NodeList doc_nodes = page_classifier.getElementsByTagName(GSXML.DOC_NODE_ELEM); 
     280        if (doc_nodes.getLength() > 0) 
     281        { 
     282            did_documents = true; 
     283            Element doc_meta_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, GSPath.appendLink(collection, "DocumentMetadataRetrieve"), lang, uid); 
     284            metadata_message.appendChild(doc_meta_request); 
     285 
     286            Element doc_list = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER); 
     287            doc_meta_request.appendChild(doc_list); 
     288 
     289            for (int c = 0; c < doc_nodes.getLength(); c++) 
     290            { 
     291 
     292                Element d = this.doc.createElement(GSXML.DOC_NODE_ELEM); 
     293                d.setAttribute(GSXML.NODE_ID_ATT, ((Element) doc_nodes.item(c)).getAttribute(GSXML.NODE_ID_ATT)); 
     294                doc_list.appendChild(d); 
     295            } 
     296 
     297            // create and add in the param list - add all for now 
     298            Element doc_param_list = createMetadataParamList(doc_meta_names); 
     299            doc_meta_request.appendChild(doc_param_list); 
     300 
     301        } 
     302 
     303        // process the metadata requests 
     304        Element metadata_response = (Element) this.mr.process(metadata_message); 
     305        if (did_classifier) 
     306        { 
     307            // the classifier one will be the first response 
     308            // add the metadata lists for each node back into the  
     309            // page_classifier nodes 
     310            path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.CLASS_NODE_ELEM + GSXML.LIST_MODIFIER); 
     311            Node pathNode = GSXML.getNodeByPath(metadata_response, path); 
     312            if (pathNode == null) 
     313            { 
     314                return page_response; 
     315            } 
     316            //NodeList meta_response_cls = (Element)pathNode.getChildNodes(); // can't handle empty elements from converting formatted strings (with empty newlines) into XML 
     317            NodeList meta_response_cls = ((Element) pathNode).getElementsByTagName(GSXML.CLASS_NODE_ELEM); 
     318            for (int i = 0; i < cl_nodes.getLength(); i++) 
     319            { 
     320                GSXML.mergeMetadataLists(cl_nodes.item(i), meta_response_cls.item(i)); 
     321            } 
     322        } 
     323 
     324        if (did_documents) 
     325        { 
     326            NodeList meta_response_docs = null; 
     327            if (!did_classifier) 
     328            { 
     329                // its the first response 
     330                path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER); 
     331                Node pathNode = GSXML.getNodeByPath(metadata_response, path); 
     332                if (pathNode == null) 
     333                { 
     334                    return page_response; 
     335                } 
     336 
     337                meta_response_docs = pathNode.getChildNodes(); 
     338 
     339            } 
     340            else 
     341            { // its the second response 
     342                Node nodes = GSXML.getChildByTagName(metadata_response.getElementsByTagName(GSXML.RESPONSE_ELEM).item(1), GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER); 
     343                if (nodes == null) 
     344                { 
     345                    return page_response; 
     346                } 
     347                meta_response_docs = nodes.getChildNodes(); 
     348            } 
     349 
     350            for (int i = 0; i < doc_nodes.getLength(); i++) 
     351            { 
     352                GSXML.mergeMetadataLists(doc_nodes.item(i), meta_response_docs.item(i)); 
     353            } 
     354        } 
     355 
     356        logger.debug("(GS2BrowseAction) Page:\n" + this.converter.getPrettyString(page_response)); 
     357        return page_response; 
    92358    } 
    93      
    94     // get the node that the user has clicked on 
    95     String classifier_node = (String)params.get(CLASSIFIER_ARG); 
    96      
    97     // if the node is not defined, return the page that we have so far 
    98     if (classifier_node ==null || classifier_node.equals("")) { 
    99         return page_response; 
     359 
     360    protected void extractMetadataNames(Element new_format, HashSet doc_meta_names, HashSet class_meta_names) 
     361    { 
     362 
     363        NodeList templates = new_format.getElementsByTagName("gsf:template"); 
     364        for (int i = 0; i < templates.getLength(); i++) 
     365        { 
     366            Element template = (Element) templates.item(i); 
     367            String match = template.getAttribute("match"); 
     368            if (match.equals("documentNode")) 
     369            { 
     370                getRequiredMetadataNames(template, doc_meta_names); 
     371            } 
     372            else if (match.equals("classifierNode")) 
     373            { 
     374                getRequiredMetadataNames(template, class_meta_names); 
     375            } 
     376        } 
    100377    } 
    101      
    102     // the id of the classifier is the top id of the selected node 
    103     String top_id = OID.getTop(classifier_node); 
    104     HashSet doc_meta_names = new HashSet(); 
    105     HashSet class_meta_names = new HashSet(); 
    106     // add in the defaults 
    107     doc_meta_names.add("Title"); 
    108     class_meta_names.add("Title"); 
    109      
    110     // add the format info into the response 
    111     Element format_elem = (Element)GSXML.getChildByTagName(format_response, GSXML.FORMAT_ELEM); 
    112     if (format_elem != null) { 
    113          
    114         // find the one for the classifier we are in 
    115         Element this_format = GSXML.getNamedElement(format_elem, GSXML.CLASSIFIER_ELEM, GSXML.NAME_ATT, top_id); 
    116         if (this_format == null) { 
    117         this_format = (Element)GSXML.getChildByTagName(format_elem, GSXML.DEFAULT_ELEM); 
    118         } 
    119  
    120         if (this_format != null) { 
    121         Element new_format = GSXML.duplicateWithNewName(this.doc, this_format, GSXML.FORMAT_ELEM, false); 
    122         extractMetadataNames(new_format, doc_meta_names, class_meta_names); 
    123         // set the format type 
    124         new_format.setAttribute(GSXML.TYPE_ATT, "browse"); 
    125  
    126         page_response.appendChild(new_format); 
    127         } 
    128     } 
    129      
    130     // find out if this classifier is horizontal at top 
    131     Element class_list = (Element)GSXML.getChildByTagName(service_description, GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER); 
    132     Element this_classifier = GSXML.getNamedElement(class_list, GSXML.CLASSIFIER_ELEM, GSXML.NAME_ATT, top_id); 
    133     boolean horizontal_at_top = false; 
    134     if (!this_classifier.getAttribute("horizontalAtTop").equals("")) { 
    135         horizontal_at_top = true; 
    136     } 
    137     if (top_id.equals(classifier_node) && horizontal_at_top) { 
    138         // we have asked for a top node - if the first list is horizontal, we will select the first element of that list 
    139         // this is a hack. also it craps out if the classifier really isn't horizontalAtTop. -  
    140         classifier_node = classifier_node+".1"; 
    141              
    142     } 
    143  
    144     // get the browse structure for the selected node 
    145     Element classify_message = this.doc.createElement(GSXML.MESSAGE_ELEM); 
    146     Element classify_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid); 
    147     classify_message.appendChild(classify_request); 
    148          
    149     //Create a parameter list to specify the required structure information 
    150     // for now, always get ancestors and children 
    151     Element param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER); 
    152     classify_request.appendChild(param_list); 
    153     Element param = this.doc.createElement(GSXML.PARAM_ELEM); 
    154     param_list.appendChild(param); 
    155     param.setAttribute(GSXML.NAME_ATT, "structure"); 
    156     param.setAttribute(GSXML.VALUE_ATT, "ancestors"); 
    157     param = this.doc.createElement(GSXML.PARAM_ELEM); 
    158     param_list.appendChild(param); 
    159     param.setAttribute(GSXML.NAME_ATT, "structure"); 
    160     param.setAttribute(GSXML.VALUE_ATT, "children"); 
    161  
    162     // put the classifier node into a classifier node list 
    163     Element classifier_list = this.doc.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER); 
    164     Element classifier = this.doc.createElement(GSXML.CLASS_NODE_ELEM); 
    165     classifier.setAttribute(GSXML.NODE_ID_ATT, classifier_node); 
    166     classifier_list.appendChild(classifier); 
    167     classify_request.appendChild(classifier_list); 
    168          
    169     if (horizontal_at_top && !classifier_node.equals(top_id)) { 
    170         // also put the top id in, to get the persistant horizontal info 
    171         classifier = this.doc.createElement(GSXML.CLASS_NODE_ELEM); 
    172         classifier.setAttribute(GSXML.NODE_ID_ATT, top_id); 
    173         classifier_list.appendChild(classifier); 
    174     } 
    175     // process the request 
    176     Element classify_response = (Element)this.mr.process(classify_message); 
    177     String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER); 
    178     Element class_node_list = (Element)GSXML.getNodeByPath(classify_response, path); 
    179      
    180     path = GSPath.appendLink(GSXML.CLASS_NODE_ELEM, GSXML.NODE_STRUCTURE_ELEM); 
    181     // assume that we always get back the top level CL1 node - this becomes the page_classifier node 
    182     path = GSPath.appendLink(path, GSXML.CLASS_NODE_ELEM); 
    183     Element cl_structure = (Element)GSXML.getNodeByPath(class_node_list, 
    184                                 path); 
    185     if (cl_structure ==null) { 
    186         logger.error("classifier structure request returned no structure"); 
    187         return page_response; 
    188     }    
    189      
    190     Element page_classifier = null; 
    191     if (horizontal_at_top && !classifier_node.equals(top_id)) { 
    192         // get the info for the top node 
    193         Element top_node = GSXML.getNamedElement(class_node_list, GSXML.CLASS_NODE_ELEM, GSXML.NODE_ID_ATT, top_id); 
    194         if (top_node !=null) { 
    195         path = GSPath.appendLink(GSXML.NODE_STRUCTURE_ELEM, GSXML.CLASS_NODE_ELEM); 
    196         Element top_structure = (Element)GSXML.getNodeByPath(top_node, path);        
    197         // add this as the classifier elem 
    198         page_classifier = GSXML.duplicateWithNewName(this.doc, top_structure,  GSXML.CLASSIFIER_ELEM, true); 
    199         page_response.appendChild(page_classifier); 
    200         // now replace the child with the structure from the other request 
    201         Element new_classifier = (Element)GSXML.getChildByTagName(cl_structure, GSXML.CLASS_NODE_ELEM); 
    202         String replace_name = new_classifier.getAttribute(GSXML.NODE_ID_ATT); 
    203          
    204         // find the appropriate child 
    205         Element old_classifier = GSXML.getNamedElement(page_classifier, GSXML.CLASS_NODE_ELEM, GSXML.NODE_ID_ATT, replace_name); 
    206         page_classifier.replaceChild(this.doc.importNode(new_classifier, true), old_classifier); 
    207         page_classifier.setAttribute(GSXML.NAME_ATT, top_id); 
    208         } else { 
    209         // add the single classifier node as the page classifier  
    210         page_classifier = GSXML.duplicateWithNewName(this.doc, cl_structure,  GSXML.CLASSIFIER_ELEM, true); 
    211         page_response.appendChild(page_classifier); 
    212         page_classifier.setAttribute(GSXML.NAME_ATT, top_id); 
    213         } 
    214          
    215     } else { 
    216         // add the single classifier node as the page classifier  
    217         page_classifier = GSXML.duplicateWithNewName(this.doc, cl_structure,  GSXML.CLASSIFIER_ELEM, true); 
    218         page_response.appendChild(page_classifier); 
    219         page_classifier.setAttribute(GSXML.NAME_ATT, top_id); 
    220     } 
    221     // get the metadata for each classifier node,  
    222     // then for each document node 
    223  
    224     Element metadata_message = this.doc.createElement(GSXML.MESSAGE_ELEM); 
    225  
    226     boolean did_classifier = false; 
    227     boolean did_documents = false; 
    228      
    229      
    230     // if there are classifier nodes  
    231     // create a metadata request for the classifier, and add it to  
    232     // the the message 
    233     NodeList cl_nodes = page_classifier.getElementsByTagName(GSXML.CLASS_NODE_ELEM); 
    234      
    235     if (cl_nodes.getLength() > 0) { 
    236         did_classifier = true; 
    237         Element cl_meta_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to+"MetadataRetrieve", lang, uid); 
    238         metadata_message.appendChild(cl_meta_request); 
    239          
    240         Element new_cl_nodes_list = this.doc.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER); 
    241         cl_meta_request.appendChild(new_cl_nodes_list); 
    242          
    243         for (int c=0; c<cl_nodes.getLength(); c++) { 
    244  
    245         Element cl = this.doc.createElement(GSXML.CLASS_NODE_ELEM); 
    246         cl.setAttribute(GSXML.NODE_ID_ATT, ((Element)cl_nodes.item(c)).getAttribute(GSXML.NODE_ID_ATT)); 
    247         new_cl_nodes_list.appendChild(cl); 
    248         } 
    249  
    250         // create and add in the param list - for now get all the metadata 
    251         // should be based on info sent in from the recept, and the  
    252         // format stuff 
    253         Element cl_param_list  = createMetadataParamList(class_meta_names); 
    254         cl_meta_request.appendChild(cl_param_list); 
    255          
    256     } 
    257  
    258     // if there are document nodes in the classification (happens  
    259     // sometimes), create a second request for document metadata and  
    260     // append to the message 
    261     NodeList doc_nodes = page_classifier.getElementsByTagName(GSXML.DOC_NODE_ELEM); 
    262     if (doc_nodes.getLength() > 0) { 
    263         did_documents = true; 
    264         Element doc_meta_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, GSPath.appendLink(collection, "DocumentMetadataRetrieve"), lang, uid); 
    265         metadata_message.appendChild(doc_meta_request); 
    266          
    267         Element doc_list = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER); 
    268         doc_meta_request.appendChild(doc_list); 
    269          
    270         for (int c=0; c<doc_nodes.getLength(); c++) { 
    271          
    272         Element d = this.doc.createElement(GSXML.DOC_NODE_ELEM); 
    273         d.setAttribute(GSXML.NODE_ID_ATT, ((Element)doc_nodes.item(c)).getAttribute(GSXML.NODE_ID_ATT)); 
    274         doc_list.appendChild(d); 
    275         } 
    276  
    277         // create and add in the param list - add all for now 
    278         Element doc_param_list  = createMetadataParamList(doc_meta_names); 
    279         doc_meta_request.appendChild(doc_param_list); 
    280  
    281     } 
    282      
    283     // process the metadata requests 
    284     Element metadata_response = (Element)this.mr.process(metadata_message); 
    285     if (did_classifier) { 
    286         // the classifier one will be the first response 
    287         // add the metadata lists for each node back into the  
    288         // page_classifier nodes 
    289         path = GSPath.appendLink(GSXML.RESPONSE_ELEM,  
    290                    GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER); 
    291             Node pathNode = GSXML.getNodeByPath(metadata_response, path); 
    292             if (pathNode ==null){ 
    293             return page_response;  
    294         } 
    295         //NodeList meta_response_cls = (Element)pathNode.getChildNodes(); // can't handle empty elements from converting formatted strings (with empty newlines) into XML 
    296         NodeList meta_response_cls = ((Element)pathNode).getElementsByTagName(GSXML.CLASS_NODE_ELEM); 
    297         for (int i = 0; i < cl_nodes.getLength(); i++) { 
    298         GSXML.mergeMetadataLists(cl_nodes.item(i), meta_response_cls.item(i)); 
    299         } 
    300     } 
    301  
    302     if (did_documents) { 
    303         NodeList meta_response_docs = null; 
    304         if (!did_classifier) { 
    305         // its the first response 
    306         path = GSPath.appendLink(GSXML.RESPONSE_ELEM,  
    307                      GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER); 
    308         Node pathNode = GSXML.getNodeByPath(metadata_response, path); 
    309         if (pathNode ==null){ 
    310             return page_response; 
    311                  } 
    312  
    313         meta_response_docs = pathNode.getChildNodes(); 
    314          
    315  
    316         } else { // its the second response 
    317                 Node nodes = GSXML.getChildByTagName(metadata_response.getElementsByTagName(GSXML.RESPONSE_ELEM).item(1), GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER); 
    318         if (nodes ==null){ 
    319             return page_response; 
    320                  } 
    321         meta_response_docs = nodes.getChildNodes(); 
    322         } 
    323          
    324         for (int i = 0; i < doc_nodes.getLength(); i++) { 
    325         GSXML.mergeMetadataLists(doc_nodes.item(i), meta_response_docs.item(i)); 
    326         } 
    327     } 
    328          
    329  
    330     logger.debug("(GS2BrowseAction) Page:\n" + this.converter.getPrettyString(page_response)); 
    331     return page_response; 
    332     } 
    333  
    334     
    335     protected void extractMetadataNames(Element new_format, HashSet doc_meta_names, HashSet class_meta_names) { 
    336      
    337     NodeList templates = new_format.getElementsByTagName("gsf:template"); 
    338     for (int i=0; i<templates.getLength(); i++) { 
    339         Element template = (Element)templates.item(i); 
    340         String match = template.getAttribute("match"); 
    341         if (match.equals("documentNode")) { 
    342             getRequiredMetadataNames(template, doc_meta_names); 
    343         } else if (match.equals("classifierNode")) { 
    344             getRequiredMetadataNames(template, class_meta_names); 
    345         } 
    346     } 
    347     } 
    348378 
    349379} 
    350  
    351