/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE
* or https://OpenDS.dev.java.net/OpenDS.LICENSE.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
* add the following below this CDDL HEADER, with the fields enclosed
* by brackets "[]" replaced with your own identifying information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2006-2008 Sun Microsystems, Inc.
*/
package org.opends.server.types;
import static org.opends.server.util.StaticUtils.*;
import java.util.Collection;
import java.util.Set;
/**
* An abstract base class for implementing new types of
* {@link Attribute}.
*/
@org.opends.server.types.PublicAPI(
stability = org.opends.server.types.StabilityLevel.UNCOMMITTED,
mayInstantiate = false,
mayExtend = false,
mayInvoke = true)
public abstract class AbstractAttribute implements Attribute
{
/**
* Creates a new abstract attribute.
*/
protected AbstractAttribute()
{
// No implementation required.
}
/**
* {@inheritDoc}
* <p>
* This implementation iterates through each attribute value in the
* provided collection, checking to see if this attribute contains
* the value using {@link #contains(AttributeValue)}.
*/
public boolean containsAll(Collection<AttributeValue> values)
{
for (AttributeValue value : values)
{
if (!contains(value))
{
return false;
}
}
return true;
}
/**
* {@inheritDoc}
*/
@Override
public final boolean equals(Object o)
{
if (this == o)
{
return true;
}
else if (o instanceof Attribute)
{
Attribute a = (Attribute) o;
if (!getAttributeType().equals(a.getAttributeType()))
{
return false;
}
if (size() != a.size())
{
return false;
}
for (AttributeValue v : a)
{
if (!contains(v))
{
return false;
}
}
return optionsEqual(a.getOptions());
}
else
{
return false;
}
}
/**
* {@inheritDoc}
* <p>
* This implementation returns the primary name associated with this
* attribute's attribute type or, if there is no primary name, the
* attribute type's OID.
*/
public String getName()
{
return getAttributeType().getNameOrOID();
}
/**
* {@inheritDoc}
* <p>
* This implementation returns this attribute's name if there are no
* attribute options, otherwise it constructs a string comprising of
* this attribute's name followed by a semi-colon and a semi-colon
* separated list of its attribute options.
*/
public String getNameWithOptions()
{
if (!hasOptions())
{
return getName();
}
else
{
StringBuilder buffer = new StringBuilder();
buffer.append(getName());
for (String option : getOptions())
{
buffer.append(';');
buffer.append(option);
}
return buffer.toString();
}
}
/**
* {@inheritDoc}
* <p>
* This implementation returns <code>true</code> if the provided
* collection of options is <code>null</code> or empty. If the
* collection is non-empty and this attribute does not have any
* options then it returns <code>false</code>. Otherwise, each
* option in the provided collection is checked using
* {@link #hasOption(String)} and <code>true</code> is
* returned if all the provided options are present.
*/
public boolean hasAllOptions(Collection<String> options)
{
if (options == null || options.isEmpty())
{
return true;
}
if (!hasOptions())
{
return false;
}
for (String option : options)
{
if (!hasOption(option))
{
return false;
}
}
return true;
}
/**
* {@inheritDoc}
*/
@Override
public final int hashCode()
{
int hashCode = getAttributeType().hashCode();
for (AttributeValue value : this)
{
hashCode += value.hashCode();
}
return hashCode;
}
/**
* {@inheritDoc}
* <p>
* This implementation calls {@link #getOptions()} to
* retrieve this attribute's set of options and then compares them
* one at a time against the provided option. All comparisons are
* case insensitive (this is why we iterate through the set of
* options, rather than doing a simpler set membership test).
*/
public boolean hasOption(String option)
{
String noption = toLowerCase(option);
// Cannot use Set.contains() because the options are not
// normalized.
for (String o : getOptions())
{
String no = toLowerCase(o);
if (no.equals(noption))
{
return true;
}
}
return false;
}
/**
* {@inheritDoc}
* <p>
* This implementation retrieves the set of options associated with
* this attribute and tests to see if it is empty.
*/
public boolean hasOptions()
{
return !getOptions().isEmpty();
}
/**
* {@inheritDoc}
* <p>
* This implementation returns <code>true</code> if the
* {@link #size()} of this attribute is zero.
*/
public boolean isEmpty()
{
return size() == 0;
}
/**
* {@inheritDoc}
* <p>
* This implementation returns !{@link #hasOptions()} if the
* provided set of options is <code>null</code>. Otherwise it
* checks that the size of the provided set of options is equal to
* the size of this attribute's options, return <code>false</code>
* if the sizes differ. If the sizes are the same then each option
* in the provided set is checked using
* {@link #hasOption(String)} and <code>true</code> is
* returned if all the provided options are present.
*/
public boolean optionsEqual(Set<String> options)
{
if (options == null)
{
return !hasOptions();
}
if (getOptions().size() != options.size())
{
return false;
}
// Cannot use Set.containsAll() because the set of options are
// not normalized.
for (String option : options)
{
if (!hasOption(option))
{
return false;
}
}
return true;
}
/**
* {@inheritDoc}
*/
@Override
public final String toString()
{
StringBuilder buffer = new StringBuilder();
toString(buffer);
return buffer.toString();
}
}