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;
014
015import com.sun.speech.freetts.util.Utilities;
016
017/**
018 * Represents an ordered set of {@link Item}s and their associated
019 * children. A relation has a name and a list of items, and is
020 * added to an {@link Utterance} via an {@link UtteranceProcessor}.
021 */
022public class Relation implements Dumpable {
023    private String name;
024    private Utterance owner;
025    private Item head;
026    private Item tail;
027
028    /**
029     * Name of the relation that contains tokens from the original
030     * input text.  This is the first thing to be added to the
031     * utterance.
032     *
033     * @see #WORD
034     */
035    public static final String TOKEN = "Token";
036
037    /**
038     * Name of the relation that contains the normalized version of
039     * the original input text.
040     *
041     * @see #TOKEN
042     */
043    public static final String WORD = "Word";
044
045    /**
046     * Name of the relation that groups elements from the Word relation
047     * into phrases.
048     */
049    public static final String PHRASE = "Phrase";
050
051    /**
052     * Name of the relation that contains the ordered list of the
053     * smallest units of speech (typically phonemes) for the entire
054     * utterance.
055     *
056     * @see #SYLLABLE
057     * @see #SYLLABLE_STRUCTURE
058     *
059     * @see Segmenter
060     */
061    public static final String SEGMENT = "Segment";
062
063    /**
064     * Name of the relation that contains the description of the
065     * syllables for the Utterance.  This is typically added to the
066     * utterance at the same time as the <code>Segment</code> and
067     * <code>SylStructure</code> relations.
068     *
069     * @see #SEGMENT
070     * @see #SYLLABLE_STRUCTURE
071     *
072     * @see Segmenter
073     */
074    public static final String SYLLABLE = "Syllable";
075
076    /**
077     * Name of the relation that contains the syllable structure
078     * for the utterance.
079     *
080     * @see #SEGMENT
081     * @see #SYLLABLE
082     *
083     * @see Segmenter
084     */
085    public static final String SYLLABLE_STRUCTURE = "SylStructure";
086
087    /**
088     * Name of the relation that maps fundamental frequency targets
089     * to absolute times for wave to be generated from the utterance.
090     */
091    public static final String TARGET = "Target";
092
093    /**
094     * Name of the relation that contains the ordered list of the
095     * units from the unit database that will be used to create
096     * the synthesized wave.
097     */
098    public static final String UNIT = "Unit";
099     
100    /**
101     * Creates a relation.
102     *
103     * @param name the name of the Relation
104     * @param owner the utterance that contains this relation
105     */
106    Relation(String name, Utterance owner) {
107        this.name = name;
108        this.owner = owner;
109        head = null;
110        tail = null;
111    }
112
113    /**
114     * Retrieves the name of this Relation.
115     *
116     * @return the name of this Relation
117     */
118    public String getName() {
119        return name;
120    }
121
122    /**
123     * Gets the head of the item list.
124     *
125     * @return the head item
126     */
127    public Item getHead() {
128        return head;
129    }
130
131    /**
132     * Sets the head of the item list.
133     *
134     * @param item the new head item
135     */
136    void setHead(Item item) {
137        head = item;
138    }
139
140    /**
141     * Gets the tail of the item list.
142     *
143     * @return the tail item
144     */
145    public Item getTail() {
146        return tail;
147    }
148
149    /**
150     * Sets the tail of the item list.
151     *
152     * @param item the new tail item
153     */
154    void setTail(Item item) {
155        tail = item;
156    }
157
158    /**
159     * Adds a new item to this relation. The item added does not share 
160     * its contents with any other item.
161     *
162     * @return the newly added item
163     */
164    public Item appendItem() {
165        return appendItem(null);
166    }
167
168    /**
169     * Adds a new item to this relation. The item added shares its
170     * contents with the original item.
171     *
172     * @param originalItem the ItemContents that will be
173     * shared by the new item
174     *
175     * @return the newly added item
176     */
177    public Item appendItem(Item originalItem) {
178        ItemContents contents;
179        Item newItem;
180
181        if (originalItem == null) {
182            contents = null;
183        } else {
184            contents = originalItem.getSharedContents();
185        }
186        newItem = new Item(this, contents);
187        if (head == null) {
188            head = newItem;
189        }
190
191        if (tail != null) {
192            tail.attach(newItem);
193        }
194        tail = newItem;
195        return newItem;
196    }
197
198
199    /**
200     * Returns the utterance that contains this relation.
201     *
202     * @return the utterance that contains this relation
203     */
204    public Utterance getUtterance() {
205        return owner;
206    }
207
208
209    /**
210     * Dumps this relation to the print writer.
211     *
212     * @param pw the output stream
213     *
214     * @param pad the padding
215     *
216     * @param title the title for the dump
217     */
218    public void dump(PrintWriter pw, int pad, String title) {
219        Utilities.dump(pw, pad, "========= Relation: " + title + " =========");
220        Item item = head;
221        while (item != null) {
222            item.dump(pw, pad + 4, title);
223            item = item.getNext();
224        }
225    }
226}