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    }