1   package org.daisy.pipeline.tts;
2   
3   import java.net.URI;
4   
5   import net.sf.saxon.s9api.Axis;
6   import net.sf.saxon.s9api.XdmNode;
7   import net.sf.saxon.s9api.XdmNodeKind;
8   import net.sf.saxon.s9api.XdmSequenceIterator;
9   
10  import org.daisy.pipeline.tts.calabash.impl.FormatSpecifications;
11  
12  import com.google.common.base.CharMatcher;
13  
14  public class Sentence implements FormatSpecifications {
15  
16  	private final String id;
17  	private int size;
18  	private final Iterable<Voice> voices;
19  	private final XdmNode text;
20  	private final TTSEngine ttsProc;
21  
22  	/**
23  	 * @param voices Assumed to contain at least one voice.
24  	 */
25  	public Sentence(TTSEngine ttsProc, Iterable<Voice> voices, XdmNode text) {
26  		id = text.getAttributeValue(Sentence_attr_id);
27  		if (id == null)
28  			throw new IllegalArgumentException("id must not be null");
29  		this.voices = voices;
30  		this.text = text;
31  		this.ttsProc = ttsProc;
32  		size = -1;
33  	}
34  
35  	public int getSize() {
36  		if (size == -1) {
37  			size = 0;
38  			size = computeSize(text);
39  		}
40  		return size;
41  	}
42  
43  	/**
44  	 * Get the preferred voice
45  	 */
46  	public Voice getPreferredVoice() {
47  		return voices.iterator().next();
48  	}
49  
50  	/**
51  	 * Get the complete ordered set of selected voices
52  	 */
53  	public Iterable<Voice> getVoices() {
54  		return voices;
55  	}
56  
57  	public XdmNode getText() {
58  		return text;
59  	}
60  
61  	public TTSEngine getTTSproc() {
62  		return ttsProc;
63  	}
64  
65  	public String getID() {
66  		return id;
67  	}
68  
69  	public URI getBaseURI() {
70  		return text.getBaseURI();
71  	}
72  
73  	public static int computeSize(XdmNode node) {
74  		int size = 0;
75  		if (node.getNodeKind() == XdmNodeKind.TEXT) {
76  			size += CharMatcher.WHITESPACE.removeFrom(node.getStringValue()).length();
77  		} else {
78  			XdmSequenceIterator iter = node.axisIterator(Axis.CHILD);
79  			while (iter.hasNext()) {
80  				size += computeSize((XdmNode) iter.next());
81  			}
82  		}
83  		return size;
84  	}
85  }