All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nuecho.rivr.voicexml.servlet.VoiceXmlInputTurnFactory Maven / Gradle / Ivy

Go to download

Rivr is a lightweight open-source dialogue engine enabling flexible VoiceXML web application development for the agile Java developer and enterprise.

There is a newer version: 1.0.13
Show newest version
/*
 * Copyright (c) 2013 Nu Echo Inc. All rights reserved.
 */

package com.nuecho.rivr.voicexml.servlet;

import java.io.*;
import java.util.*;
import java.util.regex.*;

import javax.json.*;
import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.servlet.*;

import com.nuecho.rivr.core.servlet.*;
import com.nuecho.rivr.core.util.*;
import com.nuecho.rivr.voicexml.turn.first.*;
import com.nuecho.rivr.voicexml.turn.input.*;
import com.nuecho.rivr.voicexml.util.*;
import com.nuecho.rivr.voicexml.util.json.*;

/**
 * VoiceXML specialization of {@link InputTurnFactory}.
 * 
 * @author Nu Echo Inc.
 */
public final class VoiceXmlInputTurnFactory implements InputTurnFactory {
    public static final String INPUT_TURN_PARAMETER = "inputTurn";
    public static final String ROOT_PATH = "/root/";

    //general

    //recording-related
    public static final String RECORDING_PARAMETER = "recording";
    public static final String RECORDING_META_DATA_PROPERTY = "recordingMetaData";
    public static final String TERM_CHAR_PROPERTY = "termChar";
    public static final String MAX_TIME_PROPERTY = "maxTime";
    public static final String DURATION_PROPERTY = "duration";

    //event-related
    public static final String EVENTS_PROPERTY = "events";
    public static final String EVENT_NAME_PROPERTY = "name";
    public static final String EVENT_MESSAGE_PROPERTY = "message";

    //recognition-related
    public static final String DTMF_INPUTMODE_VALUE = "dtmf";
    public static final String VOICE_INPUTMODE_VALUE = "voice";
    public static final String INPUT_MODE_PROPERTY = "inputMode";
    public static final String MARK_PROPERTY = "mark";
    public static final String MARK_NAME_PROPERTY = "name";
    public static final String MARK_TIME_PROPERTY = "time";
    public static final String RECOGNITION_PROPERTY = "recognition";
    public static final String RESULT_PROPERTY = "result";

    //transfer-related
    public static final String TRANSFER_PROPERTY = "transfer";
    public static final String TRANSFER_DURATION_PROPERTY = "duration";
    public static final String TRANSFER_STATUS_PROPERTY = "status";

    //for subdialogue, script and object
    public static final String VALUE_PROPERTY = "value";

    private static final Pattern CHAR_SET_PATTERN = Pattern.compile("charset\\s*=\\s*([^ ;])");

    @Override
    public VoiceXmlFirstTurn createFirstTurn(HttpServletRequest request, HttpServletResponse response)
            throws InputTurnFactoryException {

        Map parameters = new HashMap();

        @SuppressWarnings("unchecked")
        Enumeration parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String parameterName = parameterNames.nextElement();
            parameters.put(parameterName, request.getParameter(parameterName));
        }

