blob: 04e7513f73e449605cf06a3576e2efc8e4cce498 [file] [log] [blame]
/*
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*
*/
package org.apache.flex.abc.semantics;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Collection;
import org.apache.flex.abc.semantics.Namespace;
/**
* Nsset represents an ABC NamespaceSet, i.e., a set of Namespaces.
*/
public class Nsset implements Iterable<Namespace>
{
/**
* Manifest constant passed to Collection<T>.toArray(T[]) to cause toArray()
* to create a new array.
*/
private static final Namespace[] CREATE_NEW_NSSET_NAMESPACE_ARRAY = new Namespace[0];
/**
* A prime number unlikely to be a divisor of the hash table size, used to
* generate composite hash keys.
*
* @warn if you copy this, pick a new prime to generate distinct hash keys
* in different classes.
*/
private static final long PRIME_MULTIPLIER = 9679;
/**
* Construct a Nsset from a single Namespace.
*/
public Nsset(Namespace single_ns)
{
namespaces = new Namespace[] {single_ns};
}
/**
* Construct a Nsset from a Collection of Namespaces.
*/
public Nsset(Collection<Namespace> nss)
{
namespaces = nss.toArray(CREATE_NEW_NSSET_NAMESPACE_ARRAY);
}
/**
* The set's constituent Namespaces.
*/
private Namespace[] namespaces = null;
/**
* @return the namespace set's size.
*/
public int length()
{
return namespaces.length;
}
/**
* @return an Iterator over this set's namespaces.
*/
@Override
public Iterator<Namespace> iterator()
{
return Arrays.asList(namespaces).iterator();
}
/**
* @return the one consitutent Namespace of this set.
* @throws AssertionError if more or less than one Namespace is present.
*/
public Namespace getSingleQualifier()
{
assert (namespaces.length == 1);
return namespaces[0];
}
@Override
public String toString()
{
StringBuffer result = new StringBuffer();
result.append('{');
for (int i = 0; i < namespaces.length; i++)
{
if (i > 0)
result.append(',');
result.append(namespaces[i]);
}
result.append('}');
return result.toString();
}
/**
* Cached hash code. Generating a hash code for a Nsset is somewhat
* expensive, so it's done on demand.
*/
private Integer cachedHashCode = null;
/**
* Generate a composite hash code using the Namespaces' hashes.
* <p>
* {@inheritDoc}
*/
@Override
public int hashCode()
{
if (cachedHashCode == null)
{
int result = 0;
for (Namespace ns : namespaces)
result = (int)(PRIME_MULTIPLIER * result + ns.hashCode());
cachedHashCode = result;
}
return cachedHashCode;
}
/**
* Determine equality by checking the Namespaces' corresponding fields.
* <p>
* {@inheritDoc}
*/
@Override
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
else if (!(o instanceof Nsset) || this.hashCode() != o.hashCode())
{
return false;
}
else
{
// Do a namespace-by-namespace comparison.
Nsset other = (Nsset)o;
boolean result = this.namespaces.length == other.namespaces.length;
for (int i = 0; i < this.namespaces.length && result; i++)
result = this.namespaces[i].equals(other.namespaces[i]);
return result;
}
}
}