001 /* 002 * Copyright (C) 2010 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 026 import java.io.IOException; 027 import java.lang.annotation.Annotation; 028 import java.lang.reflect.Type; 029 import java.util.ArrayList; 030 import java.util.Collections; 031 import java.util.List; 032 033 /** 034 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> 035 * @version $Revision$ 036 */ 037 public class OptionDescriptor<B extends TypeBinding> extends ParameterDescriptor<B> { 038 039 /** . */ 040 private final int arity; 041 042 /** . */ 043 private final List<String> names; 044 045 public OptionDescriptor( 046 B binding, 047 Type javaType, 048 List<String> names, 049 Description info, 050 boolean required, 051 boolean password, 052 boolean unquote, 053 Class<? extends Completer> completerType, 054 Annotation annotation) throws IllegalValueTypeException, IllegalParameterException { 055 super( 056 binding, 057 javaType, 058 info, 059 required, 060 password, 061 unquote, 062 completerType, 063 annotation); 064 065 // 066 if (getMultiplicity() == Multiplicity.MULTI && getType() == SimpleValueType.BOOLEAN) { 067 throw new IllegalParameterException(); 068 } 069 070 // 071 names = new ArrayList<String>(names); 072 for (String name : names) { 073 if (name == null) { 074 throw new IllegalParameterException("Option name must not be null"); 075 } 076 if (name.length() == 0) { 077 throw new IllegalParameterException("Option name cannot be empty"); 078 } 079 if (name.contains("-")) { 080 throw new IllegalParameterException("Option name must not contain the hyphen character"); 081 } 082 } 083 084 // 085 if (getType() == SimpleValueType.BOOLEAN) { 086 arity = 0; 087 } else { 088 arity = 1; 089 } 090 091 // 092 this.names = Collections.unmodifiableList(names); 093 } 094 095 public int getArity() { 096 return arity; 097 } 098 099 public List<String> getNames() { 100 return names; 101 } 102 103 @Override 104 public Object parse(List<String> values) throws CmdSyntaxException { 105 if (arity == 0) { 106 if (values.size() > 0) { 107 throw new CmdSyntaxException("Too many option values: " + values); 108 } 109 // It's a boolean and it is true 110 return Boolean.TRUE; 111 } else { 112 if (getMultiplicity() == Multiplicity.SINGLE) { 113 if (values.size() > 1) { 114 throw new CmdSyntaxException("Too many option values: " + values); 115 } 116 String value = values.get(0); 117 try { 118 return parse(value); 119 } catch (Exception e) { 120 throw new CmdSyntaxException("Could not parse value: <" + value + ">"); 121 } 122 } else { 123 List<Object> v = new ArrayList<Object>(values.size()); 124 for (String value : values) { 125 try { 126 v.add(parse(value)); 127 } catch (Exception e) { 128 throw new CmdSyntaxException("Could not parse value: <" + value + ">"); 129 } 130 } 131 return v; 132 } 133 } 134 } 135 136 /** 137 * Prints the option names as an alternative of switches surrounded by a square brace, 138 * for instance: "[-f --foo]" 139 * 140 * @param writer the writer to print to 141 * @throws IOException any io exception 142 */ 143 public void printUsage(Appendable writer) throws IOException { 144 writer.append("["); 145 boolean a = false; 146 for (String optionName : names) { 147 if (a) { 148 writer.append(" | "); 149 } 150 writer.append(optionName.length() == 1 ? "-" : "--").append(optionName); 151 a = true; 152 } 153 writer.append("]"); 154 } 155 156 @Override 157 public String toString() { 158 return "OptionDescriptor[" + names + "]"; 159 } 160 }