001/*
002 * Copyright 2023 the original author or authors.
003 * <p>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p>
008 * https://www.apache.org/licenses/LICENSE-2.0
009 * <p>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package de.cuioss.test.generator.impl;
017
018import static de.cuioss.tools.base.Preconditions.checkArgument;
019import static java.util.Objects.requireNonNull;
020
021import de.cuioss.test.generator.Generators;
022import de.cuioss.test.generator.TypedGenerator;
023
024/**
025 * Generates arrays of primitive types.
026 *
027 * @author Oliver Wolff
028 */
029public enum PrimitiveArrayGenerators {
030
031    /** Provides booleans */
032    BOOLEAN {
033
034        @Override
035        public Object next() {
036            final int size = sizeGenerator.next();
037            final var generator = Generators.booleans();
038            final var array = new boolean[size];
039            for (var index = 0; index < size; index++) {
040                array[index] = generator.next();
041            }
042            return array;
043        }
044
045        @Override
046        public Class<?> getType() {
047            return boolean.class;
048        }
049    },
050    /** Provides bytes */
051    BYTE {
052
053        @Override
054        public Object next() {
055            final int size = sizeGenerator.next();
056            final var generator = Generators.bytes();
057            final var array = new byte[size];
058            for (var index = 0; index < size; index++) {
059                array[index] = generator.next();
060            }
061            return array;
062        }
063
064        @Override
065        public Class<?> getType() {
066            return byte.class;
067        }
068    },
069    /** Provides chars */
070    CHAR {
071
072        @Override
073        public Object next() {
074            final int size = sizeGenerator.next();
075            final var generator = Generators.characters();
076            final var array = new char[size];
077            for (var index = 0; index < size; index++) {
078                array[index] = generator.next();
079            }
080            return array;
081        }
082
083        @Override
084        public Class<?> getType() {
085            return char.class;
086        }
087    },
088    /** Provides shorts */
089    SHORT {
090
091        @Override
092        public Object next() {
093            final int size = sizeGenerator.next();
094            final TypedGenerator<Short> generator = new ShortObjectGenerator();
095            final var array = new short[size];
096            for (var index = 0; index < size; index++) {
097                array[index] = generator.next();
098            }
099            return array;
100        }
101
102        @Override
103        public Class<?> getType() {
104            return short.class;
105        }
106    },
107    /** Provides integers */
108    INTEGER {
109
110        @Override
111        public Object next() {
112            final int size = sizeGenerator.next();
113            final var generator = Generators.integers();
114            final var array = new int[size];
115            for (var index = 0; index < size; index++) {
116                array[index] = generator.next();
117            }
118            return array;
119        }
120
121        @Override
122        public Class<?> getType() {
123            return int.class;
124        }
125    },
126    /** Provides longs */
127    LONG {
128
129        @Override
130        public Object next() {
131            final int size = sizeGenerator.next();
132            final var generator = Generators.longs();
133            final var array = new long[size];
134            for (var index = 0; index < size; index++) {
135                array[index] = generator.next();
136            }
137            return array;
138        }
139
140        @Override
141        public Class<?> getType() {
142            return long.class;
143        }
144    },
145    /** Provides floats */
146    FLOAT {
147
148        @Override
149        public Object next() {
150            final int size = sizeGenerator.next();
151            final TypedGenerator<Float> generator = new FloatObjectGenerator();
152            final var array = new float[size];
153            for (var index = 0; index < size; index++) {
154                array[index] = generator.next();
155            }
156            return array;
157        }
158
159        @Override
160        public Class<?> getType() {
161            return float.class;
162        }
163    },
164    /** Provides doubles */
165    DOUBLE {
166
167        @Override
168        public Object next() {
169            final int size = sizeGenerator.next();
170            final var generator = Generators.doubles();
171            final var array = new double[size];
172            for (var index = 0; index < size; index++) {
173                array[index] = generator.next();
174            }
175            return array;
176        }
177
178        @Override
179        public Class<?> getType() {
180            return double.class;
181        }
182    };
183
184    private static final TypedGenerator<Integer> sizeGenerator = Generators.integers(0, 128);
185
186    /**
187     * @return an primitive array of the configured type, with the sizes 1-128
188     */
189    public abstract Object next();
190
191    /**
192     * @return the type of the primitive
193     */
194    public abstract Class<?> getType();
195
196    /**
197     * Returns a {@link PrimitiveArrayGenerators} for the given primitive type.
198     *
199     * @param primitiveType must not be null and a primitive type.
200     * @return the found {@link PrimitiveArrayGenerators} or throws an
201     *         {@link IllegalStateException} if none could be found
202     */
203    public static PrimitiveArrayGenerators resolveForType(final Class<?> primitiveType) {
204        requireNonNull(primitiveType);
205        checkArgument(primitiveType.isPrimitive(), "You must provide a primitive type, given: " + primitiveType);
206        for (final PrimitiveArrayGenerators generator : PrimitiveArrayGenerators.values()) {
207            if (primitiveType.equals(generator.getType())) {
208                return generator;
209            }
210        }
211        throw new IllegalStateException("No generator registered for type " + primitiveType);
212    }
213
214}