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