/* * Copyright (c) 2007 Tom Parker <thpr@users.sourceforge.net> * * 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.reference; import java.util.Collection; import pcgen.cdom.base.Loadable; import pcgen.cdom.enumeration.GroupingState; /** * A CDOMTransparentSingleRef is a CDOMReference which is intended to contain a * another CDOMSingleRef, to which the CDOMTransparentSingleRef will delegate * behavior. * * A CDOMTransparentSingleRef, unlike many CDOMReference objects, can be * cleared, and the underlying CDOMSingleRef can be changed. * * @see TransparentReference for a description of cases in which * TransparentReferences like CDOMTransparentSingleRef are typically used * * @param <T> * The Class of the underlying object contained by this * CDOMTransparentSingleRef */ public class CDOMTransparentSingleRef<T extends Loadable> extends CDOMSingleRef<T> implements TransparentReference<T> { /** * Holds the reference to which this CDOMTransparentSingleRef will delegate * behavior. */ private CDOMSingleRef<T> subReference = null; /** * Constructs a new CDOMTransparentSingleRef for the given Class and name. * * @param objClass * The Class of the underlying object contained by this * CDOMTransparentSingleRef. * @param key * An identifier of the object this CDOMTransparentSingleRef * contains. */ public CDOMTransparentSingleRef(Class<T> objClass, String key) { super(objClass, key); } /** * Returns true if the given Object is the Object to which this * CDOMTransparentSingleRef refers. * * Note that the behavior of this class is undefined if the underlying * CDOMSingleRef has not yet been resolved. * * @param item * The object to be tested to see if it is referred to by this * CDOMTransparentSingleRef. * @return true if the given Object is the Object to which this * CDOMTransparentSingleRef refers; false otherwise. * @throws IllegalStateException * if no underlying CDOMSingleRef has been defined. */ @Override public boolean contains(T item) { if (subReference == null) { throw new IllegalStateException("Cannot ask for contains: " + getReferenceClass().getName() + " Reference " + getName() + " has not been resolved"); } return subReference.contains(item); } /** * Returns the given Object this CDOMTransparentSingleRef contains. * * Note that the behavior of this class is undefined if the underlying * CDOMSingleRef has not yet been resolved. * * @return the given Object this CDOMTransparentSingleRef contains. * @throws IllegalStateException * if no underlying CDOMSingleRef has been defined. */ @Override public T get() { if (subReference == null) { throw new IllegalStateException( "Cannot ask for resolution: Reference has not been resolved"); } return subReference.get(); } /** * Check if the reference has been resolved yet. i.e. load of the object has been completed. * @return true if the reference has been resolved, false if not. */ @Override public boolean hasBeenResolved() { return subReference != null && subReference.hasBeenResolved(); } /** * Returns a representation of this CDOMTransparentSingleRef, suitable for * storing in an LST file. * * Note that this will return the identifier of the underlying reference (of * the types given at construction), often the "key" in LST terminology. * * @return A representation of this CDOMTransparentSingleRef, suitable for * storing in an LST file. * @see pcgen.cdom.base.CDOMReference#getLSTformat(boolean) */ @Override public String getLSTformat(boolean useAny) { return getName(); } /** * Returns true if this CDOMTransparentSingleRef is equal to the given * Object. Equality is defined as being another CDOMTransparentSingleRef * object with equal Class represented by the reference and equal name of * the underlying reference. This is NOT a deep .equals, in that neither the * actual contents of this CDOMTransparentSingleRef nor the underlying * CDOMSingleRef are tested. * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (obj instanceof CDOMTransparentSingleRef) { CDOMTransparentSingleRef<?> ref = (CDOMTransparentSingleRef<?>) obj; return getReferenceClass().equals(ref.getReferenceClass()) && getName().equals(ref.getName()); } return false; } /** * Returns the consistent-with-equals hashCode for this * CDOMTransparentSingleRef * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return getReferenceClass().hashCode() ^ getName().hashCode(); } /** * Throws an exception. This method may not be called because a * CDOMTransparentSingleRef is resolved using an underlying CDOMSingleRef. * * @see CDOMTransparentSingleRef#resolve(ReferenceManufacturer) * * @param item * ignored * @throws IllegalStateException * because a CDOMTransparentSingleRef is resolved using an * underlying CDOMSingleRef. */ @Override public void addResolution(T item) { throw new IllegalStateException( "Cannot resolve a Transparent Reference"); } /** * Resolves this CDOMTransparentSingleRef using the given * ReferenceManufacturer. The underlying CDOMSingleRef for this * CDOMTransparentSingleRef will be set to a CDOMSingleRef constructed by * the given ReferenceManufacturer (using the identifier provided during * construction of this CDOMTransparentSingleRef) * * This method may be called more than once; each time it is called it will * overwrite the existing CDOMSingleRef to which this * CDOMTransparentSingleRef delegates its behavior. * * @throws IllegalArgumentException * if the Reference Class of the given ReferenceManufacturer is * different than the Reference Class of this * CDOMTransparentSingleRef * @throws NullPointerException * if the given ReferenceManufacturer is null */ @Override public void resolve(ReferenceManufacturer<T> rm) { if (rm.getReferenceClass().equals(getReferenceClass())) { subReference = rm.getReference(getName()); } else { throw new IllegalArgumentException("Cannot resolve a " + getReferenceClass().getSimpleName() + " Reference to a " + rm.getReferenceClass().getSimpleName()); } } /** * Returns a Collection containing the single Object to which this * CDOMTransparentSingleRef refers. * * The semantics of this method are defined solely by the semantics of the * underlying CDOMSingleRef. Ownership of the Collection returned by this * method may or may not be transferred to the calling object (check the * documentation of the underlying CDOMSingleRef). * * Note that if you know this CDOMTransparentSingleRef is a CDOMSingleRef, * you are better off using resolvesTo() as the result will be much faster * than having to extract the object out of the Collection returned by this * method. * * @return A Collection containing the single Object to which this * CDOMTransparentSingleRef refers. */ @Override public Collection<T> getContainedObjects() { return subReference.getContainedObjects(); } /** * Returns the GroupingState for this CDOMTransparentSingleRef. The * GroupingState indicates how this CDOMTransparentSingleRef can be combined * with other PrimitiveChoiceFilters. * * @return The GroupingState for this CDOMTransparentSingleRef. */ @Override public GroupingState getGroupingState() { return GroupingState.ALLOWS_UNION; } @Override public String getChoice() { return subReference == null ? null : subReference.getChoice(); } @Override public void setChoice(String c) { throw new IllegalStateException( "Cannot set Choice on a Transparent Reference"); } }