TableResourceMap.java

/*
** Module   : TableResourceMap.java
** Abstract : A mutable map to track table-level database resources
**
** Copyright (c) 2018-2019, Golden Code Development Corporation.
**
** -#- -I- --Date-- -------------------------------- Description --------------------------------
** 001 ECF 20180908 Created initial version.
** 002 CA  20190509 Changed remove() signature to return a boolean if something was removed or not.

/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
** 
** Additional terms under GNU Affero GPL version 3 section 7:
** 
**   Under Section 7 of the GNU Affero GPL version 3, the following additional
**   terms apply to the works covered under the License.  These additional terms
**   are non-permissive additional terms allowed under Section 7 of the GNU
**   Affero GPL version 3 and may not be removed by you.
** 
**   0. Attribution Requirement.
** 
**     You must preserve all legal notices or author attributions in the covered
**     work or Appropriate Legal Notices displayed by works containing the covered
**     work.  You may not remove from the covered work any author or developer
**     credit already included within the covered work.
** 
**   1. No License To Use Trademarks.
** 
**     This license does not grant any license or rights to use the trademarks
**     Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
**     of Golden Code Development Corporation. You are not authorized to use the
**     name Golden Code, FWD, or the names of any author or contributor, for
**     publicity purposes without written authorization.
** 
**   2. No Misrepresentation of Affiliation.
** 
**     You may not represent yourself as Golden Code Development Corporation or FWD.
** 
**     You may not represent yourself for publicity purposes as associated with
**     Golden Code Development Corporation, FWD, or any author or contributor to
**     the covered work, without written authorization.
** 
**   3. No Misrepresentation of Source or Origin.
** 
**     You may not represent the covered work as solely your work.  All modified
**     versions of the covered work must be marked in a reasonable way to make it
**     clear that the modified work is not originating from Golden Code Development
**     Corporation or FWD.  All modified versions must contain the notices of
**     attribution required in this license.
*/

package com.goldencode.p2j.schema;

import java.io.*;
import java.util.*;

/**
 * A class to track table-level database resources (e.g., fields or indices), in order to support
 * reporting of unused resources during conversion. An instance is created and all such known
 * resources are added to it initially. As resources are identified as being referenced/used
 * during conversion, they are removed from the map. Those remaining in the map at the end of
 * conversion represent resources that are not referenced in static database code. The
 * {@link #writeContent(Writer, String)} method is used to write any remaining, unreferenced
 * resources into a lightly-formatted text stream.
 */
public final class TableResourceMap
{
   /** Map of qualified table names to sets of resource names within that table */
   private final SortedMap<String, SortedSet<String>> byTable = new TreeMap<>();
   
   /**
    * Default constructor.
    */
   public TableResourceMap()
   {
   }
   
   /**
    * Add a single resource to the map. Add a table entry to the map if this is the first
    * resource to be added which is associated with the given table.
    * 
    * @param   table
    *          Qualified, normalized table name.
    * @param   resource
    *          Resource name.
    */
   public void add(String table, String resource)
   {
      SortedSet<String> resources = byTable.get(table);
      if (resources == null)
      {
         resources = new TreeSet<>();
         byTable.put(table, resources);
      }
      resources.add(resource);
   }
   
   /**
    * Remove a single resource from the map. Remove the table entry from the map if there are no
    * resources left in the set after the removal.
    * 
    * @param   table
    *          Qualified, normalized table name.
    * @param   resource
    *          Resource name
    * 
    * @return  If the table was removed.
    */
   public boolean remove(String table, String resource)
   {
      SortedSet<String> resources = byTable.get(table);
      if (resources != null && resources.remove(resource) && resources.isEmpty())
      {
         byTable.remove(table);
         
         return true;
      }
      
      return false;
   }
   
   /**
    * Indicate whether the resource map is empty.
    * 
    * @return  {@code true} if empty, else {@code false}.
    */
   public boolean isEmpty()
   {
      return byTable.isEmpty();
   }
   
   /**
    * Write content for the remaining information, if any, in this resource map, once all
    * individual referenced resources have been removed.
    * 
    * @param   writer
    *          Writer output stream.
    * @param   heading
    *          Heading for this resource map's section of the report.
    * 
    * @throws  IOException
    *          if there is an error writing to the stream.
    */
   public void writeContent(Writer writer, String heading)
   throws IOException
   {
      if (isEmpty())
      {
         return;
      }
      
      String sep = System.lineSeparator();
      String dsep = sep + sep;
      String pad = "   ";
      String dpad = "      ";
      
      writer.write(heading + dsep);
      
      for (Map.Entry<String, SortedSet<String>> entry : byTable.entrySet())
      {
         String table = entry.getKey();
         SortedSet<String> resources = entry.getValue();
         
         writer.write(pad + "Table:  " + table + dsep);
         
         for (String resource : resources)
         {
            writer.write(dpad + resource + sep);
         }
         
         writer.write(sep);
      }
      
      writer.write(sep);
   }
}