/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library 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 (at your option) any later version. This library 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, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.collections.containers; import java.util.NoSuchElementException; import xxl.core.functions.Function; /** * Verifies each write operation of a container, that means for example after * an insert, the object is retrieved again with get and both objects are compared * (using the equals method from Object). If an operation fails * a RuntimeException is thrown. */ public class VerificationContainer extends ConstrainedDecoratorContainer { /** * A name which can be given the VerificationContainer. */ private String name; /** * Internal numbering of actions that write data (insert/update/remove). */ public long numberOfActions; /** * Constructs a new VerificationContainer. * @param container The container to be wrapped. * @param name A name which is used inside the text of exception (useful to * set if using multiple VerificationContainers). */ public VerificationContainer(Container container, String name) { super(container); this.name = name; numberOfActions = 0; } /** * Removes an Object and makes some tests if it really has been removed. * @param id an identifier of an object. * @throws NoSuchElementException if an object with an identifier * <tt>id</tt> is not in the container. */ public void remove(Object id) throws NoSuchElementException { int sizeBefore = size(); super.remove(id); int sizeAfter = size(); if (sizeAfter!=sizeBefore-1) throw new RuntimeException("VerificationContainer "+name+"("+numberOfActions+"): failed inside remove (number of objects)"); if (contains(id)) throw new RuntimeException("VerificationContainer "+name+"("+numberOfActions+"): failed inside remove"); numberOfActions++; } /** * Reserves space for an Object and tests if the identifier is * returned by the contains method. * @param getObject A parameterless function providing the object for * that an id should be reserved. * @return the reserved id. */ public Object reserve(Function getObject) { Object o = super.reserve(getObject); numberOfActions++; return o; } /** * Updates an object and tests if the retrieved object equals the original object. * @param id identifier of the element. * @param object the new object that should be associated to * <tt>id</tt>. * @param unfix signals whether the object can be removed from the * underlying buffer. * @throws NoSuchElementException if an object with an identifier * <tt>id</tt> does not exist in the container. */ public void update(Object id, Object object, boolean unfix) throws NoSuchElementException { int sizeBefore = size(); super.update(id, object, unfix); int sizeAfter = size(); if (sizeAfter!=sizeBefore) throw new RuntimeException("VerificationContainer "+name+"("+numberOfActions+"):failed inside update (number of objects)"); Object restored = get(id); if (!restored.equals(object)) throw new RuntimeException("VerificationContainer "+name+"("+numberOfActions+"): failed inside update (objects are not equal)"); numberOfActions++; } /** * Inserts an Object and tests some integrity constraints. * @param object is the new object. * @param unfix signals whether the object can be removed from the * underlying buffer. * @return the identifier of the object. */ public Object insert(Object object, boolean unfix) { int sizeBefore = size(); Object id = super.insert(object, unfix); int sizeAfter = size(); if (sizeAfter!=sizeBefore+1) throw new RuntimeException("VerificationContainer "+name+"("+numberOfActions+"):failed inside insert (number of objects)"); Object restored = get(id); if (!restored.equals(object)) throw new RuntimeException("VerificationContainer "+name+"("+numberOfActions+"): failed inside insert (objects are not equal)"); numberOfActions++; return id; } }