001/**
002 * Portions Copyright 2001 Sun Microsystems, Inc.
003 * Portions Copyright 1999-2001 Language Technologies Institute, 
004 * Carnegie Mellon University.
005 * All Rights Reserved.  Use is subject to license terms.
006 * 
007 * See the file "license.terms" for information on usage and
008 * redistribution of this file, and for a DISCLAIMER OF ALL 
009 * WARRANTIES.
010 */
011package com.sun.speech.freetts;
012
013import java.io.PrintWriter;
014import java.text.DecimalFormat;
015import java.util.ArrayList;
016import java.util.Collections;
017import java.util.Iterator;
018import java.util.LinkedHashMap;
019import java.util.List;
020import java.util.Map;
021
022import com.sun.speech.freetts.util.Utilities;
023
024/**
025 * Implementation of the FeatureSet interface.
026 */
027public class FeatureSetImpl implements FeatureSet {
028    private final Map featureMap;
029    static DecimalFormat formatter;
030
031    /**
032     * Creates a new empty feature set
033     */
034    public FeatureSetImpl() {
035        featureMap = new LinkedHashMap();
036    }
037
038    /**
039     * Determines if the given feature is present.
040     *
041     * @param name the name of the feature of interest
042     *
043     * @return true if the named feature is present
044     */
045    public boolean isPresent(String name) {
046        return featureMap.containsKey(name);
047    }
048
049
050    /**
051     * Removes the named feature from this set of features.
052     *
053     * @param name the name of the feature of interest
054     */
055    public void remove(String name) {
056        featureMap.remove(name);
057    }
058
059    /**
060     * Convenience method that returns the named feature as a string.
061     *
062     * @param name the name of the feature
063     *
064     * @return the value associated with the name or null if the value
065     *   is not found
066     *
067     * @throws ClassCastException if the associated value is not a
068     *   String
069     */
070    public String getString(String name) {
071        return (String) getObject(name);
072    }
073
074    /**
075     * Convenience method that returns the named feature as a int.
076     *
077     * @param name the name of the feature
078     *
079     * @return the value associated with the name or null if the value
080     *   is not found
081     *
082     * @throws ClassCastException if the associated value is not an int.
083     */
084    public int getInt(String name) {
085        return ((Integer) getObject(name)).intValue();
086    }
087
088    /**
089     * Convenience method that returns the named feature as a float.
090     *
091     * @param name the name of the feature
092     *
093     * @return the value associated with the name or null if the value
094     *   is not found.
095     *
096     * @throws ClassCastException if the associated value is not a
097     *   float
098     */
099    public float getFloat(String name) {
100        return ((Float) getObject(name)).floatValue();
101    }
102
103    /**
104     * Returns the named feature as an object.
105     *
106     * @param name the name of the feature
107     *
108     * @return the value associated with the name or null if the value
109     *   is not found
110     */
111    public Object getObject(String name) {
112        return featureMap.get(name);
113    }
114
115    /**
116     * Convenience method that sets the named feature as a int.
117     *
118     * @param name the name of the feature
119     * @param value the value of the feature
120     */
121    public void setInt(String name, int value) {
122        setObject(name, new Integer(value));
123    }
124
125    /**
126     * Convenience method that sets the named feature as a float.
127     *
128     * @param name the name of the feature
129     * @param value the value of the feature
130     */
131    public void setFloat(String name, float value) {
132        setObject(name, new Float(value));
133    }
134
135    /**
136     * Convenience method that sets the named feature as a String.
137     *
138     * @param name the name of the feature
139     * @param value the value of the feature
140     */
141    public void setString(String name, String value) {
142        setObject(name, value);
143    }
144
145    /**
146     * Sets the named feature.
147     *
148     * @param name the name of the feature
149     * @param value the value of the feature
150     */
151    public void setObject(String name, Object value) {
152        featureMap.put(name, value);
153    }
154
155    /**
156     * Dumps the FeatureSet in textual form.  The feature name
157     * is not included in the dump.
158     *
159     * @param output where to send the formatted output
160     * @param pad the padding
161     * @param title the title
162     */
163    public void dump(PrintWriter output, int pad, String title) {
164        dump(output, pad, title, false);
165    }
166
167    /**
168     * Dumps the FeatureSet in textual form.
169     *
170     * @param output where to send the formatted output
171     * @param pad the padding
172     * @param title the title
173     * @param showName if <code>true</code>, include the feature name
174     */
175    public void dump(PrintWriter output, int pad, String title,
176            boolean showName) {
177        List keys = new ArrayList(featureMap.keySet());
178
179        if (formatter == null) {
180            formatter = new DecimalFormat("########0.000000");
181        }
182        // Collections.sort(keys);
183         Collections.reverse(keys);  // to match flite
184
185        Utilities.dump(output, pad, title);
186        for (Iterator i = keys.iterator(); i.hasNext(); ) {
187            String key = (String) i.next();
188
189            if (!showName && key.equals("name")) {
190                continue;
191            }
192
193            Object value = getObject(key);
194            if (value instanceof Dumpable) {
195                Dumpable d = (Dumpable) value;
196                d.dump(output, pad + 4, key); 
197            } else {
198                if (value instanceof Float) {
199                    Float fval = (Float) value;
200                    Utilities.dump(output, pad + 4, key + "=" + 
201                            formatter.format(fval.floatValue()));
202                } else {
203                    Utilities.dump(output, pad + 4, key + "=" + value);
204                }
205            }
206        }
207    }
208}