001package com.plivo.api.xml;
002
003import com.plivo.api.exceptions.PlivoXmlException;
004import com.plivo.api.util.Utils;
005import java.util.ArrayList;
006import java.util.Arrays;
007import java.util.List;
008import java.util.Map;
009import javax.xml.bind.annotation.XmlAttribute;
010import javax.xml.bind.annotation.XmlElement;
011import javax.xml.bind.annotation.XmlElements;
012import javax.xml.bind.annotation.XmlMixed;
013import javax.xml.bind.annotation.XmlRootElement;
014import javax.xml.bind.annotation.XmlSeeAlso;
015import javax.xml.bind.annotation.XmlValue;
016
017
018@XmlRootElement(name = "Speak")
019@XmlSeeAlso({Lang.class,
020      Emphasis.class,
021      Break.class,
022      SayAs.class,
023      Sub.class,
024      S.class,
025      W.class,
026      P.class,
027      Phoneme.class,
028      Prosody.class,
029      })
030public class Speak extends PlivoXml implements ResponseNestable, PreAnswerNestable, GetDigitsNestable, GetInputNestable {
031
032  //public String content;
033  @XmlMixed
034  private List<Object> mixedContent = new ArrayList<Object>();
035
036  @XmlAttribute
037  private String voice;
038
039  @XmlAttribute
040  private String language;
041
042  @XmlAttribute
043  private Integer loop;
044
045  private static boolean isLang = false;
046
047  private static boolean isVoice = false;
048
049  private static int MAX_CONTENT_LENGTH = 3000;
050
051  private Speak() {
052
053  }
054
055  public Speak(String content) {
056    this.mixedContent.add(content);
057    this.voice =  "WOMAN";
058    this.language = "en-US";
059    this.loop = 1;
060  }
061
062  public String getVoice() {
063    return voice;
064  }
065
066  public String getLanguage() {
067    return language;
068  }
069
070  public Integer getLoop() {
071    return loop;
072  }
073
074  public Speak voice (final String voice) throws PlivoXmlException {
075    this.voice = voice;
076    isVoice = true;
077    if (voice == null || voice.trim().isEmpty()){
078      this.voice = "WOMAN";
079      return this;
080    }
081    if (voice.equalsIgnoreCase("MAN") || voice.equalsIgnoreCase("WOMAN")) {
082      return this;
083    }
084    this.voice = transformVoiceString(voice);
085    if (isLang) {
086      Utils.validateLanguageVoice(this.language, this.voice);
087    }
088    return this;
089  }
090
091  public Speak language ( final  String language) throws  PlivoXmlException{
092    this.language = language;
093    isLang = true;
094    if (isVoice) {
095      if (this.voice.equalsIgnoreCase("MAN") || this.voice.equalsIgnoreCase("WOMAN")) {
096        return this;
097      } else {
098        Utils.validateLanguageVoice(this.language, this.voice);
099      }
100    }
101    return this;
102  }
103
104  public Speak loop ( final Integer loop){
105    this.loop = loop;
106    return this;
107  }
108
109  private void checkIsSSMLSupported() throws PlivoXmlException {
110        if (this.voice == null || this.voice.trim().isEmpty() ||
111                        this.voice.equalsIgnoreCase("MAN") || this.voice.equalsIgnoreCase("WOMAN")) { 
112                throw new PlivoXmlException("SSML support is available only for Amazon Polly!");
113    }
114  }
115
116  private static String transformVoiceString(String voice) {
117    String[] voiceParts = voice.trim().split("\\.");
118    if (voiceParts.length == 1) {
119      return voice;
120    }
121    String voiceName = Utils.transformString(voiceParts[1]);
122    return voiceParts[0] + "." + voiceName;
123  }
124
125  public Speak addBreak(String strength, String time) throws PlivoXmlException {
126        this.checkIsSSMLSupported();
127    this.mixedContent.add(new Break(strength, time));
128    return this;
129  }
130
131  public Speak addEmphasis(String content, String level) throws PlivoXmlException {
132        this.checkIsSSMLSupported();
133    this.mixedContent.add(new Emphasis(content, level));
134    return this;
135  }
136
137  public Speak addLang(String content, String xmllang) throws PlivoXmlException {
138        this.checkIsSSMLSupported();
139    this.mixedContent.add(new Lang(content, xmllang));
140    return this;
141  }
142
143  public Speak addP(String content) throws PlivoXmlException {
144        this.checkIsSSMLSupported();
145    this.mixedContent.add(new P(content));
146    return this;
147  }
148
149  public Speak addPhoneme(String content, String alphabet, String ph) throws PlivoXmlException {
150        this.checkIsSSMLSupported();
151    this.mixedContent.add(new Phoneme(content, alphabet, ph));
152    return this;
153  }
154
155  public Speak addProsody(String content) throws PlivoXmlException {
156    this.checkIsSSMLSupported();
157    this.mixedContent.add(new Prosody(content));
158    return this;
159  }
160
161  public Speak addProsody(String content, String volume, String rate, String pitch) throws PlivoXmlException {
162    this.checkIsSSMLSupported();
163    this.mixedContent.add(new Prosody(content, volume, rate, pitch));
164    return this;
165  }
166
167  public Speak addS(String content) throws PlivoXmlException {
168        this.checkIsSSMLSupported();
169    this.mixedContent.add(new S(content));
170    return this;
171  }
172
173  public Speak addSayAs(String content, String interpretAs) throws PlivoXmlException {
174        this.checkIsSSMLSupported();
175    this.mixedContent.add(new SayAs(content, interpretAs));
176    return this;
177  }
178
179  public Speak addSayAs(String content, String interpretAs, String format) throws PlivoXmlException {
180    this.checkIsSSMLSupported();
181    this.mixedContent.add(new SayAs(content, interpretAs, format));
182    return this;
183  }
184
185  public Speak addSub(String content, String alias) throws PlivoXmlException {
186        this.checkIsSSMLSupported();
187    this.mixedContent.add(new Sub(content, alias));
188    return this;
189  }
190
191  public Speak addW(String content, String role) throws PlivoXmlException {
192        this.checkIsSSMLSupported();
193    this.mixedContent.add(new W(content, role));
194    return this;
195  }
196
197  public Speak continueSpeak(String content) throws PlivoXmlException {
198    this.mixedContent.add(content);
199    return this;
200  }
201
202  public Speak children(Object... nestables) throws PlivoXmlException {
203    for (Object obj : nestables) {
204      if (obj instanceof SpeakNestable || obj instanceof String) {
205        mixedContent.add(obj);
206      } else {
207        throw new PlivoXmlException("XML Validation Error: <" + obj.getClass().getSimpleName() + "> can not be nested in <Speak>");
208      }
209    }
210    return this;
211  }
212}