/*
* Copyright (c) Thomas Parker, 2009.
*
* This program 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 2.1 of the License, or (at your option)
* any later version.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package pcgen.cdom.facet.base;
import pcgen.cdom.base.PCGenIdentifier;
import pcgen.cdom.facet.event.DataFacetChangeEvent;
import pcgen.util.Logging;
/**
* An AbstractItemFacet is a DataFacet that contains information about Objects
* that are contained in a PlayerCharacter when a PlayerCharacter may have only
* one of that type of Object (e.g. Race, Deity). This is not used for Objects
* where the PlayerCharacter may possess more than one of that type of object
* (e.g. Template, Language)
*
* @param <IDT>
* The Type of identifier used in this AbstractItemFacet
* @param <T>
* The Type of object stored in this AbstractItemFacet
*/
public abstract class AbstractItemFacet<IDT extends PCGenIdentifier, T> extends
AbstractDataFacet<IDT, T>
{
/**
* Sets the item for this AbstractItemFacet and the Player Character
* represented by the given PCGenIdentifier to the given value.
*
* Note that a null set value is IGNORED, and an error is logged. If you
* wish to unset a value, you should use the remove(PCGenIdentifier id)
* method of AbstractItemFacet
*
* @see AbstractItemFacet#remove(PCGenIdentifier)
*
* @param id
* The PCGenIdentifier representing the Player Character for
* which the item value should be set
* @param obj
* The Item for this AbstractItemFacet and the Player Character
* represented by the given PCGenIdentifier.
* @return true if the item was set; false otherwise
*/
public boolean set(IDT id, T obj)
{
if (obj == null)
{
Logging.errorPrint(getClass() + " received null item: ignoring");
return false;
}
T old = get(id);
if (old == obj)
{
return false;
}
else
{
if (old != null)
{
fireDataFacetChangeEvent(id, old,
DataFacetChangeEvent.DATA_REMOVED);
}
setCache(id, obj);
fireDataFacetChangeEvent(id, obj, DataFacetChangeEvent.DATA_ADDED);
return true;
}
}
/**
* Removes the item for this AbstractItemFacet and the Player Character
* represented by the given PCGenIdentifier. May return null if no value was
* set for the Player Character identified by the given PCGenIdentifier.
*
* @param id
* The PCGenIdentifier representing the Player Character for
* which the item value should be removed
*/
public T remove(IDT id)
{
T old = (T) removeCache(id);
if (old != null)
{
fireDataFacetChangeEvent(id, old, DataFacetChangeEvent.DATA_REMOVED);
}
return old;
}
/**
* Returns the item value for this AbstractItemFacet and the Player
* Character represented by the given PCGenIdentifier. Note that this method
* will return null if no value for the Player Character has been set.
*
* @param id
* The PCGenIdentifier representing the PlayerCharacter for which
* the item should be returned.
* @return the item value for this AbstractItemFacet and the Player
* Character represented by the given PCGenIdentifier.
*/
public T get(IDT id)
{
return (T) getCache(id);
}
/**
* Returns true if the item in this AbstractItemFacet for the Player
* Character represented by the given PCGenIdentifier matches the given
* value. null may be used to test that there is no set value for this
* AbstractItemFacet and the Player Character represented by the given
* PCGenIdentifier.
*
* @param id
* The PCGenIdentifier representing the Player Character for
* which the item should be tested
* @param obj
* The object to test against the item in this AbstractItemFacet
* for the Player Character represented by the given
* PCGenIdentifier
* @return true if the item in this AbstractItemFacet for the Player
* Character represented by the given PCGenIdentifier matches the
* given value; false otherwise
*/
public boolean matches(IDT id, T obj)
{
T current = get(id);
return (obj == null && current == null)
|| (obj != null && obj.equals(current));
}
/**
* Copies the contents of the AbstractItemFacet from one Player Character to
* another Player Character, based on the given PCGenIdentifiers
* representing those Player Characters.
*
* This is a method in AbstractItemFacet in order to avoid exposing the
* internal contents of AbstractItemFacet to other classes. This should not
* be inlined, as the internal information should not be exposed to other
* classes.
*
* Note also the copy is a one-time event and no references are maintained
* between the Player Characters represented by the given PCGenIdentifiers
* (meaning once this copy takes place, any change to the AbstractItemFacet
* of one Player Character will only impact the Player Character where the
* AbstractItemFacet was changed).
*
* @param source
* The PCGenIdentifier representing the Player Character from
* which the information should be copied
* @param copy
* The PCGenIdentifier representing the Player Character to which
* the information should be copied
*/
@Override
public void copyContents(IDT source, IDT copy)
{
T obj = get(source);
if (obj != null)
{
setCache(copy, obj);
}
}
}