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.util.*;
013import com.nuecho.rivr.voicexml.dialogue.*;
014import com.nuecho.rivr.voicexml.rendering.voicexml.*;
015import com.nuecho.rivr.voicexml.util.json.*;
016
017/**
018 * This abstract class is the superclass of all classes representing a transfer
019 * to another entity.
020 * 
021 * @author Nu Echo Inc.
022 * @see BlindTransfer
023 * @see BridgeTransfer
024 * @see ConsultationTransfer
025 * @see <a
026 *      href="https://www.w3.org/TR/voicexml20/#dml2.3.6">https://www.w3.org/TR/voicexml20/#dml2.3.6</a>
027 * @see <a
028 *      href="https://www.w3.org/TR/voicexml21/#sec-transfer">https://www.w3.org/TR/voicexml21/#sec-transfer</a>
029 */
030public abstract class Transfer extends VoiceXmlOutputTurn {
031    private static final String TRANSFER_TURN_TYPE = "transfer";
032
033    private static final String TRANSFER_TYPE_PROPERTY = "transferType";
034    private static final String APPLICATION_TO_APPLICATION_INFORMATION_PROPERTY = "applicationToApplicationInformation";
035    private static final String DESTINATION_PROPERTY = "destination";
036
037    private final String mDestination;
038    private String mApplicationToApplicationInformation;
039
040    /**
041     * @param name The name of this turn. Not empty.
042     * @param destination The URI of the destination (telephone, IP telephony
043     *            address). Not empty.
044     */
045    public Transfer(String name, String destination) {
046        super(name);
047        Assert.notEmpty(destination, "destination");
048        mDestination = destination;
049    }
050
051    /**
052     * @param applicationToApplicationInformation A string containing data sent
053     *            to an application on the far-end, available in the session
054     *            variable session.connection.aai.
055     */
056    public final void setApplicationToApplicationInformation(String applicationToApplicationInformation) {
057        mApplicationToApplicationInformation = applicationToApplicationInformation;
058    }
059
060    public final String getDestination() {
061        return mDestination;
062    }
063
064    public final String getApplicationToApplicationInformation() {
065        return mApplicationToApplicationInformation;
066    }
067
068    protected abstract String getTransferType();
069
070    /**
071     * Allows the customization of the generated transfer element
072     * 
073     * @param transferElement The transfer element to customize.
074     * @throws VoiceXmlDocumentRenderingException when an error occurs while
075     *             rendering the VoiceXml document
076     */
077    protected void customizeTransferElement(Element transferElement) throws VoiceXmlDocumentRenderingException {}
078
079    @Override
080    protected final String getOuputTurnType() {
081        return TRANSFER_TURN_TYPE;
082    }
083
084    @Override
085    protected void addTurnProperties(JsonObjectBuilder builder) {
086        JsonUtils.add(builder, DESTINATION_PROPERTY, mDestination);
087        JsonUtils.add(builder, APPLICATION_TO_APPLICATION_INFORMATION_PROPERTY, mApplicationToApplicationInformation);
088        JsonUtils.add(builder, TRANSFER_TYPE_PROPERTY, getTransferType());
089    }
090
091    @Override
092    protected void fillVoiceXmlDocument(Document document, Element formElement, VoiceXmlDialogueContext dialogueContext)
093            throws VoiceXmlDocumentRenderingException {
094
095        Element transferElement = DomUtils.appendNewElement(formElement, TRANSFER_ELEMENT);
096
097        transferElement.setAttribute(TYPE_ATTRIBUTE, getTransferType());
098        transferElement.setAttribute(NAME_ATTRIBUTE, TRANSFER_FORM_ITEM_NAME);
099        transferElement.setAttribute(DEST_ATTRIBUTE, mDestination);
100
101        if (mApplicationToApplicationInformation != null) {
102            transferElement.setAttribute(AAI_ATTRIBUTE, mApplicationToApplicationInformation);
103        }
104
105        customizeTransferElement(transferElement);
106
107        Element filledElement = DomUtils.appendNewElement(transferElement, FILLED_ELEMENT);
108        String script = RIVR_SCOPE_OBJECT
109                        + ".addTransferResult("
110                        + TRANSFER_FORM_ITEM_NAME
111                        + ", "
112                        + TRANSFER_FORM_ITEM_NAME
113                        + "$);";
114        createScript(filledElement, script);
115        createGotoSubmit(filledElement);
116    }
117
118    /**
119     * Base class for all {@link Transfer} builders.
120     */
121    public abstract static class Builder {
122
123        private final String mName;
124        private String mDestination;
125        private String mApplicationToApplicationInformation;
126
127        protected Builder(String name) {
128            mName = name;
129        }
130
131        public Builder setDestination(String destination) {
132            mDestination = destination;
133            return this;
134        }
135
136        public Builder setApplicationToApplication(String applicationToApplicationInformation) {
137            mApplicationToApplicationInformation = applicationToApplicationInformation;
138            return this;
139        }
140
141        protected String getName() {
142            return mName;
143        }
144
145        protected String getDestination() {
146            return mDestination;
147        }
148
149        protected void build(Transfer transfer) {
150            transfer.setApplicationToApplicationInformation(mApplicationToApplicationInformation);
151        }
152    }
153
154    @Override
155    public int hashCode() {
156        final int prime = 31;
157        int result = super.hashCode();
158        result = prime * result
159                 + ((mApplicationToApplicationInformation == null)
160                         ? 0
161                         : mApplicationToApplicationInformation.hashCode());
162        result = prime * result + ((mDestination == null) ? 0 : mDestination.hashCode());
163        return result;
164    }
165
166    @Override
167    public boolean equals(Object obj) {
168        if (this == obj) return true;
169        if (!super.equals(obj)) return false;
170        if (getClass() != obj.getClass()) return false;
171        Transfer other = (Transfer) obj;
172        if (mApplicationToApplicationInformation == null) {
173            if (other.mApplicationToApplicationInformation != null) return false;
174        } else if (!mApplicationToApplicationInformation.equals(other.mApplicationToApplicationInformation))
175            return false;
176        if (mDestination == null) {
177            if (other.mDestination != null) return false;
178        } else if (!mDestination.equals(other.mDestination)) return false;
179        return true;
180    }
181
182}