Index: /trunk/gsdl3/src/java/org/greenstone/gsdl3/action/BrowseAction.java
===================================================================
--- /trunk/gsdl3/src/java/org/greenstone/gsdl3/action/BrowseAction.java	(revision 3893)
+++ /trunk/gsdl3/src/java/org/greenstone/gsdl3/action/BrowseAction.java	(revision 3894)
@@ -5,4 +5,5 @@
 // XML classes
 import org.w3c.dom.Node; 
+import org.w3c.dom.NodeList; 
 import org.w3c.dom.Document; 
 import org.w3c.dom.Element; 
@@ -51,4 +52,8 @@
 	Document style_doc = converter_.getDOM(new File(stylesheet));
 
+	// the first part of the data for the page is the cgi-params
+	Element cgi_request = (Element)doc_.importNode(request, true);
+	page.appendChild(cgi_request);
+
 	// extract the params from the cgi-request, and check that we have a coll specified
 	Element cgi_paramList = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
@@ -62,71 +67,221 @@
 	   
 	}
-
-	// get the service info from the MR - this will probably need to be cached somehow later on. 
-
-	Element mr_info_message = doc_.createElement(GSXML.MESSAGE_ELEM);
-	Element mr_info_request = doc_.createElement(GSXML.REQUEST_ELEM);
-	mr_info_message.appendChild(mr_info_request);
-	mr_info_request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_DESCRIBE);
-	mr_info_request.setAttribute(GSXML.LANG_ATT, request.getAttribute(GSXML.LANG_ATT));
-
-	String to = collection;
-	to = GSPath.appendLink(to, service_name);
-	mr_info_request.setAttribute(GSXML.TO_ATT, to);
-
-	Element mr_info_response = (Element) mr_.process(mr_info_message);
-
-	String path = GSXML.RESPONSE_ELEM;
-	path = GSPath.appendLink(path, GSXML.SERVICE_ELEM);
-
-	Element description = (Element)doc_.importNode(GSXML.getNodeByPath(mr_info_response, path), true);
-	
-	// the first part of the data for the page is the cgi-params
-	Element cgi_request = (Element)doc_.importNode(request, true);
-	page.appendChild(cgi_request);
-
+	
+	String lang = request.getAttribute(GSXML.LANG_ATT);
+	String to = GSPath.appendLink(collection, service_name);
+	
+	// the second part of the page is the service description 
+	// for now get this again from the service. 
+	// this will probably need to be cached somehow later on. 
+	
+	Element info_message = createDescribeRequest(to, lang, null); 
+	Element info_response = (Element) mr_.process(info_message);
+	String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.SERVICE_ELEM);
+	Element description = (Element)doc_.importNode(GSXML.getNodeByPath(info_response, path), true);
 	page.appendChild(description);
