package com.webobjects.foundation;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.ObjectStreamField;
import java.io.Serializable;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* <div class="en">
* NSSet reimplementation to support JDK 1.5 templates. Use with
* </div>
*
* <div class="ja">
* JDK 1.5 テンプレートをサポートする為の再実装。使用は
* </div>
*
* <pre>{@code
* NSSet<E> setA = new NSSet<E>(NSArray<E> listA);
*NSSet<E> setB = new NSSet<E>(NSArray<E> listB);
*logger.debug("intersection contains " + setA.setByIntersectingSet(setB));
* }</pre>
*
* @param <E> - type of set contents
*/
public class NSSet<E> implements Cloneable, Serializable, NSCoding, _NSFoundationCollection, Set<E> {
static final long serialVersionUID = -8833684352747517048L;
public static final Class _CLASS = _NSUtilities._classWithFullySpecifiedName("com.webobjects.foundation.NSSet");
protected static int _NSSetClassHashCode = _CLASS.hashCode();
public static final NSSet EmptySet = new NSSet();
private static final String SerializationValuesFieldKey = "objects";
private static final ObjectStreamField[] serialPersistentFields = (new ObjectStreamField[] { new ObjectStreamField(SerializationValuesFieldKey, ((Object) (_NSUtilities._NoObjectArray)).getClass()) });
public static Object decodeObject(NSCoder coder) {
return new NSSet<Object>(coder.decodeObjects());
}
protected transient int _capacity;
protected transient int _count;
protected transient int _deletionLimit;
protected transient byte[] _flags;
protected transient int _hashCache;
protected transient int _hashtableBuckets;
protected Object[] _objects;
protected transient Object[] _objectsCache;
public NSSet() {
_initializeSet();
}
public NSSet(Collection<? extends E> collection) {
Object[] objects = collection.toArray();
initFromObjects(objects, true);
}
public NSSet(NSArray<? extends E> objects) {
this(objects == null ? null : (E[])objects.objectsNoCopy(), false);
}
public NSSet(NSSet<? extends E> otherSet) {
this(otherSet == null ? null : (E[])otherSet.objectsNoCopy(), false);
}
public NSSet(Set<? extends E> set, boolean ignoreNull) {
if (set == null) {
throw new IllegalArgumentException("Set cannot be null");
}
if (!ignoreNull && set.contains(null)) {
throw new IllegalArgumentException("Attempt to insert null into an " + getClass().getName() + ".");
}
Object[] aSet = set.toArray();
initFromObjects(aSet, !ignoreNull);
}
public NSSet(E object) {
if (object == null) {
throw new IllegalArgumentException("Attempt to insert null into an " + getClass().getName() + ".");
}
_initializeSet();
_ensureCapacity(1);
if (_NSCollectionPrimitives.addValueToSet(object, _objects, _flags)) {
_setCount(count() + 1);
}
}
public NSSet(E[] objects) {
this(objects, true);
}
public NSSet(E object, E... objects) {
this(objects, true);
_ensureCapacity(count() + 1);
if (_NSCollectionPrimitives.addValueToSet(object, _objects, _flags)) {
_setCount(count() + 1);
}
}
private NSSet(E[] objects, boolean checkForNull) {
if (objects == null) {
throw new IllegalArgumentException("Objects cannot be null.");
}
initFromObjects(objects, checkForNull);
}
public Object[] _allObjects() {
int count = count();
Object[] objects = new Object[count];
if (count > 0) {
System.arraycopy(objectsNoCopy(), 0, objects, 0, count);
}
return objects;
}
protected void _clearDeletionsAndCollisions() {
int size = _hashtableBuckets;
if (count() == 0) {
_flags = new byte[size];
} else {
Object[] oldObjects = _objects;
byte[] oldFlags = _flags;
_objects = new Object[size];
_flags = new byte[size];
for (int i = 0; i < size; i++) {
if ((oldFlags[i] & 0xffffffc0) == -128) {
_NSCollectionPrimitives.addValueToSet(oldObjects[i], _objects, _flags);
}
}
}
_deletionLimit = _NSCollectionPrimitives.deletionLimitForTableBuckets(size);
}
protected void _ensureCapacity(int capacity) {
int currentCapacity = capacity();
if (capacity > currentCapacity) {
int newCapacity = _NSCollectionPrimitives.hashTableCapacityForCapacity(capacity);
if (newCapacity != currentCapacity) {
int oldSize = _hashtableBuckets;
_setCapacity(newCapacity);
_hashtableBuckets = _NSCollectionPrimitives.hashTableBucketsForCapacity(newCapacity);
int newSize = _hashtableBuckets;
if (newSize == 0) {
_objects = null;
_flags = null;
} else {
Object[] oldObjects = _objects;
byte[] oldFlags = _flags;
_objects = new Object[newSize];
_flags = new byte[newSize];
for (int i = 0; i < oldSize; i++) {
if ((oldFlags[i] & 0xffffffc0) == -128) {
_NSCollectionPrimitives.addValueToSet(oldObjects[i], _objects, _flags);
}
}
}
_deletionLimit = _NSCollectionPrimitives.deletionLimitForTableBuckets(newSize);
}
}
}
private boolean _equalsSet(NSSet<?> otherSet) {
int count = count();
if (count != otherSet.count()) {
return false;
}
Object[] objects = objectsNoCopy();
for (int i = 0; i < count; i++) {
if (otherSet.member(objects[i]) == null) {
return false;
}
}
return true;
}
protected void _initializeSet() {
_capacity = _count = 0;
_objects = _objectsCache = null;
_flags = null;
_hashtableBuckets = _NSCollectionPrimitives.hashTableBucketsForCapacity(_capacity);
_deletionLimit = _NSCollectionPrimitives.deletionLimitForTableBuckets(_hashtableBuckets);
}
public int _shallowHashCode() {
return _NSSetClassHashCode;
}
public boolean add(E o) {
throw new UnsupportedOperationException("add is not a supported operation in com.webobjects.foundation.NSSet");
}
public boolean addAll(Collection<? extends E> c) {
throw new UnsupportedOperationException("addAll is not a supported operation in com.webobjects.foundation.NSSet");
}
public NSArray<E> allObjects() {
return new NSArray<E>((E[])objectsNoCopy());
}
public E anyObject() {
return count() <= 0 ? null : (E)objectsNoCopy()[0];
}
public Class classForCoder() {
return _CLASS;
}
public void clear() {
throw new UnsupportedOperationException("clear is not a supported operation in com.webobjects.foundation.NSSet");
}
@Override
public Object clone() {
return this;
}
public boolean contains(Object o) {
return containsObject(o);
}
public boolean containsAll(Collection<?> c) {
if (c == null) {
throw new NullPointerException("Collection passed into containsAll() cannot be null");
}
Object[] objects = c.toArray();
if (objects.length > 0) {
for (int i = 0; i < objects.length; i++) {
if (objects[i] == null) {
return false;
}
if (member(objects[i]) == null) {
return false;
}
}
}
return true;
}
public boolean containsObject(Object object) {
return object == null ? false : member(object) != null;
}
public int count() {
return _count;
}
protected void _setCount(int count) {
_count = count;
}
protected int capacity() {
return _capacity;
}
protected void _setCapacity(int capacity) {
_capacity = capacity;
}
public void encodeWithCoder(NSCoder coder) {
coder.encodeObjects(objectsNoCopy());
}
@SuppressWarnings("cast")
public static <T> NSSet<T> emptySet() {
return (NSSet<T>) EmptySet;
}
@Override
public boolean equals(Object object) {
if (object == this) {
return true;
}
if (object instanceof NSSet) {
return _equalsSet((NSSet<?>) object);
}
return false;
}
@Override
public int hashCode() {
return _NSSetClassHashCode ^ count();
}
public HashSet<E> hashSet() {
E[] objects = (E[])objectsNoCopy();
HashSet<E> set = new HashSet<>(objects.length);
for (int i = 0; i < objects.length; i++) {
set.add(objects[i]);
}
return set;
}
public NSSet<E> immutableClone() {
return this;
}
private void initFromObjects(Object[] objects, boolean checkForNull) {
_initializeSet();
_ensureCapacity(objects.length);
for (int i = 0; i < objects.length; i++) {
if (objects[i] == null) {
if (checkForNull)
throw new IllegalArgumentException("Attempt to insert null object into an " + getClass().getName() + ".");
} else {
if (_NSCollectionPrimitives.addValueToSet(objects[i], _objects, _flags)) {
_setCount(count() + 1);
}
}
}
}
public boolean intersectsSet(NSSet<?> otherSet) {
if (count() != 0 && otherSet != null && otherSet.count() != 0) {
Object[] objects = objectsNoCopy();
for (int i = 0; i < objects.length; i++) {
if (otherSet.member(objects[i]) != null) {
return true;
}
}
}
return false;
}
public boolean isEmpty() {
return count() == 0;
}
public boolean isEqualToSet(NSSet<?> otherSet) {
if (otherSet == null) {
return false;
}
if (otherSet == this) {
return true;
}
return _equalsSet(otherSet);
}
public boolean isSubsetOfSet(NSSet<?> otherSet) {
int count = count();
if (otherSet == null || otherSet.count() < count) {
return false;
}
if (count == 0) {
return true;
}
Object[] objects = objectsNoCopy();
for (int i = 0; i < objects.length; i++) {
if (otherSet.member(objects[i]) == null) {
return false;
}
}
return true;
}
@SuppressWarnings("unchecked")
public Iterator<E> iterator() {
return new _NSJavaSetIterator(objectsNoCopy());
}
public E member(Object object) {
return count() != 0 && object != null ? (E) _NSCollectionPrimitives.findValueInHashTable(object, _objects, _objects, _flags) : null;
}
public NSMutableSet<E> mutableClone() {
return new NSMutableSet<E>(this);
}
@SuppressWarnings("unchecked")
public Enumeration<E> objectEnumerator() {
return new _NSCollectionEnumerator(_objects, _flags, count());
}
protected Object[] objectsNoCopy() {
if (_objectsCache == null) {
_objectsCache = count() != 0 ? _NSCollectionPrimitives.valuesInHashTable(_objects, _objects, _flags, capacity(), _hashtableBuckets) : _NSCollectionPrimitives.EmptyArray;
}
return _objectsCache;
}
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
java.io.ObjectInputStream.GetField fields = null;
fields = s.readFields();
Object[] keys = (Object[]) fields.get(SerializationValuesFieldKey, ((_NSUtilities._NoObjectArray)));
keys = keys != null ? keys : _NSUtilities._NoObjectArray;
initFromObjects(keys, true);
}
private Object readResolve() throws ObjectStreamException {
if (getClass() == _CLASS && count() == 0) {
return EmptySet;
}
return this;
}
public boolean remove(Object o) {
throw new UnsupportedOperationException("remove is not a supported operation in com.webobjects.foundation.NSSet");
}
public boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException("removeAll is not a supported operation in com.webobjects.foundation.NSSet");
}
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException("retainAll is not a supported operation in com.webobjects.foundation.NSSet");
}
public NSSet<E> setByIntersectingSet(NSSet<?> otherSet) {
NSMutableSet<E> set = new NSMutableSet<>(this);
set.intersectSet(otherSet);
return set;
}
public NSSet<E> setBySubtractingSet(NSSet<?> otherSet) {
NSMutableSet<E> set = new NSMutableSet<>(this);
set.subtractSet(otherSet);
return set;
}
public NSSet<E> setByUnioningSet(NSSet<? extends E> otherSet) {
NSMutableSet<E> set = new NSMutableSet<>(this);
set.unionSet(otherSet);
return set;
}
public int size() {
return count();
}
public Object[] toArray() {
Object[] currObjects = objectsNoCopy();
Object[] objects = new Object[currObjects.length];
if (currObjects.length > 0) {
System.arraycopy(currObjects, 0, objects, 0, currObjects.length);
}
return objects;
}
public <T> T[] toArray(T[] objects) {
if (objects == null) {
throw new NullPointerException("Cannot pass null as parameter");
}
Object[] currObjects = objectsNoCopy();
if (objects.length < currObjects.length) {
objects = (T[]) java.lang.reflect.Array.newInstance(objects.getClass().getComponentType(), currObjects.length);
}
System.arraycopy(currObjects, 0, objects, 0, currObjects.length);
return objects;
}
@Override
public String toString() {
StringBuilder buffer = new StringBuilder(128);
buffer.append('(');
Object[] objects = objectsNoCopy();
for (int i = 0; i < objects.length; i++) {
Object object = objects[i];
if (i > 0) {
buffer.append(", ");
}
if (object instanceof String) {
buffer.append('"');
buffer.append((String) object);
buffer.append('"');
continue;
}
if (object instanceof Boolean) {
buffer.append(((Boolean) object).booleanValue() ? "true" : "false");
}
else {
buffer.append(object.toString());
}
}
buffer.append(')');
return buffer.toString();
}
private void writeObject(ObjectOutputStream s) throws IOException {
java.io.ObjectOutputStream.PutField fields = s.putFields();
fields.put(SerializationValuesFieldKey, ((_allObjects())));
s.writeFields();
}
}