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