From 2ccd4a1f40d371100b94c676c4c39c97829e153b Mon Sep 17 00:00:00 2001 From: twyen Date: Mon, 22 Jan 2018 11:52:16 -0800 Subject: Implement blocking commands Test: Unit tests PiperOrigin-RevId: 182813080 Change-Id: I952f49352fb57c02c4efb9cc4ede84dc7c32c893 --- java/com/android/dialer/commandline/Arguments.java | 144 +++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 java/com/android/dialer/commandline/Arguments.java (limited to 'java/com/android/dialer/commandline/Arguments.java') diff --git a/java/com/android/dialer/commandline/Arguments.java b/java/com/android/dialer/commandline/Arguments.java new file mode 100644 index 000000000..84ed0e422 --- /dev/null +++ b/java/com/android/dialer/commandline/Arguments.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.dialer.commandline; + +import android.support.annotation.Nullable; +import com.android.dialer.commandline.Command.IllegalCommandLineArgumentException; +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterators; +import com.google.common.collect.PeekingIterator; +import com.google.common.collect.UnmodifiableIterator; + +/** + * Parses command line arguments into optional flags (--foo, --key=value, --key value) and required + * positionals (which must be passed in order). Flags must start with "--" and are always before + * positionals. If flags are used "--" must be placed before positionals. + * + *

--flag will be interpreted as --flag=true, and --noflag as --flag=false + * + *

Grammar:
+ * dialer-cmd.py
+ * = ( -- ) |
+ * = "no"?()?
+ * = " " | "=" + */ +@AutoValue +public abstract class Arguments { + + public static final Arguments EMPTY = + new AutoValue_Arguments(ImmutableMap.of(), ImmutableList.of()); + + public abstract ImmutableMap getFlags(); + + public abstract ImmutableList getPositionals(); + + /** + * Return the positional at {@code position}. Throw {@link IllegalCommandLineArgumentException} if + * it is absent and reports to the user {@code name} is expected. + */ + public String expectPositional(int position, String name) + throws IllegalCommandLineArgumentException { + if (getPositionals().size() <= position) { + throw new IllegalCommandLineArgumentException(name + " expected"); + } + return getPositionals().get(position); + } + + public Boolean getBoolean(String flag, boolean defaultValue) + throws IllegalCommandLineArgumentException { + if (!getFlags().containsKey(flag)) { + return defaultValue; + } + switch (getFlags().get(flag)) { + case "true": + return true; + case "false": + return false; + default: + throw new IllegalCommandLineArgumentException("boolean value expected for " + flag); + } + } + + public static Arguments parse(@Nullable String[] rawArguments) + throws IllegalCommandLineArgumentException { + if (rawArguments == null) { + return EMPTY; + } + return parse(Iterators.forArray(rawArguments)); + } + + public static Arguments parse(Iterable rawArguments) + throws IllegalCommandLineArgumentException { + return parse(Iterators.unmodifiableIterator(rawArguments.iterator())); + } + + public static Arguments parse(UnmodifiableIterator iterator) + throws IllegalCommandLineArgumentException { + PeekingIterator peekingIterator = Iterators.peekingIterator(iterator); + ImmutableMap flags = parseFlags(peekingIterator); + ImmutableList positionals = parsePositionals(peekingIterator); + + return new AutoValue_Arguments(flags, positionals); + } + + private static ImmutableMap parseFlags(PeekingIterator iterator) + throws IllegalCommandLineArgumentException { + ImmutableMap.Builder flags = ImmutableMap.builder(); + if (!iterator.hasNext()) { + return flags.build(); + } + if (!iterator.peek().startsWith("--")) { + return flags.build(); + } + + while (iterator.hasNext()) { + String peek = iterator.peek(); + if (peek.equals("--")) { + iterator.next(); + return flags.build(); + } + if (peek.startsWith("--")) { + String key = iterator.next().substring(2); + String value; + if (iterator.hasNext() && !iterator.peek().startsWith("--")) { + value = iterator.next(); + } else if (key.contains("=")) { + String[] entry = key.split("=", 2); + key = entry[0]; + value = entry[1]; + } else if (key.startsWith("no")) { + key = key.substring(2); + value = "false"; + } else { + value = "true"; + } + flags.put(key, value); + } else { + throw new IllegalCommandLineArgumentException("flag or '--' expected"); + } + } + return flags.build(); + } + + private static ImmutableList parsePositionals(PeekingIterator iterator) { + ImmutableList.Builder positionals = ImmutableList.builder(); + positionals.addAll(iterator); + return positionals.build(); + } +} -- cgit v1.2.3