        return new VoiceXmlFirstTurn(parameters);
    }

    @Override
    public VoiceXmlInputTurn createInputTurn(HttpServletRequest request, HttpServletResponse response)
            throws InputTurnFactoryException {

        Map parameters = new HashMap();
        Map files = new HashMap();
        processRequestParametersAndFiles(request, parameters, files);

        String result = parameters.get(INPUT_TURN_PARAMETER);

        if (result == null)
            throw new InputTurnFactoryException("Unable to process request. Missing '"
                                                + INPUT_TURN_PARAMETER
                                                + "' parameter.");

        JsonReader jsonReader = JsonUtils.createReader(result);
        JsonObject resultObject = jsonReader.readObject();
        VoiceXmlInputTurn voiceXmlInputTurn = new VoiceXmlInputTurn();
        voiceXmlInputTurn.setFiles(files);

        addEvents(resultObject, voiceXmlInputTurn);
        addObject(resultObject, voiceXmlInputTurn);
        addTransferStatusInfo(resultObject, voiceXmlInputTurn);
        addRecognitionInfo(resultObject, voiceXmlInputTurn);
        addRecordingInfo(resultObject, voiceXmlInputTurn, files);
        return voiceXmlInputTurn;
    }

    private static void addEvents(JsonObject resultObject, VoiceXmlInputTurn voiceXmlInputTurn) {
        if (!resultObject.containsKey(EVENTS_PROPERTY)) return;

        List eventObjects = resultObject.getJsonArray(EVENTS_PROPERTY);
        List events = new ArrayList();
        for (JsonValue jsonValue : eventObjects) {
            JsonObject eventObject = (JsonObject) jsonValue;

            String name = eventObject.getString(EVENT_NAME_PROPERTY);
            String message = eventObject.getString(EVENT_MESSAGE_PROPERTY, null);

            events.add(new VoiceXmlEvent(name, message));
        }

        voiceXmlInputTurn.setEvents(events);
    }

    private static void addObject(JsonObject resultObject, VoiceXmlInputTurn voiceXmlInputTurn) {
        if (!resultObject.containsKey(VALUE_PROPERTY)) return;

        JsonValue subdialogueResultJsonValue = resultObject.get(VALUE_PROPERTY);
        voiceXmlInputTurn.setJsonValue(subdialogueResultJsonValue);
    }

    private static void addTransferStatusInfo(JsonObject resultObject, VoiceXmlInputTurn voiceXmlInputTurn) {
        if (!resultObject.containsKey(TRANSFER_PROPERTY)) return;

        JsonObject transferResultObject = resultObject.getJsonObject(TRANSFER_PROPERTY);

        TransferStatus transferStatus = new TransferStatus(transferResultObject.getString(TRANSFER_STATUS_PROPERTY));

        long durationValue;

        if (transferResultObject.containsKey(TRANSFER_DURATION_PROPERTY)) {
            durationValue = JsonUtils.getLongProperty(transferResultObject, TRANSFER_DURATION_PROPERTY);
        } else {
            durationValue = 0;
        }

        Duration duration = Duration.milliseconds(durationValue);

        voiceXmlInputTurn.setTransferResult(new TransferStatusInfo(transferStatus, duration));
    }

    private static void addRecordingInfo(JsonObject resultObject,
                                         VoiceXmlInputTurn voiceXmlInputTurn,
                                         Map files) {
        if (!resultObject.containsKey(RECORDING_META_DATA_PROPERTY)) return;

        JsonObject recordingMetaData = resultObject.getJsonObject(RECORDING_META_DATA_PROPERTY);

        Duration duration;
        if (recordingMetaData.containsKey(DURATION_PROPERTY)) {
            long durationInMilliseconds = JsonUtils.getLongProperty(recordingMetaData, DURATION_PROPERTY);
            duration = Duration.milliseconds(durationInMilliseconds);
        } else {
            duration = null;
        }

        boolean maxTime = recordingMetaData.getBoolean(MAX_TIME_PROPERTY, false);

        String dtmfTermChar = recordingMetaData.getString(TERM_CHAR_PROPERTY, null);

        FileUpload file;
        if (!files.containsKey(RECORDING_PARAMETER)) {
            file = null;
        } else {
            file = files.get(RECORDING_PARAMETER);
        }

        voiceXmlInputTurn.setRecordingInfo(new RecordingInfo(file, duration, maxTime, dtmfTermChar));
    }

    private void addRecognitionInfo(JsonObject jsonObject, VoiceXmlInputTurn voiceXmlInputTurn) {

        if (!jsonObject.containsKey(RECOGNITION_PROPERTY)) return;

        JsonObject recognitionObject = jsonObject.getJsonObject(RECOGNITION_PROPERTY);

        JsonArray recognitionResultArray = recognitionObject.getJsonArray(RESULT_PROPERTY);

        MarkInfo markInfo = null;
        if (recognitionObject.containsKey(MARK_PROPERTY)) {
            JsonObject markObject = recognitionObject.getJsonObject(MARK_PROPERTY);
            long timeInMilliseconds = JsonUtils.getLongProperty(markObject, MARK_TIME_PROPERTY);
            markInfo = new MarkInfo(markObject.getString(MARK_NAME_PROPERTY), Duration.milliseconds(timeInMilliseconds));
        }

        voiceXmlInputTurn.setRecognitionInfo(new RecognitionInfo(recognitionResultArray, markInfo));
    }

    private void processRequestParametersAndFiles(HttpServletRequest request,
                                                  Map parameters,
                                                  Map files) throws InputTurnFactoryException {
        if (ServletFileUpload.isMultipartContent(request)) {
            ServletFileUpload servletFileUpload = new ServletFileUpload();
            try {
                FileItemIterator itemIterator = servletFileUpload.getItemIterator(request);
                while (itemIterator.hasNext()) {
                    FileItemStream fileItemStream = itemIterator.next();

                    byte[] bytes;
                    try {
                        InputStream stream = fileItemStream.openStream();
                        bytes = IOUtils.toByteArray(stream);
                    } catch (IOException exception) {
                        throw new ServletException("Unable to read stream from " + fileItemStream.getFieldName(),
                                                   exception);
                    }

                    if (!fileItemStream.isFormField()) {
                        FileUpload fileUpload = new FileUpload(fileItemStream.getName(),
                                                               fileItemStream.getContentType(),
                                                               bytes,
                                                               getHeaders(fileItemStream));

                        files.put(fileItemStream.getFieldName(), fileUpload);
                    } else {
                        String encoding = findEncoding(request, fileItemStream);
                        parameters.put(fileItemStream.getFieldName(), new String(bytes, encoding));
                    }

                }
            } catch (Exception exception) {
                throw new InputTurnFactoryException("Unable to get recording.", exception);
            }
        } else {
            @SuppressWarnings("unchecked")
            Enumeration parameterNames = request.getParameterNames();
            while (parameterNames.hasMoreElements()) {
                String parameterName = parameterNames.nextElement();
                parameters.put(parameterName, request.getParameter(parameterName));
            }
        }

    }

    private String findEncoding(HttpServletRequest request, FileItemStream fileItemStream) {

        String encoding = null;

        String contentType = fileItemStream.getContentType();

        if (contentType != null && contentType.startsWith("text/plain")) {
            Matcher matcher = CHAR_SET_PATTERN.matcher(contentType);
            if (matcher.find()) {
                encoding = matcher.group(1);
            } else {
                encoding = Encoding.US_ASCII.getId();
            }
        }

        if (encoding == null) {
            encoding = request.getCharacterEncoding();
        }

        if (encoding == null) {
            encoding = Encoding.US_ASCII.getId();
        }

        return encoding;
    }

    private Map getHeaders(FileItemStream fileItemStream) {
        Map headers = new HashMap();
        FileItemHeaders sourceHeaders = fileItemStream.getHeaders();

        if (sourceHeaders == null) return headers;

        @SuppressWarnings("unchecked")
        Iterator headerNames = sourceHeaders.getHeaderNames();
        while (headerNames.hasNext()) {
            String headerName = headerNames.next();
            headers.put(headerName, sourceHeaders.getHeader(headerName));
        }
        return headers;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy