| /* Copyright 2004 The Apache Software Foundation |
| * |
| * Licensed 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. |
| */ |
| /** |
| * Author: Cezar Andrei ( cezar.andrei at bea.com ) |
| * Date: Apr 25, 2004 |
| */ |
| package org.apache.xmlbeans.impl.config; |
| |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| /** |
| * Represents a non finite set of names. |
| * |
| * @see NameSetBuilder |
| */ |
| public class NameSet { |
| /** |
| * An empty NameSet, it doesn't contain any name |
| */ |
| public static final NameSet EMPTY = new NameSet(true, Collections.EMPTY_SET); |
| /** |
| * The NameSet that contains any name |
| */ |
| public static final NameSet EVERYTHING = new NameSet(false, Collections.EMPTY_SET); |
| |
| /* |
| There are two big cases: |
| 1) - it represents "*", ie all except a finite set of names: _isFinite==false |
| 2) - if represents only a finite set of names: _isFinite==true |
| */ |
| private boolean _isFinite; |
| private Set<String> _finiteSet; |
| |
| private NameSet(boolean isFinite, Set<String> finiteSet) { |
| _isFinite = isFinite; |
| _finiteSet = finiteSet; |
| } |
| |
| static NameSet newInstance(boolean isFinite, Set<String> finiteSet) { |
| if (finiteSet.size() == 0) { |
| if (isFinite) { |
| return NameSet.EMPTY; |
| } else { |
| return NameSet.EVERYTHING; |
| } |
| } else { |
| Set<String> fs = new HashSet<>(); |
| fs.addAll(finiteSet); |
| return new NameSet(isFinite, fs); |
| } |
| } |
| |
| private static Set<String> intersectFiniteSets(Set<String> a, Set<String> b) { |
| Set<String> intersection = new HashSet<>(); |
| //compute the intersection of _finiteSet with withSet |
| while (a.iterator().hasNext()) { |
| String name = (String) a.iterator().next(); |
| if (b.contains(name)) { |
| intersection.add(name); |
| } |
| } |
| return intersection; |
| } |
| |
| /** |
| * Returns the union of this NameSet with the 'with' NameSet. |
| */ |
| public NameSet union(NameSet with) { |
| if (_isFinite) { |
| if (with._isFinite) { |
| Set<String> union = new HashSet<>(); |
| union.addAll(_finiteSet); |
| union.addAll(with._finiteSet); |
| return newInstance(true, union); |
| } else { |
| Set<String> subst = new HashSet<>(); |
| subst.addAll(with._finiteSet); |
| subst.removeAll(_finiteSet); |
| return newInstance(false, subst); |
| } |
| } else { |
| if (with._isFinite) { |
| Set<String> subst = new HashSet<>(); |
| subst.addAll(_finiteSet); |
| subst.removeAll(with._finiteSet); |
| return newInstance(false, subst); |
| } else { |
| return newInstance(false, intersectFiniteSets(_finiteSet, with._finiteSet)); |
| } |
| } |
| } |
| |
| /** |
| * Returns the intersection of this NameSet with the 'with' NameSet |
| */ |
| public NameSet intersect(NameSet with) { |
| if (_isFinite) { |
| if (with._isFinite) { |
| return newInstance(true, intersectFiniteSets(_finiteSet, with._finiteSet)); |
| } else { |
| Set<String> subst = new HashSet<>(); |
| subst.addAll(_finiteSet); |
| subst.removeAll(with._finiteSet); |
| return newInstance(false, subst); |
| } |
| } else { |
| if (with._isFinite) { |
| Set<String> subst = new HashSet<>(); |
| subst.addAll(with._finiteSet); |
| subst.removeAll(_finiteSet); |
| return newInstance(true, subst); |
| } else { |
| Set<String> union = new HashSet<>(); |
| union.addAll(_finiteSet); |
| union.addAll(with._finiteSet); |
| return newInstance(false, union); |
| } |
| } |
| } |
| |
| /** |
| * Returns the result of substracting this NameSet from 'from' NameSet |
| * |
| * @see NameSet#substract |
| */ |
| public NameSet substractFrom(NameSet from) { |
| return from.substract(this); |
| } |
| |
| /** |
| * Returns the result of substracting 'what' NameSet from this NameSet |
| * |
| * @see NameSet#substractFrom |
| */ |
| public NameSet substract(NameSet what) { |
| if (_isFinite) { |
| if (what._isFinite) { |
| // it's the subst of _finiteSet with what._finiteSet |
| Set<String> subst = new HashSet<>(); |
| subst.addAll(_finiteSet); |
| subst.removeAll(what._finiteSet); |
| return newInstance(true, subst); |
| } else { |
| return newInstance(true, intersectFiniteSets(_finiteSet, what._finiteSet)); |
| } |
| } else { |
| if (what._isFinite) { |
| // it's the union of _finiteSet with what._finiteSet |
| Set<String> union = new HashSet<>(); |
| union.addAll(_finiteSet); |
| union.addAll(what._finiteSet); |
| return newInstance(false, union); |
| } else { |
| // what's in thisSet and it's not in whatSet |
| Set<String> subst = new HashSet<>(); |
| subst.addAll(what._finiteSet); |
| subst.removeAll(_finiteSet); |
| return newInstance(true, subst); |
| } |
| } |
| } |
| |
| /** |
| * Returns an inversion of this NameSet |
| */ |
| public NameSet invert() { |
| return newInstance(!_isFinite, _finiteSet); |
| } |
| |
| public boolean contains(String name) { |
| if (_isFinite) { |
| return _finiteSet.contains(name); |
| } else { |
| return !_finiteSet.contains(name); |
| } |
| } |
| } |