1 /* Copyright 2004 The Apache Software Foundation 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 /** 16 * Author: Cezar Andrei ( cezar.andrei at bea.com ) 17 * Date: Apr 25, 2004 18 */ 19 package org.apache.xmlbeans.impl.config; 20 21 import java.util.Set; 22 import java.util.Collections; 23 import java.util.HashSet; 24 25 /** 26 * Reprezents a non finite set of names. 27 * @see NameSetBuilder 28 */ 29 public class NameSet 30 { 31 /** 32 * An empty NameSet, it doesn't contain any name 33 */ 34 public static NameSet EMPTY = new NameSet(true, Collections.EMPTY_SET); 35 /** 36 * The NameSet that contains any name 37 */ 38 public static NameSet EVERYTHING = new NameSet(false, Collections.EMPTY_SET); 39 40 /* 41 There are two big cases: 42 1) - it reprezents "*", ie all except a finite set of names: _isFinite==false 43 2) - if reprezents only a finite set of names: _isFinite==true 44 */ 45 private boolean _isFinite; 46 private Set _finiteSet; 47 48 private NameSet(boolean isFinite, Set finiteSet) 49 { 50 _isFinite = isFinite; 51 _finiteSet = finiteSet; 52 } 53 54 static NameSet newInstance(boolean isFinite, Set finiteSet) 55 { 56 if ( finiteSet.size()==0 ) 57 if ( isFinite ) 58 return NameSet.EMPTY; 59 else 60 return NameSet.EVERYTHING; 61 else 62 { 63 Set fs = new HashSet(); 64 fs.addAll(finiteSet); 65 return new NameSet(isFinite, fs); 66 } 67 } 68 69 private static Set intersectFiniteSets(Set a, Set b) 70 { 71 Set intersection = new HashSet(); 72 //compute the intersection of _finiteSet with withSet 73 while (a.iterator().hasNext()) 74 { 75 String name = (String) a.iterator().next(); 76 if (b.contains(name)) 77 intersection.add(name); 78 } 79 return intersection; 80 } 81 82 /** 83 * Returns the union of this NameSet with the 'with' NameSet. 84 */ 85 public NameSet union(NameSet with) 86 { 87 if (_isFinite) 88 { 89 if (with._isFinite) 90 { 91 Set union = new HashSet(); 92 union.addAll(_finiteSet); 93 union.addAll(with._finiteSet); 94 return newInstance(true, union); 95 } 96 else 97 { 98 Set subst = new HashSet(); 99 subst.addAll(with._finiteSet); 100 subst.removeAll(_finiteSet); 101 return newInstance(false, subst); 102 } 103 } 104 else 105 { 106 if (with._isFinite) 107 { 108 Set subst = new HashSet(); 109 subst.addAll(_finiteSet); 110 subst.removeAll(with._finiteSet); 111 return newInstance(false, subst); 112 } 113 else 114 { 115 return newInstance(false, intersectFiniteSets(_finiteSet, with._finiteSet)); 116 } 117 } 118 } 119 120 /** 121 * Returns the intersection of this NameSet with the 'with' NameSet 122 */ 123 public NameSet intersect(NameSet with) 124 { 125 if (_isFinite) 126 { 127 if (with._isFinite) 128 { 129 return newInstance(true, intersectFiniteSets(_finiteSet, with._finiteSet)); 130 } 131 else 132 { 133 Set subst = new HashSet(); 134 subst.addAll(_finiteSet); 135 subst.removeAll(with._finiteSet); 136 return newInstance(false, subst); 137 } 138 } 139 else 140 { 141 if (with._isFinite) 142 { 143 Set subst = new HashSet(); 144 subst.addAll(with._finiteSet); 145 subst.removeAll(_finiteSet); 146 return newInstance(true, subst); 147 } 148 else 149 { 150 Set union = new HashSet(); 151 union.addAll(_finiteSet); 152 union.addAll(with._finiteSet); 153 return newInstance(false, union); 154 } 155 } 156 } 157 158 /** 159 * Returns the result of substracting this NameSet from 'from' NameSet 160 * @see NameSet#substract 161 */ 162 public NameSet substractFrom(NameSet from) 163 { 164 return from.substract(this); 165 } 166 167 /** 168 * Returns the result of substracting 'what' NameSet from this NameSet 169 * @see NameSet#substractFrom 170 */ 171 public NameSet substract(NameSet what) 172 { 173 if (_isFinite) 174 { 175 if ( what._isFinite ) 176 { 177 // it's the subst of _finiteSet with what._finiteSet 178 Set subst = new HashSet(); 179 subst.addAll(_finiteSet); 180 subst.removeAll(what._finiteSet); 181 return newInstance(true, subst); 182 } 183 else 184 { 185 return newInstance(true, intersectFiniteSets(_finiteSet, what._finiteSet)); 186 } 187 } 188 else 189 { 190 if ( what._isFinite ) 191 { 192 // it's the union of _finiteSet with what._finiteSet 193 Set union = new HashSet(); 194 union.addAll(_finiteSet); 195 union.addAll(what._finiteSet); 196 return newInstance(false, union); 197 } 198 else 199 { 200 // what's in thisSet and it's not in whatSet 201 Set subst = new HashSet(); 202 subst.addAll(what._finiteSet); 203 subst.removeAll(_finiteSet); 204 return newInstance(true, subst); 205 } 206 } 207 } 208 209 /** 210 * Returns an inversion of this NameSet 211 */ 212 public NameSet invert() 213 { 214 return newInstance(!_isFinite, _finiteSet); 215 } 216 217 public boolean contains(String name) 218 { 219 if (_isFinite) 220 return _finiteSet.contains(name); 221 else 222 return !_finiteSet.contains(name); 223 } 224 }