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.voicexml.rendering.voicexml.VoiceXmlDomUtil.*;
008
009import java.util.Map.Entry;
010
011import javax.json.*;
012
013import org.w3c.dom.*;
014
015import com.nuecho.rivr.core.util.*;
016import com.nuecho.rivr.voicexml.dialogue.*;
017import com.nuecho.rivr.voicexml.rendering.voicexml.*;
018import com.nuecho.rivr.voicexml.turn.*;
019import com.nuecho.rivr.voicexml.util.json.*;
020
021/**
022 * A {@link Script} is a {@link VoiceXmlOutputTurn} that declares variables
023 * and/or executes a script.
024 * 
025 * @author Nu Echo Inc.
026 */
027public class Script extends VoiceXmlOutputTurn {
028    private static final String SCRIPT_TURN_TYPE = "script";
029
030    private static final String CODE_PROPERTY = "code";
031    private static final String VARIABLES_PROPERTY = "variables";
032
033    private VariableList mVariables = new VariableList();
034    private String mCode;
035
036    /**
037     * @param name The name of this turn. Not empty.
038     */
039    public Script(String name) {
040        super(name);
041    }
042
043    /**
044     * @param variables The list of variables to declare. Not null.
045     */
046    public final void setVariables(VariableList variables) {
047        Assert.notNull(variables, "variables");
048        mVariables = variables;
049    }
050
051    /**
052     * @param code The (optional) code to execute.
053     */
054    public final void setCode(String code) {
055        mCode = code;
056    }
057
058    public final VariableList getVariables() {
059        return mVariables;
060    }
061
062    public final String getCode() {
063        return mCode;
064    }
065
066    @Override
067    protected final String getOuputTurnType() {
068        return SCRIPT_TURN_TYPE;
069    }
070
071    @Override
072    protected void addTurnProperties(JsonObjectBuilder builder) {
073        JsonUtils.add(builder, CODE_PROPERTY, mCode);
074        JsonUtils.add(builder, VARIABLES_PROPERTY, mVariables);
075    }
076
077    @Override
078    protected void fillVoiceXmlDocument(Document document, Element formElement, VoiceXmlDialogueContext dialogueContext)
079            throws VoiceXmlDocumentRenderingException {
080        addVariables(formElement, mVariables);
081
082        Element blockElement = DomUtils.appendNewElement(formElement, BLOCK_ELEMENT);
083
084        if (mCode != null) {
085            Element scriptElement = DomUtils.appendNewElement(blockElement, SCRIPT_ELEMENT);
086            DomUtils.appendNewText(scriptElement, mCode);
087        }
088
089        StringBuffer scriptBuffer = new StringBuffer();
090
091        scriptBuffer.append(RIVR_SCOPE_OBJECT + ".addValueResult({");
092        boolean first = true;
093        for (Entry<String, String> entry : mVariables) {
094            if (!first) {
095                scriptBuffer.append(", ");
096            } else {
097                first = false;
098            }
099            scriptBuffer.append("\"");
100            scriptBuffer.append(entry.getKey());
101            scriptBuffer.append("\": ");
102            scriptBuffer.append("dialog.");
103            scriptBuffer.append(entry.getKey());
104        }
105        scriptBuffer.append("});");
106
107        createScript(blockElement, scriptBuffer.toString());
108        createGotoSubmit(blockElement);
109    }
110
111    /**
112     * Builder used to ease the creation of instances of {@link Script}.
113     */
114    public static class Builder {
115
116        private final String mName;
117        private final VariableList mVariables = new VariableList();
118        private String mCode;
119
120        public Builder(String name) {
121            mName = name;
122        }
123
124        public Builder addVariable(String name) {
125            mVariables.add(name);
126            return this;
127        }
128
129        public Builder addVariableString(String name, String string) {
130            mVariables.addWithString(name, string);
131            return this;
132        }
133
134        public Builder addVariableExpression(String name, String expression) {
135            mVariables.addWithExpression(name, expression);
136            return this;
137        }
138
139        public Builder setCode(String code) {
140            mCode = code;
141            return this;
142        }
143
144        public Script build() {
145            Script script = new Script(mName);
146            script.setCode(mCode);
147            script.setVariables(mVariables);
148            return script;
149        }
150    }
151
152    @Override
153    public int hashCode() {
154        final int prime = 31;
155        int result = super.hashCode();
156        result = prime * result + ((mCode == null) ? 0 : mCode.hashCode());
157        result = prime * result + ((mVariables == null) ? 0 : mVariables.hashCode());
158        return result;
159    }
160
161    @Override
162    public boolean equals(Object obj) {
163        if (this == obj) return true;
164        if (!super.equals(obj)) return false;
165        if (getClass() != obj.getClass()) return false;
166        Script other = (Script) obj;
167        if (mCode == null) {
168            if (other.mCode != null) return false;
169        } else if (!mCode.equals(other.mCode)) return false;
170        if (mVariables == null) {
171            if (other.mVariables != null) return false;
172        } else if (!mVariables.equals(other.mVariables)) return false;
173        return true;
174    }
175
176}