001/*
002 * Copyright (c) 2013 Nu Echo Inc. All rights reserved.
003 */
004
005package com.nuecho.rivr.voicexml.turn;
006
007import java.util.*;
008
009import javax.json.*;
010
011import org.w3c.dom.*;
012
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.last.*;
017import com.nuecho.rivr.voicexml.turn.output.*;
018import com.nuecho.rivr.voicexml.util.json.*;
019
020/**
021 * Base class for {@link VoiceXmlOutputTurn} and {@link VoiceXmlLastTurn}. A
022 * {@link VoiceXmlDocumentTurn} has a <code>name</code> and a list (possibly
023 * empty) of {@link VoiceXmlDocumentAdapter}.
024 *
025 * @author Nu Echo Inc.
026 */
027public abstract class VoiceXmlDocumentTurn implements JsonSerializable {
028
029    private static final String DATA_PROPERTY = "data";
030    private static final String NAME_PROPERTY = "name";
031
032    private final String mName;
033
034    private final List<VoiceXmlDocumentAdapter> mAdapters = new ArrayList<VoiceXmlDocumentAdapter>();
035
036    public VoiceXmlDocumentTurn(String name) {
037        Assert.notEmpty(name, "name");
038        mName = name;
039    }
040
041    protected abstract Document createVoiceXmlDocument(VoiceXmlDialogueContext dialogueContext)
042            throws VoiceXmlDocumentRenderingException;
043
044    /**
045     * Adds top level properties to the JSON representation of this turn
046     *
047     * @param builder A {@link JsonObjectBuilder} that can be used to create the
048     *            top level JSON properties
049     */
050    protected void addTopLevelProperties(JsonObjectBuilder builder) {}
051
052    protected abstract void addTurnProperties(JsonObjectBuilder builder);
053
054    public final void addAdapter(VoiceXmlDocumentAdapter adapter) {
055        mAdapters.add(adapter);
056    }
057
058    public final String getName() {
059        return mName;
060    }
061
062    public final Document getVoiceXmlDocument(VoiceXmlDialogueContext dialogueContext)
063            throws VoiceXmlDocumentRenderingException {
064        Document document = createVoiceXmlDocument(dialogueContext);
065        for (VoiceXmlDocumentAdapter adapter : mAdapters) {
066            adapter.adaptVoiceXmlDocument(document);
067        }
068        return document;
069    }
070
071    @Override
072    public final String toString() {
073        return asJson().toString();
074    }
075
076    @Override
077    public final JsonValue asJson() {
078        JsonObjectBuilder builder = JsonUtils.createObjectBuilder();
079        JsonObjectBuilder dataBuilder = JsonUtils.createObjectBuilder();
080        addTurnProperties(dataBuilder);
081
082        JsonUtils.add(builder, NAME_PROPERTY, getName());
083        JsonUtils.add(builder, DATA_PROPERTY, dataBuilder.build());
084        addTopLevelProperties(builder);
085        return builder.build();
086    }
087
088    @Override
089    public int hashCode() {
090        final int prime = 31;
091        int result = 1;
092        result = prime * result + ((mAdapters == null) ? 0 : mAdapters.hashCode());
093        result = prime * result + ((mName == null) ? 0 : mName.hashCode());
094        return result;
095    }
096
097    @Override
098    public boolean equals(Object obj) {
099        if (this == obj) return true;
100        if (obj == null) return false;
101        if (getClass() != obj.getClass()) return false;
102        VoiceXmlDocumentTurn other = (VoiceXmlDocumentTurn) obj;
103        if (mAdapters == null) {
104            if (other.mAdapters != null) return false;
105        } else if (!mAdapters.equals(other.mAdapters)) return false;
106        if (mName == null) {
107            if (other.mName != null) return false;
108        } else if (!mName.equals(other.mName)) return false;
109        return true;
110    }
111
112}