001/*
002 * Java Genetic Algorithm Library (jenetics-8.0.0).
003 * Copyright (c) 2007-2024 Franz Wilhelmstötter
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 * Author:
018 *    Franz Wilhelmstötter (franz.wilhelmstoetter@gmail.com)
019 */
020package io.jenetics.internal.util;
021
022import static java.util.Objects.requireNonNull;
023
024import java.util.Optional;
025import java.util.function.Function;
026import java.util.stream.Stream;
027
028import io.jenetics.util.ISeq;
029
030/**
031 * Helper class for parsing command line arguments.
032 *
033 * @author <a href="mailto:franz.wilhelmstoetter@gmail.com">Franz Wilhelmstötter</a>
034 * @version 3.4
035 * @since 3.4
036 */
037public class Args {
038
039        private final ISeq<String> _args;
040
041        private Args(final String[] args) {
042                _args = ISeq.of(requireNonNull(args));
043        }
044
045        /**
046         * Return the parameter with the given name.
047         *
048         * @param name the parameter name
049         * @return the parameter with the given name, if any
050         */
051        public Optional<String> arg(final String name) {
052                int index = _args.indexOf("--" + name);
053                if (index == -1) index = _args.indexOf("-" + name);
054
055                return index >= 0 && index < _args.length() - 1
056                        ? Optional.of(_args.get(index + 1))
057                        : Optional.empty();
058        }
059
060        /**
061         * Return the int-argument with the given name.
062         *
063         * @param name the argument name
064         * @return the int argument value, if any
065         */
066        public Optional<Integer> intArg(final String name) {
067                return arg(name)
068                        .flatMap(s -> parse(s, Integer::valueOf));
069        }
070
071        public ISeq<Integer> intArgs(final String name) {
072                return  arg(name).stream()
073                        .flatMap(a -> Stream.of(a.split("@")))
074                        .flatMap(s -> parse(s, Integer::valueOf).stream())
075                        .collect(ISeq.toISeq());
076        }
077
078        /**
079         * Return the long-argument with the given name.
080         *
081         * @param name the argument name
082         * @return the long argument value, if any
083         */
084        public Optional<Long> longArg(final String name) {
085                return arg(name)
086                        .flatMap(s -> parse(s, Long::valueOf));
087        }
088
089        /**
090         * Return the double-argument with the given name.
091         *
092         * @param name the argument name
093         * @return the double argument value, if any
094         */
095        public Optional<Double> doubleArg(final String name) {
096                return arg(name)
097                        .flatMap(s -> parse(s, Double::valueOf));
098        }
099
100        private static <T> Optional<T> parse(
101                final String string,
102                final Function<String, T> parser
103        ) {
104                Optional<T> value = Optional.empty();
105                try {
106                        value = Optional.of(parser.apply(string));
107                } catch (Exception ignore) {
108                }
109
110                return value;
111        }
112
113        @Override
114        public String toString() {
115                return _args.toString();
116        }
117
118        /**
119         * Wraps the given argument array into an {@code Args} object.
120         *
121         * @param args the underlying command line arguments
122         * @return the wrapped argument object
123         */
124        public static Args of(final String[] args) {
125                return new Args(args);
126        }
127
128}