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/Action.java

    r27998 r28382  
    2424    /** the system set up variables */
    2525    protected HashMap<String, Object> config_params = null;
    26     /** container Document to create XML Nodes */
    27     protected Document doc = null;
     26   
     27   
    2828    /** a converter class to parse XML and create Docs */
    2929    protected XMLConverter converter = null;
     
    3939    {
    4040        this.converter = new XMLConverter();
    41         this.doc = this.converter.newDOM();
    4241    }
    4342
     
    193192    }
    194193
    195     protected Element createMetadataParamList(HashSet<String> metadata_names)
    196     {
    197         Element param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     194    protected Element createMetadataParamList(Document doc, HashSet<String> metadata_names)
     195    {
     196        Element param_list = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
    198197
    199198        Element param = null;
     
    202201        {
    203202            String name = i.next();
    204             param = this.doc.createElement(GSXML.PARAM_ELEM);
     203            param = doc.createElement(GSXML.PARAM_ELEM);
    205204            param_list.appendChild(param);
    206205            param.setAttribute(GSXML.NAME_ATT, "metadata");
     
    240239    protected void addSiteMetadata(Element element, UserContext userContext)
    241240    {
     241        Document doc = element.getOwnerDocument();
     242       
    242243        //ADD SITE METADATA
    243         Element metadata_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, "", userContext);
     244        Element metadata_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", userContext);
    244245        //create a hashmap of params
    245246        HashMap subset_params = new HashMap(1);
    246247        subset_params.put(GSXML.SUBSET_PARAM, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
    247248        //create the element to put the params in
    248         Element param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     249        Element param_list = doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
    249250        //put them in
    250         GSXML.addParametersToList(this.doc, param_list, subset_params);
     251        GSXML.addParametersToList(doc, param_list, subset_params);
    251252        metadata_request.appendChild(param_list);
    252253        //create the message
    253         Element metadata_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
     254        Element metadata_message = doc.createElement(GSXML.MESSAGE_ELEM);
    254255        metadata_message.appendChild(metadata_request);
    255256        //get response
     
    263264    protected void addInterfaceOptions(Element elem)
    264265    {
    265         Element documentOptionList = this.doc.createElement("interfaceOptions");
     266        Document doc = elem.getOwnerDocument();
     267       
     268        Element documentOptionList = doc.createElement("interfaceOptions");
    266269        for (Object key : this.config_params.keySet())
    267270        {
    268             Element option = this.doc.createElement("option");
     271            Element option = doc.createElement("option");
    269272            option.setAttribute(GSXML.NAME_ATT, (String) key);
    270273            option.setAttribute(GSXML.VALUE_ATT, this.config_params.get(key).toString());
     
    276279    protected Element getFormatInfo(String to, UserContext userContext)
    277280    {
    278         Element mr_format_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
    279         Element mr_format_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_FORMAT, to, userContext);
     281        // Eclipse call hierarchy shows the element returned from this method is
     282        // subsequently used in a 'importNode'.  For this reason it is safe here
     283        // for call up our own document DOM. 
     284        //
     285        // If this pattern changes for any reason, then the DOM will need to be
     286        // passed in as a parameter
     287       
     288        Document doc = this.converter.newDOM();
     289       
     290        Element mr_format_message = doc.createElement(GSXML.MESSAGE_ELEM);
     291        Element mr_format_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_FORMAT, to, userContext);
    280292        mr_format_message.appendChild(mr_format_request);
    281293
Note: See TracChangeset for help on using the changeset viewer.