OrderedTableNameMap.java

  1. /*
  2.  *
  3.  * The DbUnit Database Testing Framework
  4.  * Copyright (C)2002-2004, DbUnit.org
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2.1 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with this library; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  *
  20.  */
  21. package org.dbunit.dataset;

  22. import java.util.ArrayList;
  23. import java.util.Collection;
  24. import java.util.HashMap;
  25. import java.util.Iterator;
  26. import java.util.List;
  27. import java.util.Locale;
  28. import java.util.Map;

  29. import org.dbunit.database.AmbiguousTableNameException;
  30. import org.slf4j.Logger;
  31. import org.slf4j.LoggerFactory;

  32. /**
  33.  * Associates a table name with an arbitrary object. Moreover the
  34.  * order of the added table names is maintained and the ordered table
  35.  * names can be retrieved via {@link #getTableNames()}.
  36.  * <p>
  37.  * The map ensures that one table name can only be added once.
  38.  * </p>
  39.  *
  40.  * TODO In the future it might be discussed if a ListOrderedMap (apache-commons-collections) can/should be used.
  41.  *
  42.  * @author gommma
  43.  * @author Last changed by: $Author$
  44.  * @version $Revision$
  45.  * @since 2.4.0
  46.  */
  47. public class OrderedTableNameMap
  48. {
  49.     /**
  50.      * Logger for this class
  51.      */
  52.     private static final Logger LOGGER = LoggerFactory.getLogger(OrderedTableNameMap.class);

  53.     /**
  54.      * The map for fast access to the existing table names and for
  55.      * associating an arbitrary object with a table name
  56.      */
  57.     private Map _tableMap = new HashMap();
  58.     /**
  59.      * Chronologically ordered list of table names - keeps the order
  60.      * in which the table names have been added as well as the case in
  61.      * which the table has been added
  62.      */
  63.     private List _tableNames = new ArrayList();
  64.    
  65.     private String _lastTableNameOverride;
  66.    
  67.     /**
  68.      * Whether or not case sensitive table names should be used. Defaults to false.
  69.      */
  70.     private boolean _caseSensitiveTableNames = false;
  71.    
  72.    
  73.     /**
  74.      * Creates a new map which does strictly force that one table can only occur once.
  75.      * @param caseSensitiveTableNames Whether or not table names should be case sensitive
  76.      */
  77.     public OrderedTableNameMap(boolean caseSensitiveTableNames)
  78.     {
  79.         _caseSensitiveTableNames = caseSensitiveTableNames;
  80.     }

  81.     /**
  82.      * Returns the object associated with the given table name
  83.      * @param tableName The table name for which the associated object is retrieved
  84.      * @return The object that has been associated with the given table name
  85.      */
  86.     public Object get(String tableName)
  87.     {
  88.         String correctedCaseTableName = this.getTableName(tableName);
  89.         return this._tableMap.get(correctedCaseTableName);
  90.     }


  91.     /**
  92.      * Provides the ordered table names having the same order in which the table
  93.      * names have been added via {@link #add(String, Object)}.
  94.      * @return The list of table names ordered in the sequence as
  95.      * they have been added to this map
  96.      */
  97.     public String[] getTableNames()
  98.     {
  99.         return (String[])this._tableNames.toArray(new String[0]);
  100.     }

  101.     /**
  102.      * Checks if this map contains the given table name
  103.      * @param tableName
  104.      * @return Returns <code>true</code> if the map of tables contains the given table name
  105.      */
  106.     public boolean containsTable(String tableName)
  107.     {
  108.         String correctedCaseTableName = this.getTableName(tableName);
  109.         return _tableMap.containsKey(correctedCaseTableName);
  110.     }

  111.     /**
  112.      * @param tableName The table name to check
  113.      * @return <code>true</code> if the given tableName matches the last table that has been added to this map.
  114.      */
  115.     public boolean isLastTable(String tableName)
  116.     {
  117.         if(LOGGER.isDebugEnabled())
  118.             LOGGER.debug("isLastTable(tableName={}) - start", tableName);
  119.        
  120.         if(this._tableNames.size() == 0)
  121.         {
  122.             return false;
  123.         }
  124.         else
  125.         {
  126.             String lastTable = getLastTableName();
  127.             String lastTableCorrectCase = this.getTableName(lastTable);
  128.             String inputTableCorrectCase = this.getTableName(tableName);
  129.             return lastTableCorrectCase.equals(inputTableCorrectCase);
  130.         }
  131.     }

  132.     /**
  133.      * @return The name of the last table that has been added to this map. Returns <code>null</code> if no
  134.      * table has been added yet.
  135.      */
  136.     public String getLastTableName()
  137.     {
  138.         if(LOGGER.isDebugEnabled())
  139.             LOGGER.debug("getLastTableName() - start");
  140.        
  141.         if(_lastTableNameOverride != null)
  142.         {
  143.             return _lastTableNameOverride;
  144.         }
  145.        
  146.         if(_tableNames.size()>0)
  147.         {
  148.             String lastTable = (String) _tableNames.get(this._tableNames.size()-1);
  149.             return lastTable;
  150.         }
  151.         else
  152.         {
  153.             return null;
  154.         }
  155.     }
  156.    

  157.     public void setLastTable(String tableName) throws NoSuchTableException
  158.     {
  159.         if(LOGGER.isDebugEnabled())
  160.             LOGGER.debug("setLastTable(name{}) - start", tableName);
  161.        
  162.         if(!this.containsTable(tableName))
  163.         {
  164.             throw new NoSuchTableException(tableName);
  165.         }
  166.        
  167.         this._lastTableNameOverride = tableName;
  168.     }

  169.     /**
  170.      * Adds the given table name to the map of table names, associating
  171.      * it with the given object.
  172.      * @param tableName The table name to be added
  173.      * @param object Object to be associated with the given table name. Can be null
  174.      * @throws AmbiguousTableNameException If the given table name already exists
  175.      */
  176.     public void add(String tableName, Object object) throws AmbiguousTableNameException
  177.     {
  178.         if(LOGGER.isDebugEnabled())
  179.             LOGGER.debug("add(tableName={}, object={}) - start", tableName, object);
  180.        
  181.         // Get the table name in the correct case
  182.         String tableNameCorrectedCase = this.getTableName(tableName);
  183.         // prevent table name conflict
  184.         if (this.containsTable(tableNameCorrectedCase))
  185.         {
  186.             throw new AmbiguousTableNameException(tableNameCorrectedCase);
  187.         }
  188.         else {
  189.             this._tableMap.put(tableNameCorrectedCase, object);
  190.             this._tableNames.add(tableName);
  191.             // Reset the override of the lastTableName
  192.             this._lastTableNameOverride = null;
  193.         }
  194.     }
  195.    
  196.     /**
  197.      * @return The values of this map ordered in the sequence they have been added
  198.      */
  199.     public Collection orderedValues()
  200.     {
  201.         if(LOGGER.isDebugEnabled())
  202.             LOGGER.debug("orderedValues() - start");

  203.         List orderedValues = new ArrayList(this._tableNames.size());
  204.         for (Iterator iterator = _tableNames.iterator(); iterator.hasNext();) {
  205.             String tableName = (String) iterator.next();
  206.             Object object = this.get(tableName);
  207.             orderedValues.add(object);
  208.         }
  209.         return orderedValues;
  210.     }
  211.    
  212.     /**
  213.      * Updates the value associated with the given table name. Must be invoked if
  214.      * the table name has already been added before.
  215.      * @param tableName The table name for which the association should be updated
  216.      * @param object The new object to be associated with the given table name
  217.      */
  218.     public void update(String tableName, Object object)
  219.     {
  220.         if(LOGGER.isDebugEnabled())
  221.             LOGGER.debug("update(tableName={}, object={}) - start", tableName, object);

  222.         // prevent table name conflict
  223.         if (!this.containsTable(tableName))
  224.         {
  225.             throw new IllegalArgumentException("The table name '" + tableName + "' does not exist in the map");
  226.         }
  227.         tableName = this.getTableName(tableName);
  228.         this._tableMap.put(tableName, object);
  229.     }

  230.     /**
  231.      * Returns the table name in the correct case (for example as upper case string)
  232.      * @param tableName The input table name to be resolved
  233.      * @return The table name for the given string in the correct case.
  234.      */
  235.     public String getTableName(String tableName)
  236.     {
  237.         if(LOGGER.isDebugEnabled())
  238.             LOGGER.debug("getTableName(tableName={}) - start", tableName);
  239.        
  240.         String result = tableName;
  241.         if(!_caseSensitiveTableNames)
  242.         {
  243.             // "Locale.ENGLISH" Fixes bug #1537894 when clients have a special
  244.             // locale like turkish. (for release 2.4.3)
  245.             result = tableName.toUpperCase(Locale.ENGLISH);
  246.         }

  247.         if(LOGGER.isDebugEnabled())
  248.             LOGGER.debug("getTableName(tableName={}) - end - result={}", tableName, result);
  249.        
  250.         return result;
  251.     }

  252.     public String toString()
  253.     {
  254.         final StringBuilder sb = new StringBuilder();
  255.         sb.append(getClass().getName()).append("[");
  256.         sb.append("_tableNames=").append(_tableNames);
  257.         sb.append(", _tableMap=").append(_tableMap);
  258.         sb.append(", _caseSensitiveTableNames=").append(_caseSensitiveTableNames);
  259.         sb.append("]");
  260.         return sb.toString();
  261.     }
  262.    
  263. }