2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.datamodel.features;
23 import jalview.datamodel.ContiguousI;
25 import java.util.ArrayList;
26 import java.util.List;
29 * Each node of the NCList tree consists of a range, and (optionally) the NCList
30 * of ranges it encloses
34 class NCNode<V extends ContiguousI> implements ContiguousI
37 * deep size (number of ranges included)
44 * null, or an object holding contained subregions of this nodes region
46 private NCList<V> subregions;
49 * Constructor given a list of ranges
53 NCNode(List<V> ranges)
59 * Constructor given a single range
65 List<V> ranges = new ArrayList<>();
70 NCNode(V entry, NCList<V> newNCList)
73 subregions = newNCList;
74 size = 1 + newNCList.size();
80 protected void build(List<V> ranges)
84 if (!ranges.isEmpty())
86 region = ranges.get(0);
88 if (ranges.size() > 1)
90 subregions = new NCList<V>(ranges.subList(1, ranges.size()));
97 return region.getBegin();
103 return region.getEnd();
107 * Formats the node as a bracketed list e.g.
110 * [1-100 [10-30 [10-20]], 15-30 [20-20]]
114 public String toString() {
115 StringBuilder sb = new StringBuilder(10 * size);
116 sb.append(region.getBegin()).append("-").append(region.getEnd());
117 if (subregions != null)
119 sb.append(" ").append(subregions.toString());
121 return sb.toString();
124 void prettyPrint(StringBuilder sb, int offset, int indent) {
125 for (int i = 0 ; i < offset ; i++) {
128 sb.append(region.getBegin()).append("-").append(region.getEnd());
129 if (subregions != null)
131 sb.append(System.lineSeparator());
132 subregions.prettyPrint(sb, offset + 2, indent);
136 * Add any ranges that overlap the from-to range to the result list
142 void findOverlaps(long from, long to, List<V> result)
144 if (region.getBegin() <= to && region.getEnd() >= from)
148 if (subregions != null)
150 subregions.findOverlaps(from, to, result);
155 * Add one range to this subrange
159 synchronized void add(V entry)
161 if (entry.getBegin() < region.getBegin() || entry.getEnd() > region.getEnd()) {
162 throw new IllegalArgumentException(String.format(
163 "adding improper subrange %d-%d to range %d-%d",
164 entry.getBegin(), entry.getEnd(), region.getBegin(),
167 if (subregions == null)
169 subregions = new NCList<V>(entry);
173 subregions.add(entry);
179 * Answers true if the data held satisfy the rules of construction of an
180 * NCList, else false.
187 * we don't handle reverse ranges
189 if (region != null && region.getBegin() > region.getEnd())
193 if (subregions == null)
197 return subregions.isValid(getBegin(), getEnd());
201 * Adds all contained entries to the given list
205 void getEntries(List<V> entries)
208 if (subregions != null)
210 subregions.getEntries(entries);
215 * Answers true if this object contains the given entry (by object equals
221 boolean contains(V entry)
227 if (entry.equals(region))
231 return subregions == null ? false : subregions.contains(entry);
235 * Answers the 'root' region modelled by this object
245 * Answers the (possibly null) contained regions within this object
249 NCList<V> getSubRegions()
255 * Nulls the subregion reference if it is empty (after a delete entry
258 void deleteSubRegionsIfEmpty()
260 if (subregions != null && subregions.size() == 0)
267 * Answers the (deep) size of this node i.e. the number of ranges it models