001 /* 002 * Copyright (c) 2006 Henri Sivonen 003 * 004 * Permission is hereby granted, free of charge, to any person obtaining a 005 * copy of this software and associated documentation files (the "Software"), 006 * to deal in the Software without restriction, including without limitation 007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 008 * and/or sell copies of the Software, and to permit persons to whom the 009 * Software is furnished to do so, subject to the following conditions: 010 * 011 * The above copyright notice and this permission notice shall be included in 012 * all copies or substantial portions of the Software. 013 * 014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 017 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 019 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 020 * DEALINGS IN THE SOFTWARE. 021 */ 022 023 package org.whattf.checker.table; 024 025 import org.xml.sax.Locator; 026 027 /** 028 * Represents a contiguous range of columns that was established by a single 029 * element and that does not yet have cells in it. 030 * 031 * @version $Id: ColumnRange.java 189 2007-10-08 11:27:05Z hsivonen $ 032 * @author hsivonen 033 */ 034 final class ColumnRange { 035 036 /** 037 * The locator associated with the element that established this column range. 038 */ 039 private final Locator locator; 040 041 /** 042 * The local name of the element that established this column range. 043 */ 044 private final String element; 045 046 /** 047 * The leftmost column that is part of this range. 048 */ 049 private int left; 050 051 /** 052 * The first column to the right that is not part of this range. 053 */ 054 private int right; 055 056 /** 057 * The next range in the linked list of ranges. 058 */ 059 private ColumnRange next; 060 061 /** 062 * Constructor 063 * @param element the local name of the establishing element 064 * @param locator a locator associated with the establishing element; 065 * <em>must be suitable for retaining out-of-SAX-event!</em> 066 * @param left the leftmost column that is part of this range 067 * @param right the first column to the right that is not part of this range 068 */ 069 public ColumnRange(String element, Locator locator, int left, int right) { 070 super(); 071 assert right > left; 072 this.element = element; 073 this.locator = locator; 074 this.left = left; 075 this.right = right; 076 this.next = null; 077 } 078 079 /** 080 * Returns the element. 081 * 082 * @return the element 083 */ 084 String getElement() { 085 return element; 086 } 087 088 /** 089 * Returns the locator. 090 * 091 * @return the locator 092 */ 093 Locator getLocator() { 094 return locator; 095 } 096 097 /** 098 * Hit testing. 099 * @param column column index 100 * @return -1 if the column is to the left of this range, 101 * 0 if the column is in this range and 102 * 1 if the column is to the right of this range 103 */ 104 int hits(int column) { 105 if (column < left) { 106 return -1; 107 } if (column >= right) { 108 return 1; 109 } else { 110 return 0; 111 } 112 } 113 114 /** 115 * Removes a column from the range possibly asking it to be destroyed or 116 * splitting it. 117 * @param column a column index 118 * @return <code>null</code> if this range gets destroyed, 119 * <code>this</code> if the range gets resized and 120 * the new right half range if the range gets split 121 */ 122 ColumnRange removeColumn(int column) { 123 // first, let's see if this is a 1-column range that should 124 // be destroyed 125 if (isSingleCol()) { 126 return null; 127 } else if (column == left) { 128 left++; 129 return this; 130 } else if (column + 1 == right) { 131 right--; 132 return this; 133 } else { 134 ColumnRange created = new ColumnRange(this.element, this.locator, 135 column + 1, this.right); 136 created.next = this.next; 137 this.next = created; 138 this.right = column; 139 return created; 140 } 141 } 142 143 /** 144 * Returns the next. 145 * 146 * @return the next 147 */ 148 ColumnRange getNext() { 149 return next; 150 } 151 152 /** 153 * Sets the next. 154 * 155 * @param next the next to set 156 */ 157 void setNext(ColumnRange next) { 158 this.next = next; 159 } 160 161 boolean isSingleCol() { 162 return left + 1 == right; 163 } 164 165 /** 166 * @see java.lang.Object#toString() 167 */ 168 public String toString() { 169 if (isSingleCol()) { 170 return Integer.toString(right); 171 } else { 172 return (left + 1) + "\u2026" + (right); 173 } 174 } 175 176 }