001package org.unix4j.convert; 002 003import org.unix4j.option.DefaultOptionSet; 004import org.unix4j.option.Option; 005import org.unix4j.option.OptionSet; 006 007public class OptionSetConverters { 008 public static class OptionToSingletonSetConverter<O extends Enum<O> & Option> implements ValueConverter<OptionSet<O>> { 009 private final Class<O> optionEnumClass; 010 public OptionToSingletonSetConverter(Class<O> optionEnumClass) { 011 this.optionEnumClass = optionEnumClass; 012 } 013 @Override 014 public OptionSet<O> convert(Object value) throws IllegalArgumentException { 015 if (optionEnumClass.isInstance(value)) { 016 final O option = optionEnumClass.cast(value); 017 return toSingletonSet(option); 018 } 019 return null; 020 } 021 } 022 public static class NameOrAcronymToOptionConverter<O extends Enum<O> & Option> implements ValueConverter<O> { 023 private final O[] options; 024 public NameOrAcronymToOptionConverter(Class<O> optionEnumClass) { 025 this.options = optionEnumClass.getEnumConstants(); 026 } 027 @Override 028 public O convert(Object value) throws IllegalArgumentException { 029 if (value != null) { 030 final String optionString = value.toString(); 031 if (optionString.length() > 0) { 032 for (final O option : options) { 033 if (option.name().equals(optionString) || (optionString.length() == 1 && optionString.charAt(0) == option.acronym())) { 034 return option; 035 } 036 } 037 } 038 } 039 return null; 040 } 041 } 042 public static class OptionNameStringToSingletonSetConverter<O extends Enum<O> & Option> implements ValueConverter<OptionSet<O>> { 043 private final Class<O> optionEnumClass; 044 public OptionNameStringToSingletonSetConverter(Class<O> optionEnumClass) { 045 this.optionEnumClass = optionEnumClass; 046 } 047 @Override 048 public OptionSet<O> convert(Object value) throws IllegalArgumentException { 049 if (value != null) { 050 final String optionString = value.toString(); 051 if (optionString.startsWith("--")) { 052 final String optionName = optionString.substring(2); 053 final O option; 054 try { 055 option = Enum.valueOf(optionEnumClass, optionName); 056 } catch (IllegalArgumentException e) { 057 return null; 058 } 059 return toSingletonSet(option); 060 } 061 } 062 return null; 063 } 064 } 065 public static class AcronymStringToOptionSetConverter<O extends Enum<O> & Option> implements ValueConverter<OptionSet<O>> { 066 private final Class<O> optionEnumClass; 067 private final O[] options; 068 public AcronymStringToOptionSetConverter(Class<O> optionEnumClass) { 069 this.optionEnumClass = optionEnumClass; 070 this.options = optionEnumClass.getEnumConstants(); 071 } 072 @Override 073 public OptionSet<O> convert(Object value) throws IllegalArgumentException { 074 if (value != null) { 075 final String optionString = value.toString(); 076 if (optionString.startsWith("-")) { 077 DefaultOptionSet<O> set = null; 078 for (int i = 1; i < optionString.length(); i++) { 079 final char acronym = optionString.charAt(i); 080 O found = null; 081 for (final O option : options) { 082 if (option.acronym() == acronym) { 083 found = option; 084 break; 085 } 086 } 087 if (found == null) { 088 return null; 089 } 090 if (set == null) { 091 set = new DefaultOptionSet<O>(optionEnumClass); 092 } 093 set.set(found); 094 set.setUseAcronymFor(found, true); 095 } 096 return set; 097 } 098 } 099 return null; 100 } 101 } 102 public static class IterableOfOptionNameOrAcronymToOptionSetConverter<O extends Enum<O> & Option> implements ValueConverter<OptionSet<O>> { 103 private final Class<O> optionEnumClass; 104 private final NameOrAcronymToOptionConverter<O> optionConverter; 105 public IterableOfOptionNameOrAcronymToOptionSetConverter(Class<O> optionEnumClass) { 106 this.optionEnumClass = optionEnumClass; 107 this.optionConverter = new NameOrAcronymToOptionConverter<O>(optionEnumClass); 108 } 109 @Override 110 public OptionSet<O> convert(Object value) throws IllegalArgumentException { 111 if (value instanceof Iterable) { 112 final Iterable<?> iterable = (Iterable<?>)value; 113 DefaultOptionSet<O> set = null; 114 for (final Object optionNameOrAcronym : iterable) { 115 final O option = optionConverter.convert(optionNameOrAcronym); 116 if (option == null) { 117 return null; 118 } 119 if (set == null) { 120 set = new DefaultOptionSet<O>(optionEnumClass); 121 } 122 set.set(option); 123 set.setUseAcronymFor(option, !option.name().equals(optionNameOrAcronym)); 124 } 125 return set; 126 } 127 return null; 128 } 129 } 130 131 public static class OptionSetConverter<O extends Enum<O> & Option> extends CompositeValueConverter<OptionSet<O>> { 132 public OptionSetConverter(Class<O> optionEnumClass) { 133 add(new OptionToSingletonSetConverter<O>(optionEnumClass)); 134 add(new IterableOfOptionNameOrAcronymToOptionSetConverter<O>(optionEnumClass)); 135 add(new ConcatenatedConverter<OptionSet<O>>(new NameOrAcronymToOptionConverter<O>(optionEnumClass), new OptionToSingletonSetConverter<O>(optionEnumClass))); 136 } 137 } 138 139 private static <O extends Enum<O> & Option> OptionSet<O> toSingletonSet(O option) { 140 if (option instanceof OptionSet) { 141 @SuppressWarnings("unchecked") 142 final OptionSet<O> set = (OptionSet<O>)option; 143 return set; 144 } 145 return new DefaultOptionSet<O>(option); 146 } 147}