001    package org.maltparser.core.options;
002    
003    import java.util.SortedMap;
004    import java.util.SortedSet;
005    import java.util.TreeMap;
006    import java.util.TreeSet;
007    
008    import org.maltparser.core.options.option.Option;
009    
010    /**
011     * An option container stores the option values for one instance usage. For example, a
012     * single malt configuration there will only be one option container, but for an ensemble parser there
013     * could be several option containers. 
014     * 
015     * There are four types internal option container:
016     * <ul>
017     * <li>SAVEDOPTION, contains option values load from the saved option file.
018     * <li>DEPENDENCIES_RESOLVED, contains option values that overload option values in COMMANDLINE and OPTIONFILE
019     * due to dependencies with other options.
020     * <li>COMMANDLINE, contains option values that are read from the command-line prompt.
021     * <li>OPTIONFILE, contains option values that are read from the option file.
022     * </ul>
023     * <p>These internal option containers have following priority: SAVEDOPTION, DEPENDENCIES_RESOLVED, COMMANDLINE,
024     * OPTIONFILE. If an option cannot be found in the SAVEDOPTION internal option container it will continue to
025     * look in the DEPENDENCIES_RESOLVED internal option container and and so fourth. If the option value cannot be
026     * found in none of the internal option container, the option manager uses the default option value provided by
027     * the option description.</p>
028     *
029     * @author Johan Hall
030     * @since 1.0
031    **/
032    public class OptionContainer implements Comparable<OptionContainer>{
033            /* Types of internal option container */
034            public static final int SAVEDOPTION = 0;
035            public static final int DEPENDENCIES_RESOLVED = 1; 
036            public static final int COMMANDLINE = 2; 
037            public static final int OPTIONFILE = 3;
038            
039            private int index;
040            private SortedMap<Option,Object> savedOptionMap;
041            private SortedMap<Option,Object> dependenciesResolvedOptionMap;
042            private SortedMap<Option,Object> commandLineOptionMap;
043            private SortedMap<Option,Object> optionFileOptionMap;
044    
045            /**
046             * Creates an option container
047             * 
048             * @param index The index of the option container (0..n).
049             */
050            public OptionContainer(int index) throws OptionException {
051                    setIndex(index);
052                    savedOptionMap = new TreeMap<Option,Object>();
053                    dependenciesResolvedOptionMap = new TreeMap<Option,Object>();
054                    commandLineOptionMap = new TreeMap<Option,Object>();
055                    optionFileOptionMap = new TreeMap<Option,Object>();
056            }
057            
058            /**
059             * Adds an option value to an option to one of the internal option container specified by the type.
060             * 
061             * @param type  the internal option container
062             * @param option        the option object
063             * @param value         the option value object
064             * @throws OptionException
065             */
066            public void addOptionValue(int type, Option option, Object value) throws OptionException {
067                    if (type == OptionContainer.SAVEDOPTION) {
068                            savedOptionMap.put(option, value);
069                    } else if (type == OptionContainer.DEPENDENCIES_RESOLVED) {
070                            dependenciesResolvedOptionMap.put(option, value);
071                    } else if (type == OptionContainer.COMMANDLINE) {
072                            commandLineOptionMap.put(option, value);
073                    } else if (type == OptionContainer.OPTIONFILE) {
074                            optionFileOptionMap.put(option, value);
075                    } else {
076                            throw new OptionException("Unknown option container type");
077                    }
078            }
079            
080            /**
081             * Returns the option value object for the option. It uses the priority amongst the internal 
082             * option containers.
083             * 
084             * @param option the option object
085             * @return the option value object
086             */
087            public Object getOptionValue(Option option) {
088                    Object value = null;
089                    for (int i = OptionContainer.SAVEDOPTION; i <= OptionContainer.OPTIONFILE; i++) {
090                            if (i == OptionContainer.SAVEDOPTION) {
091                                    value = savedOptionMap.get(option);
092                            } else if (i == OptionContainer.DEPENDENCIES_RESOLVED) {
093                                    value = dependenciesResolvedOptionMap.get(option);
094                            } else if (i == OptionContainer.COMMANDLINE) {
095                                    value = commandLineOptionMap.get(option);
096                            } else if (i == OptionContainer.OPTIONFILE) {
097                                    value = optionFileOptionMap.get(option);
098                            }
099                            if (value != null) {
100                                    return value;
101                            }
102                    }
103                    return null;
104            }
105            
106            /**
107             * Returns a string representation of the option value for the specified option. It uses the priority 
108             * amongst the internal option containers.
109             * 
110             * @param option the option object
111             * @return a string representation of the option value
112             */
113            public String getOptionValueString(Option option) {
114                    String value = null;
115                    for (int i = OptionContainer.SAVEDOPTION; i <= OptionContainer.OPTIONFILE; i++) {
116                            if (i == OptionContainer.SAVEDOPTION) {
117                                    value = option.getStringRepresentation(savedOptionMap.get(option));
118                            } else if (i == OptionContainer.DEPENDENCIES_RESOLVED) {
119                                    value = option.getStringRepresentation(dependenciesResolvedOptionMap.get(option));
120                            } else if (i == OptionContainer.COMMANDLINE) {
121                                    value = option.getStringRepresentation(commandLineOptionMap.get(option));
122                            } else if (i == OptionContainer.OPTIONFILE) {
123                                    value = option.getStringRepresentation(optionFileOptionMap.get(option));
124                            }
125                            if (value != null) {
126                                    return value;
127                            }
128                    }
129                    return null;
130            }
131            
132            
133            /**
134             * Returns true if the option is present in the specified internal option container, otherwise false.
135             * 
136             * @param type  the internal option container
137             * @param option        the option object
138             * @return true if the option is present in the specified internal option container, otherwise false
139             * @throws OptionException
140             */
141            public boolean contains(int type, Option option) throws OptionException {
142                    if (type == OptionContainer.SAVEDOPTION) {
143                            return savedOptionMap.containsValue(option);
144                    } else if (type == OptionContainer.DEPENDENCIES_RESOLVED) {
145                            return dependenciesResolvedOptionMap.containsValue(option);
146                    } else if (type == OptionContainer.COMMANDLINE) {
147                            return commandLineOptionMap.containsValue(option);
148                    } else if (type == OptionContainer.OPTIONFILE) {
149                            return optionFileOptionMap.containsValue(option);
150                    } else {
151                            throw new OptionException("Unknown option container type");
152                    }       
153            }
154            
155            /**
156             * Returns the number of option values amongst all internal option containers.
157             * 
158             * @return the number of option values amongst all internal option containers
159             */
160            public int getNumberOfOptionValues() {
161                    SortedSet<Option> union = new TreeSet<Option>(savedOptionMap.keySet());
162                    union.addAll(dependenciesResolvedOptionMap.keySet());
163                    union.addAll(commandLineOptionMap.keySet());
164                    union.addAll(optionFileOptionMap.keySet());
165                    return union.size();
166            }
167            
168            /**
169             * Returns the option container index.
170             * 
171             * @return the option container index
172             */
173            public int getIndex() {
174                    return index;
175            }
176            
177            /**
178             * Sets the option container index, if the index is great than or equal 0.
179             * @param index the option container index
180             * @throws OptionException
181             */
182            private void setIndex(int index) throws OptionException {
183                    if (index < 0) {
184                            throw new OptionException("The option container index must be an integer value great than or equal 0. ");
185                    }
186                    this.index = index;
187            }
188    
189            public int compareTo(OptionContainer that) {
190                    final int BEFORE = -1;
191                final int EQUAL = 0;
192                final int AFTER = 1;
193                if (this == that) return EQUAL;
194                if (this.index < that.index) return BEFORE;
195                if (this.index > that.index) return AFTER;
196                return EQUAL;
197            }
198            
199            
200            /* (non-Javadoc)
201             * @see java.lang.Object#toString()
202             */
203            public String toString() {
204                    final StringBuilder sb = new StringBuilder();
205                    SortedSet<Option> union = new TreeSet<Option>(savedOptionMap.keySet());
206                    union.addAll(dependenciesResolvedOptionMap.keySet());
207                    union.addAll(commandLineOptionMap.keySet());
208                    union.addAll(optionFileOptionMap.keySet());
209                    for (Option option : union) {
210                            Object value = null;
211                            for (int i = OptionContainer.SAVEDOPTION; i <= OptionContainer.OPTIONFILE; i++) {
212                                    if (i == OptionContainer.SAVEDOPTION) {
213                                            value = savedOptionMap.get(option);
214                                    } else if (i == OptionContainer.DEPENDENCIES_RESOLVED) {
215                                            value = dependenciesResolvedOptionMap.get(option);
216                                    } else if (i == OptionContainer.COMMANDLINE) {
217                                            value = commandLineOptionMap.get(option);
218                                    } else if (i == OptionContainer.OPTIONFILE) {
219                                            value = optionFileOptionMap.get(option);
220                                    }
221                                    if (value != null) {
222                                            break;
223                                    }
224                            }
225                            sb.append(option.getGroup().getName()+"\t"+option.getName()+"\t"+value+"\n");
226                    }
227                    return sb.toString();
228            }
229    
230    }