ODF Toolkit
  1. ODF Toolkit
  2. ODFTOOLKIT-106

OdfTable.removeColumnsByIndex gives "java.lang.IllegalArgumentException: index should be nonnegative integer"

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: odfdom-0.8.5
    • Fix Version/s: odfdom-0.8.7
    • Component/s: java
    • Labels:
      None
    • Environment:
      Operating System: Linux
      Platform: PC

      Description

      I created a new Spreadsheet document. I then deleted all tables that had been added to it. I then created a new table, and it started with 2 rows and 5 columns for some reason. I decided to delete them. Attempted deletion of the columns gave the error

      OdfDocument doc = null;
      String filename = "test.ods";

      File file = new File(filename);
      if (!file.exists())
      {
      // ODF spreadsheet doesn't exist, so create
      System.out.println(">> OdfDocument.newSpreadsheetDocument()");
      doc = OdfSpreadsheetDocument.newSpreadsheetDocument();

      // Delete any tables that ODFDOM created for us
      List<OdfTable> tables = new ArrayList(doc.getTableList());
      System.out.println(">> numtables=" + tables.size());
      Iterator<OdfTable> tableIter = tables.iterator();
      while (tableIter.hasNext())

      { OdfTable tbl = tableIter.next(); tbl.remove(); System.out.println(">> table=" + tbl.getTableName()); }

      System.out.println(">> numtables(after)=" + doc.getTableList().size());
      System.out.println(">> OdfDocument.save(" + file + ")");
      doc.save(file);
      }

      // Load the document
      System.out.println(">> OdfDocument.loadDocument(" + file + ")");
      doc = OdfDocument.loadDocument(file);

      // Add the table and its columns
      OdfTable table = OdfTable.newTable(doc);
      String sheetName = "FirstSheet";
      table.setTableName(sheetName);

      // Delete any columns that ODFDOM created for us
      System.out.println(">> numcols=" + table.getColumnCount());
      System.out.println(">> calling table.removeColumnsByIndex(0, " + table.getColumnCount() + ")");
      table.removeColumnsByIndex(0, table.getColumnCount());
      System.out.println(">> numcols(after)=" + table.getColumnCount());

      // Delete any rows that ODFDOM created for us
      System.out.println(">> numrows=" + table.getRowCount());
      table.removeRowsByIndex(0, table.getRowCount());
      System.out.println(">> numrows(after)=" + table.getRowCount());

      Output from this simple app is as follows

      >> file=test.ods
      >> OdfDocument.newSpreadsheetDocument()
      >> numtables=1
      >> table=Sheet1
      >> numtables(after)=0
      >> OdfDocument.save(test.ods)
      >> OdfDocument.loadDocument(test.ods)
      >> numcols=5
      >> calling table.removeColumnsByIndex(0, 5)
      java.lang.IllegalArgumentException: index should be nonnegative integer.
      at org.odftoolkit.odfdom.doc.table.OdfTableRow.getCellByIndex(OdfTableRow.java:274)
      at org.odftoolkit.odfdom.doc.table.OdfTableRow.removeCellByIndex(OdfTableRow.java:928)
      at org.odftoolkit.odfdom.doc.table.OdfTable.removeColumnsByIndex(OdfTable.java:1150)
      at org.datanucleus.test.Main.main(Main.java:54)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:290)
      at java.lang.Thread.run(Thread.java:619)

      So I'm calling OdfTable.removeColumnsByIndex(0, 5) and it thinks some input is negative. Why ?

      How do I get a simple OdfSpreadsheet without any creation artifacts (tables, rows, columns) ?

        Issue Links

          Activity

          Hide
          Wei Hua Wang added a comment -

          What the table looks like if it has no columns and no rows. And in odf editor application such as Symphony, OpenOffice, etc, it is not allowed to create a table with 0 columns and 0 rows, I think the new table should has at least one column and one row. Do you agree?
          So if you want to remove all the column of the table, it is not allowed.
          Of course, we will throw a reasonable exception when user do such operation, the same explanation to https://odftoolkit.org/bugzilla/show_bug.cgi?id=176 ,pls wait for my patch.

          By the way, in https://odftoolkit.org/bugzilla/show_bug.cgi?id=176#c1, you said that "Sadly that doesn't allow me to start with 0 rows and 0 cols ", i am curious why you have requirement to create a table with 0 cols and 0 rows, if you want to do the action on the first cell, such as set value, set style, you can use
          OdfTableCell cell = table.getCellByPosition(0,0) to get the reference and setValue or use OdfTableCell.getOdfElement() method to get the dom layer element.

          Show
          Wei Hua Wang added a comment - What the table looks like if it has no columns and no rows. And in odf editor application such as Symphony, OpenOffice, etc, it is not allowed to create a table with 0 columns and 0 rows, I think the new table should has at least one column and one row. Do you agree? So if you want to remove all the column of the table, it is not allowed. Of course, we will throw a reasonable exception when user do such operation, the same explanation to https://odftoolkit.org/bugzilla/show_bug.cgi?id=176 ,pls wait for my patch. By the way, in https://odftoolkit.org/bugzilla/show_bug.cgi?id=176#c1 , you said that "Sadly that doesn't allow me to start with 0 rows and 0 cols ", i am curious why you have requirement to create a table with 0 cols and 0 rows, if you want to do the action on the first cell, such as set value, set style, you can use OdfTableCell cell = table.getCellByPosition(0,0) to get the reference and setValue or use OdfTableCell.getOdfElement() method to get the dom layer element.
          Hide
          datanucleus added a comment -

          Hi,

          If it has 0 rows and 0 columns then it doesn't "look like" anything. The whole point here is that my application will then add the columns and rows before saving it. A table will not actually be saved with 0 columns and rows.

          I do not want "header"s. A "header" is an artificial thing that may not be present on many spreadsheets, so I should not be forced to have one. As far as my users go, it is an optional thing that by default they will not have.

          FYI. My application allows people to persist a Java object as a row in an ODF table. When they start and say "persist this object" it will add a table if the table doesn't yet exist, and then add a row for the object (with however many columns are needed). So no table will be saved with zero rows (or columns).

          In 0.6 I could do this. I created a table and it had no dummy rows and columns to cater for. What did the XML doc look like when created from version 0.6.16 without columns and rows ?

          Show
          datanucleus added a comment - Hi, If it has 0 rows and 0 columns then it doesn't "look like" anything. The whole point here is that my application will then add the columns and rows before saving it. A table will not actually be saved with 0 columns and rows. I do not want "header"s. A "header" is an artificial thing that may not be present on many spreadsheets, so I should not be forced to have one. As far as my users go, it is an optional thing that by default they will not have. FYI. My application allows people to persist a Java object as a row in an ODF table. When they start and say "persist this object" it will add a table if the table doesn't yet exist, and then add a row for the object (with however many columns are needed). So no table will be saved with zero rows (or columns). In 0.6 I could do this. I created a table and it had no dummy rows and columns to cater for. What did the XML doc look like when created from version 0.6.16 without columns and rows ?
          Hide
          Ying Chun Guo added a comment -

          Hi,

          The current convenient table methods doesn't allow you to create an empty table. Do you want to move your existing code to the latest ODFDOM release, or do you create your code from scratch based on the latest ODFDOM?

          If it is latter one, I would suggest you to try the new table convenient function - table will be expended automatically as needed. You don't need to add rows and columns. If you want to get the first row, just call getRowByIndex(0); If you want to get the second row, just call getRowByIndex(1); If you want to get the 10th row, just call getRowByIndex(9). You don't need to care whether or not the table has 10 rows. If the table doesn't has enough rows, it will be expended automatically.

          If it is the former one, I have to suggest you to move to DOM layer methods. See http://odftoolkit.org/projects/odfdom/lists/users/archive/2010-03/message/6. I have a sample here for you to reference how to create an empty table, append columns and rows.

          Hope what I write can help you.

          Regards
          Daisy

          Show
          Ying Chun Guo added a comment - Hi, The current convenient table methods doesn't allow you to create an empty table. Do you want to move your existing code to the latest ODFDOM release, or do you create your code from scratch based on the latest ODFDOM? If it is latter one, I would suggest you to try the new table convenient function - table will be expended automatically as needed. You don't need to add rows and columns. If you want to get the first row, just call getRowByIndex(0); If you want to get the second row, just call getRowByIndex(1); If you want to get the 10th row, just call getRowByIndex(9). You don't need to care whether or not the table has 10 rows. If the table doesn't has enough rows, it will be expended automatically. If it is the former one, I have to suggest you to move to DOM layer methods. See http://odftoolkit.org/projects/odfdom/lists/users/archive/2010-03/message/6 . I have a sample here for you to reference how to create an empty table, append columns and rows. Hope what I write can help you. Regards Daisy
          Hide
          Wei Hua Wang added a comment -

          I understand your requirement now, and I have to say that the table api has been refactored from 0.6.16 to 0.8.5, because we found that create a table with 0 rows and 0 columns is not reasonable, especially when append a row on this empty table, we can not know how many cells should be added on this row.You said that "So no table will be saved with zero rows (or columns)." in your scenario, but we can not avoid user to save such empty table without appending any columns and row.
          I have three solutions based on your special requirement.
          Option1: do not chang the table API implementation.
          First create a table with 1 cols and 1 rows, then append a row which is a persist java object, delete the first row which is auto created when call newTable(OdfDocument, 1, 1)
          Is this work for you? If not, use another option
          Option2: change the table API implementation.
          Add the api for creating empty table and removing all columns/all rows. But I am afraid that this will induce disaster if the user save the table without any row or column. So these new added method should be deprecated.
          Option3: Keep the original table api of 0.6.16 to the incubator package, so you can still reuse your code.
          Pls let me know which one you like better, and I will discuss these solutions with my colleague tomorrow.

          By the way, if you do not want the "header", you can create table without adding the parameter of column header count and row header count. As i know, there is a bug that an emtpy row header is created even you create a table without any row header, i will solve this issue.

          Show
          Wei Hua Wang added a comment - I understand your requirement now, and I have to say that the table api has been refactored from 0.6.16 to 0.8.5, because we found that create a table with 0 rows and 0 columns is not reasonable, especially when append a row on this empty table, we can not know how many cells should be added on this row.You said that "So no table will be saved with zero rows (or columns)." in your scenario, but we can not avoid user to save such empty table without appending any columns and row. I have three solutions based on your special requirement. Option1: do not chang the table API implementation. First create a table with 1 cols and 1 rows, then append a row which is a persist java object, delete the first row which is auto created when call newTable(OdfDocument, 1, 1) Is this work for you? If not, use another option Option2: change the table API implementation. Add the api for creating empty table and removing all columns/all rows. But I am afraid that this will induce disaster if the user save the table without any row or column. So these new added method should be deprecated. Option3: Keep the original table api of 0.6.16 to the incubator package, so you can still reuse your code. Pls let me know which one you like better, and I will discuss these solutions with my colleague tomorrow. By the way, if you do not want the "header", you can create table without adding the parameter of column header count and row header count. As i know, there is a bug that an emtpy row header is created even you create a table without any row header, i will solve this issue.
          Hide
          Wei Hua Wang added a comment -

          The new added write() method just like the OutputStreamWriter.write(), right? I like this idea.
          But if user call save() which include write() and close() , they have to reload the document, what will happen and what should we do if user still use the previous OdfDocument handler after save()?

          Show
          Wei Hua Wang added a comment - The new added write() method just like the OutputStreamWriter.write(), right? I like this idea. But if user call save() which include write() and close() , they have to reload the document, what will happen and what should we do if user still use the previous OdfDocument handler after save()?
          Hide
          Wei Hua Wang added a comment -

          comment in http://odftoolkit.org/bugzilla/show_bug.cgi?id=175#c5 should be comment for bug173, sorry.

          Show
          Wei Hua Wang added a comment - comment in http://odftoolkit.org/bugzilla/show_bug.cgi?id=175#c5 should be comment for bug173, sorry.
          Hide
          Svante Schubert added a comment -

          Created an attachment (id=312)
          A test, where the get of a column does cause the same problem

          A test, where the get of a column does cause the same problem

          Show
          Svante Schubert added a comment - Created an attachment (id=312) A test, where the get of a column does cause the same problem A test, where the get of a column does cause the same problem
          Hide
          Svante Schubert added a comment -

          Hi Weihua,

          Could you verfiy the importance of this issue as it is flagged as P5 (least important) on the other hand seem to happen quite frequent when newbies testing the Table API..

          Regards,
          Svante

          Show
          Svante Schubert added a comment - Hi Weihua, Could you verfiy the importance of this issue as it is flagged as P5 (least important) on the other hand seem to happen quite frequent when newbies testing the Table API.. Regards, Svante
          Hide
          Svante Schubert added a comment -

          Hi Daisy,

          could we add this to our next milestone, e.g. SNAPSHOT?

          It is some kind of blocker to me,

          Thanks,
          Svante

          Show
          Svante Schubert added a comment - Hi Daisy, could we add this to our next milestone, e.g. SNAPSHOT? It is some kind of blocker to me, Thanks, Svante
          Hide
          Ying Chun Guo added a comment -

          Hi, Svante

          I read your code. Actually, I don't think it is a reasonable case. You created <table:table>, <table:table-row>, <table:table-cell> with dom level methods, and then you invoked table convenient methods and wanted a <table:table-column> could be added automatically.

          I have to say, the current table convenient methods don't have such function. So you got an IllegalArgumentException because there was no <table:table-column> there but the function "OdfTableCell.getInstance(mycell).getTableColumn()" was trying to get a column.

          If you are using dom level methods, you have to know the detail of specification, or else, you will generate an invalide ODF. If you are using doc level methods, you don't need to.

          BTW, we validated a document with an empty table (no rows and no columns) by the ODF validation tool and it turns out an empty table is not valid. So I suggest to close this issue because this issue is caused by the customer who want to remove all rows and all columns. The table convenient method doesn't allow to do that.

          Your opinion?

          Regards
          Daisy

          Show
          Ying Chun Guo added a comment - Hi, Svante I read your code. Actually, I don't think it is a reasonable case. You created <table:table>, <table:table-row>, <table:table-cell> with dom level methods, and then you invoked table convenient methods and wanted a <table:table-column> could be added automatically. I have to say, the current table convenient methods don't have such function. So you got an IllegalArgumentException because there was no <table:table-column> there but the function "OdfTableCell.getInstance(mycell).getTableColumn()" was trying to get a column. If you are using dom level methods, you have to know the detail of specification, or else, you will generate an invalide ODF. If you are using doc level methods, you don't need to. BTW, we validated a document with an empty table (no rows and no columns) by the ODF validation tool and it turns out an empty table is not valid. So I suggest to close this issue because this issue is caused by the customer who want to remove all rows and all columns. The table convenient method doesn't allow to do that. Your opinion? Regards Daisy
          Hide
          devin added a comment -
          Show
          devin added a comment -
          Hide
          Svante Schubert added a comment -

          ODF does not allow empty tables/spreadsheets without column/row/cell, see

          http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-schema.rng

          and

          http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part1.html#__RefHeading__1415586_253892949

          If there should be another default number as a single cell in a table, we should discuss this on the list. As the DOC API has been deprecated in favor of the Simple API this issue is kind of outdated and will be closed for now.

          Show
          Svante Schubert added a comment - ODF does not allow empty tables/spreadsheets without column/row/cell, see http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-schema.rng and http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part1.html#__RefHeading__1415586_253892949 If there should be another default number as a single cell in a table, we should discuss this on the list. As the DOC API has been deprecated in favor of the Simple API this issue is kind of outdated and will be closed for now.

            People

            • Assignee:
              Unassigned
              Reporter:
              datanucleus
            • Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development