001/*
002 * Copyright (c) 2013 Nu Echo Inc. All rights reserved.
003 */
004package com.nuecho.rivr.voicexml.turn.output;
005
006import static com.nuecho.rivr.voicexml.rendering.voicexml.VoiceXmlDomUtil.*;
007
008import javax.json.*;
009
010import org.w3c.dom.*;
011
012import com.nuecho.rivr.core.channel.*;
013import com.nuecho.rivr.core.util.*;
014import com.nuecho.rivr.voicexml.dialogue.*;
015import com.nuecho.rivr.voicexml.rendering.voicexml.*;
016import com.nuecho.rivr.voicexml.turn.*;
017import com.nuecho.rivr.voicexml.util.json.*;
018
019/**
020 * This abstract class is the superclass of all classes representing a turn
021 * interpreted by the VoiceXML platform.
022 * 
023 * @author Nu Echo Inc.
024 * @see Interaction
025 * @see Message
026 * @see ObjectCall
027 * @see Script
028 * @see SubdialogueCall
029 * @see Transfer
030 */
031public abstract class VoiceXmlOutputTurn extends VoiceXmlDocumentTurn implements OutputTurn {
032    private static final String OUTPUT_TURN_TYPE_PROPERTY = "outputTurnType";
033
034    /**
035     * @param name The name of this turn. Not empty.
036     */
037    public VoiceXmlOutputTurn(String name) {
038        super(name);
039    }
040
041    protected abstract String getOuputTurnType();
042
043    @Override
044    protected void addTopLevelProperties(JsonObjectBuilder builder) {
045        JsonUtils.add(builder, OUTPUT_TURN_TYPE_PROPERTY, getOuputTurnType());
046    }
047
048    @Override
049    protected Document createVoiceXmlDocument(VoiceXmlDialogueContext dialogueContext)
050            throws VoiceXmlDocumentRenderingException {
051        Document document = createDocument(dialogueContext);
052        Element formElement = createForm(document);
053        fillVoiceXmlDocument(document, formElement, dialogueContext);
054        addEventHandler(document.getDocumentElement());
055        addFatalErrorHandlerForm(dialogueContext, document, this);
056        addSubmitForm(dialogueContext, document, this);
057        return document;
058    }
059
060    private static void addEventHandler(Element vxmlElement) {
061        Element catchElement = DomUtils.appendNewElement(vxmlElement, CATCH_ELEMENT);
062
063        Element ifErrorElement = DomUtils.appendNewElement(catchElement, IF_ELEMENT);
064        ifErrorElement.setAttribute(COND_ATTRIBUTE, "_event.substring(0, 5) == \"error\"");
065
066        Element ifErrorHandlingElement = DomUtils.appendNewElement(ifErrorElement, IF_ELEMENT);
067        ifErrorHandlingElement.setAttribute(COND_ATTRIBUTE, RIVR_SCOPE_OBJECT + "." + LOCAL_ERROR_HANDLING_PROPERTY);
068        createGotoFatalHandler(ifErrorHandlingElement);
069
070        DomUtils.appendNewElement(ifErrorHandlingElement, ELSE_ELEMENT);
071
072        StringBuilder setErrorHandlingScript = new StringBuilder();
073        setErrorHandlingScript.append(RIVR_SCOPE_OBJECT)
074                              .append(".")
075                              .append(LOCAL_ERROR_HANDLING_PROPERTY)
076                              .append("=")
077                              .append(TRUE);
078        createScript(ifErrorHandlingElement, setErrorHandlingScript.toString());
079
080        addEventHandlerScript(catchElement);
081        createGotoSubmit(catchElement);
082    }
083
084    protected static void addEventHandlerScript(Element parent) {
085        StringBuilder addEventScript = new StringBuilder();
086        addEventScript.append(RIVR_SCOPE_OBJECT)
087                      .append(".addEventResult(")
088                      .append(EVENT_NAME_VARIABLE)
089                      .append(", ")
090                      .append(EVENT_MESSAGE_VARIABLE)
091                      .append(")");
092
093        createScript(parent, addEventScript.toString());
094    }
095
096    protected abstract void fillVoiceXmlDocument(Document document,
097                                                 Element formElement,
098                                                 VoiceXmlDialogueContext dialogueContext)
099            throws VoiceXmlDocumentRenderingException;
100}