Bug 65965

Summary: setParagraph and setTable don't properly set XML references
Product: POI Reporter: jared.wilkin
Component: XWPFAssignee: POI Developers List <dev>
Status: NEW ---    
Severity: major    
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: All   

Description jared.wilkin 2022-03-18 18:00:22 UTC
after calling setTable the CTTbl objects in the XWPFDocument object and the CTDocument object don't match:

from a client the following is false:
doc.getTableArray(pos).getCTTbl() == doc.getDocument().getBody().getTblArray(pos)

from inside XWPFDocument class the following is false:
this.tables.get(pos).getCTTbl() == table.getBody().getTableArray(pos)

it appears that the CTTbl object is not set, but rather its contents are copied in place when setTblArray is called on the body. This problem also is seen when calling setParagraph. This is seen in version 4.1.1
Comment 1 jared.wilkin 2022-03-18 18:05:50 UTC
the second equality test should read (indicating the CTTbl object as stored by the table in the tables array isn't the same as the CTTbl object in the xml tree):

this.tables.get(pos).getCTTbl() == this.ctDocument.getBody().getTblArray(pos)
Comment 2 PJ Fanning 2022-03-18 18:27:24 UTC
Can you provide a test case for latest POI code? The current description is ambiguous. If you provide a full code sample, then the ambiguity disappears.
Comment 3 jared.wilkin 2022-03-18 19:32:35 UTC
this is a contrived and truncated example, but the idea is setting a newly created table into a document attempting to replace the table already there.  after this action the CTTbl retrieved from the XWPFTable object stored in the XWPFDocument tables array should presumably be the same instance as the CTTbl retrieved from the xml objects.

XWPFDocument newDoc = new XWPFDocument();
XWPFTable newTbl = newDoc.createTable();
XWPFTable newTbl1 = new XWPFTable(CTTbl.Factory.newInstance(),  newTbl.getBody());
int position = newDoc.getPosOfTable(newTbl);
  != newDoc.getDocument().getBody().getTblArray(position)){
    System.out.println("This should be true");
Comment 4 jared.wilkin 2022-03-23 19:12:41 UTC
I failed to mention the actual impact of this problem in my prior comments...

Among other things this has two significant problems that require dubious work-arounds.  These problems exist not only for tables, but other places where set is called, ex. setParagraph().

1)  changes made to the entity XWPF entity after "setting" don't actually make it into the resulting document.  This is due to the fact that the XML object in the document isn't associated with the XWPF object and thus any changes or modifications get applied to the XWPF object and by extension applied to its XML object are not actually part of the document's XML tree.

2)  any cursors derived from the XMPF entity after "setting" aren't valid as they don't point to the correct place in the document tree.  For the same reasons outlined above the cursor and any actions done on it don't produce the expected outcome as it is not pointing to the underlying document's XML tree.

While I have been able to work around both of these problems mostly successfully, the state and outcomes were certainly not expected and I would assume probably would not be expected by most if not all other users.