001// Copyright (c) 2001 Hursh Jain (http://www.mollypages.org) 002// The Molly framework is freely distributable under the terms of an 003// MIT-style license. For details, see the molly pages web site at: 004// http://www.mollypages.org/. Use, modify, have fun ! 005 006package fc.util; 007 008import java.util.*; 009 010 011/** A set of char ranges. **/ 012public class CharRangeSet 013{ 014CharRange seedRange; 015List union; 016List intersect; 017 018/** 019Constructs a new CharRangeSet with the initial set containing 020only the specified charrange 021 022@param cs the initial charrange 023**/ 024public CharRangeSet(CharRange cs) 025 { 026 Argcheck.notnull(cs); 027 seedRange = cs; 028 //do _not_ lazy instantiate, otherwise have to put in 029 //null checks in other places 030 union = new ArrayList(); 031 intersect = new ArrayList(); 032 } 033 034/** 035Adds this specified range as a union to the existing set of 036ranges (for purposes of {@link inRange(char)} method). 037Overlapping ranges are ok. 038 039@param cs a charrange to unite with 040@throws IllegalArgumentException 041 if the specified range was null 042**/ 043public void union(CharRange r) 044 { 045 Argcheck.notnull(r); 046 union.add(r); 047 } 048 049/** 050Adds the specified range as an intersection to the existing 051ranges (for purposes of {@link inRange(char)} method). 052Overlapping ranges are ok. 053 054@param r the range to add 055**/ 056public void intersection(CharRange r) 057 { 058 Argcheck.notnull(r); 059 intersect.add(r); 060 } 061 062/** 063Consider a set of ranges <tt>A</tt>, <tt>B</tt> added as a union 064(logical <tt>or</tt>) and ranges <tt>C</tt> and <tt>D</tt> added as an 065intersection (logical <tt>and</tt>). A character <tt>c</tt> is in range if 066it exists in: 067 068<blockquote> <tt> 069 070(A.inRange(c) || B.inRange(c) || ...) && C.inRange(c) && D.inRange(c) 071&& ... 072 073</tt></blockquote> 074 075This can be generalized to an arbitrary number of sub ranges. If 076intersection or union ranges don't exist, then they are not 077considered in the above expression. Note, the interaction may be 078subtle if any of the ranges (<tt>A, B, C...</tt>etc) are 079individually negated because in that case the inRange method for 080that negated range would return true if the specified character 081was <b>not</b> in that range. 082 083@return <tt>true</tt> if the passed in character is allowed by this 084 set of ranges. 085 086**/ 087public boolean inRange(char c) 088 { 089 boolean result = seedRange.inRange(c); 090 for (int i = 0, n = union.size(); i < n; i++) { 091 CharRange item = (CharRange) union.get(i); 092 result = result || item.inRange(c); 093 } 094 for (int i = 0, n = intersect.size(); i < n; i++) { 095 CharRange item = (CharRange) intersect.get(i); 096 result = result && item.inRange(c); 097 } 098 return result; 099 } 100 101public String toString() { 102 StringBuffer buf = new StringBuffer(128); 103 buf.append("CharRangeSet:["); 104 105 if (intersect.size() > 0) 106 buf.append("("); 107 108 buf.append(seedRange); 109 110 int len = union.size(); 111 if (len > 0) 112 { 113 buf.append(" || " ); 114 for (int i = 0; i < len; i++) { 115 buf.append(union.get(i).toString()); 116 if (i < (len-1)) 117 buf.append(" || "); 118 } 119 } 120 121 len = intersect.size(); 122 if (len > 0) 123 { 124 buf.append(") && " ); 125 for (int i = 0; i < len; i++) { 126 buf.append(intersect.get(i).toString()); 127 if (i < (len-1)) 128 buf.append(" && "); 129 } 130 } 131 132 buf.append("]"); 133 return buf.toString(); 134 } 135 136 137public static void main(String[] args) 138 { 139 CharRange r = new CharRange('b', 'd'); 140 CharRange r2 = new CharRange('x', 'y'); 141 CharRangeSet crs = new CharRangeSet(r); 142 crs.union(r2); 143 System.out.println("constructed: " + crs); 144 145 //normal 146 test(crs); 147 148 crs.intersection(new CharRange('a', 'x')); 149 System.out.println("added intersection, now: "); 150 System.out.println(crs); 151 test(crs); 152 153 crs.union(new CharRange('a', 'z')); 154 crs.intersection(new CharRange('s', 't')); 155 System.out.println("added union, intersection, now: "); 156 System.out.println(crs); 157 158 test(crs); 159 } 160 161private static void test(CharRangeSet r) 162 { 163 System.out.println("'b' in range:" + r.inRange('b')); 164 System.out.println("'z' in range:" + r.inRange('z')); 165 System.out.println("'s' in range:" + r.inRange('s')); 166 System.out.println("'m' in range:" + r.inRange('m')); 167 } 168}