1 package com.Lomikel.Utils;
2 
3 // Java
4 import java.util.List;
5 import java.util.ArrayList;
6 import java.util.Collections;
7 
8 /** <code>Interval</code> represents interval of {@link String}
9   * with usual interval operations.
10  * @opt attributes
11  * @opt operations
12  * @opt types
13  * @opt visibility
14  * @author <a href="mailto:Julius.Hrivnac@cern.ch">J.Hrivnac</a> */
15public class Interval implements Comparable<Interval> {
16
17  /** Selftest. */
18  public static void main(String[] args) {
19    String[] testArray = {"abc..xyz", "xyz..def", "abc..uvw", "abcd..uvw", "zzz..zzz"};
20    List<Interval> testList = Interval.createList(testArray);
21    Collections.sort(testList);
22    System.out.println("sorted:");
23    for (Interval i : testList) {
24      System.out.println("  " + i);
25      }
26    Interval i1;
27    Interval i2;
28    Interval i3;
29    i1 = new Interval("abc..xyz");
30    i2 = new Interval("def..xyz");
31    System.out.println("min: " + min(i1, i2)); 
32    System.out.println("max: " + max(i1, i2));
33    i1 = new Interval("abc..ijk");
34    i2 = new Interval("def..xyz");
35    i3 = new Interval("uvw..xyz");
36    System.out.println("overlaps("       + i1 + "," + i2 + "): " + i1.overlaps(i2));
37    System.out.println("overlaps("       + i1 + "," + i3 + "): " + i1.overlaps(i3));
38    System.out.println("union("          + i1 + "," + i2 + "): " + i1.union(  i2));
39    System.out.println("union("          + i1 + "," + i3 + "): " + i1.union(  i3));
40    System.out.println("intersection("   + i1 + "," + i2 + "): " + i1.intersection(  i2));
41    System.out.println("intersection("   + i1 + "," + i3 + "): " + i1.intersection(  i3));
42    }
43
44  /** Create from two {@link String}s.
45    * The interval start will be respresented by the smaller
46    * {@link String}, the interval end will be respresented
47    * by the bigger {@link String}.
48    * @param s1 The first {@link String}.
49    * @param s2 The first {@link String}. */
50  public Interval(String s1, String s2) {
51    if (s1.compareTo(s2) < 0) {
52      lo = s1;
53      hi = s2;
54      }
55    else {
56      lo = s2;
57      hi = s1;
58      }
59    expandHash();      
60    }
61    
62  /** Create from one {@link String}.
63    * If input {@link String} contains <em>..</em> separator,
64    * it will be used to extract start and end {@link String}s.
65    * Otherwise start and end will be identical.
66    * @param s The input {@link String}. */
67  public Interval(String s) {
68    String l;
69    String h;
70    int i = s.indexOf("..");
71    if (i < 0) {
72      l = s;
73      h = s;
74      }
75    else {
76      l = s.substring(0    , i       );
77      h = s.substring(i + 2, s.length());
78      }
79    if (l.compareTo(h) < 0) {
80      lo = l;
81      hi = h;
82      }
83    else {
84      lo = h;
85      hi = l;
86      }
87    expandHash();      
88    }
89    
90  /** Add minimal and maximal value after key, if key contanins hash symbol
91    * (which means, that it represents a sequence of keys). */
92  private void expandHash() {
93    if (lo.substring(lo.length() - 1, lo.length()).equals("#")) {
94      lo = lo + "000000000";
95      }
96    if (hi.substring(hi.length() - 1, hi.length()).equals("#")) {
97      hi = hi + Integer.MAX_VALUE;
98      }
99    }
00  
01  /** Create {@link List} of intervals.
02    * @param s The array of {@link Strings} to be converted.
03    * @return  The created {@link List} of intervals. */ 
04  public static List<Interval> createList(String[] s) {
05    List<Interval> list = new ArrayList<Interval>();
06    for (String i : s) {
07      list.add(new Interval(i));
08      }
09    return list;
10    }
11    
12  /** Give the smaller (= first) interval of two.
13    * @param i1 The first interval.
14    * @param i2 The second interval.
15    * @return   The smaller of two intervales. */
16  public static Interval min(Interval i1, Interval i2) {
17    if (i1.compareTo(i2) >= 0) {
18      return i2;
19      }
20    else {
21      return i1;
22      }
23    }
24
25  /** Give the bigger (= second) interval of two.
26    * @param i1 The first interval.
27    * @param i2 The second interval.
28    * @return   The bigger of two intervales. */
29  public static Interval max(Interval i1, Interval i2) {
30    if (i1.compareTo(i2) >= 0) {
31      return i1;
32      }
33    else {
34      return i2;
35      }
36    }
37
38  /** Tell whether two intervals overlap (even on the border).
39    * @param other The other interval.
40    * @return      Whether two intervals overlap. */
41  public boolean overlaps(Interval other) {
42    if (hi.compareTo(other.lo) <= 0 || lo.compareTo(other.hi) >= 0) {
43      return false;
44      }
45    return true;
46    }
47    
48  /** Give union of two intervals.
49    * @param other The other interval.
50    * @return      The union interval. <tt>null</tt> if intervals
51    *               don't overlap. */  
52  public Interval union(Interval other) {
53    if (overlaps(other)) {
54      return new Interval(min(this, other).lo, max(this, other).hi);
55      }
56    return null;
57    }
58    
59  /** Give intersection of two intervals.
60    * @param other The other interval.
61    * @return      The intersection interval. <tt>null</tt> if intervals
62    *               don't overlap. */  
63  public Interval intersection(Interval other) {
64    if (overlaps(other)) {
65      return new Interval(min(this, other).hi, max(this, other).lo);
66      }
67    return null;
68    }
69
70  @Override
71  public int compareTo(Interval other) {
72    if (this.equals(other)) {
73      return 0;
74      }
75    if (lo.equals(other.lo)) {
76      return hi.compareTo(other.hi);
77      }
78    else {
79      return lo.compareTo(other.lo);
80      }
81    }
82
83  @Override
84  public boolean equals(Object other) {
85    if (other instanceof Interval && lo.equals(((Interval)other).lo) && hi.equals(((Interval)other).hi)) {
86      return true;
87      }
88    return false;
89    }
90    
91  @Override
92  public int hashCode() {
93    return lo.hashCode() + hi.hashCode();
94    }
95    
96  @Override
97  public String toString() {
98    return lo + ".." + hi;
99    }
00
01  public String lo;
02  
03  public String hi;
04
05  }
06