#735: IntRanges.java

projectforge-business/src/main/java/org/projectforge/framework/utils/IntRanges.java Lines: 54 · Author: Kai Reinhard · Type: Java — extends Ranges<Integer> · interface org.projectforge.framework.utils 54 lines · 15 code · 34 comments · 5 blank

Purpose

Represents a union of integer intervals — parses strings like "1,3-5,10-15,20" into a structured set of ranges and individual values, then provides doesMatch(value) to test membership. This is the integer specialization of the generic Ranges<T> abstract base class (#742).

The concrete use case is timesheet week number filtering. When an admin configures "show timesheets for weeks 1-5, 10, and 20-25", that config string is passed to new IntRanges("1-5,10,20-25"), and each timesheet entry's week number is tested with ranges.doesMatch(weekNumber). This is simpler and more readable than building complex SQL WHERE week IN (...) clauses, especially when the range list is configurable per user.

Class hierarchy

Ranges<T extends Comparable<T>>  (abstract, 176 lines)
  └── IntRanges extends Ranges<Integer>  (54 lines, this file)

Ranges handles all the parsing logic — splitting on commas/semicolons (separatorChars = ";,"), detecting hyphens as range delimiters (rangesSeparatorChar = '-'), and building a list of Range<T> objects plus isolated values. IntRanges only provides the concrete parseValue(String) method that converts a string to an Integer — this is the Template Method pattern: the abstract base defines the algorithm, the subclass defines the type conversion.

The parsing algorithm (in Ranges base class)

Given input "1-5,10,20-25":

  1. Split on , or ;["1-5", "10", "20-25"]
  2. For each part, check if it contains -:
    • If yes: split on -, parse both sides → Range(1, 5) or Range(20, 25)
    • If no: parse as single value → add 10 to the values list

The doesMatch(value) method tests against all ranges (using Range.doesMatch() which checks min <= value <= max) and all individual values (using Comparable.compareTo() for exact match). A nullRangeMatchesAlways flag controls behavior when no ranges/values are specified (defaults to false — nothing matches).

Key design details

Usage in the codebase

Primarily used in the timesheet module for week number filtering. The timesheet filter (#598) allows filtering by week numbers — the admin or user enters a range expression like "1-10, 15, 20-25", which is parsed into an IntRanges instance. When displaying timesheets, each entry's week number is tested against the ranges to determine visibility. The Serializable interface (inherited from Ranges) allows the ranges to be saved in user preferences XML.