https://bz.apache.org/bugzilla/show_bug.cgi?id=62484

            Bug ID: 62484
           Summary: XSSFRow:OnDocumentWrite Unordered row will generate
                    CTCells that are not referenced by _cells Treemap
           Product: POI
           Version: 3.17-FINAL
          Hardware: All
                OS: All
            Status: NEW
          Severity: blocker
          Priority: P2
         Component: XSSF
          Assignee: dev@poi.apache.org
          Reporter: fr...@tygron.com
  Target Milestone: ---

I have a Microsoft Excel file which has several rows that are not ordered
alphabetically. Reading and writing to this Excel file will work well, until I
write the XSSF-document to a file for the first time.

When I continued reading from and writing to cells in this document, I noticed
some cells did not update properly in the CTRows of XSSFRows.

I debugged deeper and noticed that onDocumentWrite, for XSSFRows that are not
ordered, new CTCells are created through a copy. I understand this code and it
seemed logical.

<code from XSSFRow::OnDocumentWrite>
if(!isOrdered){
  cArray = new CTCell[_cells.size()];
  int i = 0;
  for (XSSFCell xssfCell : _cells.values()) {
    cArray[i] = (CTCell) xssfCell.getCTCell().copy();

    // we have to copy and re-create the XSSFCell here because the 
    // elements as otherwise setCArray below invalidates all the columns!
    // see Bug 56170, XMLBeans seems to always release previous objects
    // in the CArray, so we need to provide completely new ones here!
    // _cells.put(entry.getKey(), new XSSFCell(this, cArray[i]));
    // xssfCell.setCTCell(cArray[i]);
    i++;
  }
  _row.setCArray(cArray);
}

However, when this new CTCell array is set to the CTRow:
 _row.setCArray(cArray);
code in this method can (or often will) also copy these Cell objects again for
its own internal row.

(The underlying classes and methods doing this are:
 XmlComplexContentImpl::arraySetterHelper( XmlObject[] sources, QName elemName)
 XmlObject::set(XmlObject src) 
  -> 
    if (monitor() == obj.monitor())             // both are in the same locale
    {
      if (noSyncThis)                         // the locale is not sync
        newObj = setterHelper( obj );
      else                                    // the locale is sync
      {
        synchronized (monitor()) {
          newObj = setterHelper( obj ); <-- new CTCell object is created
        }
      }
    }

)

The result is that the CTRow will now reference other CTCells than the _cells
TreeMap of the XSSFRow. Writing new values to these cells will only end up in
the _cells TreeMap and not in the CTRow any more. 
Consequently, writing the document a second time after having changed cell
values in these rows will write the wrong cell values.

Hopefully others are also able to reproduce this issue!

-- 
You are receiving this mail because:
You are the assignee for the bug.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@poi.apache.org
For additional commands, e-mail: dev-h...@poi.apache.org

Reply via email to