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