/*
*
* 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 java.util.List;
import pcgen.base.util.FormatManager;
import pcgen.cdom.base.CDOMReference;
import pcgen.cdom.base.Loadable;
/**
* A ReferenceManufacturer is an object capable of creating CDOMReferences of a
* given "form". That "form" includes a specific Class of CDOMObject, or a
* specific Class/Category for Categorized CDOMObjects.
*
* The Class serves two purposes.
*
* 1) This provides a universal interface, so it simplifies the LoadContext
* class structure/code under categorized/non-categorized conditions
*
* 2) This provides a method of constructing references after the class (or
* class and context) have been established. By separating these actions,
* references can be constructed at a time that is independent of the
* class/context resolution. This allows for tokens which can refer to both
* categorized and non-categorized objects (e.g. QUALIFY) to operate clearly and
* with methods that are Generic-friendly.
*
* Behavioral Notes: It is expected that various methods will interact with each
* other. This is especially true with respect to buildDeferredObjects(). It is
* expected that object identifiers passed to constructIfNecessary(String) not
* result in objects being constructed (with appropriate consequences to methods
* like containsObject(T) ) before buildDeferredObjects() is called, but will
* result in objects being constructed (with appropriate consequences to methods
* like containsObject(T) ) after buildDeferredObjects() is called.
*
* @param <T>
* The Class of object this ReferenceManufacturer can manufacture
*/
public interface ReferenceManufacturer<T extends Loadable> extends
SelectionCreator<T>, FormatManager<T>
{
/**
* Constructs a new CDOMObject of the Class or Class/Category represented by
* this ReferenceManufacturer
*
* Implementation Note: At this point, the "key" provided is likely to be
* the "display name" of an object, not the actual "KEY". This is due to the
* need to construct an object at the time it is first encountered, which is
* probably not the time at which the KEY is known (the intent is not to do
* "lookahead", as it fails under .MOD conditions anyway). In order to
* "rename" an object once a KEY is encountered, see renameObject(String, T)
*
* @param key
* The identifier of the CDOMObject to be constructed
* @return The new CDOMObject of the Class or Class/Category represented by
* this ReferenceManufacturer
*/
public T constructObject(String key);
/**
* Adds an object to the contents of this ReferenceManufacturer. This is
* used in conditions where this ReferenceManufacturer was not used to
* construct the object.
*
* Implementation Note: There are various situations where this "external
* construction" may happen - the primary one being loading of "game mode"
* information like CDOMStat objects.
*
* @param item
* The object to be imported into this ReferenceManufacturer
* @param key
* The identifier of the object to be imported into this
* ReferenceManufacturer
*/
public void addObject(T item, String key);
/**
* Returns true if this ReferenceManufacturer contains an object of the
* Class or Class/Category represented by this ReferenceManufacturer.
*
* Note that this is testing *object* presence. This will not return true if
* a reference for the given identifier has been requested; it will only
* return true if an object with the given identifier has actually been
* constructed by or imported into this ReferenceManufacturer.
*
* @param key
* The identifier of the object to be checked if it is present in
* this ReferenceManufacturer.
* @return true if this ReferenceManufacturer contains an object of the
* Class or Class/Category represented by this
* ReferenceManufacturer; false otherwise.
*/
public boolean containsObject(String key);
/**
* Gets the object represented by the given identifier. Will return null if
* an object with the given identifier is not present in this
* ReferenceManufacturer. Does not make a test to establish if the given
* identifier is unique - must act silently.
*
* Note that this is testing *object* presence. This will not return an
* object if a reference for the given identifier has been requested; it
* will only return true if an object with the given identifier has actually
* been constructed by or imported into this ReferenceManufacturer.
*
* @param key
* identifier of the object to be returned
* @return The object stored in this ReferenceManufacturer with the given
* identifier, or null if this ReferenceManufacturer does not
* contain an object with the given identifier.
*/
public T getActiveObject(String key);
/**
* Gets the object represented by the given identifier. Will return null if
* an object with the given identifier is not present in this
* ReferenceManufacturer.
*
* Note that this is testing *object* presence. This will not return an
* object if a reference for the given identifier has been requested; it
* will only return true if an object with the given identifier has actually
* been constructed by or imported into this ReferenceManufacturer.
*
* @param key
* identifier of the object to be returned
* @return The object stored in this ReferenceManufacturer with the given
* identifier, or null if this ReferenceManufacturer does not
* contain an object with the given identifier.
*/
public T getObject(String key);
/**
* Returns a Collection of all of the objects contained in this
* ReferenceManufacturer sorted by their KeyName. This will not return null,
* it will return an empty list if no objects have been constructed by or
* imported into this ReferenceManufacturer.
*
* @return A Collection of all of the objects contained in this
* ReferenceManufacturer
*/
public Collection<T> getAllObjects();
/**
* Returns a List of all of the objects contained in this
* ReferenceManufacturer sorted by the order they were added to the
* ReferenceManufacturer. This will not return null, it will return an empty
* list if no objects have been constructed by or imported into this
* ReferenceManufacturer.
*
* @return A List of all of the objects contained in this
* ReferenceManufacturer
*/
public List<T> getOrderSortedObjects();
/**
* Changes the identifier for a given object, as stored in this
* ReferenceManufacturer.
*
* @param key
* The new identifier to be used for the given object
* @param item
* The object for which the identifier in this
* ReferenceManufacturer should be changed
*/
public void renameObject(String key, T item);
/**
* Remove the given object from this ReferenceManufacturer. Returns true if
* the object was removed from this ReferenceManufacturer; false otherwise.
*
* @param item
* The object to be removed from this ReferenceManufacturer.
* @return true if the object was removed from this ReferenceManufacturer;
* false otherwise.
*/
public boolean forgetObject(T item);
/**
* Resolves the references that have been requested from this
* ReferenceManufacturer, using the objects contained within this
* ReferenceManufacturer.
*
* This method guarantees that all references are resolved.
*
* Note: Implementations of ReferenceManufacturer may place limits on the
* number of times resolveReferences() can be called. The reason for this is
* that some references may only be resolved once, and the
* ReferenceManufacturer is not required to maintain a list of references
* that have been resolved and those which have not been resolved.
*/
public boolean resolveReferences(UnconstructedValidator validator);
/**
* Instructs the ReferenceManufacturer that the object with the given
* identifier should be constructed automatically if it is necessary when
* buildDeferredObjects() is called. The object will be constructed only if
* no object with the matching identifier has been constructed or imported
* into this ReferenceManufacturer.
*
* Implementation Note: This is generally used for backwards compatibility
* to previous versions of PCGen or to items that are built automatically
* (such as Weapon Proficiencies for Natural Attacks)
*
* @param key
* The identifier of the CDOMObject to be built (if otherwise not
* constructed or imported into this ReferenceManufacturer) when
* buildDeferredObjects() is called.
*/
public void constructIfNecessary(String key);
/**
* Builds any objects whose construction was deferred. Identifiers for
* objects for which construction was deferred were inserted into the
* ReferenceManufacturer using constructIfNecessary(String). Objects will be
* constructed only if no object with the matching identifier has been
* constructed or imported into this ReferenceManufacturer.
*
* Construction or import into the ReferenceManufacturer could occur at any
* time before buildDeferredObjects() is called, either before or after
* constructIfNecessary(String) was called with the relevant identifier.
* However, construction or import of an object with an identical identifier
* after buildDeferredObjects() is called will result in a duplicate object
* being formed. ReferenceManufacturer is not responsible for deleting
* automatically built objects under those conditions.
*/
public void buildDeferredObjects();
/**
* Returns true if this ReferenceManufacturer is "valid". A "valid"
* ReferenceManufacturer is one where all of the following are true:
*
* (1) Any object stored in the ReferenceManufacturer reports that it's KEY
* (as defined by CDOMObject.getKeyName()) matches the identifier used to
* store the object in the ReferenceManufacturer.
*
* (2) All objects stored in the ReferenceManufacturer have valid names
* (do not use illegal characters in the names)
*
* (3) No two objects in the ReferenceManufacturer have a matching
* identifier.
*
* @param validator
* UnconstructedValidator which can suppress unconstructed
* reference warnings
*
* @return true if the ReferenceManufacturer is "valid"; false otherwise.
*/
public boolean validate(UnconstructedValidator validator);
/**
* Triggers immediate construction of the object with the given identifier
* if it does not exist. This is an alternative to constructIfNecessary that
* should be used sparingly (generally direct access like this is higher
* risk, but necessary in some cases)
*
* Note that use of this method is inherently risky when taken in context to
* .MOD and .COPY. Changes to keys may change the object to which an
* identifier refers. Therefore, any resolution that should take place at
* runtime should use getReference and resolve the reference.
*
* The object will be constructed only if no object with the matching
* identifier has been constructed or imported into this
* ReferenceManufacturer. If the object has already been constructed, then
* the previously constructed object is returned.
*
* This method is effectively a convenience method that wraps
* containsObject, getObject, and constructObject into a single method call
* (and avoids the contains-triggered branch)
*
* @param key
* The identifier of the CDOMObject to be built (if otherwise not
* constructed or imported into this ReferenceManufacturer), or
* if an object with that identifier already exists, the
* identifier of the object to be returned.
* @return The previously existing or new CDOMObject with the given
* identifier.
*/
public T constructNowIfNecessary(String key);
/**
* Adds an UnconstructedListener to this ReferenceManufacturer, that will
* receive UnconstructedEvents if the validate method of this
* ReferenceManufacturer is called and the UnconstructedValidator given to
* the validate method does not report that the unconstructed reference is
* permitted.
*
* @param listener
* The UnconstructedListener to be registered with this
* ReferenceManufacturer
*/
public void addUnconstructedListener(UnconstructedListener listener);
/**
* Returns an array of UnconstructedListeners that are registered with this
* ReferenceManufacturer.
*
* @return An array of UnconstructedListeners that are registered with this
* ReferenceManufacturer.
*/
public UnconstructedListener[] getUnconstructedListeners();
/**
* Removes an UnconstructedListener from this ReferenceManufacturer, so that
* it will no longer receive UnconstructedEvents from this
* ReferenceManufacturer
*
* @param listener
* The UnconstructedListener to be removed from registration with
* this ReferenceManufacturer
*/
public void removeUnconstructedListener(UnconstructedListener listener);
/**
* Returns the number of objects that are constructed in this
* ReferenceManufacturer (These could be natively constructed or imported
* objects and does not count duplicates)
*
* @return The number of objects that are constructed in this
* ReferenceManufacturer
*/
public int getConstructedObjectCount();
public T getItemInOrder(int index);
public String getReferenceDescription();
public T buildObject(String name);
public void fireUnconstuctedEvent(CDOMReference<?> reference);
public Collection<CDOMSingleRef<T>> getReferenced();
public ManufacturableFactory<T> getFactory();
public Collection<CDOMReference<T>> getAllReferences();
public void injectConstructed(ReferenceManufacturer<T> rm);
public void addDerivativeObject(T obj);
public Collection<T> getDerivativeObjects();
}