-	
-	// if there is a cl field in the cgi params, get the classifier info
-	String node = (String)params.get(CLASSIFIER_ARG);
-	
-	if (node!=null && !node.equals("")) {
-
-	    // get the info for the selected node
-	    Element mr_query_message = doc_.createElement(GSXML.MESSAGE_ELEM);
-	    Element mr_query_request = doc_.createElement(GSXML.REQUEST_ELEM);
-	    mr_query_message.appendChild(mr_query_request);
-	    
-	    mr_query_request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_QUERY);
-	    mr_query_request.setAttribute(GSXML.TO_ATT, to);
-	    mr_query_request.setAttribute(GSXML.LANG_ATT, request.getAttribute(GSXML.LANG_ATT));
-	    
-	    
-	    // paramList - empty for now
-	    Element paramList = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
-	    mr_query_request.appendChild(paramList);
-	    
-	    Element document_list = doc_.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
-	    Element document = doc_.createElement(GSXML.CLASS_NODE_ELEM);
-	    document.setAttribute(GSXML.CLASS_NODE_ID_ATT, node);
-	    document_list.appendChild(document);
-	    mr_query_request.appendChild(document_list);
-	    
-	    Element mr_query_response = (Element)mr_.process(mr_query_message);
-	    
-	    Element response = (Element)GSXML.getChildByTagName(mr_query_response, GSXML.RESPONSE_ELEM);
-	    Node new_style = GSXML.getChildByTagName(response, GSXML.STYLESHEET_ELEM);
-	    if (new_style !=null) {
-		GSXSLT.mergeStylesheets(style_doc, (Element)new_style);
-		response.removeChild(new_style);
-	    }
-	    // add the response to the page data
-	    page.appendChild(doc_.importNode(response, true));
-
-	}
-	
+
+
+//  	Element info_message = doc_.createElement(GSXML.MESSAGE_ELEM);
+//  	Element info_request = doc_.createElement(GSXML.REQUEST_ELEM);
+//  	info_message.appendChild(info_request);
+//  	info_request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_DESCRIBE);
+//  	info_request.setAttribute(GSXML.LANG_ATT, request.getAttribute(GSXML.LANG_ATT));
+	
+//  	String to = collection;
+//  	to = GSPath.appendLink(to, service_name);
+//  	info_request.setAttribute(GSXML.TO_ATT, to);
+	
+	
+	// the main response for the page is in a response element
+	Element response = doc_.createElement(GSXML.RESPONSE_ELEM);
+	page.appendChild(response);
+	
+	// get the node that the user has clicked on
+	String classifier_node = (String)params.get(CLASSIFIER_ARG);
+	
+	// if the node is not defined, return the page that we have so far
+	if (classifier_node ==null || classifier_node.equals("")) {
+	    GSXSLT.absoluteIncludePaths(style_doc, config_);
+	    return (Element)transformer_.transform(style_doc, page);
+	}
+	
+	
+	// create a classifier elem to return in the page
+	Element page_classifier = doc_.createElement(GSXML.CLASSIFIER_ELEM);
+	response.appendChild(page_classifier);
+
+	// the id of the classifier is the top id of the selected node
+	String top_id = OID.getTop(classifier_node);
+	page_classifier.setAttribute(GSXML.NAME_ATT, top_id);
+	    
+	// get the browse structure for the selected node
+	Element classify_message = doc_.createElement(GSXML.MESSAGE_ELEM);
+	Element classify_request = doc_.createElement(GSXML.REQUEST_ELEM);
+	classify_message.appendChild(classify_request);
+	    
+	classify_request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
+	classify_request.setAttribute(GSXML.TO_ATT, to);
+	classify_request.setAttribute(GSXML.LANG_ATT, lang);
+	
+	    
+	//Create a parameter list to specify the required structure information
+	// for now, always get ancestors and children
+	Element param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	classify_request.appendChild(param_list);
+	Element param = doc_.createElement(GSXML.PARAM_ELEM);
+	param_list.appendChild(param);
+	param.setAttribute(GSXML.NAME_ATT, "structure");
+	param.setAttribute(GSXML.VALUE_ATT, "ancestors");
+	param = doc_.createElement(GSXML.PARAM_ELEM);
+	param_list.appendChild(param);
+	param.setAttribute(GSXML.NAME_ATT, "structure");
+	param.setAttribute(GSXML.VALUE_ATT, "children");
+
+	// put the classifier node into a classifier node list
+	Element classifier_list = doc_.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
+	Element classifier = doc_.createElement(GSXML.CLASS_NODE_ELEM);
+	classifier.setAttribute(GSXML.NODE_ID_ATT, classifier_node);
+	classifier_list.appendChild(classifier);
+	classify_request.appendChild(classifier_list);
+	    
+	// process the request
+	Element classify_response = (Element)mr_.process(classify_message);
+	// get the structure element
+	path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
+	path = GSPath.appendLink(path, GSXML.CLASS_NODE_ELEM);
+	path = GSPath.appendLink(path, GSXML.DOC_NODE_STRUCTURE_ELEM);
+	// assume that we always get back the top level CL1 node - want to throw this away
+	path = GSPath.appendLink(path, GSXML.CLASS_NODE_ELEM);
+	Element cl_structure = (Element)GSXML.getNodeByPath(classify_response,
+							    path);
+	if (cl_structure ==null) {
+	    System.out.println("BrowseAction: classifier structure request returned no structure");
+		
+	    // return the page so far
+	    GSXSLT.absoluteIncludePaths(style_doc, config_);
+	    return (Element)transformer_.transform(style_doc, page);
+	}   
+    
+	// add the classifier nodes from the structure request into teh page_classifier
+	NodeList cl_nodes = cl_structure.getChildNodes();
+	for (int i=0; i<cl_nodes.getLength(); i++) {
+	    Node n = cl_nodes.item(i);
+	    if (n.getNodeType() == Node.TEXT_NODE) {
+		// ignore
+		continue;
+	    }
+	    page_classifier.appendChild(doc_.importNode(n, true));
+	}
+
+	// get the metadata for each classifier node, 
+	// then for each document node
+	Element metadata_message = doc_.createElement(GSXML.MESSAGE_ELEM);
+
+	boolean did_classifier = false;
+	boolean did_documents = false;
+	
+	// Create a parameter list to specify the required metadata information
+	// for now get Title
+	Element meta_param_list = doc_.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
+	Element meta_param = doc_.createElement(GSXML.PARAM_ELEM);
+	meta_param_list.appendChild(meta_param);
+	meta_param.setAttribute(GSXML.NAME_ATT, "metadata");
+	meta_param.setAttribute(GSXML.VALUE_ATT, "Title");
+	    
+	// if there are classifier nodes (I think there always will be) 
+	// create a metadata request for the classifier, and add it to 
+	// the the message
+	cl_nodes = page_classifier.getElementsByTagName(GSXML.CLASS_NODE_ELEM);
+	    
+	if (cl_nodes.getLength() > 0) {
+	    did_classifier = true;
+	    Element cl_meta_request = doc_.createElement(GSXML.REQUEST_ELEM);
+	    metadata_message.appendChild(cl_meta_request);
+	    cl_meta_request.setAttribute(GSXML.TO_ATT, to+"MetadataRetrieve");
+	    cl_meta_request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
+	    cl_meta_request.setAttribute(GSXML.LANG_ATT, lang);
+	    
+	    cl_meta_request.appendChild(meta_param_list);
+	    
+	    Element new_cl_nodes_list = doc_.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
+	    cl_meta_request.appendChild(new_cl_nodes_list);
+	    
+	    for (int c=0; c<cl_nodes.getLength(); c++) {
+
+		Element cl = doc_.createElement(GSXML.CLASS_NODE_ELEM);
+		cl.setAttribute(GSXML.NODE_ID_ATT, ((Element)cl_nodes.item(c)).getAttribute(GSXML.NODE_ID_ATT));
+		new_cl_nodes_list.appendChild(cl);
+	    }
+	}
+	
+	// if there are document nodes in the classification (happens 
+	// sometimes), create a second request for document metadata and 
+	// append to the message
+	NodeList doc_nodes = page_classifier.getElementsByTagName(GSXML.DOC_NODE_ELEM);
+	if (doc_nodes.getLength() > 0) {
+	    did_documents = true;
+	    Element doc_meta_request = doc_.createElement(GSXML.REQUEST_ELEM);
+	    metadata_message.appendChild(doc_meta_request);
+	    doc_meta_request.setAttribute(GSXML.TO_ATT, GSPath.appendLink(collection, "DocumentMetadataRetrieve"));
+	    doc_meta_request.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
+	    doc_meta_request.setAttribute(GSXML.LANG_ATT, lang);
+	    
+	    // for now, use the same metadata list - this will probably change once we look at format statements
+	    doc_meta_request.appendChild(meta_param_list.cloneNode(true));
+	    
+	    Element doc_list = doc_.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
+	    doc_meta_request.appendChild(doc_list);
+	    
+	    for (int c=0; c<doc_nodes.getLength(); c++) {
+		
+		Element d = doc_.createElement(GSXML.DOC_NODE_ELEM);
+		d.setAttribute(GSXML.NODE_ID_ATT, ((Element)doc_nodes.item(c)).getAttribute(GSXML.NODE_ID_ATT));
+		doc_list.appendChild(d);
+	    }
+
+	}
+
+	// process the metadata requests
+	Element metadata_response = (Element)mr_.process(metadata_message);
+	if (did_classifier) {
+	    // the classifier one will be the first response
+	    // add the metadata lists for each node back into the 
+	    // page_classifier nodes
+	    path = GSPath.appendLink(GSXML.RESPONSE_ELEM, 
+				   GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
+	    NodeList meta_response_cls = GSXML.getNodeByPath(metadata_response, path).getChildNodes();
+	    for (int i = 0; i < cl_nodes.getLength(); i++) {
+		GSXML.mergeMetadataLists(cl_nodes.item(i), meta_response_cls.item(i));
+	    }
+	}
+	if (did_documents) {
+	    NodeList meta_response_docs = null;
+	    if (!did_classifier) {
+		// its the first response
+		path = GSPath.appendLink(GSXML.RESPONSE_ELEM, 
+					 GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
+		meta_response_docs = GSXML.getNodeByPath(metadata_response, path).getChildNodes();
+	    } else { // its the second response
+		meta_response_docs = GSXML.getChildByTagName(metadata_response.getElementsByTagName(GSXML.RESPONSE_ELEM).item(1), GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER).getChildNodes();
+	    }
+	    
+	    for (int i = 0; i < doc_nodes.getLength(); i++) {
+		GSXML.mergeMetadataLists(doc_nodes.item(i), meta_response_docs.item(i));
+	    }
+	}
+	    
+	
+	//Node new_style = GSXML.getChildByTagName(response, GSXML.STYLESHEET_ELEM);
+	//if (new_style !=null) {
+	//	GSXSLT.mergeStylesheets(style_doc, (Element)new_style);
+	//	response.removeChild(new_style);
+	//}
+	// add the response to the page data
+	//page.appendChild(doc_.importNode(response, true));
+	
+	
+	// transform the page
 	GSXSLT.absoluteIncludePaths(style_doc, config_);
-
-	//System.out.println("page=");
+	//System.out.println("browse page=");
 	//System.out.println(converter_.getString(page));
 	return (Element)transformer_.transform(style_doc, page);
