/** * Copyright (C) 2002-2012 The FreeCol Team * * This file is part of FreeCol. * * FreeCol is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * FreeCol 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with FreeCol. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.freecol.common.model; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.logging.Logger; import org.freecolandroid.xml.stream.XMLStreamException; import org.freecolandroid.xml.stream.XMLStreamReader; import org.freecolandroid.xml.stream.XMLStreamWriter; /** * The <code>GoodsLocation</code> is a place where {@link Unit}s and * {@link Goods} can be put. The GoodsLocation can not store any other * Locatables, such as {@link TileItem}s. * * @see Locatable */ public abstract class GoodsLocation extends UnitLocation { private static final Logger logger = Logger.getLogger(GoodsLocation.class.getName()); /** * Describe goodsContainer here. */ private GoodsContainer goodsContainer; protected GoodsLocation() { // empty constructor } /** * Creates a new <code>GoodsLocation</code> instance. * * @param game a <code>Game</code> value */ public GoodsLocation(Game game) { super(game); } /** * Creates a new <code>GoodsLocation</code> instance. * * @param game a <code>Game</code> value * @param in a <code>XMLStreamReader</code> value * @exception XMLStreamException if an error occurs */ public GoodsLocation(Game game, XMLStreamReader in) throws XMLStreamException { super(game, in); } /** * Creates a new <code>GoodsLocation</code> instance. * * @param game a <code>Game</code> value * @param id a <code>String</code> value */ public GoodsLocation(Game game, String id) { super(game, id); } /** * Gets the maximum number of <code>Goods</code> this Location * can hold. * * @return the capacity for goods */ public abstract int getGoodsCapacity(); /** * Gets an <code>Iterator</code> of every <code>Goods</code> in this * <code>GoodsContainer</code>. Each <code>Goods</code> have a maximum * amount of GoodsContainer.CARGO_SIZE. * * @return The <code>Iterator</code>. */ public Iterator<Goods> getGoodsIterator() { return goodsContainer.getGoodsIterator(); } /** * Gets an <code>List</code> with every <code>Goods</code> in this * <code>Colony</code>. There is only one <code>Goods</code> for each * type of goods. * * @return The <code>Iterator</code>. */ public List<Goods> getCompactGoods() { return goodsContainer.getCompactGoods(); } /** * Gets the reason why a given <code>Locatable</code> can not be * added to this Location. * * @param locatable The <code>Locatable</code> to test. * @return The reason why adding would fail. */ public NoAddReason getNoAddReason(Locatable locatable) { if (locatable instanceof Goods) { // WARNING: Goods can always be added to settlements. Any // excess Goods will be removed during end-of-turn // processing. If Units should inherit from GoodsLocation, // this needs to be changed. return NoAddReason.NONE; } else { return super.getNoAddReason(locatable); } } /** * Adds a <code>Locatable</code> to this Location. * * @param locatable * The <code>Locatable</code> to add to this Location. */ @Override public boolean add(Locatable locatable) { if (locatable instanceof Goods) { return addGoods((Goods) locatable); } else { return super.add(locatable); } } /** * Removes a <code>Locatable</code> from this Location. * * @param locatable * The <code>Locatable</code> to remove from this Location. */ public boolean remove(Locatable locatable) { if (locatable instanceof Goods) { return removeGoods((Goods) locatable) != null; } else { return super.remove(locatable); } } /** * Checks if this <code>Location</code> contains the specified * <code>Locatable</code>. * * @param locatable * The <code>Locatable</code> to test the presence of. * @return * <ul> * <li><i>true</i> if the specified <code>Locatable</code> is * on this <code>Location</code> and * <li><i>false</i> otherwise. * </ul> */ public boolean contains(Locatable locatable) { if (locatable instanceof Goods) { return goodsContainer.contains((Goods) locatable); } else { return super.contains(locatable); } } /** * Gets the <code>GoodsContainer</code> this <code>Location</code> * use for storing it's goods, or <code>null</code> if the * <code>Location</code> cannot store any goods. * * @return A <code>GoodsContainer</code> value */ public final GoodsContainer getGoodsContainer() { return goodsContainer; } /** * Set the <code>GoodsContainer</code> value. * * @param newGoodsContainer The new GoodsContainer value. */ public final void setGoodsContainer(final GoodsContainer newGoodsContainer) { this.goodsContainer = newGoodsContainer; } /** * Gets the storage capacity of this settlement. * * @return The storage capacity of this settlement. * @see #getGoodsCapacity */ public int getWarehouseCapacity() { return getGoodsCapacity(); } /** * Removes a specified amount of a type of Goods from this Settlement. * * @param type The type of Goods to remove from this settlement. * @param amount The amount of Goods to remove from this settlement. */ public Goods removeGoods(GoodsType type, int amount) { return goodsContainer.removeGoods(type, amount); } /** * Removes the given Goods from the Settlement. * * @param goods a <code>Goods</code> value */ public Goods removeGoods(AbstractGoods goods) { return goodsContainer.removeGoods(goods); } /** * Removes all Goods of the given type from the Settlement. * * @param type a <code>GoodsType</code> value */ public Goods removeGoods(GoodsType type) { return goodsContainer.removeGoods(type); } /** * Describe <code>addGoods</code> method here. * * @param type a <code>GoodsType</code> value * @param amount an <code>int</code> value */ public boolean addGoods(GoodsType type, int amount) { return goodsContainer.addGoods(type, amount); } /** * Describe <code>addGoods</code> method here. * * @param goods an <code>AbstractGoods</code> value */ public boolean addGoods(AbstractGoods goods) { return addGoods(goods.getType(), goods.getAmount()); } /** * Gets the amount of one type of Goods at this Settlement. * * @param type The type of goods to look for. * @return The amount of this type of Goods at this Location. */ public int getGoodsCount(GoodsType type) { return goodsContainer.getGoodsCount(type); } /** * Removes all references to this object. * * @return A list of disposed objects. */ public List<FreeColGameObject> disposeList() { List<FreeColGameObject> objects = new ArrayList<FreeColGameObject>(); if (goodsContainer != null) { objects.addAll(goodsContainer.disposeList()); goodsContainer = null; } objects.addAll(super.disposeList()); return objects; } /** * Dispose of this GoodsLocation. */ public void dispose() { disposeList(); } /** * {@inheritDoc} */ protected void writeChildren(XMLStreamWriter out, Player player, boolean showAll, boolean toSavedGame) throws XMLStreamException { super.writeChildren(out, player, showAll, toSavedGame); if (goodsContainer != null) { goodsContainer.toXML(out, player, showAll, toSavedGame); } } /** * {@inheritDoc} */ protected void readChild(XMLStreamReader in) throws XMLStreamException { if (GoodsContainer.getXMLElementTagName().equals(in.getLocalName())) { goodsContainer = (GoodsContainer) getGame().getFreeColGameObject(in.getAttributeValue(null, ID_ATTRIBUTE)); if (goodsContainer == null) { goodsContainer = new GoodsContainer(getGame(), this, in); } else { goodsContainer.readFromXML(in); } } else { super.readChild(in); } } }