001 /*
002 * ????
003 * 1/5/2006 this code was copied from the Knowtator annotation tool
004 * for internal use at Mayo. The Knowtator code was originally copied
005 * from the WordFreak library and modified extensively for Knowtator.
006 *
007 * The contents of this file are subject to the Mozilla Public
008 * License Version 1.1 (the "License"); you may not use this file
009 * except in compliance with the License. You may obtain a copy of
010 * the License at http://www.mozilla.org/MPL/
011 *
012 * Software distributed under the License is distributed on an "AS
013 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
014 * implied. See the License for the specific language governing
015 * rights and limitations under the License.
016 *
017 * The Original Code is the WordFreak annotation tool.
018 *
019 * The Initial Developer of the Original Code is Thomas S. Morton
020 * Copyright (C) 2002. All Rights Reserved.
021 *
022 * Contributor(s):
023 * Thomas S. Morton <tsmorton@cis.upenn.edu> (Original Author)
024 * Jeremy LaCivita <lacivita@linc.cis.upenn.edu>
025 */
026
027 /**
028 * This code was taken from the wordfreak project and modified for Knowtator. See
029 * license above for more information.
030 *
031 */
032 package edu.uchsc.ccp.iaa;
033
034 import java.util.List;
035
036 public class Span implements Comparable {
037 private int start;
038
039 private int end;
040
041 public Span(int start, int end) {
042 this.start = start;
043 this.end = end;
044 if (start > end) {
045 throw new IndexOutOfBoundsException(
046 "Span is invalid because the start of the span is greater than the end of it: start=" + start
047 + " end=" + end);
048 }
049 if (start < 0) {
050 throw new IndexOutOfBoundsException(
051 "Span is invalid because the start of the span is less than zero: start=" + start);
052 }
053 }
054
055 public static boolean isValid(int start, int end) {
056 if (start > end || start < 0)
057 return false;
058 return true;
059 }
060
061 public int length() {
062 return end - start;
063 }
064
065 public int getStart() {
066 return start;
067 }
068
069 public int getEnd() {
070 return end;
071 }
072
073 /**
074 * @return the length of the span (end - start)
075 *
076 */
077 public int getSize() {
078 return getEnd() - getStart();
079 }
080
081 public int compareTo(Object object) {
082 Span span = (Span) object;
083 if (getStart() < span.getStart()) {
084 return -1;
085 } else if (getStart() == span.getStart()) {
086 if (getEnd() > span.getEnd()) {
087 return -1;
088 } else if (getEnd() < span.getEnd()) {
089 return 1;
090 } else {
091 return 0;
092 }
093 } else {
094 return 1;
095 }
096 }
097
098 public String toString() {
099 return "" + start + "|" + end;
100 }
101
102 public boolean equals(Object object) {
103 if (object == null || !(object instanceof Span)) {
104 return false;
105 }
106 Span span = (Span) object;
107 return getStart() == span.getStart() && getEnd() == span.getEnd();
108 }
109
110 public int hashCode() {
111 return ((this.start << 16) | (0x0000FFFF | this.end));
112 }
113
114 public boolean contains(Span span) {
115 return (getStart() <= span.getStart() && span.getEnd() <= getEnd());
116 }
117
118 public boolean contains(int i) {
119 return (getStart() <= i && i < getEnd());
120 }
121
122 /**
123 * we need some junit tests
124 */
125 public boolean intersects(Span span) {
126 int spanStart = span.getStart();
127 // either span's start is in this or this' start is in span
128 return this.contains(span)
129 || span.contains(this)
130 || (getStart() <= spanStart && spanStart < getEnd() || spanStart <= getStart()
131 && getStart() < span.getEnd());
132 }
133
134 public boolean crosses(Span span) {
135 int spanStart = span.getStart();
136
137 // either s's start is in this or this' start is in s
138 return !this.contains(span)
139 && !span.contains(this)
140 && (getStart() <= spanStart && spanStart < getEnd() || spanStart <= getStart()
141 && getStart() < span.getEnd());
142 }
143
144 public boolean lessThan(Span span) {
145 return getStart() < span.getStart() && getEnd() < span.getEnd();
146 }
147
148 public boolean greaterThan(Span span) {
149 return getStart() > span.getStart() && getEnd() > span.getEnd();
150 }
151
152 public static Span parseSpan(String spanString) {
153 String startString = spanString.substring(0, spanString.indexOf("|"));
154 String endString = spanString.substring(spanString.indexOf("|") + 1);
155 int start = Integer.parseInt(startString);
156 int end = Integer.parseInt(endString);
157 return new Span(start, end);
158 }
159
160 public static boolean intersects(List<Span> spans1, List<Span> spans2) {
161 for (Span span1 : spans1) {
162 for (Span span2 : spans2) {
163 if (span1.intersects(span2))
164 return true;
165 }
166 }
167 return false;
168 }
169
170 /**
171 * This method assumes that the both lists of spans are sorted the same way
172 * and that a span in one list at the same index as a span in the other list
173 * should be the same.
174 *
175 * @param spans1
176 * sorted list of spans
177 * @param spans2
178 * sorted list of spans
179 * @return true if the two lists of spans are the same.
180 */
181 public static boolean spansMatch(List<Span> spans1, List<Span> spans2) {
182 if (spans1.size() == spans2.size()) {
183 for (int i = 0; i < spans1.size(); i++) {
184 if (!spans1.get(i).equals(spans2.get(i))) {
185 return false;
186 }
187 }
188 return true;
189 }
190 return false;
191 }
192
193 public static Span shortest(List<Span> spans) {
194 if (spans.size() == 0)
195 return null;
196 if (spans.size() == 1)
197 return spans.get(0);
198
199 Span shortestSpan = spans.get(0);
200 int shortestSize = shortestSpan.getSize();
201 for (int i = 1; i < spans.size(); i++) {
202 if (spans.get(i).getSize() < shortestSize) {
203 shortestSpan = spans.get(i);
204 shortestSize = shortestSpan.getSize();
205 }
206 }
207
208 return shortestSpan;
209 }
210
211 public static String substring(String string, Span span) {
212 int start = Math.max(0, span.getStart());
213 start = Math.min(start, string.length() - 1);
214 int end = Math.max(0, span.getEnd());
215 end = Math.min(end, string.length() - 1);
216 return string.substring(start, end);
217 }
218 }