ShortNames.java

  1. /*
  2.  * *************************************************************************************************************************************************************
  3.  *
  4.  * TheseFoolishThings: Miscellaneous utilities
  5.  * http://tidalwave.it/projects/thesefoolishthings
  6.  *
  7.  * Copyright (C) 2009 - 2024 by Tidalwave s.a.s. (http://tidalwave.it)
  8.  *
  9.  * *************************************************************************************************************************************************************
  10.  *
  11.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
  12.  * You may obtain a copy of the License at
  13.  *
  14.  *     http://www.apache.org/licenses/LICENSE-2.0
  15.  *
  16.  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  17.  * CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and limitations under the License.
  18.  *
  19.  * *************************************************************************************************************************************************************
  20.  *
  21.  * git clone https://bitbucket.org/tidalwave/thesefoolishthings-src
  22.  * git clone https://github.com/tidalwave-it/thesefoolishthings-src
  23.  *
  24.  * *************************************************************************************************************************************************************
  25.  */
  26. package it.tidalwave.util;

  27. import java.lang.reflect.InvocationTargetException;
  28. import javax.annotation.Nonnull;
  29. import javax.annotation.Nullable;
  30. import java.util.Arrays;
  31. import java.util.List;
  32. import lombok.extern.slf4j.Slf4j;
  33. import static java.util.stream.Collectors.*;

  34. /***************************************************************************************************************************************************************
  35.  *
  36.  * A utility that returns short qualified names for class literals and objects.
  37.  *
  38.  * @author  Fabrizio Giudici
  39.  * @since   3.2-ALPHA-17
  40.  *
  41.  **************************************************************************************************************************************************************/
  42. @Slf4j
  43. public class ShortNames
  44.   {
  45.     /***********************************************************************************************************************************************************
  46.      * Returns the short name for a class literal.
  47.      *
  48.      * @param     clazz     the class
  49.      * @return              the short name
  50.      **********************************************************************************************************************************************************/
  51.     @Nonnull
  52.     public static String shortName (@Nonnull final Class<?> clazz)
  53.       {
  54.         return shortName(clazz, false);
  55.       }

  56.     /***********************************************************************************************************************************************************
  57.      * Returns the short name for a class literal, eventually adding interface names (but not those in the java.*
  58.      * package).
  59.      *
  60.      * @param     clazz               the class
  61.      * @param     withInterfaces      whether the interfaces must be listed
  62.      * @return                        the short name
  63.      **********************************************************************************************************************************************************/
  64.     @Nonnull
  65.     public static String shortName (@Nonnull final Class<?> clazz, final boolean withInterfaces)
  66.         {
  67.           var className = clazz.getName();
  68.           var prefix = "";

  69.         if (className.contains("EnhancerByMockito"))
  70.           {
  71.             prefix = "mock-of-";
  72.             className = className.replaceAll("\\$\\$EnhancerByMockito.*", "");
  73.           }

  74.         final var parts = className.split("\\.");
  75.         final var s = new StringBuilder();

  76.         for (var i = 0; i < parts.length; i++)
  77.           {
  78.             s.append((i < parts.length - 1) ? parts[i].charAt(0) + "." : parts[i]);
  79.           }

  80.         if (withInterfaces)
  81.           {
  82.             final var interfaces = clazz.getInterfaces();

  83.             if (interfaces.length > 0)
  84.               {
  85.                 s.append(Arrays.stream(interfaces)
  86.                                .filter(i -> !i.getPackage().getName().startsWith("java"))
  87.                                .map(ShortNames::shortName).collect(joining(", ", "{", "}")));
  88.               }
  89.           }

  90.         return prefix + s;
  91.       }

  92.     /***********************************************************************************************************************************************************
  93.      * Returns the short name for class literals, eventually adding interface names (but not those in the java.*
  94.      * package).
  95.      *
  96.      * @param     classes   the classes
  97.      * @return              the short names
  98.      **********************************************************************************************************************************************************/
  99.     @Nonnull
  100.     public static String shortNames (@Nonnull final Iterable<Class<?>> classes)
  101.       {
  102.         final var result = new StringBuilder();
  103.         var separator = "";

  104.         for (final var clazz : classes)
  105.           {
  106.             result.append(separator).append(shortName(clazz));
  107.             separator = ", ";
  108.           }

  109.         return "[" + result + "]";
  110.       }

  111.     /***********************************************************************************************************************************************************
  112.      * Return the short name for an object. If the object contains a method named {@code getId()}, the id is part of
  113.      * the result.
  114.      *
  115.      * @param     object    the object
  116.      * @return              the short name
  117.      **********************************************************************************************************************************************************/
  118.     @Nonnull
  119.     public static String shortId (@Nullable final Object object)
  120.       {
  121.         if (object == null)
  122.           {
  123.             return "null";
  124.           }

  125.         final var s = new StringBuilder();
  126.         s.append(String.format("%s@%x", shortName(object.getClass()), System.identityHashCode(object)));

  127.         try
  128.           {
  129.             final var id = object.getClass().getMethod("getId").invoke(object);
  130.             s.append("/").append(id != null ? id.toString() : "null");
  131.           }
  132.         catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored)
  133.           {
  134.             // log.trace("While invoking 'getId(): {}", e.toString());
  135.           }

  136.         return s.toString();
  137.       }

  138.     /***********************************************************************************************************************************************************
  139.      * Return the short names for some objects.
  140.      *
  141.      * @param     objects   the objects
  142.      * @return              the short names
  143.      **********************************************************************************************************************************************************/
  144.     @Nonnull
  145.     public static String shortIds (@Nonnull final Iterable<?> objects)
  146.       {
  147.         final var result = new StringBuilder();
  148.         var separator = "";

  149.         for (final var object : objects)
  150.           {
  151.             result.append(separator).append(shortId(object));
  152.             separator = ", ";
  153.           }

  154.         return "[" + result + "]";
  155.       }

  156.     /***********************************************************************************************************************************************************
  157.      * Return the short names for some objects.
  158.      *
  159.      * @param     objects   the objects
  160.      * @return              the short names
  161.      **********************************************************************************************************************************************************/
  162.     @Nonnull
  163.     public static String shortIds (@Nonnull final Object... objects)
  164.       {
  165.         return shortIds(List.of(objects));
  166.       }
  167.   }