001/* 002 * Copyright (c) 2013 Nu Echo Inc. All rights reserved. 003 */ 004 005package com.nuecho.rivr.voicexml.turn.output; 006 007import static com.nuecho.rivr.core.util.Assert.*; 008import static com.nuecho.rivr.voicexml.rendering.voicexml.VoiceXmlDomUtil.*; 009 010import java.util.*; 011 012import javax.json.*; 013 014import org.w3c.dom.*; 015 016import com.nuecho.rivr.core.util.*; 017import com.nuecho.rivr.voicexml.dialogue.*; 018import com.nuecho.rivr.voicexml.rendering.voicexml.*; 019import com.nuecho.rivr.voicexml.turn.output.audio.*; 020import com.nuecho.rivr.voicexml.util.json.*; 021 022/** 023 * A {@link Message} is a {@link VoiceXmlOutputTurn} that plays a sequence of 024 * {@link AudioItem}. 025 * 026 * @author Nu Echo Inc. 027 * @see AudioItem 028 * @see <a href= 029 * "https://www.w3.org/TR/voicexml20/#dml4.1.8">https://www.w3.org/TR/voicexml20/#dml4.1.8</a> 030 */ 031public class Message extends VoiceXmlOutputTurn { 032 private static final String MESSAGE_TURN_TYPE = "message"; 033 034 private static final String BARGE_IN_PROPERTY = "bargeIn"; 035 private static final String LANGUAGE_PROPERTY = "language"; 036 private static final String AUDIO_ITEMS_PROPERTY = "audioItems"; 037 038 private final List<AudioItem> mAudioItems; 039 private String mLanguage; 040 private Boolean mBargeIn; 041 042 /** 043 * @param name The name of this turn. Not empty. 044 * @param audioItems The sequence of {@link AudioItem} to play. Not empty. 045 */ 046 public Message(String name, List<AudioItem> audioItems) { 047 super(name); 048 Assert.notEmpty(audioItems, "audioItems"); 049 mAudioItems = new ArrayList<AudioItem>(audioItems); 050 } 051 052 /** 053 * @param name The name of this turn. Not empty. 054 * @param audioItems The sequence of {@link AudioItem} to play. Not empty. 055 */ 056 public Message(String name, AudioItem... audioItems) { 057 this(name, asListChecked(audioItems)); 058 } 059 060 /** 061 * @param language The language identifier (e.g. "en-US") for the message. 062 * <code>null</code> to use the VoiceXML platform default 063 */ 064 public final void setLanguage(String language) { 065 mLanguage = language; 066 } 067 068 /** 069 * @param bargeIn 070 * <ul> 071 * <li>{@link Boolean#TRUE} to enable barge-in</li> 072 * <li>{@link Boolean#FALSE} to disable barge-in</li> 073 * <li><code>null</code> to use the VoiceXML platform 074 * default</li> 075 * </ul> 076 */ 077 public final void setBargeIn(Boolean bargeIn) { 078 mBargeIn = bargeIn; 079 } 080 081 public final List<AudioItem> getAudioItems() { 082 return Collections.unmodifiableList(mAudioItems); 083 } 084 085 public final String getLanguage() { 086 return mLanguage; 087 } 088 089 public final Boolean getBargeIn() { 090 return mBargeIn; 091 } 092 093 @Override 094 protected final String getOuputTurnType() { 095 return MESSAGE_TURN_TYPE; 096 } 097 098 @Override 099 protected void addTurnProperties(JsonObjectBuilder builder) { 100 JsonUtils.add(builder, AUDIO_ITEMS_PROPERTY, JsonUtils.toJson(mAudioItems)); 101 JsonUtils.add(builder, LANGUAGE_PROPERTY, mLanguage); 102 if (mBargeIn == null) { 103 builder.addNull(BARGE_IN_PROPERTY); 104 } else { 105 builder.add(BARGE_IN_PROPERTY, mBargeIn.booleanValue()); 106 } 107 } 108 109 @Override 110 protected void fillVoiceXmlDocument(Document document, Element formElement, VoiceXmlDialogueContext dialogueContext) 111 throws VoiceXmlDocumentRenderingException { 112 Element blockElement = addBlockElement(formElement); 113 createPrompt(mLanguage, blockElement, dialogueContext, mBargeIn, mAudioItems); 114 createGotoSubmit(blockElement); 115 } 116 117 /** 118 * Builder used to ease the creation of instances of {@link Message}. 119 */ 120 public static class Builder { 121 122 private final String mName; 123 private final List<AudioItem> mAudioItems = new ArrayList<AudioItem>(); 124 private String mLanguage; 125 private Boolean mBargeIn; 126 127 public Builder(String name) { 128 mName = name; 129 } 130 131 /** 132 * Add an audio item. 133 * 134 * @param audioItem the audio item to add 135 * @return this builder 136 * @deprecated Use {@link #addAudioItem(AudioItem)} instead 137 */ 138 @Deprecated 139 public Builder addAudio(AudioItem audioItem) { 140 return addAudioItem(audioItem); 141 } 142 143 /** 144 * Add an audio item. 145 * 146 * @param audioItem the audio item to add 147 * @return this builder 148 * @since 1.0.1 149 */ 150 public Builder addAudioItem(AudioItem audioItem) { 151 Assert.notNull(audioItem, "audioItem"); 152 mAudioItems.add(audioItem); 153 return this; 154 } 155 156 /** 157 * Add some audio items. 158 * 159 * @param audioItems the audio items to add 160 * @return this builder 161 * @since 1.0.1 162 */ 163 public Builder addAudioItems(AudioItem... audioItems) { 164 return addAudioItems(asListChecked(audioItems)); 165 } 166 167 /** 168 * Add some audio items. 169 * 170 * @param audioItems the audio items to add 171 * @return this builder 172 */ 173 public Builder addAudioItems(List<AudioItem> audioItems) { 174 Assert.noNullValues(audioItems, mLanguage); 175 mAudioItems.addAll(audioItems); 176 return this; 177 } 178 179 public Builder setLanguage(String language) { 180 mLanguage = language; 181 return this; 182 } 183 184 public Builder setBargein(Boolean bargeIn) { 185 mBargeIn = bargeIn; 186 return this; 187 } 188 189 /** 190 * Build the message. 191 * 192 * @return the message 193 */ 194 public Message build() { 195 Message message = new Message(mName, mAudioItems); 196 message.setBargeIn(mBargeIn); 197 message.setLanguage(mLanguage); 198 return message; 199 } 200 } 201 202 @Override 203 public int hashCode() { 204 final int prime = 31; 205 int result = super.hashCode(); 206 result = prime * result + ((mAudioItems == null) ? 0 : mAudioItems.hashCode()); 207 result = prime * result + ((mBargeIn == null) ? 0 : mBargeIn.hashCode()); 208 result = prime * result + ((mLanguage == null) ? 0 : mLanguage.hashCode()); 209 return result; 210 } 211 212 @Override 213 public boolean equals(Object obj) { 214 if (this == obj) return true; 215 if (!super.equals(obj)) return false; 216 if (getClass() != obj.getClass()) return false; 217 Message other = (Message) obj; 218 if (mAudioItems == null) { 219 if (other.mAudioItems != null) return false; 220 } else if (!mAudioItems.equals(other.mAudioItems)) return false; 221 if (mBargeIn == null) { 222 if (other.mBargeIn != null) return false; 223 } else if (!mBargeIn.equals(other.mBargeIn)) return false; 224 if (mLanguage == null) { 225 if (other.mLanguage != null) return false; 226 } else if (!mLanguage.equals(other.mLanguage)) return false; 227 return true; 228 } 229 230}