001package org.maltparser.core.options.option;
002
003import java.util.Collections;
004import java.util.Formatter;
005import java.util.HashMap;
006import java.util.Map;
007import java.util.SortedSet;
008import java.util.TreeSet;
009
010import org.maltparser.core.exception.MaltChainedException;
011import org.maltparser.core.options.OptionException;
012import org.maltparser.core.options.OptionGroup;
013
014/**
015 * A string enum type option is an option that can only contain string value that corresponds to another string.
016 *
017 * @author Johan Hall
018 * @since 1.0
019**/
020public class StringEnumOption extends Option{
021        private String defaultValue;
022        private final SortedSet<String> legalValues;
023        private final Map<String,String> legalValueDesc;
024        private final Map<String,String> valueMapto;
025        private final Map<String, String> maptoValue;
026        
027        /**
028         * Creates a stringenum type option description
029         * 
030         * @param group a reference to the option group.
031         * @param name  the name of the option.
032         * @param shortDescription      a short description of the option.
033         * @param flag  a short string that can be used in the command line.
034         * @param usage a string that explains the usage of the option.
035         * @throws OptionException
036         */
037        public StringEnumOption(OptionGroup group, 
038                                                String name, 
039                                                String shortDescription, 
040                                                String flag, 
041                                                String usage) throws MaltChainedException {
042                super(group, name, shortDescription, flag, usage);
043                legalValues = Collections.synchronizedSortedSet(new TreeSet<String>());
044                legalValueDesc = Collections.synchronizedMap(new HashMap<String,String>());
045                valueMapto = Collections.synchronizedMap(new HashMap<String,String>());
046                maptoValue = Collections.synchronizedMap(new HashMap<String, String>());
047        }
048
049        /* (non-Javadoc)
050         * @see org.maltparser.core.options.option.Option#getValueObject(java.lang.String)
051         */
052        public Object getValueObject(String value) throws MaltChainedException {
053                if (value == null) {
054                        return null;
055                } else if (legalValues.contains(value)) {
056                        return new String(valueMapto.get(value));
057                } else {
058                        return new String(value);
059                }       
060        }
061        
062        /* (non-Javadoc)
063         * @see org.maltparser.core.options.option.Option#getDefaultValueObject()
064         */
065        public Object getDefaultValueObject() throws MaltChainedException {
066                        return new String(defaultValue);
067        }
068
069        /**
070         * Returns the legal value identifier name (an enumerate string value)
071         * 
072         * @param value the mapped legal value
073         * @return the legal value identifier name, null if it could not be found
074         * @throws MaltChainedException
075         */
076        public String getLegalValueString(String value) throws MaltChainedException {
077                return new String(maptoValue.get(value));
078        }
079        
080        /**
081         * Returns the mapped legal value
082         * 
083         * @param value an enumerate string value
084         * @return the mapped legal value, null if it could not be found
085         * @throws MaltChainedException
086         */
087        public String getLegalValueMapToString(String value) throws MaltChainedException {
088                return new String(valueMapto.get(value));
089        }
090        
091        /* (non-Javadoc)
092         * @see org.maltparser.core.options.option.Option#setDefaultValue(java.lang.String)
093         */
094        public void setDefaultValue(String defaultValue) throws MaltChainedException {
095                if (defaultValue == null) {
096                        if (legalValues.isEmpty()) {
097                                throw new OptionException("The default value is null and the legal value set is empty for the '"+getName()+"' option. ");
098                        } else {
099                                this.defaultValue = valueMapto.get(((TreeSet<String>)valueMapto.keySet()).first()); 
100                        }
101                } else if (legalValues.contains(defaultValue.toLowerCase())) {
102                        this.defaultValue = valueMapto.get(defaultValue.toLowerCase());
103                } else if (defaultValue.equals("")) {
104                        this.defaultValue = defaultValue;
105                } else {
106                        throw new OptionException("The default value '"+defaultValue+"' for the '"+getName()+"' option is not a legal value. ");
107                }
108        }
109        
110        /* (non-Javadoc)
111         * @see org.maltparser.core.options.option.Option#getDefaultValueString()
112         */
113        public String getDefaultValueString() {
114                return defaultValue.toString();
115        }
116        
117        /**
118         * Returns the mapped legal value that corresponds to the enumerate string value.
119         * 
120         * @param value an enumerate string value
121         * @return the mapped legal value that corresponds to the enumerate string value.
122         */
123        public String getMapto(String value) {
124                return new String(valueMapto.get(value));
125        }
126
127        /**
128         * Adds a legal value that corresponds to another string
129         * 
130         * @param value a legal value name
131         * @param desc  a short description of the legal value
132         * @param mapto a mapto string value
133         * @throws OptionException
134         */
135        public void addLegalValue(String value, String desc, String mapto) throws MaltChainedException {
136                if (value == null || value.equals("")) {
137                        throw new OptionException("The legal value is missing for the option "+getName()+".");
138                } else if (legalValues.contains(value.toLowerCase())) {
139                        throw new OptionException("The legal value "+value+" already exists for the option "+getName()+". ");
140                } else {
141                        legalValues.add(value.toLowerCase());
142                        if (desc == null || desc.equals("")) {
143                                legalValueDesc.put(value.toLowerCase(), "Description is missing. ");
144                        } else {
145                                legalValueDesc.put(value.toLowerCase(), desc);
146                        }
147                        if (mapto == null || mapto.equals("")) {
148                                throw new OptionException("A mapto value is missing for the option "+getName()+". ");
149                        } else {
150                                valueMapto.put(value, mapto);
151                                maptoValue.put(mapto, value);
152                        }
153                }
154        }
155        
156        /* (non-Javadoc)
157         * @see org.maltparser.core.options.option.Option#getStringRepresentation(java.lang.Object)
158         */
159        public String getStringRepresentation(Object value) {
160                if (value instanceof String) {
161                        if (legalValues.contains(value)) {
162                                return valueMapto.get(value);
163                        } else {
164                                return value.toString();
165                        }
166                }
167                return null;
168        }
169        
170        /* (non-Javadoc)
171         * @see org.maltparser.core.options.option.Option#toString()
172         */
173        public String toString() {
174                final StringBuilder sb = new StringBuilder();
175                sb.append(super.toString());
176                Formatter formatter = new Formatter(sb);
177                for (String value : legalValues) {
178                        formatter.format("%2s%-10s - %-20s\n", "", value, legalValueDesc.get(value));
179                }
180                return sb.toString();
181        }
182}