org.apache.james.imap.api.message.UidRange Maven / Gradle / Ivy
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.imap.api.message;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.james.mailbox.MessageUid;
import org.apache.james.mailbox.model.MessageRange;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet;
public final class UidRange implements Iterable {
public static String toString(UidRange[] ranges) {
return Optional.ofNullable(ranges)
.map(ImmutableList::copyOf)
.toString();
}
public static List mergeRanges(List ranges) {
if (ranges.isEmpty()) {
return ranges;
}
RangeSet rangeSet = createSortedRangeSet(ranges);
List> mergedRanges = mergeContiguousRanges(rangeSet);
return toUidRanges(mergedRanges);
}
private static RangeSet createSortedRangeSet(List ranges) {
RangeSet rangeSet = TreeRangeSet.create();
for (UidRange range: ranges) {
rangeSet.add(Range.closed(range.getLowVal(), range.getHighVal()));
}
return rangeSet;
}
private static LinkedList> mergeContiguousRanges(RangeSet rangeSet) {
LinkedList> mergedRanges = new LinkedList<>();
for (Range range: rangeSet.asRanges()) {
Range previous = mergedRanges.peekLast();
if (rangesShouldBeMerged(range, previous)) {
replaceLastRange(mergedRanges, mergeRanges(range, previous));
} else {
mergedRanges.add(range);
}
}
return mergedRanges;
}
private static boolean rangesShouldBeMerged(Range range, Range previous) {
return previous != null && previous.upperEndpoint().distance(range.lowerEndpoint()) <= 1;
}
private static void replaceLastRange(LinkedList> mergedRanges, Range newRange) {
mergedRanges.removeLast();
mergedRanges.add(newRange);
}
private static Range mergeRanges(Range range, Range previous) {
return Range.closed(previous.lowerEndpoint(), range.upperEndpoint());
}
private static LinkedList toUidRanges(List> mergedRanges) {
return mergedRanges.stream()
.map(range -> new UidRange(range.lowerEndpoint(), range.upperEndpoint()))
.collect(Collectors.toCollection(LinkedList::new));
}
private final MessageRange range;
public UidRange(MessageUid singleVal) {
this.range = singleVal.toRange();
}
public UidRange(MessageUid minValue, MessageUid messageUid) {
if (minValue.compareTo(messageUid) > 0) {
throw new IllegalArgumentException("LowVal must be <= HighVal");
}
this.range = MessageRange.range(minValue, messageUid);
}
public MessageUid getLowVal() {
return range.getUidFrom();
}
public MessageUid getHighVal() {
return range.getUidTo();
}
public boolean includes(MessageUid value) {
return range.includes(value);
}
public int hashCode() {
return Objects.hashCode(range);
}
public boolean equals(Object obj) {
if (obj instanceof UidRange) {
UidRange other = (UidRange) obj;
return Objects.equal(this.range, other.range);
}
return false;
}
public String toString() {
return "IdRange : " + range.toString();
}
public String getFormattedString() {
if (range.getUidFrom().equals(range.getUidTo())) {
return String.valueOf(range.getUidFrom().asLong());
} else {
return range.getUidFrom().asLong() + ":" + range.getUidTo().asLong();
}
}
@Override
public Iterator iterator() {
return range.iterator();
}
public MessageRange toMessageRange() {
return range;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy