Ignore:
Timestamp:
2013-10-10T17:21:30+13:00 (11 years ago)
Author:
davidb
Message:

Elimination of the 'this.doc' field from the Action baseclass and the subclasses that rely on it. For Greenstone3 purposes it is unsafe to create this object in the constructor to the action and then store it for other methods to access. This is because the Greenstone 3 (and in particular calls to 'process' operate in a multi-threaded context, that is managed by the Servlet server (e.g. Tomcat by default). Calls to DOM methods are not guaranteed to be thread safe, this became apparent when we started looking in to an exception that was being thrown, and centred around use of the DOM method 'item(i)'. The change this commit makes is to remove 'this.doc' being stored as a field. A document is now created in the top level of a call to 'process()' and when a DOM reference is needed in a subsequent method an Element variable (typically passed in as a parameter to the method) is used (through 'Document doc = element.getOwnerDocument()') to gain access to the DOM

File:
1 edited

Legend:

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

    r27145 r28382  
    1111import org.greenstone.gsdl3.util.GSXSLT;
    1212import org.greenstone.gsdl3.util.UserContext;
     13import org.w3c.dom.Document;
    1314import org.w3c.dom.Element;
    1415import org.w3c.dom.Node;
     
    2627    public Node process(Node message_node)
    2728    {
    28 
    2929        Element message = this.converter.nodeToElement(message_node);
    30 
     30        Document doc = message.getOwnerDocument();
     31       
    3132        // get the request - assume there is only one
    3233        Element request = (Element) GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
    3334
    3435        // create the return message
    35         Element result = this.doc.createElement(GSXML.MESSAGE_ELEM);
     36        Element result = doc.createElement(GSXML.MESSAGE_ELEM);
    3637        Element response = basicQuery(request);
    37         result.appendChild(this.doc.importNode(response, true));
     38        result.appendChild(doc.importNode(response, true));
    3839        return result;
    3940    }
     
    4748    {
    4849        // the result
    49         Element page_response = this.doc.createElement(GSXML.RESPONSE_ELEM);
     50        Document doc = request.getOwnerDocument();
     51        Element page_response = doc.createElement(GSXML.RESPONSE_ELEM);
    5052
    5153        // extract the params from the cgi-request, and check that we have a coll specified
     
    7577        format_elem.setAttribute(GSXML.TYPE_ATT, "search");
    7678        // for now just add to the response
    77         page_response.appendChild(this.doc.importNode(format_elem, true));
     79        page_response.appendChild(doc.importNode(format_elem, true));
    7880
    7981        if (request_type.indexOf("d") != -1)
    8082        {
    8183            // we have been asked for the service description
    82             Element mr_info_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
    83             Element mr_info_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, to, userContext);
     84            Element mr_info_message = doc.createElement(GSXML.MESSAGE_ELEM);
     85            Element mr_info_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, to, userContext);
    8486            mr_info_message.appendChild(mr_info_request);
    8587
     
    9092            Element service_response = (Element) GSXML.getChildByTagName(mr_info_response, GSXML.RESPONSE_ELEM);
    9193
    92             Element service_description = (Element) this.doc.importNode(GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM), true);
     94            Element service_description = (Element) doc.importNode(GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM), true);
    9395            page_response.appendChild(service_description);
    9496        }
     
    114116
    115117        // create the query request
    116         Element mr_query_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
    117         Element mr_query_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, userContext);
     118        Element mr_query_message = doc.createElement(GSXML.MESSAGE_ELEM);
     119        Element mr_query_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_PROCESS, to, userContext);
    118120        mr_query_message.appendChild(mr_query_request);
    119121
    120         Element query_param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
    121         GSXML.addParametersToList(this.doc, query_param_list, service_params);
     122        Element query_param_list = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     123        GSXML.addParametersToList(doc, query_param_list, service_params);
    122124        mr_query_request.appendChild(query_param_list);
    123125
     
    144146        else
    145147        { // add it into the page response
    146             page_response.appendChild(this.doc.importNode(query_result_metadata_list, true));
     148            page_response.appendChild(doc.importNode(query_result_metadata_list, true));
    147149        }
    148150
     
    154156        else
    155157        { // add it into the page response
    156             page_response.appendChild(this.doc.importNode(query_term_info_list, true));
     158            page_response.appendChild(doc.importNode(query_term_info_list, true));
    157159        }
    158160
     
    164166        else
    165167        { // add it into the page response
    166             page_response.appendChild(this.doc.importNode(facet_list, true));
     168            page_response.appendChild(doc.importNode(facet_list, true));
    167169        }
    168170
     
    173175        {
    174176            // add in a dummy doc node list - used by the display. need to think about this
    175             page_response.appendChild(this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER));
     177            page_response.appendChild(doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER));
    176178            //append site metadata
    177179            addSiteMetadata(page_response, userContext);
     
    186188            logger.error("have already found metadata!");
    187189            // append the doc list to the result
    188             page_response.appendChild(this.doc.importNode(document_list, true));
     190            page_response.appendChild(doc.importNode(document_list, true));
    189191            //append site metadata
    190192            addSiteMetadata(page_response, userContext);
     
    203205
    204206        // paging of the results is done here - we filter the list to remove unwanted entries before retrieving metadata
    205         Element filtered_doc_list = filterDocList(params, service_params, document_list);
     207        Element filtered_doc_list = filterDocList(doc, params, service_params, document_list);
    206208
    207209        // do the metadata request on the filtered list
    208         Element mr_metadata_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
     210        Element mr_metadata_message = doc.createElement(GSXML.MESSAGE_ELEM);
    209211        to = "DocumentMetadataRetrieve";
    210212        if (collection != null)
     
    212214            to = GSPath.prependLink(to, collection);
    213215        }
    214         Element mr_metadata_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, userContext);
     216        Element mr_metadata_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_PROCESS, to, userContext);
    215217        mr_metadata_message.appendChild(mr_metadata_request);
    216218
     
    228230        }
    229231
    230         Element dm_param_list = createMetadataParamList(metadata_names);
     232        Element dm_param_list = createMetadataParamList(doc,metadata_names);
    231233
    232234        mr_metadata_request.appendChild(dm_param_list);
     
    246248        if (query_result_document_list != null)
    247249        {
    248             page_response.appendChild(this.doc.importNode(query_result_document_list, true));
     250            page_response.appendChild(doc.importNode(query_result_document_list, true));
    249251        }
    250252
     
    257259
    258260    /** this filters out some of the doc results for result paging */
    259     protected Element filterDocList(HashMap<String, Serializable> params, HashMap service_params, Element orig_doc_list)
     261    protected Element filterDocList(Document doc, HashMap<String, Serializable> params, HashMap service_params, Element orig_doc_list)
    260262    {
    261263
     
    265267        {
    266268            // the service is doing the paging, so we want to display all of the returned docs(???)
    267             //    return (Element)this.doc.importNode(orig_doc_list, true);
     269            //    return (Element)doc.importNode(orig_doc_list, true);
    268270            // try hitsPerPage in the globle param
    269271            hits_pp = (String) params.get("hitsPerPage");
     
    285287        if (hits == -1)
    286288        { // all
    287             return (Element) this.doc.importNode(orig_doc_list, true);
     289            return (Element) doc.importNode(orig_doc_list, true);
    288290        }
    289291        NodeList result_docs = orig_doc_list.getElementsByTagName(GSXML.DOC_NODE_ELEM);
     
    293295        {
    294296            // too few docs to do paging
    295             return (Element) this.doc.importNode(orig_doc_list, true);
     297            return (Element) doc.importNode(orig_doc_list, true);
    296298        }
    297299
    298300        // now we need our own doc list
    299         Element result_list = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
     301        Element result_list = doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
    300302
    301303        String start_p = (String) service_params.get("startPage");
     
    335337        for (int i = start_from; i <= end_at; i++)
    336338        {
    337             result_list.appendChild(this.doc.importNode(result_docs.item(i), true));
     339            result_list.appendChild(doc.importNode(result_docs.item(i), true));
    338340        }
    339341
Note: See TracChangeset for help on using the changeset viewer.