blob: 4bf7b32fb09a5e1a8f67c4f319941b75f8ead627 [file] [log] [blame]
/* 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);
}
}
}