View Javadoc
1   /*
2    * *************************************************************************************************************************************************************
3    *
4    * TheseFoolishThings: Miscellaneous utilities
5    * http://tidalwave.it/projects/thesefoolishthings
6    *
7    * Copyright (C) 2009 - 2025 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  
28  import javax.annotation.CheckForNull;
29  import javax.annotation.Nonnull;
30  import java.util.ArrayList;
31  import java.util.Collection;
32  import java.util.List;
33  import lombok.AccessLevel;
34  import lombok.RequiredArgsConstructor;
35  
36  /***************************************************************************************************************************************************************
37   *
38   * This class provides a few static utility methods to manipulate arguments to methods.
39   *
40   * @author  Fabrizio Giudici
41   * @it.tidalwave.javadoc.stable
42   *
43   **************************************************************************************************************************************************************/
44  @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
45  public final class Parameters
46    {
47      /***********************************************************************************************************************************************************
48       * A convenience method for transforming a varargs of objects to a {@link Collection}. It supports concatenating
49       * collections: that is, each varargs item that is a {@link Collection} is flattened.
50       *
51       * @param   objects                   the objects as varargs
52       * @return                            the objects as collection
53       * @since                             3.2-ALPHA-3
54       * @it.tidalwave.javadoc.experimental
55       **********************************************************************************************************************************************************/
56      @Nonnull
57      public static Collection<Object> r (@Nonnull final Object... objects)
58        {
59          // Don't use streams() for performance reasons.
60          final List<Object> result = new ArrayList<>();
61  
62          for (final var object : objects)
63            {
64              if (!(object instanceof Collection))
65                {
66                  result.add(object);
67                }
68              else
69                {
70                  result.addAll((Collection<?>)object);
71                }
72            }
73  
74          return result;
75        }
76  
77      /***********************************************************************************************************************************************************
78       * Extracts a singled-value parameter of the given type from an array. If the parameter is not found, the default
79       * value is returned. If more than a single parameter is found, an {@link IllegalArgumentException} is thrown.
80       *
81       * @param   <T>                       the static type of the parameter
82       * @param   parameterClass            the dynamic type of the parameter
83       * @param   defaultOption             the default value of the parameter
84       * @param   parameters                the array of parameters
85       * @return                            the value of the parameter
86       * @throws IllegalArgumentException   if more than a single value is found
87       **********************************************************************************************************************************************************/
88      @CheckForNull
89      public static <T> T find (@Nonnull final Class<? extends T> parameterClass,
90                                @CheckForNull final T defaultOption,
91                                @Nonnull final Object... parameters)
92              throws IllegalArgumentException
93        {
94          // Don't use streams() for performance reasons.
95          final var c = find(parameterClass, parameters);
96  
97          if (c.size() > 1)
98            {
99              throw new IllegalArgumentException(String.format("Multiple values for %s have been specified",
100                                                              parameterClass.getSimpleName()));
101           }
102 
103         return c.isEmpty() ? defaultOption : c.iterator().next();
104       }
105 
106     /***********************************************************************************************************************************************************
107      * Extracts multiple-value parameters of the given type from an array. If the parameter is not found, an empty
108      * collection is returned.
109      *
110      * @param   <T>                       the static type of the parameter
111      * @param   parameterClass            the class of the parameter to retrieve
112      * @param   parameters                the array of parameters
113      * @return                            the value of the parameter
114      **********************************************************************************************************************************************************/
115     @Nonnull
116     public static <T> Collection<T> find (@Nonnull final Class<? extends T> parameterClass,
117                                           @Nonnull final Object... parameters)
118       {
119         // Don't use streams() for performance reasons.
120         final Collection<T> result = new ArrayList<>();
121 
122         for (final var parameter : parameters)
123           {
124             if (parameterClass.isAssignableFrom(parameter.getClass()))
125               {
126                 result.add(parameterClass.cast(parameter));
127               }
128           }
129 
130         return result;
131       }
132 
133     /***********************************************************************************************************************************************************
134      * <b>This method is for internal implementation only.</b> Ensures that a given object is neither an array nor a
135      * collection.
136      *
137      * @param   object    the object to check
138      * @param   message   the message to put in the exception
139      * @return            the object itself for calling this method as a function
140      **********************************************************************************************************************************************************/
141     @Nonnull
142     public static Object mustNotBeArrayOrCollection (@Nonnull final Object object, @Nonnull final String message)
143       {
144         if (object instanceof Collection)
145           {
146             throw new IllegalArgumentException(message + " can't be a Collection");
147           }
148 
149         if (object.getClass().isArray())
150           {
151             throw new IllegalArgumentException(message + " can't be an array");
152           }
153 
154         return object;
155       }
156   }