Changeset 24987


Ignore:
Timestamp:
01/26/12 11:33:15 (9 years ago)
Author:
sjm84
Message:

Reformatting this file ahead of some changes

File:
1 edited

Legend:

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

    r24889 r24987  
    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.Text; 
    9 import org.w3c.dom.Document; 
    10 import org.w3c.dom.Element; 
     6import org.w3c.dom.Node;
     7import org.w3c.dom.NodeList;
     8import org.w3c.dom.Text;
     9import org.w3c.dom.Document;
     10import org.w3c.dom.Element;
    1111
    1212import java.util.HashMap;
     
    2020
    2121/** action class for queries */
    22 public class QueryAction extends Action {
    23 
    24 
    25      static Logger logger = Logger.getLogger(org.greenstone.gsdl3.action.QueryAction.class.getName());
    26    
    27     /** process - processes a request.
    28      */
    29     public Node process (Node message_node) {
    30 
    31     Element message = this.converter.nodeToElement(message_node);
    32 
    33     // get the request - assume there is only one
    34     Element request = (Element)GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
    35 
    36     // create the return message
    37     Element result = this.doc.createElement(GSXML.MESSAGE_ELEM);
    38     Element response = basicQuery(request);
    39     result.appendChild(this.doc.importNode(response, true));
    40     return result;
    41     }
    42    
    43     /** a generic query handler
    44      * this gets the service description, does the query (just passes all the
    45      * params to the service, then gets the titles for any results
    46      */
    47     protected Element basicQuery(Element request) {
    48 
    49     // the result
    50     Element page_response = this.doc.createElement(GSXML.RESPONSE_ELEM);
    51 
    52     // extract the params from the cgi-request, and check that we have a coll specified
    53     Element cgi_param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
    54     HashMap params = GSXML.extractParams(cgi_param_list, false);
    55    
    56     String request_type = (String)params.get(GSParams.REQUEST_TYPE);
    57     String service_name = (String)params.get(GSParams.SERVICE);
    58     String collection = (String)params.get(GSParams.COLLECTION);
    59 
    60     // collection may be null or empty when we are doing cross coll services
    61     if (collection == null || collection.equals("")) {
    62         collection = null;
     22public class QueryAction extends Action
     23{
     24
     25    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.action.QueryAction.class.getName());
     26
     27    /**
     28     * process - processes a request.
     29     */
     30    public Node process(Node message_node)
     31    {
     32
     33        Element message = this.converter.nodeToElement(message_node);
     34
     35        // get the request - assume there is only one
     36        Element request = (Element) GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
     37
     38        // create the return message
     39        Element result = this.doc.createElement(GSXML.MESSAGE_ELEM);
     40        Element response = basicQuery(request);
     41        result.appendChild(this.doc.importNode(response, true));
     42        return result;
    6343    }
    64    
    65     String lang = request.getAttribute(GSXML.LANG_ATT);
    66     String uid = request.getAttribute(GSXML.USER_ID_ATT);
    67     String to = service_name;
    68     if (collection != null) {
    69         to = GSPath.prependLink(to, collection);
     44
     45    /**
     46     * a generic query handler this gets the service description, does the query
     47     * (just passes all the params to the service, then gets the titles for any
     48     * results
     49     */
     50    protected Element basicQuery(Element request)
     51    {
     52
     53        // the result
     54        Element page_response = this.doc.createElement(GSXML.RESPONSE_ELEM);
     55
     56        // extract the params from the cgi-request, and check that we have a coll specified
     57        Element cgi_param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     58        HashMap params = GSXML.extractParams(cgi_param_list, false);
     59
     60        String request_type = (String) params.get(GSParams.REQUEST_TYPE);
     61        String service_name = (String) params.get(GSParams.SERVICE);
     62        String collection = (String) params.get(GSParams.COLLECTION);
     63
     64        // collection may be null or empty when we are doing cross coll services
     65        if (collection == null || collection.equals(""))
     66        {
     67            collection = null;
     68        }
     69
     70        String lang = request.getAttribute(GSXML.LANG_ATT);
     71        String uid = request.getAttribute(GSXML.USER_ID_ATT);
     72        String to = service_name;
     73        if (collection != null)
     74        {
     75            to = GSPath.prependLink(to, collection);
     76        }
     77
     78        if (request_type.indexOf("d") != -1)
     79        {
     80            // we have been asked for the service description
     81            Element mr_info_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
     82            Element mr_info_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, to, lang, uid);
     83            mr_info_message.appendChild(mr_info_request);
     84
     85            // process the message
     86            Element mr_info_response = (Element) this.mr.process(mr_info_message);
     87            // the response
     88            Element service_response = (Element) GSXML.getChildByTagName(mr_info_response, GSXML.RESPONSE_ELEM);
     89
     90            Element service_description = (Element) this.doc.importNode(GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM), true);
     91            page_response.appendChild(service_description);
     92        }
     93
     94        if (request_type.indexOf("r") == -1)
     95        {
     96            // just a display request, no actual processing to do
     97            //append site metadata
     98            addSiteMetadata(page_response, lang, uid);
     99            return page_response;
     100        }
     101
     102        // check that we have some service params
     103        HashMap service_params = (HashMap) params.get("s1");
     104        if (service_params == null)
     105        { // no query
     106            //append site metadata
     107            addSiteMetadata(page_response, lang, uid);
     108            return page_response;
     109        }
     110
     111        // create the query request
     112        Element mr_query_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
     113        Element mr_query_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
     114        mr_query_message.appendChild(mr_query_request);
     115
     116        Element query_param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     117        GSXML.addParametersToList(this.doc, query_param_list, service_params);
     118        mr_query_request.appendChild(query_param_list);
     119
     120        // also get the format stuff now if there is some
     121        Element format_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_FORMAT, to, lang, uid);
     122        mr_query_message.appendChild(format_request);
     123
     124        logger.debug(GSXML.xmlNodeToString(mr_query_message, false));
     125
     126        // do the query
     127        Element mr_query_response = (Element) this.mr.process(mr_query_message);
     128
     129        // check for errors
     130        if (processErrorElements(mr_query_response, page_response))
     131        {
     132            //append site metadata
     133            addSiteMetadata(page_response, lang, uid);
     134            return page_response;
     135        }
     136
     137        NodeList responses = mr_query_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
     138        Element query_response = (Element) responses.item(0);
     139        Element format_response = (Element) responses.item(1);
     140
     141        Element query_result_metadata_list = (Element) GSXML.getChildByTagName(query_response, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
     142        if (query_result_metadata_list == null)
     143        {
     144            logger.error("No query result metadata.\n");
     145        }
     146        else
     147        { // add it into the page response
     148            page_response.appendChild(this.doc.importNode(query_result_metadata_list, true));
     149        }
     150
     151        Element query_term_info_list = (Element) GSXML.getChildByTagName(query_response, GSXML.TERM_ELEM + GSXML.LIST_MODIFIER);
     152        if (query_term_info_list == null)
     153        {
     154            logger.error("No query term information.\n");
     155        }
     156        else
     157        { // add it into the page response
     158            page_response.appendChild(this.doc.importNode(query_term_info_list, true));
     159        }
     160
     161        // check that there are some documents - for now check the list, but later should use a numdocs metadata elem   
     162        Element document_list = (Element) GSXML.getChildByTagName(query_response, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
     163        // documentList not present if no docs found
     164        if (document_list == null)
     165        {
     166            // add in a dummy doc node list - used by the display. need to think about this
     167            page_response.appendChild(this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER));
     168            //append site metadata
     169            addSiteMetadata(page_response, lang, uid);
     170            return page_response;
     171        }
     172
     173        // now we check to see if there is metadata already - some search services return predefined metadata. if there is some, don't do a metadata request
     174        NodeList doc_metadata = document_list.getElementsByTagName(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
     175        if (doc_metadata.getLength() > 0)
     176        {
     177            logger.error("have already found metadata!");
     178            // append the doc list to the result
     179            page_response.appendChild(this.doc.importNode(document_list, true));
     180            //append site metadata
     181            addSiteMetadata(page_response, lang, uid);
     182            return page_response;
     183        }
     184
     185        // get the metadata elements needed from the format statement if any
     186        HashSet metadata_names = new HashSet();
     187        metadata_names.add("Title");
     188        // add in the format info to the stylesheet if there is any
     189        Element format_elem = (Element) GSXML.getChildByTagName(format_response, GSXML.FORMAT_ELEM);
     190        if (format_elem != null)
     191        {
     192            // set the format type
     193            format_elem.setAttribute(GSXML.TYPE_ATT, "search");
     194            // for now just add to the response
     195            page_response.appendChild(this.doc.importNode(format_elem, true));
     196            getRequiredMetadataNames(format_elem, metadata_names);
     197        }
     198
     199        // paging of the results is done here - we filter the list to remove unwanted entries before retrieving metadata
     200        Element filtered_doc_list = filterDocList(params, service_params, document_list);
     201
     202        // do the metadata request on the filtered list
     203        Element mr_metadata_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
     204        to = "DocumentMetadataRetrieve";
     205        if (collection != null)
     206        {
     207            to = GSPath.prependLink(to, collection);
     208        }
     209        Element mr_metadata_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
     210        mr_metadata_message.appendChild(mr_metadata_request);
     211
     212        // just get all for now - the receptionist should perhaps pass in some
     213        // metadata that it wants, and QueryAction should look through the format stuff to see if there is any other?
     214
     215        Element dm_param_list = createMetadataParamList(metadata_names);
     216
     217        mr_metadata_request.appendChild(dm_param_list);
     218
     219        // add in the doc node list too
     220        mr_metadata_request.appendChild(filtered_doc_list);
     221
     222        Element mr_metadata_response = (Element) this.mr.process(mr_metadata_message);
     223        // check for errors
     224        processErrorElements(mr_metadata_response, page_response);
     225
     226        Element metadata_response = (Element) GSXML.getChildByTagName(mr_metadata_response, GSXML.RESPONSE_ELEM);
     227
     228        Element query_result_document_list = (Element) GSXML.getChildByTagName(metadata_response, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
     229
     230        if (query_result_document_list != null)
     231        {
     232            page_response.appendChild(this.doc.importNode(query_result_document_list, true));
     233        }
     234
     235        logger.debug("Query page:\n" + this.converter.getPrettyString(page_response));
     236        //append site metadata
     237        addSiteMetadata(page_response, lang, uid);
     238        return page_response;
    70239    }
    71    
    72     if (request_type.indexOf("d")!=-1) {
    73         // we have been asked for the service description
    74         Element mr_info_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
    75         Element mr_info_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE,  to, lang, uid);
    76         mr_info_message.appendChild(mr_info_request);
    77        
    78         // process the message
    79         Element mr_info_response = (Element) this.mr.process(mr_info_message);
    80         // the response
    81         Element service_response = (Element)GSXML.getChildByTagName(mr_info_response, GSXML.RESPONSE_ELEM);
    82        
    83         Element service_description = (Element)this.doc.importNode(GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM), true);
    84         page_response.appendChild(service_description);
     240
     241    /** this filters out some of the doc results for result paging */
     242    protected Element filterDocList(HashMap params, HashMap service_params, Element orig_doc_list)
     243    {
     244
     245        // check the hits_per_page param - is it a service param??
     246        String hits_pp = (String) service_params.get("hitsPerPage");
     247        if (hits_pp == null)
     248        {
     249            // the service is doing the paging, so we want to display all of the returned docs(???)
     250            //    return (Element)this.doc.importNode(orig_doc_list, true);
     251            // try hitsPerPage in the globle param
     252            hits_pp = (String) params.get("hitsPerPage");
     253        }
     254
     255        int hits = 20;
     256        if (hits_pp != null && !hits_pp.equals(""))
     257        {
     258            try
     259            {
     260                hits = Integer.parseInt(hits_pp);
     261            }
     262            catch (Exception e)
     263            {
     264                hits = 20;
     265            }
     266        }
     267
     268        if (hits == -1)
     269        { // all
     270            return (Element) this.doc.importNode(orig_doc_list, true);
     271        }
     272        NodeList result_docs = orig_doc_list.getElementsByTagName(GSXML.DOC_NODE_ELEM);
     273
     274        int num_docs = result_docs.getLength();
     275        if (num_docs <= hits)
     276        {
     277            // too few docs to do paging
     278            return (Element) this.doc.importNode(orig_doc_list, true);
     279        }
     280
     281        // now we need our own doc list
     282        Element result_list = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
     283
     284        String start_p = (String) service_params.get("startPage");
     285        if (start_p == null)
     286        {
     287            start_p = (String) params.get("startPage");
     288        }
     289
     290        int start = 1;
     291        if (start_p != null && !start_p.equals(""))
     292        {
     293            try
     294            {
     295                start = Integer.parseInt(start_p);
     296            }
     297            catch (Exception e)
     298            {
     299                start = 1;
     300            }
     301        }
     302
     303        int start_from = (start - 1) * hits;
     304        int end_at = (start * hits) - 1;
     305
     306        if (start_from > num_docs)
     307        {
     308            // something has gone wrong
     309            return result_list;
     310        }
     311
     312        if (end_at > num_docs)
     313        {
     314            end_at = num_docs - 1;
     315        }
     316
     317        // now we finally have the docs numbers to use
     318        for (int i = start_from; i <= end_at; i++)
     319        {
     320            result_list.appendChild(this.doc.importNode(result_docs.item(i), true));
     321        }
     322
     323        return result_list;
    85324    }
    86325
    87     if (request_type.indexOf("r") == -1) {
    88         // just a display request, no actual processing to do
    89         //append site metadata
    90         addSiteMetadata( page_response, lang, uid);
    91         return page_response;
    92     }
    93 
    94     // check that we have some service params
    95     HashMap service_params = (HashMap)params.get("s1");
    96     if (service_params == null) { // no query
    97         //append site metadata
    98         addSiteMetadata( page_response, lang, uid);
    99         return page_response;
    100     }
    101 
    102     // create the query request
    103     Element mr_query_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
    104     Element mr_query_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
    105     mr_query_message.appendChild(mr_query_request);
    106    
    107     Element query_param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
    108     GSXML.addParametersToList(this.doc, query_param_list, service_params);
    109     mr_query_request.appendChild(query_param_list);
    110    
    111     // also get the format stuff now if there is some
    112     Element format_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_FORMAT, to, lang, uid);
    113     mr_query_message.appendChild(format_request);
    114 
    115     logger.debug(GSXML.xmlNodeToString(mr_query_message, false));
    116 
    117     // do the query
    118         Element mr_query_response = (Element)this.mr.process(mr_query_message);
    119 
    120     // check for errors
    121     if (processErrorElements(mr_query_response, page_response)) {
    122         //append site metadata
    123         addSiteMetadata( page_response, lang, uid);
    124         return page_response;
    125     }
    126    
    127     NodeList responses = mr_query_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
    128     Element query_response = (Element) responses.item(0);
    129     Element format_response = (Element) responses.item(1);
    130    
    131     Element query_result_metadata_list = (Element) GSXML.getChildByTagName(query_response, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
    132     if (query_result_metadata_list == null) {
    133         logger.error("No query result metadata.\n");
    134     } else { // add it into the page response
    135         page_response.appendChild(this.doc.importNode(query_result_metadata_list, true));
    136     }
    137    
    138     Element query_term_info_list = (Element) GSXML.getChildByTagName(query_response, GSXML.TERM_ELEM+GSXML.LIST_MODIFIER);
    139     if (query_term_info_list == null) {
    140         logger.error("No query term information.\n");
    141     } else { // add it into the page response
    142         page_response.appendChild(this.doc.importNode(query_term_info_list, true));
    143     }
    144    
    145     // check that there are some documents - for now check the list, but later should use a numdocs metadata elem   
    146     Element document_list = (Element)GSXML.getChildByTagName(query_response, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
    147     // documentList not present if no docs found
    148     if (document_list == null) {
    149         // add in a dummy doc node list - used by the display. need to think about this
    150         page_response.appendChild(this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER));
    151         //append site metadata
    152         addSiteMetadata( page_response, lang, uid);
    153         return page_response;
    154     }
    155 
    156     // now we check to see if there is metadata already - some search services return predefined metadata. if there is some, don't do a metadata request
    157     NodeList doc_metadata = document_list.getElementsByTagName(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
    158     if (doc_metadata.getLength()>0) {
    159         logger.error("have already found metadata!");
    160         // append the doc list to the result
    161         page_response.appendChild(this.doc.importNode(document_list, true));
    162         //append site metadata
    163         addSiteMetadata( page_response, lang, uid);
    164         return page_response;
    165     }
    166    
    167     // get the metadata elements needed from the format statement if any
    168     HashSet metadata_names = new HashSet();
    169     metadata_names.add("Title");
    170     // add in the format info to the stylesheet if there is any
    171     Element format_elem = (Element)GSXML.getChildByTagName(format_response, GSXML.FORMAT_ELEM);
    172     if (format_elem != null) {
    173         // set the format type
    174         format_elem.setAttribute(GSXML.TYPE_ATT, "search");
    175         // for now just add to the response
    176         page_response.appendChild(this.doc.importNode(format_elem, true));
    177         getRequiredMetadataNames(format_elem, metadata_names);
    178     }
    179    
    180     // paging of the results is done here - we filter the list to remove unwanted entries before retrieving metadata
    181     Element filtered_doc_list = filterDocList(params, service_params, document_list);
    182    
    183     // do the metadata request on the filtered list
    184     Element mr_metadata_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
    185     to = "DocumentMetadataRetrieve";
    186     if (collection != null) {
    187         to = GSPath.prependLink(to, collection);
    188     }
    189     Element mr_metadata_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
    190     mr_metadata_message.appendChild(mr_metadata_request);
    191    
    192     // just get all for now - the receptionist should perhaps pass in some
    193     // metadata that it wants, and QueryAction should look through the format stuff to see if there is any other?
    194    
    195     Element dm_param_list  = createMetadataParamList(metadata_names);
    196    
    197     mr_metadata_request.appendChild(dm_param_list);
    198    
    199     // add in the doc node list too
    200     mr_metadata_request.appendChild(filtered_doc_list);
    201 
    202     Element mr_metadata_response = (Element) this.mr.process(mr_metadata_message); 
    203     // check for errors
    204     processErrorElements(mr_metadata_response, page_response);
    205    
    206     Element metadata_response = (Element) GSXML.getChildByTagName(mr_metadata_response, GSXML.RESPONSE_ELEM);
    207 
    208     Element query_result_document_list = (Element) GSXML.getChildByTagName(metadata_response, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
    209    
    210     if (query_result_document_list != null) {
    211         page_response.appendChild(this.doc.importNode(query_result_document_list, true));
    212     }
    213    
    214     logger.debug("Query page:\n" + this.converter.getPrettyString(page_response));
    215     //append site metadata
    216     addSiteMetadata( page_response, lang, uid);
    217     return page_response;
    218     }
    219 
    220     /** this filters out some of the doc results for result paging */
    221     protected Element filterDocList(HashMap params, HashMap service_params, Element orig_doc_list) {
    222    
    223     // check the hits_per_page param - is it a service param??
    224     String hits_pp = (String) service_params.get("hitsPerPage");
    225     if (hits_pp == null) {
    226         // the service is doing the paging, so we want to display all of the returned docs(???)
    227     //    return (Element)this.doc.importNode(orig_doc_list, true);
    228     // try hitsPerPage in the globle param
    229          hits_pp = (String)params.get("hitsPerPage");
    230         }
    231    
    232     int hits = 20;
    233     if (hits_pp != null && !hits_pp.equals("")) {
    234         try {
    235         hits = Integer.parseInt(hits_pp);
    236         } catch (Exception e) {
    237         hits=20;
    238         }
    239     }
    240 
    241     if (hits == -1) { // all
    242         return (Element)this.doc.importNode(orig_doc_list, true);
    243     }
    244     NodeList result_docs = orig_doc_list.getElementsByTagName(GSXML.DOC_NODE_ELEM);
    245    
    246     int num_docs = result_docs.getLength();
    247     if (num_docs <= hits) {
    248         // too few docs to do paging
    249         return (Element)this.doc.importNode(orig_doc_list, true);
    250     }
    251 
    252     // now we need our own doc list
    253     Element result_list = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
    254    
    255     String start_p = (String) service_params.get("startPage");
    256     if(start_p == null){
    257         start_p = (String)params.get("startPage");
    258     }
    259 
    260     int start = 1;
    261     if (start_p != null && !start_p.equals("")) {
    262         try {
    263         start = Integer.parseInt(start_p);
    264         } catch (Exception e) {
    265         start = 1;
    266         }
    267     }
    268 
    269     int start_from = (start-1)*hits;
    270     int end_at = (start*hits)-1;
    271 
    272     if (start_from > num_docs) {
    273         // something has gone wrong
    274         return result_list;
    275     }
    276    
    277     if (end_at > num_docs) {
    278         end_at = num_docs-1;
    279     }
    280 
    281     // now we finally have the docs numbers to use
    282     for (int i=start_from; i<=end_at; i++) {
    283         result_list.appendChild(this.doc.importNode(result_docs.item(i), true));
    284     }
    285 
    286     return result_list;
    287     }
    288 
    289326}
Note: See TracChangeset for help on using the changeset viewer.