2 * Copyright © 2016-2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 * Modifications Copyright (c) 2019 Samsung
20 package org.onap.config;
22 import com.virtlink.commons.configuration2.jackson.JsonConfiguration;
23 import net.sf.corn.cps.CPScanner;
24 import net.sf.corn.cps.ResourceFilter;
25 import org.apache.commons.configuration2.Configuration;
26 import org.apache.commons.configuration2.CompositeConfiguration;
27 import org.apache.commons.configuration2.FileBasedConfiguration;
28 import org.apache.commons.configuration2.PropertiesConfiguration;
29 import org.apache.commons.configuration2.XMLConfiguration;
30 import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
31 import org.apache.commons.configuration2.builder.FileBasedConfigurationBuilder;
32 import org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder;
33 import org.apache.commons.configuration2.builder.fluent.Configurations;
34 import org.apache.commons.configuration2.builder.fluent.Parameters;
35 import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
36 import org.apache.commons.configuration2.ex.ConfigurationException;
37 import org.apache.commons.io.IOUtils;
38 import org.onap.config.api.Config;
39 import org.onap.config.api.ConfigurationManager;
40 import org.onap.config.impl.YamlConfiguration;
41 import org.onap.config.type.ConfigurationMode;
42 import org.onap.config.type.ConfigurationType;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 import java.lang.reflect.Field;
48 import java.lang.reflect.ParameterizedType;
49 import java.lang.reflect.Type;
50 import java.net.MalformedURLException;
52 import java.nio.charset.Charset;
53 import java.nio.file.Files;
54 import java.nio.file.Path;
55 import java.util.ArrayDeque;
56 import java.util.ArrayList;
57 import java.util.Arrays;
58 import java.util.Collection;
59 import java.util.Collections;
60 import java.util.Deque;
61 import java.util.HashMap;
62 import java.util.HashSet;
63 import java.util.List;
65 import java.util.Objects;
66 import java.util.Optional;
67 import java.util.Queue;
69 import java.util.SortedSet;
70 import java.util.TreeSet;
71 import java.util.concurrent.BlockingQueue;
72 import java.util.concurrent.ConcurrentLinkedQueue;
73 import java.util.concurrent.LinkedBlockingQueue;
74 import java.util.concurrent.LinkedTransferQueue;
75 import java.util.concurrent.TransferQueue;
76 import java.util.regex.Matcher;
77 import java.util.regex.Pattern;
78 import java.util.stream.Collectors;
80 import static java.util.Optional.ofNullable;
81 import static org.onap.config.api.Hint.EXTERNAL_LOOKUP;
82 import static org.onap.config.api.Hint.LATEST_LOOKUP;
83 import static org.onap.config.api.Hint.NODE_SPECIFIC;
85 public class ConfigurationUtils {
87 private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationUtils.class);
89 private static final String CONFIGURATION_TYPE_NOT_SUPPORTED = "Configuration type not supported:";
91 private static final Map<Class, Class> ARRAY_CLASS_MAP;
93 private static final String CONFIG_REGEX_TPL_OPT_1 = "CONFIG(-\\w*){0,1}(-(%s|%s|%s)){0,1}\\.(%s|%s|%s|%s)$";
95 private static final String CONFIG_REGEX_TPL_OPT_2 = "CONFIG(.)*\\.(%s|%s|%s|%s)$";
98 Map<Class, Class> arrayTypes = new HashMap<>();
99 arrayTypes.put(Byte.class, Byte[].class);
100 arrayTypes.put(Short.class, Short[].class);
101 arrayTypes.put(Integer.class, Integer[].class);
102 arrayTypes.put(Long.class, Long[].class);
103 arrayTypes.put(Float.class, Float[].class);
104 arrayTypes.put(Double.class, Double[].class);
105 arrayTypes.put(Boolean.class, Boolean[].class);
106 arrayTypes.put(Character.class, Character[].class);
107 arrayTypes.put(String.class, String[].class);
108 ARRAY_CLASS_MAP = Collections.unmodifiableMap(arrayTypes);
111 private ConfigurationUtils() {
112 // prevent instantiation
115 public static Collection<File> getAllFiles(File file, boolean recursive, boolean onlyDirectory) {
117 ArrayList<File> collection = new ArrayList<>();
118 if (file.isDirectory() && file.exists()) {
119 File[] files = file.listFiles();
120 for (File innerFile : Objects.requireNonNull(files)) {
121 if (innerFile.isFile() && !onlyDirectory) {
122 collection.add(innerFile);
123 } else if (innerFile.isDirectory()) {
124 collection.add(innerFile);
126 collection.addAll(getAllFiles(innerFile, true, onlyDirectory));
134 public static String getCommaSeparatedList(String[] list) {
135 return (list == null) || (list.length == 0) ? "" : getCommaSeparatedList(Arrays.asList(list));
138 public static String getCommaSeparatedList(List<?> list) {
140 if ((list == null) || list.isEmpty()) {
144 return list.stream().filter(o -> o != null && !o.toString().trim().isEmpty())
145 .map(o -> o.toString().trim()).collect(Collectors.joining(","));
148 public static boolean isConfig(URL url) {
149 return isConfig(url.getFile());
152 public static boolean isConfig(String file) {
153 file = file.toUpperCase().substring(file.lastIndexOf('!') + 1);
154 file = file.substring(file.lastIndexOf('/') + 1);
157 CONFIG_REGEX_TPL_OPT_1,
158 ConfigurationMode.OVERRIDE,
159 ConfigurationMode.MERGE,
160 ConfigurationMode.UNION,
161 ConfigurationType.PROPERTIES.name(),
162 ConfigurationType.XML.name(),
163 ConfigurationType.JSON.name(),
164 ConfigurationType.YAML.name()
168 CONFIG_REGEX_TPL_OPT_2,
169 ConfigurationType.PROPERTIES.name(),
170 ConfigurationType.XML.name(),
171 ConfigurationType.JSON.name(),
172 ConfigurationType.YAML.name()
177 public static boolean isConfig(File file) {
178 return file != null && file.exists() && isConfig(file.getName());
181 private static Optional<String> readNamespace(Configuration config) {
182 return ofNullable(config).flatMap(configuration -> ofNullable(configuration.getString(Constants.NAMESPACE_KEY)))
183 .map(String::toUpperCase);
186 private static Optional<String> readMergeStrategy(Configuration config) {
187 return ofNullable(config).flatMap(configuration -> ofNullable(configuration.getString(Constants.MODE_KEY)))
188 .map(String::toUpperCase);
191 public static ConfigurationMode getMergeStrategy(File file) {
192 Optional<ConfigurationMode> configurationMode =
193 getConfiguration(file).flatMap(ConfigurationUtils::readMergeStrategy)
194 .flatMap(ConfigurationUtils::convertConfigurationMode);
195 return configurationMode.orElseGet(() -> getMergeStrategy(file.getName().toUpperCase()));
198 public static ConfigurationMode getMergeStrategy(URL url) {
199 Optional<ConfigurationMode> configurationMode =
200 getConfiguration(url).flatMap(ConfigurationUtils::readMergeStrategy)
201 .flatMap(ConfigurationUtils::convertConfigurationMode);
202 return configurationMode.orElseGet(() -> getMergeStrategy(url.getFile().toUpperCase()));
205 public static ConfigurationMode getMergeStrategy(String file) {
207 file = file.toUpperCase().substring(file.lastIndexOf('!') + 1);
208 file = file.substring(file.lastIndexOf('/') + 1);
209 Pattern pattern = Pattern.compile(
211 CONFIG_REGEX_TPL_OPT_1,
212 ConfigurationMode.OVERRIDE,
213 ConfigurationMode.MERGE,
214 ConfigurationMode.UNION,
215 ConfigurationType.PROPERTIES.name(),
216 ConfigurationType.XML.name(),
217 ConfigurationType.JSON.name(),
218 ConfigurationType.YAML.name()
221 Matcher matcher = pattern.matcher(file);
222 boolean b1 = matcher.matches();
224 for (int i = 1; i <= matcher.groupCount(); i++) {
225 String modeName = matcher.group(i);
226 if (modeName != null) {
227 modeName = modeName.substring(1);
230 return Enum.valueOf(ConfigurationMode.class, modeName);
231 } catch (Exception exception) {
232 LOGGER.debug("Configuration mode for merge strategy '{}' not found", modeName, exception);
240 public static Optional<FileBasedConfiguration> getConfiguration(URL url) {
244 ConfigurationType configType = ConfigurationUtils.getConfigType(url);
245 switch (configType) {
247 return Optional.of(new Configurations().fileBased(PropertiesConfiguration.class, url));
249 return Optional.of(new Configurations().fileBased(XMLConfiguration.class, url));
251 return Optional.of(new Configurations().fileBased(JsonConfiguration.class, url));
253 return Optional.of(new Configurations().fileBased(YamlConfiguration.class, url));
255 throw new ConfigurationException(CONFIGURATION_TYPE_NOT_SUPPORTED + configType);
257 } catch (ConfigurationException exception) {
258 LOGGER.error("Error reading configuration at {}.", url.toString(), exception);
261 return Optional.empty();
264 public static Optional<FileBasedConfiguration> getConfiguration(File file) {
267 return getConfiguration(file.getAbsoluteFile().toURI().toURL());
268 } catch (MalformedURLException e) {
269 throw new IllegalStateException("Malformed URL: " + file.getAbsolutePath());
273 public static ConfigurationType getConfigType(File file) {
274 Objects.requireNonNull(file, "File cannot be null");
275 return Enum.valueOf(ConfigurationType.class,
276 file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf('.') + 1).toUpperCase());
279 public static ConfigurationType getConfigType(URL url) {
280 Objects.requireNonNull(url, "URL cannot be null");
281 return Enum.valueOf(ConfigurationType.class,
282 url.getFile().substring(url.getFile().lastIndexOf('.') + 1).toUpperCase());
285 private static Optional<ConfigurationMode> convertConfigurationMode(String configMode) {
286 ConfigurationMode configurationMode = null;
288 configurationMode = ConfigurationMode.valueOf(configMode);
289 } catch (Exception exception) {
290 LOGGER.error("Could not find convert {} into configuration mode.", configMode, exception);
292 return Optional.ofNullable(configurationMode);
295 public static Class getCollectionGenericType(Field field) {
296 Type type = field.getGenericType();
298 if (type instanceof ParameterizedType) {
300 ParameterizedType paramType = (ParameterizedType) type;
301 Type[] arr = paramType.getActualTypeArguments();
302 if (arr.length > 0) {
303 Class<?> clazz = (Class<?>) arr[0];
304 if (isWrapperClass(clazz)) {
307 throw new IllegalArgumentException("Collection of type " + clazz.getName() + " not supported.");
312 return String[].class;
315 public static boolean isWrapperClass(Class clazz) {
316 return clazz == String.class || clazz == Boolean.class || clazz == Character.class
317 || Number.class.isAssignableFrom(clazz);
320 public static Class getArrayClass(Class clazz) {
321 return ARRAY_CLASS_MAP.getOrDefault(clazz, null);
324 public static List<URL> getAllClassPathResources() {
325 return CPScanner.scanResources(new ResourceFilter());
328 public static BasicConfigurationBuilder<FileBasedConfiguration> getConfigurationBuilder(File file) {
329 FileBasedConfigurationBuilder<FileBasedConfiguration> builder;
330 ConfigurationType configType = ConfigurationUtils.getConfigType(file);
331 builder = getFileBasedConfigurationBuilder(configType);
332 builder.configure(new Parameters().fileBased().setFile(file)
333 .setListDelimiterHandler(new DefaultListDelimiterHandler(',')));
337 public static BasicConfigurationBuilder<FileBasedConfiguration> getConfigurationBuilder(URL url) {
338 ConfigurationType configType = ConfigurationUtils.getConfigType(url);
339 ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder =
340 getFileBasedConfigurationBuilder(configType);
342 new Parameters().fileBased().setURL(url).setListDelimiterHandler(new DefaultListDelimiterHandler(',')));
346 private static ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> getFileBasedConfigurationBuilder(
347 ConfigurationType configType) {
349 ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder;
350 switch (configType) {
352 builder = new ReloadingFileBasedConfigurationBuilder<>(PropertiesConfiguration.class);
355 builder = new ReloadingFileBasedConfigurationBuilder<>(XMLConfiguration.class);
358 builder = new ReloadingFileBasedConfigurationBuilder<>(JsonConfiguration.class);
361 builder = new ReloadingFileBasedConfigurationBuilder<>(YamlConfiguration.class);
364 throw new IllegalArgumentException(CONFIGURATION_TYPE_NOT_SUPPORTED + configType);
369 public static <T> T read(Configuration config, Class<T> clazz, String keyPrefix) throws Exception {
370 Config confAnnotation = clazz.getAnnotation(Config.class);
371 if (confAnnotation != null) {
372 keyPrefix += (confAnnotation.key() + ".");
374 T objToReturn = clazz.newInstance();
375 for (Field field : clazz.getDeclaredFields()) {
376 Config fieldAnnotation = field.getAnnotation(Config.class);
377 if (fieldAnnotation != null) {
378 field.setAccessible(true);
379 field.set(objToReturn, config.getProperty(keyPrefix + fieldAnnotation.key()));
380 } else if (field.getType().getAnnotation(Config.class) != null) {
381 field.set(objToReturn, read(config, field.getType(), keyPrefix));
387 public static Object getPrimitiveArray(Collection collection, Class clazz) {
388 switch (clazz.getName()) {
390 return getIntsPrimitiveArray(collection);
392 return getBytesPrimitiveArray(collection);
394 return getShortsPrimitiveArray(collection);
396 return getLongsPrimitiveArray(collection);
398 return getFloatsPrimitiveArray(collection);
400 return getDoublesPrimitiveArray(collection);
402 return getBooleansPrimitiveArray(collection);
408 public static String getCollectionString(String input) {
409 Pattern pattern = Pattern.compile("^\\[(.*)\\]$");
410 Matcher matcher = pattern.matcher(input);
411 if (matcher.matches()) {
412 input = matcher.group(1);
417 public static String processVariablesIfPresent(String tenant, String namespace, String data) {
418 Pattern pattern = Pattern.compile("^.*\\$\\{(.*)\\}.*");
419 Matcher matcher = pattern.matcher(data);
420 if (matcher.matches()) {
421 final int substringStartIndex = 4;
422 String key = matcher.group(1);
424 if (key.toUpperCase().startsWith("ENV:")) {
425 value = System.getenv(key.substring(substringStartIndex));
426 } else if (key.toUpperCase().startsWith("SYS:")) {
427 value = System.getProperty(key.substring(substringStartIndex));
429 value = ConfigurationUtils.getCollectionString(
430 ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key).toString());
432 return processVariablesIfPresent(tenant, namespace, data.replaceAll("\\$\\{" + key + "}",
433 value == null ? "" : value.replace("\\", "\\\\")));
439 public static String getFileContents(String path) {
442 return IOUtils.toString(new URL(path), Charset.defaultCharset());
444 } catch (Exception exception) {
445 LOGGER.error("Error while getting '{}' content", path, exception);
450 public static String getFileContents(Path path) {
453 return new String(Files.readAllBytes(path));
455 } catch (Exception exception) {
456 LOGGER.error("Error while getting '{}' content", path.toString(), exception);
461 public static Object getDefaultFor(Class clazz) {
462 if (byte.class == clazz) {
463 return new Byte("0");
464 } else if (short.class == clazz) {
465 return new Short("0");
466 } else if (int.class == clazz) {
467 return new Integer("0");
468 } else if (float.class == clazz) {
469 return new Float("0");
470 } else if (long.class == clazz) {
471 return new Long("0");
472 } else if (double.class == clazz) {
473 return new Double("0");
474 } else if (boolean.class == clazz) {
475 return Boolean.FALSE;
480 public static Collection getCompatibleCollectionForAbstractDef(Class clazz) {
481 if (TransferQueue.class.isAssignableFrom(clazz)) {
482 return getConcreteCollection(TransferQueue.class);
484 if (BlockingQueue.class.isAssignableFrom(clazz)) {
485 return getConcreteCollection(BlockingQueue.class);
487 if (Deque.class.isAssignableFrom(clazz)) {
488 return getConcreteCollection(Deque.class);
490 if (Queue.class.isAssignableFrom(clazz)) {
491 return getConcreteCollection(Queue.class);
493 if (SortedSet.class.isAssignableFrom(clazz)) {
494 return getConcreteCollection(SortedSet.class);
496 if (Set.class.isAssignableFrom(clazz)) {
497 return getConcreteCollection(Set.class);
499 if (List.class.isAssignableFrom(clazz)) {
500 return getConcreteCollection(List.class);
502 throw new IllegalArgumentException("Only corresponding array classes and any are allowed as argument."
503 + "assignable from TransferQueue, BlockingQueue, Deque, Queue, SortedSet, Set, List class");
506 public static Collection getConcreteCollection(Class clazz) {
507 switch (clazz.getName()) {
508 case "java.util.Collection":
509 case "java.util.List":
510 return new ArrayList<>();
511 case "java.util.Set":
512 return new HashSet<>();
513 case "java.util.SortedSet":
514 return new TreeSet<>();
515 case "java.util.Queue":
516 return new ConcurrentLinkedQueue<>();
517 case "java.util.Deque":
518 return new ArrayDeque<>();
519 case "java.util.concurrent.TransferQueue":
520 return new LinkedTransferQueue<>();
521 case "java.util.concurrent.BlockingQueue":
522 return new LinkedBlockingQueue<>();
524 throw new IllegalArgumentException("Only corresponding array classes and any are allowed as argument."
525 + "assignable from TransferQueue, BlockingQueue, Deque, Queue, SortedSet, Set, List class");
529 public static String getConfigurationRepositoryKey(File file) {
530 return getConfigurationRepositoryKey(
531 ConfigurationUtils.getNamespace(file).split(Constants.TENANT_NAMESPACE_SEPARATOR));
534 public static String getConfigurationRepositoryKey(URL url) {
535 return getConfigurationRepositoryKey(
536 ConfigurationUtils.getNamespace(url).split(Constants.TENANT_NAMESPACE_SEPARATOR));
539 public static String getConfigurationRepositoryKey(String[] array) {
540 Deque<String> stack = new ArrayDeque<>();
541 stack.push(Constants.DEFAULT_TENANT);
542 for (String element : array) {
545 String toReturn = stack.pop();
546 return stack.pop() + Constants.KEY_ELEMENTS_DELIMITER + toReturn;
549 public static String getNamespace(File file) {
550 Optional<String> namespace =
551 getConfiguration(file).flatMap(ConfigurationUtils::readNamespace).map(String::toUpperCase);
552 return namespace.orElseGet(() -> getNamespace(file.getName().toUpperCase()));
555 public static String getNamespace(String file) {
556 file = file.toUpperCase().substring(file.lastIndexOf('!') + 1);
557 file = file.substring(file.lastIndexOf('/') + 1);
558 Pattern pattern = Pattern.compile(
560 CONFIG_REGEX_TPL_OPT_1,
561 ConfigurationMode.OVERRIDE,
562 ConfigurationMode.MERGE,
563 ConfigurationMode.UNION,
564 ConfigurationType.PROPERTIES.name(),
565 ConfigurationType.XML.name(),
566 ConfigurationType.JSON.name(),
567 ConfigurationType.YAML.name()
570 Matcher matcher = pattern.matcher(file);
571 boolean b1 = matcher.matches();
573 if (matcher.group(1) != null) {
574 String moduleName = matcher.group(1).substring(1);
575 return moduleName.equalsIgnoreCase(ConfigurationMode.OVERRIDE.name()) || moduleName.equalsIgnoreCase(
576 ConfigurationMode.UNION.name()) || moduleName.equalsIgnoreCase(ConfigurationMode.MERGE.name())
577 ? Constants.DEFAULT_NAMESPACE : moduleName;
579 return Constants.DEFAULT_NAMESPACE;
581 } else if (isConfig(file)) {
582 return Constants.DEFAULT_NAMESPACE;
588 public static String getNamespace(URL url) {
590 Optional<String> namespace =
591 getConfiguration(url).flatMap(ConfigurationUtils::readNamespace).map(String::toUpperCase);
593 return namespace.orElseGet(() -> getNamespace(url.getFile().toUpperCase()));
596 public static Object getProperty(Configuration config, String key, int processingHints) {
597 if (!isDirectLookup(processingHints) && isNodeSpecific(processingHints) && (config instanceof CompositeConfiguration)) {
598 CompositeConfiguration conf = (CompositeConfiguration) config;
599 for (int i = 0; i < conf.getNumberOfConfigurations(); i++) {
600 Object obj = conf.getConfiguration(i).getProperty(key);
606 return config.getProperty(key);
609 public static boolean isCollection(String input) {
610 Pattern pattern = Pattern.compile("^\\[(.*)\\]$");
611 Matcher matcher = pattern.matcher(input);
612 return matcher.matches();
615 public static boolean isDirectLookup(int hints) {
616 return (hints & LATEST_LOOKUP.value()) == LATEST_LOOKUP.value();
619 public static boolean isNodeSpecific(int hints) {
620 return (hints & NODE_SPECIFIC.value()) == NODE_SPECIFIC.value();
623 public static boolean isExternalLookup(int hints) {
624 return (hints & EXTERNAL_LOOKUP.value()) == EXTERNAL_LOOKUP.value();
627 public static boolean isZeroLengthArray(Class clazz, Object obj) {
628 if (clazz.isArray() && clazz.getComponentType().isPrimitive()) {
629 if (clazz.getComponentType() == int.class) {
630 return ((int[]) obj).length == 0;
631 } else if (clazz.getComponentType() == byte.class) {
632 return ((byte[]) obj).length == 0;
633 } else if (clazz.getComponentType() == short.class) {
634 return ((short[]) obj).length == 0;
635 } else if (clazz.getComponentType() == float.class) {
636 return ((float[]) obj).length == 0;
637 } else if (clazz.getComponentType() == boolean.class) {
638 return ((boolean[]) obj).length == 0;
639 } else if (clazz.getComponentType() == double.class) {
640 return ((double[]) obj).length == 0;
641 } else if (clazz.getComponentType() == long.class) {
642 return ((long[]) obj).length == 0;
644 return ((Object[]) obj).length == 0;
651 public static boolean isBlank(String value) {
652 return value == null || value.trim().isEmpty();
655 // private methods section starts here
657 private static int[] getIntsPrimitiveArray(Collection collection) {
658 int collectionSize = collection.size();
659 int[] array = new int[collectionSize];
660 Object[] objArray = collection.toArray();
661 for (int i = 0; i < collectionSize; i++) {
662 array[i] = (int) objArray[i];
667 private static byte[] getBytesPrimitiveArray(Collection collection) {
668 int collectionSize = collection.size();
669 byte[] array = new byte[collectionSize];
670 Object[] objArray = collection.toArray();
671 for (int i = 0; i < collectionSize; i++) {
672 array[i] = (byte) objArray[i];
677 private static short[] getShortsPrimitiveArray(Collection collection) {
678 int collectionSize = collection.size();
679 short[] array = new short[collectionSize];
680 Object[] objArray = collection.toArray();
681 for (int i = 0; i < collectionSize; i++) {
682 array[i] = (short) objArray[i];
687 private static long[] getLongsPrimitiveArray(Collection collection) {
688 int collectionSize = collection.size();
689 long[] array = new long[collectionSize];
690 Object[] objArray = collection.toArray();
691 for (int i = 0; i < collectionSize; i++) {
692 array[i] = (long) objArray[i];
697 private static float[] getFloatsPrimitiveArray(Collection collection) {
698 int collectionSize = collection.size();
699 float[] array = new float[collectionSize];
700 Object[] objArray = collection.toArray();
701 for (int i = 0; i < collectionSize; i++) {
702 array[i] = (float) objArray[i];
707 private static double[] getDoublesPrimitiveArray(Collection collection) {
708 int collectionSize = collection.size();
709 double[] array = new double[collectionSize];
710 Object[] objArray = collection.toArray();
711 for (int i = 0; i < collectionSize; i++) {
712 array[i] = (double) objArray[i];
717 private static boolean[] getBooleansPrimitiveArray(Collection collection) {
718 int collectionSize = collection.size();
719 boolean[] array = new boolean[collectionSize];
720 Object[] objArray = collection.toArray();
721 for (int i = 0; i < collectionSize; i++) {
722 array[i] = (boolean) objArray[i];