001 /*
002 * Copyright (C) 2012 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019
020 package org.crsh.cmdline;
021
022 import org.crsh.cmdline.binding.TypeBinding;
023 import org.crsh.cmdline.matcher.CmdSyntaxException;
024 import org.crsh.cmdline.spi.Completer;
025 import org.crsh.cmdline.type.ValueType;
026
027 import java.io.IOException;
028 import java.lang.annotation.Annotation;
029 import java.util.ArrayList;
030 import java.util.Collections;
031 import java.util.List;
032
033 public class OptionDescriptor<B extends TypeBinding> extends ParameterDescriptor<B> {
034
035 /** . */
036 private final int arity;
037
038 /** . */
039 private final List<String> names;
040
041 public OptionDescriptor(
042 B binding,
043 ParameterType<?> type,
044 List<String> names,
045 Description info,
046 boolean required,
047 boolean password,
048 boolean unquote,
049 Class<? extends Completer> completerType,
050 Annotation annotation) throws IllegalValueTypeException, IllegalParameterException {
051 super(
052 binding,
053 type,
054 info,
055 required,
056 password,
057 unquote,
058 completerType,
059 annotation);
060
061 //
062 if (getMultiplicity() == Multiplicity.MULTI && getType() == ValueType.BOOLEAN) {
063 throw new IllegalParameterException();
064 }
065
066 //
067 names = new ArrayList<String>(names);
068 for (String name : names) {
069 if (name == null) {
070 throw new IllegalParameterException("Option name must not be null");
071 }
072 if (name.length() == 0) {
073 throw new IllegalParameterException("Option name cannot be empty");
074 }
075 if (name.contains("-")) {
076 throw new IllegalParameterException("Option name must not contain the hyphen character");
077 }
078 }
079
080 //
081 if (getType() == ValueType.BOOLEAN) {
082 arity = 0;
083 } else {
084 arity = 1;
085 }
086
087 //
088 this.names = Collections.unmodifiableList(names);
089 }
090
091 public int getArity() {
092 return arity;
093 }
094
095 public List<String> getNames() {
096 return names;
097 }
098
099 @Override
100 public Object parse(List<String> values) throws CmdSyntaxException {
101 if (arity == 0) {
102 if (values.size() > 0) {
103 throw new CmdSyntaxException("Too many option values: " + values);
104 }
105 // It's a boolean and it is true
106 return Boolean.TRUE;
107 } else {
108 if (getMultiplicity() == Multiplicity.SINGLE) {
109 if (values.size() > 1) {
110 throw new CmdSyntaxException("Too many option values: " + values);
111 }
112 String value = values.get(0);
113 try {
114 return parse(value);
115 } catch (Exception e) {
116 throw new CmdSyntaxException("Could not parse value: <" + value + ">");
117 }
118 } else {
119 List<Object> v = new ArrayList<Object>(values.size());
120 for (String value : values) {
121 try {
122 v.add(parse(value));
123 } catch (Exception e) {
124 throw new CmdSyntaxException("Could not parse value: <" + value + ">");
125 }
126 }
127 return v;
128 }
129 }
130 }
131
132 /**
133 * Prints the option names as an alternative of switches surrounded by a square brace,
134 * for instance: "[-f --foo]"
135 *
136 * @param writer the writer to print to
137 * @throws IOException any io exception
138 */
139 public void printUsage(Appendable writer) throws IOException {
140 writer.append("[");
141 boolean a = false;
142 for (String optionName : names) {
143 if (a) {
144 writer.append(" | ");
145 }
146 writer.append(optionName.length() == 1 ? "-" : "--").append(optionName);
147 a = true;
148 }
149 writer.append("]");
150 }
151
152 @Override
153 public String toString() {
154 return "OptionDescriptor[" + names + "]";
155 }
156 }