blob: 146b83360758c5fdd3e2ff125bc694c493cf7081 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2001, 2007 Oracle Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Oracle Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.jsf.common.sets;
import java.util.AbstractSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.w3c.dom.NodeList;
/**
* A set backed by a W3C NodeList so as to avoid copying. Note that operations
* that return new sets still invoke a copy. Also, membership operations
* require O(n) time. This should generally used for sets that are assumed to be
* small where O(n) search time will be small compared to doing a full copy.
*
* This set is immutable (mutation methods throw exceptions)
*
* <p><b>Provisional API - subject to change</b></p>
*
* @author cbateman
*
*/
public class NodeSet extends AbstractSet implements AxiomaticSet
{
private NodeList _data;
/**
* @param data -- wrap the actual data source
*/
public NodeSet(NodeList data)
{
_data = data;
}
public Iterator iterator() {
return new Iterator()
{
private int pos = 0;
public boolean hasNext() {
return pos < _data.getLength();
}
public Object next() {
return _data.item(pos++);
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public int size() {
return _data.getLength();
}
public AxiomaticSet intersect(AxiomaticSet set) {
ConcreteAxiomaticSet newSet = new ConcreteAxiomaticSet();
AxiomaticSetUtil.intersect(newSet, this, set);
return newSet;
}
public boolean isEquivalent(AxiomaticSet toSet) {
if (this == toSet)
{
return true;
}
if (toSet instanceof NodeSet
&& ((NodeSet)toSet)._data == this._data)
{
return true;
}
// if different sizes, false
if (toSet.size() != size())
{
return false;
}
// otherwise, compare item by item
// Iterator through me with the hope that look ups
// are more efficent in toSet
for (Iterator it = iterator(); it.hasNext();)
{
Object obj = it.next();
if (!toSet.contains(obj))
{
// fail fase on membership mismatch
return false;
}
}
// if we get to here then the item by item match succeeded
return true;
}
public AxiomaticSet union(AxiomaticSet set) {
ConcreteAxiomaticSet newSet = new ConcreteAxiomaticSet();
AxiomaticSetUtil.union(newSet, this, set);
return newSet;
}
public boolean isDisjoint(AxiomaticSet set) {
return AxiomaticSetUtil.isDisjoint(this, set);
}
public Object getFirstElement() {
if (_data.getLength()>0)
{
return _data.item(0);
}
throw new NoSuchElementException("Set is empty"); //$NON-NLS-1$
}
public AxiomaticSet subtract(AxiomaticSet set) {
return AxiomaticSetUtil.subtract(this, set);
}
}