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 fi.iki.hsivonen.xml.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,v 1.4 2006/12/01 12:34:30 hsivonen Exp $ 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 this.element = element; 072 this.locator = locator; 073 this.left = left; 074 this.right = right; 075 this.next = null; 076 } 077 078 /** 079 * Returns the element. 080 * 081 * @return the element 082 */ 083 String getElement() { 084 return element; 085 } 086 087 /** 088 * Returns the locator. 089 * 090 * @return the locator 091 */ 092 Locator getLocator() { 093 return locator; 094 } 095 096 /** 097 * Hit testing. 098 * @param column column index 099 * @return -1 if the column is to the left of this range, 100 * 0 if the column is in this range and 101 * 1 if the column is to the right of this range 102 */ 103 int hits(int column) { 104 if (column < left) { 105 return -1; 106 } if (column >= right) { 107 return 1; 108 } else { 109 return 0; 110 } 111 } 112 113 /** 114 * Removes a column from the range possibly asking it to be destroyed or 115 * splitting it. 116 * @param column a column index 117 * @return <code>null</code> if this range gets destroyed, 118 * <code>this</code> if the range gets resized and 119 * the new right half range if the range gets split 120 */ 121 ColumnRange removeColumn(int column) { 122 // first, let's see if this is a 1-column range that should 123 // be destroyed 124 if (isSingleCol()) { 125 return null; 126 } else if (column == left) { 127 left++; 128 return this; 129 } else if (column + 1 == right) { 130 right--; 131 return this; 132 } else { 133 ColumnRange created = new ColumnRange(this.element, this.locator, 134 column + 1, this.right); 135 created.next = this.next; 136 this.next = created; 137 this.right = column; 138 return created; 139 } 140 } 141 142 /** 143 * Returns the next. 144 * 145 * @return the next 146 */ 147 ColumnRange getNext() { 148 return next; 149 } 150 151 /** 152 * Sets the next. 153 * 154 * @param next the next to set 155 */ 156 void setNext(ColumnRange next) { 157 this.next = next; 158 } 159 160 boolean isSingleCol() { 161 return left + 1 == right; 162 } 163 164 /** 165 * @see java.lang.Object#toString() 166 */ 167 public String toString() { 168 if (isSingleCol()) { 169 return Integer.toString(right); 170 } else { 171 return (left + 1) + "\u2026" + (right); 172 } 173 } 174 175 }