/**
* Copyright (c) Codice Foundation
* <p/>
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or any later version.
* <p/>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. A copy of the GNU Lesser General Public License
* is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*/
package ddf.catalog.data.impl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import ddf.catalog.data.AttributeDescriptor;
import ddf.catalog.data.MetacardType;
/**
* Default implementation of the {@link MetacardType}, used by {@link BasicTypes} to create the
* {@link BasicTypes#BASIC_METACARD}.
*
* <p>
* This class is {@link java.io.Serializable} and care should be taken with compatibility if changes are
* made.
* </p>
*
* <p>
* For what constitutes a compatible change in serialization, see <a href=
* "http://docs.oracle.com/javase/6/docs/platform/serialization/spec/version.html#6678" >Sun's
* Guidelines</a>.
* </p>
*
* @author ddf.isgs@lmco.com
*
*/
public class MetacardTypeImpl implements MetacardType {
private static final long serialVersionUID = 1L;
/**
* Set of {@link AttributeDescriptor}s
*/
protected transient Set<AttributeDescriptor> descriptors = new HashSet<AttributeDescriptor>();
/**
* The name of this {@code MetacardTypeImpl}
*
* @serial
*/
protected String name;
/**
* Creates a {@code MetacardTypeImpl} with the provided {@code name} and
* {@link AttributeDescriptor}s.
*
* @param name
* the name of this {@code MetacardTypeImpl}
* @param descriptors
* the set of descriptors for this {@code MetacardTypeImpl}
*/
public MetacardTypeImpl(String name, Set<AttributeDescriptor> descriptors) {
/*
* If any defensive logic is added to this constructor, then that logic should be reflected
* in the deserialization (readObject()) of this object so that the integrity of a
* serialized object is maintained. For instance, if a null check is added in the
* constructor, the same check should be added in the readObject() method.
*/
this.name = name;
if (descriptors != null) {
this.descriptors.addAll(descriptors);
}
}
@Override
public String getName() {
return name;
}
@Override
public Set<AttributeDescriptor> getAttributeDescriptors() {
return Collections.unmodifiableSet(descriptors);
}
@Override
public AttributeDescriptor getAttributeDescriptor(String attributeName) {
if (attributeName == null) {
return null;
}
// TODO could this be faster?
for (AttributeDescriptor descriptor : descriptors) {
if (attributeName.equals(descriptor.getName())) {
return descriptor;
}
}
return null;
}
/**
* Serializes this {@link MetacardTypeImpl} instance.
*
* @serialData First, the name is written as a {@code String} by the default Java serialization
* implementation, then the number of {@link AttributeDescriptor} objects is written
* as an ( {@code int}), followed by all of the {@code AttributeDescriptor} objects
* in no guaranteed sequence or order.
* @param stream
* the {@link ObjectOutputStream} that contains the object to be serialized
* @throws IOException
*/
private void writeObject(ObjectOutputStream stream) throws IOException {
/*
* defaultWriteObject() is invoked for greater flexibility and compatibility. See the
* *Serialization Note* in MetacardImpl's class Javadoc.
*/
stream.defaultWriteObject();
stream.writeInt(descriptors.size());
for (AttributeDescriptor descriptor : descriptors) {
stream.writeObject(descriptor);
}
}
/**
* Deserializes this {@link MetacardTypeImpl} instance.
*
* @param stream
* the {@link ObjectInputStream} that contains the bytes of the object
* @throws IOException
* @throws ClassNotFoundException
*/
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
/*
* defaultReadObject() is invoked for greater flexibility and compatibility. See the
* *Serialization Note* in MetacardImpl's class Javadoc.
*/
stream.defaultReadObject();
int numElements = stream.readInt();
descriptors = new HashSet<AttributeDescriptor>();
for (int i = 0; i < numElements; i++) {
descriptors.add((AttributeDescriptor) stream.readObject());
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result += (descriptors == null) ? 0 : descriptors.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof MetacardType)) {
return false;
}
MetacardTypeImpl other = (MetacardTypeImpl) obj;
if (name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
return false;
}
if (descriptors == null) {
if (other.descriptors != null) {
return false;
}
} else if (!descriptors.equals(other.descriptors)) {
return false;
}
return true;
}
}