001package com.pi4j.util;
002
003/*
004 * #%L
005 * **********************************************************************
006 * ORGANIZATION  :  Pi4J
007 * PROJECT       :  Pi4J :: Java Library (Core)
008 * FILENAME      :  CommandArgumentParser.java
009 *
010 * This file is part of the Pi4J project. More information about
011 * this project can be found here:  http://www.pi4j.com/
012 * **********************************************************************
013 * %%
014 * Copyright (C) 2012 - 2016 Pi4J
015 * %%
016 * This program is free software: you can redistribute it and/or modify
017 * it under the terms of the GNU Lesser General Public License as
018 * published by the Free Software Foundation, either version 3 of the
019 * License, or (at your option) any later version.
020 *
021 * This program is distributed in the hope that it will be useful,
022 * but WITHOUT ANY WARRANTY; without even the implied warranty of
023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
024 * GNU General Lesser Public License for more details.
025 *
026 * You should have received a copy of the GNU General Lesser Public
027 * License along with this program.  If not, see
028 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
029 * #L%
030 */
031
032import com.pi4j.io.gpio.GpioPin;
033import com.pi4j.io.gpio.Pin;
034import com.pi4j.io.gpio.PinProvider;
035import com.pi4j.io.gpio.PinPullResistance;
036import com.pi4j.io.serial.*;
037
038import java.lang.reflect.Method;
039import java.lang.reflect.Type;
040import java.util.Arrays;
041
042/**
043 *
044 */
045public class CommandArgumentParser {
046
047    /**
048     * This utility method searches for "--pin (#)" or "-p (#)" in the command
049     * arguments array and returns a Pin instance based on the pin
050     * address/number specified.
051     *
052     * @param pinProviderClass pin provider class to get pin instance from
053     * @param defaultPin default pin instance to use if no --pin argument is found
054     * @param args the argument array to search in
055     * @return GPIO pin instance
056     */
057    public static Pin getPin(Class<? extends PinProvider> pinProviderClass, Pin defaultPin, String ... args){
058        // search all arguments for the "--pin" or "-p" option
059        // we skip the last argument in the array because we expect a value defined after the option designator
060        for(int index = 0; index < (args.length-1); index++){
061            if(args[index].toLowerCase().equals("--pin") ||
062               args[index].toLowerCase().equals("-p")){
063                try {
064                    int pinAddress = Integer.parseInt(args[index+1]);
065                    Method m = pinProviderClass.getDeclaredMethod("getPinByAddress", int.class);
066                    Object pin = m.invoke(null, pinAddress);
067                    return (Pin)pin;
068                }
069                catch(Exception ex){
070                    System.err.println(ex.getMessage());
071                }
072            }
073        }
074        return defaultPin;
075    }
076
077    /**
078     * This utility method searches for "--pull (up|down|off)", "--l (up|down|off)", "--up", or "--down" in the command
079     * arguments array and returns a PinPullResistance instance based on the option
080     * value provided.
081     *
082     * @param defaultPull default pin pull resistance to apply if no option/argument is found
083     * @param args the argument array to search in
084     * @return pill pull resistance enum
085     */
086    public static PinPullResistance getPinPullResistance(PinPullResistance defaultPull, String ... args){
087
088        // search all arguments for the argument option designators
089        for(int index = 0; index < args.length; index++){
090
091            if(args[index].toLowerCase().equals("--up")){
092                return PinPullResistance.PULL_UP;
093            }
094            else if(args[index].toLowerCase().equals("--down")){
095                return PinPullResistance.PULL_DOWN;
096            }
097            else if(args[index].toLowerCase().equals("--pull") ||
098                    args[index].toLowerCase().equals("-l")){
099                // if using this option designator, we must have an additional
100                // argument in the array to read the value from
101                if(index < (args.length-1)){
102                    String pull = args[index+1].toLowerCase();
103                    if(pull.equals("up")){
104                        return PinPullResistance.PULL_UP;
105                    }
106                    else if(pull.equals("1")){
107                        return PinPullResistance.PULL_UP;
108                    }
109                    else if(pull.equals("down")){
110                        return PinPullResistance.PULL_DOWN;
111                    }
112                    else if(pull.equals("0")){
113                        return PinPullResistance.PULL_DOWN;
114                    }
115                    else{
116                        return PinPullResistance.OFF;
117                    }
118                }
119            }
120        }
121        return defaultPull;
122    }
123
124    /**
125     * This utility method searches for the following options:
126     *
127     *   "--device (device-path)"                   [DEFAULT: /dev/ttyAMA0]
128     *   "--baud (baud-rate)"                       [DEFAULT: 38400]
129     *   "--data-bits (5|6|7|8)"                    [DEFAULT: 8]
130     *   "--parity (none|odd|even)"                 [DEFAULT: none]
131     *   "--stop-bits (1|2)"                        [DEFAULT: 1]
132     *   "--flow-control (none|hardware|software)"  [DEFAULT: none]
133     *
134     * in the arguments array and returns a SerialConfig instance based on the option
135     * values detected.
136     *
137     * @param defaultConfig default serial configuration to apply if no option/arguments are found
138     * @param args the argument array to search in
139     * @return serial config object
140     */
141    public static SerialConfig getSerialConfig(SerialConfig defaultConfig, String ... args){
142
143        // search all arguments for the argument option designators
144        // we skip the last argument in the array because we expect a value defined after each option designator
145        for(int index = 0; index < (args.length-1); index++){
146
147            // "--device (device-path)"                   [DEFAULT: /dev/ttyAMA0]
148            if(args[index].toLowerCase().equals("--device")){
149                defaultConfig.device(args[index+1]);
150                index++;
151                continue;
152            }
153
154            // "--baud (baud-rate)"                       [DEFAULT: 38400]
155            if(args[index].toLowerCase().equals("--baud")){
156                defaultConfig.baud(Baud.getInstance(Integer.parseInt(args[index + 1])));
157                index++;
158                continue;
159            }
160
161            // "--data-bits (5|6|7|8)"                    [DEFAULT: 8]
162            if(args[index].toLowerCase().equals("--data-bits")){
163                defaultConfig.dataBits(DataBits.getInstance(Integer.parseInt(args[index + 1])));
164                index++;
165                continue;
166            }
167
168            // "--parity (none|odd|even)"                 [DEFAULT: none]
169            if(args[index].toLowerCase().equals("--parity")){
170                defaultConfig.parity(Parity.getInstance(args[index + 1]));
171                index++;
172                continue;
173            }
174
175            // "--stop-bits (1|2)"                        [DEFAULT: 1]
176            if(args[index].toLowerCase().equals("--stop-bits")){
177                defaultConfig.stopBits(StopBits.getInstance(Integer.parseInt(args[index + 1])));
178                index++;
179                continue;
180            }
181
182            // "--flow-control (none|hardware|software)"  [DEFAULT: none]
183            if(args[index].toLowerCase().equals("--flow-control")){
184                defaultConfig.flowControl(FlowControl.getInstance(args[index + 1]));
185                index++;
186                continue;
187            }
188        }
189        return defaultConfig;
190    }
191}