]> source.dussan.org Git - poi.git/commitdiff
mv o.a.p.hssf.record.cf.CellRangeUtil o.a.p.ss.util.CellRangeUtil
authorJaven O'Neal <onealj@apache.org>
Mon, 20 Jun 2016 00:25:29 +0000 (00:25 +0000)
committerJaven O'Neal <onealj@apache.org>
Mon, 20 Jun 2016 00:25:29 +0000 (00:25 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1749240 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/record/CFHeaderBase.java
src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java [deleted file]
src/java/org/apache/poi/ss/util/CellRangeUtil.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheetConditionalFormatting.java
src/testcases/org/apache/poi/hssf/record/cf/TestCellRange.java

index dc7052de4539979054642ae69df8f41be7dd8cf2..3784638657a0ba680e0a200fec43e29a9b6468b6 100644 (file)
@@ -17,9 +17,9 @@
 
 package org.apache.poi.hssf.record;
 
-import org.apache.poi.hssf.record.cf.CellRangeUtil;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.ss.util.CellRangeUtil;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
diff --git a/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java b/src/java/org/apache/poi/hssf/record/cf/CellRangeUtil.java
deleted file mode 100644 (file)
index cde666a..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/* ====================================================================
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-==================================================================== */
-
-package org.apache.poi.hssf.record.cf;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.poi.ss.util.CellRangeAddress;
-
-/**
- * TODO Should this move to org.apache.poi.ss.util ?
- */
-public final class CellRangeUtil {
-    private CellRangeUtil() {
-        // no instance of this class
-    }
-
-    public static final int NO_INTERSECTION = 1;
-    public static final int OVERLAP = 2;
-    /** first range is within the second range */
-    public static final int INSIDE = 3;
-    /** first range encloses or is equal to the second */
-    public static final int ENCLOSES = 4;
-
-    /**
-     * Intersect this range with the specified range.
-     * 
-     * @param crB - the specified range
-     * @return code which reflects how the specified range is related to this range.<br/>
-     * Possible return codes are:      
-     *                 NO_INTERSECTION - the specified range is outside of this range;<br/> 
-     *                 OVERLAP - both ranges partially overlap;<br/>
-     *                 INSIDE - the specified range is inside of this one<br/>
-     *                 ENCLOSES - the specified range encloses (possibly exactly the same as) this range<br/>
-     */
-    public static int intersect(CellRangeAddress crA, CellRangeAddress crB )
-    {
-
-        int firstRow = crB.getFirstRow();
-        int lastRow  = crB.getLastRow();
-        int firstCol = crB.getFirstColumn();
-        int lastCol  = crB.getLastColumn();
-
-        if
-        ( 
-                               gt(crA.getFirstRow(),lastRow) || 
-                               lt(crA.getLastRow(),firstRow) ||
-                               gt(crA.getFirstColumn(),lastCol) || 
-                               lt(crA.getLastColumn(),firstCol) 
-        )
-        {
-            return NO_INTERSECTION;
-        }
-        else if( contains(crA, crB) )
-        {
-            return INSIDE;
-        }
-        else if( contains(crB, crA))
-        {
-            return ENCLOSES;
-        }
-        else
-        {
-            return OVERLAP;
-        }
-    }
-
-    /**
-     * Do all possible cell merges between cells of the list so that:<br>
-     *         <li>if a cell range is completely inside of another cell range, it gets removed from the list 
-     *         <li>if two cells have a shared border, merge them into one bigger cell range
-     * @param cellRanges
-     * @return updated List of cell ranges
-     */
-    public static CellRangeAddress[] mergeCellRanges(CellRangeAddress[] cellRanges) {
-        if(cellRanges.length < 1) {
-            return cellRanges;
-        }
-
-        List<CellRangeAddress> lst = new ArrayList<CellRangeAddress>();
-        for(CellRangeAddress cr : cellRanges) {
-            lst.add(cr);
-        }
-        List<CellRangeAddress> temp = mergeCellRanges(lst);
-        return toArray(temp);
-    }
-
-    private static List<CellRangeAddress> mergeCellRanges(List<CellRangeAddress> cellRangeList)
-    {
-        // loop until either only one item is left or we did not merge anything any more
-        while (cellRangeList.size() > 1) {
-            boolean somethingGotMerged = false;
-
-            // look at all cell-ranges
-            for (int i = 0; i < cellRangeList.size(); i++) {
-                CellRangeAddress range1 = cellRangeList.get(i);
-
-                // compare each cell range to all other cell-ranges
-                for (int j = i + 1; j < cellRangeList.size(); j++) {
-                    CellRangeAddress range2 = cellRangeList.get(j);
-
-                    CellRangeAddress[] mergeResult = mergeRanges(range1, range2);
-                    if (mergeResult == null) {
-                        continue;
-                    }
-                    somethingGotMerged = true;
-                    // overwrite range1 with first result
-                    cellRangeList.set(i, mergeResult[0]);
-                    // remove range2
-                    cellRangeList.remove(j--);
-                    // add any extra results beyond the first
-                    for (int k = 1; k < mergeResult.length; k++) {
-                        j++;
-                        cellRangeList.add(j, mergeResult[k]);
-                    }
-                }
-            }
-            if (!somethingGotMerged) {
-                break;
-            }
-        }
-
-        return cellRangeList;
-    }
-
-    /**
-     * @return the new range(s) to replace the supplied ones.  <code>null</code> if no merge is possible
-     */
-    private static CellRangeAddress[] mergeRanges(CellRangeAddress range1, CellRangeAddress range2) {
-        int x = intersect(range1, range2);
-        switch(x)
-        {
-                       case CellRangeUtil.NO_INTERSECTION: 
-                           // nothing in common: at most they could be adjacent to each other and thus form a single bigger area  
-                               if(hasExactSharedBorder(range1, range2)) {
-                                       return new CellRangeAddress[] { createEnclosingCellRange(range1, range2), };
-                               }
-                               // else - No intersection and no shared border: do nothing 
-                               return null;
-                       case CellRangeUtil.OVERLAP:
-                           // commented out the cells overlap implementation, it caused endless loops, see Bug 55380
-                           // disabled for now, the algorithm will not detect some border cases this way currently!
-                               //return resolveRangeOverlap(range1, range2);
-                           return null;
-                       case CellRangeUtil.INSIDE:
-                               // Remove range2, since it is completely inside of range1
-                               return new CellRangeAddress[] { range1 };
-                       case CellRangeUtil.ENCLOSES:
-                               // range2 encloses range1, so replace it with the enclosing one
-                               return new CellRangeAddress[] { range2 };
-               }
-               throw new RuntimeException("unexpected intersection result (" + x + ")");
-       }
-
-    private static CellRangeAddress[] toArray(List<CellRangeAddress> temp) {
-        CellRangeAddress[] result = new CellRangeAddress[temp.size()];
-        temp.toArray(result);
-        return result;
-    }
-
-    /**
-     *  Check if the specified range is located inside of this cell range.
-     *  
-     * @param crB
-     * @return true if this cell range contains the argument range inside if it's area
-     */
-    public static boolean contains(CellRangeAddress crA, CellRangeAddress crB)
-    {
-        int firstRow = crB.getFirstRow();
-        int lastRow = crB.getLastRow();
-        int firstCol = crB.getFirstColumn();
-        int lastCol = crB.getLastColumn();
-        return le(crA.getFirstRow(), firstRow) && ge(crA.getLastRow(), lastRow)
-                && le(crA.getFirstColumn(), firstCol) && ge(crA.getLastColumn(), lastCol);
-    }
-
-    /**
-     * Check if the two cell ranges have a shared border.
-     * 
-     * @return <code>true</code> if the ranges have a complete shared border (i.e.
-     * the two ranges together make a simple rectangular region.
-     */
-    public static boolean hasExactSharedBorder(CellRangeAddress crA, CellRangeAddress crB) {
-        int oFirstRow = crB.getFirstRow();
-        int oLastRow  = crB.getLastRow();
-        int oFirstCol = crB.getFirstColumn();
-        int oLastCol  = crB.getLastColumn();
-
-        if (crA.getFirstRow() > 0 && crA.getFirstRow()-1 == oLastRow || 
-                oFirstRow > 0 && oFirstRow-1 == crA.getLastRow()) {
-            // ranges have a horizontal border in common
-            // make sure columns are identical:
-            return crA.getFirstColumn() == oFirstCol && crA.getLastColumn() == oLastCol;
-        }
-
-        if (crA.getFirstColumn()>0 && crA.getFirstColumn() - 1 == oLastCol ||
-                oFirstCol>0 && crA.getLastColumn() == oFirstCol -1) {
-            // ranges have a vertical border in common
-            // make sure rows are identical:
-            return crA.getFirstRow() == oFirstRow && crA.getLastRow() == oLastRow;
-        }
-        return false;
-    }
-
-    /**
-     * Create an enclosing CellRange for the two cell ranges.
-     * 
-     * @return enclosing CellRange
-     */
-    public static CellRangeAddress createEnclosingCellRange(CellRangeAddress crA, CellRangeAddress crB) {
-        if( crB == null) {
-            return crA.copy();
-        }
-
-        return new CellRangeAddress(
-                   lt(crB.getFirstRow(),   crA.getFirstRow())   ?crB.getFirstRow()   :crA.getFirstRow(),
-                   gt(crB.getLastRow(),    crA.getLastRow())    ?crB.getLastRow()    :crA.getLastRow(),
-                   lt(crB.getFirstColumn(),crA.getFirstColumn())?crB.getFirstColumn():crA.getFirstColumn(),
-                   gt(crB.getLastColumn(), crA.getLastColumn()) ?crB.getLastColumn() :crA.getLastColumn()
-        );
-    }
-
-    /**
-     * @return true if a < b
-     */
-    private static boolean lt(int a, int b)
-    {
-        return a == -1 ? false : (b == -1 ? true : a < b);
-    }
-
-    /**
-     * @return true if a <= b
-     */
-    private static boolean le(int a, int b)
-    {
-        return a == b || lt(a,b);
-    }
-
-    /**
-     * @return true if a > b
-     */
-    private static boolean gt(int a, int b)
-    {
-        return lt(b,a);
-    }
-
-    /**
-     * @return true if a >= b
-     */
-    private static boolean ge(int a, int b)
-    {
-        return !lt(a,b);
-    }
-}
diff --git a/src/java/org/apache/poi/ss/util/CellRangeUtil.java b/src/java/org/apache/poi/ss/util/CellRangeUtil.java
new file mode 100644 (file)
index 0000000..3ecba18
--- /dev/null
@@ -0,0 +1,264 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.ss.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class CellRangeUtil {
+    private CellRangeUtil() {
+        // no instance of this class
+    }
+
+    public static final int NO_INTERSECTION = 1;
+    public static final int OVERLAP = 2;
+    /** first range is within the second range */
+    public static final int INSIDE = 3;
+    /** first range encloses or is equal to the second */
+    public static final int ENCLOSES = 4;
+
+    /**
+     * Intersect this range with the specified range.
+     * 
+     * @param crB - the specified range
+     * @return code which reflects how the specified range is related to this range.<br/>
+     * Possible return codes are:      
+     *                 NO_INTERSECTION - the specified range is outside of this range;<br/> 
+     *                 OVERLAP - both ranges partially overlap;<br/>
+     *                 INSIDE - the specified range is inside of this one<br/>
+     *                 ENCLOSES - the specified range encloses (possibly exactly the same as) this range<br/>
+     */
+    public static int intersect(CellRangeAddress crA, CellRangeAddress crB )
+    {
+
+        int firstRow = crB.getFirstRow();
+        int lastRow  = crB.getLastRow();
+        int firstCol = crB.getFirstColumn();
+        int lastCol  = crB.getLastColumn();
+
+        if
+        ( 
+                               gt(crA.getFirstRow(),lastRow) || 
+                               lt(crA.getLastRow(),firstRow) ||
+                               gt(crA.getFirstColumn(),lastCol) || 
+                               lt(crA.getLastColumn(),firstCol) 
+        )
+        {
+            return NO_INTERSECTION;
+        }
+        else if( contains(crA, crB) )
+        {
+            return INSIDE;
+        }
+        else if( contains(crB, crA))
+        {
+            return ENCLOSES;
+        }
+        else
+        {
+            return OVERLAP;
+        }
+    }
+
+    /**
+     * Do all possible cell merges between cells of the list so that:<br>
+     *         <li>if a cell range is completely inside of another cell range, it gets removed from the list 
+     *         <li>if two cells have a shared border, merge them into one bigger cell range
+     * @param cellRanges
+     * @return updated List of cell ranges
+     */
+    public static CellRangeAddress[] mergeCellRanges(CellRangeAddress[] cellRanges) {
+        if(cellRanges.length < 1) {
+            return cellRanges;
+        }
+
+        List<CellRangeAddress> lst = new ArrayList<CellRangeAddress>();
+        for(CellRangeAddress cr : cellRanges) {
+            lst.add(cr);
+        }
+        List<CellRangeAddress> temp = mergeCellRanges(lst);
+        return toArray(temp);
+    }
+
+    private static List<CellRangeAddress> mergeCellRanges(List<CellRangeAddress> cellRangeList)
+    {
+        // loop until either only one item is left or we did not merge anything any more
+        while (cellRangeList.size() > 1) {
+            boolean somethingGotMerged = false;
+
+            // look at all cell-ranges
+            for (int i = 0; i < cellRangeList.size(); i++) {
+                CellRangeAddress range1 = cellRangeList.get(i);
+
+                // compare each cell range to all other cell-ranges
+                for (int j = i + 1; j < cellRangeList.size(); j++) {
+                    CellRangeAddress range2 = cellRangeList.get(j);
+
+                    CellRangeAddress[] mergeResult = mergeRanges(range1, range2);
+                    if (mergeResult == null) {
+                        continue;
+                    }
+                    somethingGotMerged = true;
+                    // overwrite range1 with first result
+                    cellRangeList.set(i, mergeResult[0]);
+                    // remove range2
+                    cellRangeList.remove(j--);
+                    // add any extra results beyond the first
+                    for (int k = 1; k < mergeResult.length; k++) {
+                        j++;
+                        cellRangeList.add(j, mergeResult[k]);
+                    }
+                }
+            }
+            if (!somethingGotMerged) {
+                break;
+            }
+        }
+
+        return cellRangeList;
+    }
+
+    /**
+     * @return the new range(s) to replace the supplied ones.  <code>null</code> if no merge is possible
+     */
+    private static CellRangeAddress[] mergeRanges(CellRangeAddress range1, CellRangeAddress range2) {
+        int x = intersect(range1, range2);
+        switch(x)
+        {
+                       case CellRangeUtil.NO_INTERSECTION: 
+                           // nothing in common: at most they could be adjacent to each other and thus form a single bigger area  
+                               if(hasExactSharedBorder(range1, range2)) {
+                                       return new CellRangeAddress[] { createEnclosingCellRange(range1, range2), };
+                               }
+                               // else - No intersection and no shared border: do nothing 
+                               return null;
+                       case CellRangeUtil.OVERLAP:
+                           // commented out the cells overlap implementation, it caused endless loops, see Bug 55380
+                           // disabled for now, the algorithm will not detect some border cases this way currently!
+                               //return resolveRangeOverlap(range1, range2);
+                           return null;
+                       case CellRangeUtil.INSIDE:
+                               // Remove range2, since it is completely inside of range1
+                               return new CellRangeAddress[] { range1 };
+                       case CellRangeUtil.ENCLOSES:
+                               // range2 encloses range1, so replace it with the enclosing one
+                               return new CellRangeAddress[] { range2 };
+               }
+               throw new RuntimeException("unexpected intersection result (" + x + ")");
+       }
+
+    private static CellRangeAddress[] toArray(List<CellRangeAddress> temp) {
+        CellRangeAddress[] result = new CellRangeAddress[temp.size()];
+        temp.toArray(result);
+        return result;
+    }
+
+    /**
+     *  Check if the specified range is located inside of this cell range.
+     *  
+     * @param crB
+     * @return true if this cell range contains the argument range inside if it's area
+     */
+    public static boolean contains(CellRangeAddress crA, CellRangeAddress crB)
+    {
+        int firstRow = crB.getFirstRow();
+        int lastRow = crB.getLastRow();
+        int firstCol = crB.getFirstColumn();
+        int lastCol = crB.getLastColumn();
+        return le(crA.getFirstRow(), firstRow) && ge(crA.getLastRow(), lastRow)
+                && le(crA.getFirstColumn(), firstCol) && ge(crA.getLastColumn(), lastCol);
+    }
+
+    /**
+     * Check if the two cell ranges have a shared border.
+     * 
+     * @return <code>true</code> if the ranges have a complete shared border (i.e.
+     * the two ranges together make a simple rectangular region.
+     */
+    public static boolean hasExactSharedBorder(CellRangeAddress crA, CellRangeAddress crB) {
+        int oFirstRow = crB.getFirstRow();
+        int oLastRow  = crB.getLastRow();
+        int oFirstCol = crB.getFirstColumn();
+        int oLastCol  = crB.getLastColumn();
+
+        if (crA.getFirstRow() > 0 && crA.getFirstRow()-1 == oLastRow || 
+                oFirstRow > 0 && oFirstRow-1 == crA.getLastRow()) {
+            // ranges have a horizontal border in common
+            // make sure columns are identical:
+            return crA.getFirstColumn() == oFirstCol && crA.getLastColumn() == oLastCol;
+        }
+
+        if (crA.getFirstColumn()>0 && crA.getFirstColumn() - 1 == oLastCol ||
+                oFirstCol>0 && crA.getLastColumn() == oFirstCol -1) {
+            // ranges have a vertical border in common
+            // make sure rows are identical:
+            return crA.getFirstRow() == oFirstRow && crA.getLastRow() == oLastRow;
+        }
+        return false;
+    }
+
+    /**
+     * Create an enclosing CellRange for the two cell ranges.
+     * 
+     * @return enclosing CellRange
+     */
+    public static CellRangeAddress createEnclosingCellRange(CellRangeAddress crA, CellRangeAddress crB) {
+        if( crB == null) {
+            return crA.copy();
+        }
+
+        return new CellRangeAddress(
+                   lt(crB.getFirstRow(),   crA.getFirstRow())   ?crB.getFirstRow()   :crA.getFirstRow(),
+                   gt(crB.getLastRow(),    crA.getLastRow())    ?crB.getLastRow()    :crA.getLastRow(),
+                   lt(crB.getFirstColumn(),crA.getFirstColumn())?crB.getFirstColumn():crA.getFirstColumn(),
+                   gt(crB.getLastColumn(), crA.getLastColumn()) ?crB.getLastColumn() :crA.getLastColumn()
+        );
+    }
+
+    /**
+     * @return true if a < b
+     */
+    private static boolean lt(int a, int b)
+    {
+        return a == -1 ? false : (b == -1 ? true : a < b);
+    }
+
+    /**
+     * @return true if a <= b
+     */
+    private static boolean le(int a, int b)
+    {
+        return a == b || lt(a,b);
+    }
+
+    /**
+     * @return true if a > b
+     */
+    private static boolean gt(int a, int b)
+    {
+        return lt(b,a);
+    }
+
+    /**
+     * @return true if a >= b
+     */
+    private static boolean ge(int a, int b)
+    {
+        return !lt(a,b);
+    }
+}
index 82eddd46d8d4eddf2260d775f54489d1f6ebf3b6..a3781d22dd1c2c447ae0cddd85afcd3653387963 100644 (file)
@@ -22,7 +22,6 @@ package org.apache.poi.xssf.usermodel;
 import java.util.ArrayList;\r
 import java.util.List;\r
 \r
-import org.apache.poi.hssf.record.cf.CellRangeUtil;\r
 import org.apache.poi.ss.SpreadsheetVersion;\r
 import org.apache.poi.ss.usermodel.ComparisonOperator;\r
 import org.apache.poi.ss.usermodel.ConditionalFormatting;\r
@@ -31,6 +30,7 @@ import org.apache.poi.ss.usermodel.ExtendedColor;
 import org.apache.poi.ss.usermodel.IconMultiStateFormatting.IconSet;\r
 import org.apache.poi.ss.usermodel.SheetConditionalFormatting;\r
 import org.apache.poi.ss.util.CellRangeAddress;\r
+import org.apache.poi.ss.util.CellRangeUtil;\r
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;\r
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting;\r
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;\r
index f01a2a3912f9031da7fa8d3c3532bbab42634462..54f1702e23ca6c1e678d771502161b526cf23519 100644 (file)
@@ -23,6 +23,7 @@ import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
 import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellRangeUtil;
 
 /**
  * Tests CellRange operations.