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}