8160087: Change IOOBE to warning in the scenarios when it had not being thrown before the JDK-8078514
authorssadetsky
Wed, 30 Nov 2016 10:47:57 +0300
changeset 42728 f61c320cee03
parent 42727 bd56c4c834bb
child 42729 6df8255b1bd9
8160087: Change IOOBE to warning in the scenarios when it had not being thrown before the JDK-8078514 Reviewed-by: azvegint, alexsch
jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java
jdk/test/javax/swing/JTable/SorterIOOBEtest/DefaultRowSorterIOOBEtest.java
--- a/jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java	Tue Nov 29 11:12:53 2016 -0800
+++ b/jdk/src/java.desktop/share/classes/javax/swing/DefaultRowSorter.java	Wed Nov 30 10:47:57 2016 +0300
@@ -182,6 +182,8 @@
      */
     private int modelRowCount;
 
+    // Whether to print warning about JDK-8160087
+    private static boolean warning8160087 = true;
 
     /**
      * Creates an empty <code>DefaultRowSorter</code>.
@@ -489,10 +491,7 @@
      */
     public int convertRowIndexToView(int index) {
         if (modelToView == null) {
-            if (index < 0 || index >= modelRowCount) {
-                throw new IndexOutOfBoundsException("Invalid index");
-            }
-            return index;
+            return convertUnsortedUnfiltered(index);
         }
         return modelToView[index];
     }
@@ -504,14 +503,30 @@
      */
     public int convertRowIndexToModel(int index) {
         if (viewToModel == null) {
-            if (index < 0 || index >= modelRowCount) {
-                throw new IndexOutOfBoundsException("Invalid index");
-            }
-            return index;
+            return convertUnsortedUnfiltered(index);
         }
         return viewToModel[index].modelIndex;
     }
 
+    private int convertUnsortedUnfiltered(int index) {
+        if (index < 0 || index >= modelRowCount) {
+            if(index >= modelRowCount &&
+                                      index < getModelWrapper().getRowCount()) {
+                // 8160087
+                if(warning8160087) {
+                    warning8160087 = false;
+                    System.err.println("WARNING: row index is bigger than " +
+                            "sorter's row count. Most likely this is a wrong " +
+                            "sorter usage.");
+                }
+            } else {
+                throw new IndexOutOfBoundsException("Invalid index");
+            }
+        }
+        return index;
+    }
+
+
     private boolean isUnsorted() {
         List<? extends SortKey> keys = getSortKeys();
         int keySize = keys.size();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/SorterIOOBEtest/DefaultRowSorterIOOBEtest.java	Wed Nov 30 10:47:57 2016 +0300
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8160087
+ * @summary Change IOOBE to warning in the scenarios when it had not being
+ *          thrown before the JDK-8078514
+ * @run main/othervm DefaultRowSorterIOOBEtest
+ */
+
+import javax.swing.*;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableModel;
+import javax.swing.table.TableRowSorter;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DefaultRowSorterIOOBEtest extends TableRowSorter<TableModel> {
+    static List<String> rows = new ArrayList<>();
+
+    static TableModel tableModel = new AbstractTableModel() {
+
+        @Override
+        public int getRowCount() {
+            return rows.size();
+        }
+
+        @Override
+        public int getColumnCount() {
+            return 1;
+        }
+
+        @Override
+        public Object getValueAt(int rowIndex, int columnIndex) {
+            return rows.get(rowIndex);
+        }
+    };
+
+    public static void main(String[] args) {
+        DefaultRowSorter<TableModel, Integer> sorter =
+            new DefaultRowSorter<>() {
+            {
+                setModelWrapper(new SorterModelWrapper());
+            }
+        };
+
+        PrintStream err = System.err;
+        ByteArrayOutputStream bos = new ByteArrayOutputStream(10000) {
+            @Override
+            public synchronized void write(byte[] b, int off, int len) {
+                super.write(b, off, len);
+                err.print(new String(b, off, len));
+            }
+        };
+        System.setErr(new PrintStream(bos));
+
+        rows.add("New");
+
+        sorter.convertRowIndexToView(0);
+        sorter.convertRowIndexToModel(0);
+
+        String out = new String(bos.toByteArray());
+        if(out.indexOf("WARNING:") < 0) {
+            throw new RuntimeException("No warnings found");
+        }
+    }
+
+    static class SorterModelWrapper extends
+                            DefaultRowSorter.ModelWrapper<TableModel, Integer> {
+
+        @Override
+        public TableModel getModel() {
+            return tableModel;
+        }
+
+        @Override
+        public int getColumnCount() {
+            return tableModel.getColumnCount();
+        }
+
+        @Override
+        public int getRowCount() {
+            return tableModel.getRowCount();
+        }
+
+        @Override
+        public Object getValueAt(int row, int column) {
+            return tableModel.getValueAt(row, column);
+        }
+
+        @Override
+        public Integer getIdentifier(int row) {
+            return row;
+        }
+    }
+}