001/*-------------------------------------------------------------------------+ 002| | 003| Copyright 2005-2011 the ConQAT Project | 004| | 005| Licensed under the Apache License, Version 2.0 (the "License"); | 006| you may not use this file except in compliance with the License. | 007| You may obtain a copy of the License at | 008| | 009| http://www.apache.org/licenses/LICENSE-2.0 | 010| | 011| Unless required by applicable law or agreed to in writing, software | 012| distributed under the License is distributed on an "AS IS" BASIS, | 013| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 014| See the License for the specific language governing permissions and | 015| limitations under the License. | 016+-------------------------------------------------------------------------*/ 017package org.conqat.lib.commons.region; 018 019import java.io.Serializable; 020import java.util.Comparator; 021import java.util.Objects; 022 023import org.conqat.lib.commons.js_export.ExportToJavaScript; 024 025import com.fasterxml.jackson.annotation.JsonProperty; 026 027/** 028 * A simple region with only start and end. If you also need a description 029 * string (origin), use {@link Region}. Both start and end positions are 030 * inclusive. 031 */ 032@ExportToJavaScript 033public class SimpleRegion implements Comparable<SimpleRegion>, Serializable { 034 035 /** Version for serialization. */ 036 private static final long serialVersionUID = 1; 037 038 /** The name of the JSON property name for {@link #start}. */ 039 protected static final String START_PROPERTY = "start"; 040 041 /** The name of the JSON property name for {@link #end}. */ 042 protected static final String END_PROPERTY = "end"; 043 044 /** 045 * Compares {@link SimpleRegion}s first by their start and then by their end. 046 */ 047 public static final Comparator<SimpleRegion> START_AND_END_COMPARATOR = Comparator.comparing(SimpleRegion::getStart) 048 .thenComparing(SimpleRegion::getEnd); 049 050 /** Region start position (inclusive). */ 051 @JsonProperty(START_PROPERTY) 052 private final int start; 053 054 /** Region end position (inclusive). */ 055 @JsonProperty(END_PROPERTY) 056 private final int end; 057 058 /** Constructor. */ 059 public SimpleRegion(int start, int end) { 060 this.start = start; 061 this.end = end; 062 } 063 064 /** Checks if the region contains a position */ 065 public boolean containsPosition(int position) { 066 return (start <= position && end >= position); 067 } 068 069 /** Checks if two regions are overlapping */ 070 public boolean overlaps(SimpleRegion r) { 071 // Region with smaller start value performs overlap check 072 if (r.start < start) { 073 return r.overlaps(this); 074 } 075 076 return (start <= r.start && end >= r.start); 077 } 078 079 /** Checks if two regions are adjacent */ 080 public boolean adjacent(SimpleRegion r) { 081 // Region with smaller start value performs adjacency check 082 if (r.start < start) { 083 return r.adjacent(this); 084 } 085 086 return (end + 1 == r.start); 087 } 088 089 /** 090 * Gets the end position of the region. This may be less than start for an empty 091 * region (see also {@link #isEmpty()}). 092 */ 093 public int getEnd() { 094 return end; 095 } 096 097 /** Gets the start position of the region */ 098 public int getStart() { 099 return start; 100 } 101 102 /** 103 * Gets the length of the region. Empty regions have a length of 0. 104 */ 105 public int getLength() { 106 if (isEmpty()) { 107 return 0; 108 } 109 return end - start + 1; 110 } 111 112 /** Returns whether this region is empty. */ 113 public boolean isEmpty() { 114 return end < start; 115 } 116 117 /** {@inheritDoc} */ 118 @Override 119 public String toString() { 120 return "[" + start + "-" + end + "]"; 121 } 122 123 /** Compares regions by their start position */ 124 @Override 125 public int compareTo(SimpleRegion other) { 126 return Integer.compare(start, other.start); 127 } 128 129 /** 130 * Returns whether start and end of the region is the same as for this region. 131 */ 132 public boolean equalsStartEnd(SimpleRegion other) { 133 return start == other.start && end == other.end; 134 } 135 136 /** {@inheritDoc} */ 137 @Override 138 public int hashCode() { 139 return Objects.hash(start, end); 140 } 141 142 /** {@inheritDoc} */ 143 @Override 144 public boolean equals(Object other) { 145 if (this == other) { 146 return true; 147 } 148 if (other == null) { 149 return false; 150 } 151 if (getClass() != other.getClass()) { 152 return false; 153 } 154 155 SimpleRegion otherRegion = (SimpleRegion) other; 156 return equalsStartEnd(otherRegion); 157 } 158}