/* * Copyright (c) 2011 Patrick Meyer * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.itemanalysis.jmetrik.commandbuilder; import java.util.Formatter; import java.util.HashMap; import java.util.Iterator; public class PairedOptionList extends AbstractOption{ private HashMap<String, String> option = null; private HashMap<String, OptionValueType> typeMap = null; private HashMap<String, String> stringMap = null; private HashMap<String, Double> doubleMap = null; private HashMap<String, Integer> intMap = null; public PairedOptionList(String optionName, String optionDescription){ this(optionName, optionDescription, false); } public PairedOptionList(String optionName, String optionDescription, boolean required){ this.optionName = optionName; this.optionDescription = optionDescription; this.required = required; this.optionType = OptionType.ARGUMENT_VALUE_OPTION_LIST; option = new HashMap<String, String>(); typeMap = new HashMap<String, OptionValueType>(); stringMap = new HashMap<String, String>(); doubleMap = new HashMap<String, Double>(); intMap = new HashMap<String, Integer>(); } public int getNumberOfValues(){ return option.size(); } /** * Add required arguments and argument types. This method is used for defining the list. * * @param argumentName * @param optionValueType */ public void add(String argumentName, OptionValueType optionValueType){ addArgument(argumentName, "", optionValueType); } public void addArgument(String argumentName, String argumentDescription, OptionValueType optionValueType){ typeMap.put(argumentName, optionValueType); option.put(argumentName, argumentDescription); } /** * This method is used for processing user input * * @param argumentName * @param value */ public void addValue(String argumentName, String value)throws IllegalArgumentException{ if(option.containsKey(argumentName)){ try{ OptionValueType type = typeMap.get(argumentName); switch(type){ case STRING: stringMap.put(argumentName, value); break; case DOUBLE: doubleMap.put(argumentName, Double.parseDouble(value)); break; case INTEGER: intMap.put(argumentName, Integer.parseInt(value)); break; } }catch(ClassCastException ex){ throw new IllegalArgumentException("Type mismatch for argument [" + argumentName + "] in " + optionName + "."); } } } public void addValue(String argumentName, Double value) throws IllegalArgumentException{ if(option.containsKey(argumentName)){ if(typeMap.get(argumentName)!= OptionValueType.DOUBLE) { throw new IllegalArgumentException("Type mismatch for argument [" + argumentName + "] in " + optionName + "."); } try{ doubleMap.put(argumentName, value); }catch(ClassCastException ex){ throw new IllegalArgumentException("Type mismatch for argument [" + argumentName + "] in " + optionName + "."); } } } public void addValue(String argumentName, Integer value) throws IllegalArgumentException{ if(option.containsKey(argumentName)){ if(typeMap.get(argumentName)!= OptionValueType.INTEGER) { throw new IllegalArgumentException("Type mismatch for argument [" + argumentName + "] in " + optionName + "."); } try{ intMap.put(argumentName, value); }catch(ClassCastException ex){ throw new IllegalArgumentException("Type mismatch for argument [" + argumentName + "] in " + optionName + "."); } } } public String getStringAt(String argumentName)throws IllegalArgumentException{ if(option.containsKey(argumentName)){ if(typeMap.get(argumentName)!= OptionValueType.STRING) { throw new IllegalArgumentException("Argument [" + argumentName + "] is not of type String"); } if(stringMap.get(argumentName)!=null){ return stringMap.get(argumentName); }else{ return null; } }else{ throw new IllegalArgumentException("Argument not found"); } } public Double getDoubleAt(String argumentName)throws IllegalArgumentException{ if(option.containsKey(argumentName)){ if(typeMap.get(argumentName)!= OptionValueType.DOUBLE){ throw new IllegalArgumentException("Argument [" + argumentName + "] is not of type Double"); } if(doubleMap.get(argumentName)!=null){ return doubleMap.get(argumentName); }else{ return null; } }else{ throw new IllegalArgumentException("Argument not found"); } } public Integer getIntegerAt(String argumentName)throws IllegalArgumentException{ if(option.containsKey(argumentName)){ if(typeMap.get(argumentName)!= OptionValueType.INTEGER){ throw new IllegalArgumentException("Argument [" + argumentName + "] is not of type Integer"); } if(intMap.get(argumentName)!=null){ return intMap.get(argumentName); }else{ return null; } }else{ throw new IllegalArgumentException("Argument not found"); } } public boolean hasAllArguments(){ int rCount = option.size(); int count = 0; for(String s : option.keySet()){ if(typeMap.get(s)== OptionValueType.STRING && stringMap.get(s)!=null) count++; if(typeMap.get(s)== OptionValueType.DOUBLE && doubleMap.get(s)!=null) count++; if(typeMap.get(s)== OptionValueType.INTEGER && doubleMap.get(s)!=null) count++; } return count==rCount; } public void clear(){ for(String s : option.keySet()){ if(typeMap.get(s)== OptionValueType.STRING) stringMap.clear(); if(typeMap.get(s)== OptionValueType.DOUBLE) doubleMap.clear(); if(typeMap.get(s)== OptionValueType.INTEGER) intMap.clear(); } typeMap.clear(); option.clear(); } public boolean hasValue(){ int count = 0; for(String s : option.keySet()){ OptionValueType t = typeMap.get(s); if(t== OptionValueType.DOUBLE){ count+=doubleMap.size(); }else if(t== OptionValueType.INTEGER){ count+=intMap.size(); }else{ count+=stringMap.size(); } } return count>0; } public String getHelpText(){ Formatter f = new Formatter(); String n = "<" + optionName + ">"; f.format("%5s", ""); f.format("%-20s", "Argument: "); f.format("%-100s", n + " " + optionDescription); f.format("%n"); if(hasValue()){ f.format("%5s", ""); f.format("%-20s", "Named index: "); f.format("%1s", "["); Iterator<String> iter = option.keySet().iterator(); while(iter.hasNext()){ String temp = iter.next(); f.format("%"+temp.toString().length()+"s", temp.toString()); if(iter.hasNext()){ f.format("%3s", " | "); }else{ f.format("%1s", "]"); } } f.format("%n"); } f.format("%5s", ""); f.format("%-20s", "Required: "); if(required){ f.format("%-3s", "Yes"); }else{ f.format("%-2s", "No"); } f.format("%5s", ""); f.format("%n"); return f.toString(); } /** * Processes user input formnatted as follows: * * option(arg1=value1, arg2 = value2, arg2= value3); when there are multiple arg-value pairs * option(arg1=value1); when there is a single arg-value pair * * * @param line * @return * @throws IllegalArgumentException */ public void split(String line)throws IllegalArgumentException{ String text = line.replaceAll("[\\n\\r]", "");//eliminate carriage returns and line feeds text = text.trim(); int first = text.indexOf("("); int last = text.lastIndexOf(")"); if(first==-1 || last==-1) throw new IllegalArgumentException("Missing opening or closing parentheses for " + optionName); String opName = text.substring(0, first); String opValue = text.substring(first+1, last); // String[] arg = opValue.split(","); String REGEX = ",(?![^()]*+\\))";//split only on commas not contained in parentheses String[] arg = opValue.split(REGEX); String[] pair = null; if(opName.equals(optionName)){ for(String s : arg){ if(s.indexOf("=")==-1) throw new IllegalArgumentException("Invalid argument: " + s); pair = s.trim().split("="); pair[0] = pair[0].trim(); pair[1] = pair[1].trim(); if(option.get(pair[0])==null) throw new IllegalArgumentException("Argument not found: " + pair[0]); if(option.keySet().contains(pair[0])){ try{ addValue(pair[0], pair[1]); }catch(IllegalArgumentException ex){ throw new IllegalArgumentException(ex); } } } } } public String paste(){ String argString = optionName + "("; OptionValueType t = null; if(!hasValue()){ //no optional values selected return ""; }else{ Iterator<String> iter = option.keySet().iterator(); String ni = ""; while(iter.hasNext()){ ni = iter.next(); t = typeMap.get(ni); argString += ni + " = "; if(t== OptionValueType.DOUBLE){ argString += doubleMap.get(ni); }else if(t== OptionValueType.INTEGER){ argString += intMap.get(ni); }else{ argString += stringMap.get(ni); } if(iter.hasNext()) argString += ", "; } argString += ");"; } return argString; } @Override public String toString(){ return optionName; } @Override public boolean equals(Object o){ if(!(o instanceof Option)) return false; if(o==this) return true; Option arg = (Option)o; if(arg.toString().equals(this.toString())) return true; return false; } @Override public int hashCode(){ return optionName.hashCode(); } }