001package org.maltparser.core.options.option;
002
003import java.util.Formatter;
004
005import org.maltparser.core.exception.MaltChainedException;
006import org.maltparser.core.options.OptionException;
007import org.maltparser.core.options.OptionGroup;
008
009/**
010 * Abstract class that contains description of an option that are the same over all option types.
011 *
012 * @author Johan Hall
013 * @since 1.0
014**/
015public abstract class Option implements Comparable<Option>{
016        public static final int NONE = 0; 
017        /**
018         * The option is only relevant during learning 
019         */
020        public static final int TRAIN = 1; 
021        /**
022         * The option is only relevant during processing (parsing)
023         */
024        public static final int PROCESS = 2; 
025        /**
026         * The option is relevant both during learning and processing (parsing)
027         */
028        public static final int BOTH = 3; 
029        /**
030         * The option is saved during learning and cannot be overloaded during processing (parsing)
031         */
032        public static final int SAVE = 4; 
033        
034        private final OptionGroup group;
035        private final String name;
036        private final String shortDescription;
037        private String flag;
038        private int usage;
039        private boolean ambiguous;
040        
041        /**
042         * Creates an option description
043         * 
044         * @param group a reference to the option group.
045         * @param name  the name of the option.
046         * @param shortDescription      a short description of the option.
047         * @param flag  a flag that can be used in the command line.
048         * @param usage a string that explains the usage of the option.
049         * @throws OptionException
050         */
051        public Option(OptionGroup group, String name, String shortDescription, String flag, String usage) throws MaltChainedException {
052                this.group = group;
053                if (name == null || name.length() == 0) {
054                        throw new OptionException("The option name has no value. ");    
055                }
056                this.name = name.toLowerCase();
057                this.shortDescription = shortDescription;
058                setFlag(flag);
059                setUsage(usage);
060                setAmbiguous(false);
061        } 
062        
063        /**
064         * Returns the corresponding object for the option value (specified as a string value).
065         * 
066         * @param value the string option value
067         * @return the corresponding object for the option value (specified as a string value).
068         * @throws OptionException
069         */
070        public abstract Object getValueObject(String value) throws MaltChainedException;
071        
072        /**
073         * Returns the object for the default value for option.
074         * 
075         * @return      the object for the default value for option.
076         * @throws OptionException
077         */
078        public abstract Object getDefaultValueObject() throws MaltChainedException;
079        
080        /**
081         * Returns a string representation of the default value.
082         * 
083         * @return a string representation of the default value
084         */
085        public abstract String getDefaultValueString();
086        
087        /**
088         * Sets the default value for the option.
089         * 
090         * @param defaultValue  the string default value
091         * @throws OptionException
092         */
093        public abstract void setDefaultValue(String defaultValue) throws MaltChainedException;
094        
095        
096        /**
097         * Returns a string representation of the option value.
098         * 
099         * @param value an option value object
100         * @return a string representation of the option value, if the option value could not be found null is returned.
101         */
102        public abstract String getStringRepresentation(Object value);
103        
104        /**
105         * Returns a reference to a option group.
106         * 
107         * @return      a reference to a option group.
108         */
109        public OptionGroup getGroup() {
110                return group;
111        }
112        
113        /**
114         * Returns the name of the option.
115         * 
116         * @return      the name of the option.
117         */
118        public String getName() {
119                return name;
120        }
121
122        /**
123         * Returns a short description of the option
124         * 
125         * @return      a short description of the option
126         */
127        public String getShortDescription() {
128                return shortDescription;
129        }
130
131        /**
132         * Returns a character that is used as a flag for the command line input
133         * 
134         * @return      a character that is used as a flag for the command line input
135         */
136        public String getFlag() {
137                return flag;
138        }
139        /**
140         * Sets a character that is used as a flag for the command line input
141         * 
142         * @param flag  a character that is used as a flag for the command line input
143         * @throws OptionException
144         */
145        public void setFlag(String flag) throws MaltChainedException {
146                if (flag == null) {
147                        this.flag = null;
148                } else {
149                        this.flag = flag;
150                } 
151        }
152        /**
153         * Returns the usage of the option.
154         * 
155         * @return      the usage of the option.
156         */
157        public int getUsage() {
158                return usage;
159        }
160        /**
161         * Sets the usage of the option.
162         * 
163         * @param usage the usage of the option.
164         * @throws OptionException
165         */
166        public void setUsage(String usage) throws MaltChainedException {
167                if (usage == null || usage.equals("") || usage.toLowerCase().equals("none")) {
168                        this.usage = Option.NONE;
169                } else if (usage.toLowerCase().equals("train")) {
170                        this.usage = Option.TRAIN;
171                } else if (usage.toLowerCase().equals("process")) {
172                        this.usage = Option.PROCESS;
173                } else if (usage.toLowerCase().equals("both")) {
174                        this.usage = Option.BOTH;
175                } else if (usage.toLowerCase().equals("save")) {
176                        this.usage = Option.SAVE;
177                } else {
178                        throw new OptionException("Illegal use of the usage attibute value: "+usage+" for the '"+getName()+"' option. ");
179                }
180        }
181        /**
182         * Sets the usage of the option.
183         * 
184         * @param usage the usage of the option.
185         * @throws OptionException
186         */
187        public void setUsage(int usage) throws MaltChainedException {
188                if (usage >= 0 && usage <= 4) {
189                        this.usage = usage;
190                } else {
191                        throw new OptionException("Illegal use of the usage attibute value: "+usage+" for the '"+getName()+"' option. ");
192                }
193        }
194        
195        /**
196         * Returns true if the option name is ambiguous over all option groups, otherwise false.
197         * 
198         * @return      true if the option name is ambiguous over all option groups, otherwise false.
199         */
200        public boolean isAmbiguous() {
201                return ambiguous;
202        }
203
204        /**
205         * Sets true if the option name is ambiguous over all option groups, otherwise false.
206         * 
207         * @param ambiguous     true if the option name is ambiguous over all option groups, otherwise false.
208         */
209        public void setAmbiguous(boolean ambiguous) {
210                this.ambiguous = ambiguous;
211        }
212
213        public int compareTo(Option o) {
214                if (group.getName().equals(o.group.getName())) {
215                        return name.compareTo(o.getName());
216                } 
217                return group.getName().compareTo(o.group.getName());
218        }
219
220        /* (non-Javadoc)
221         * @see java.lang.Object#toString()
222         */
223        public String toString() {
224                int splitsize = 45;
225                final StringBuilder sb = new StringBuilder();
226                Formatter formatter = new Formatter(sb);
227                formatter.format("%-20s ", getName());
228                if (isAmbiguous()) {
229                        formatter.format("*");
230                } else {
231                        sb.append(" ");
232                }
233                if (getFlag() != null) {
234                        formatter.format("(%4s) : ", "-"+getFlag());
235                } else {
236                        sb.append("       : ");
237                }
238                int r = shortDescription.length() / splitsize;
239                for (int i = 0; i <= r; i++) {
240                        if (shortDescription.substring(splitsize*i).length() <= splitsize) {
241                                formatter.format(((i==0)?"%s":"%28s")+"%-45s\n", "", shortDescription.substring(splitsize*i));
242                        } else {
243                                formatter.format(((i==0)?"%s":"%28s")+"%-45s\n", "", shortDescription.substring(splitsize*i, splitsize*i+splitsize));                           
244                        }
245                }
246                return sb.toString();
247        }
248}