Source: Session.js

/**
 * Copyright (c) 2017 Baidu, Inc. All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


'use strict';

const extend = require('node.extend');

/**
 * 封装对session的操作。DuerOS提过了多轮对话的能力,也能替Bot管理多轮对话,无须Bot自己维护session状态。
 * 同时,也提供了Session存储,Bot还可以将对话的状态保存session中,自己处理多轮逻辑。
 * 但是,存储在session中的数据,DuerOS是无法将其自动应用到下一轮的query解析中,对话状态的维护需要Bot自己完成
 *
 * @class Session 
 **/
class Session  {

    /**
     * @param {Object} data 请求bot的session数据
     **/
    constructor (data) {
        let attributes = data.attributes;
        // 如果session是空数组,改为空对象
        if (attributes instanceof Array && attributes.length == 0) {
            attributes = {}; 
        }

        this._data = extend(true, {}, attributes);
        this.sessionId = data.sessionId;
        this.isNew = data['new'];

        // request 中原始session attributes
        this.requestSessionAttribute = attributes;
    }

    /**
     * 清空session的所有attributes
     *
     * @public
     **/
    clear () {
        this._data = {}; 
    }

    /**
     * 将session输出response的格式
     *
     * @return {Object}
     **/
    toResponse () {
        return {
            attributes: this._data
        }; 
    }

    /**
     * 从session中获取一个属性的值
     *
     * @example
     * this.getData('status');
     * this.getData('status', '1');
     *
     * @param {string} field  属性名称
     * @param {string} def 默认值
     * @return {string|Object}
     * @public
     **/
    getData (field, def = null) {
        if(field === null) {
            return this._data; 
        }

        let tmp = this._data;

        for (let f of field.split('.')) {
            if(!tmp.hasOwnProperty(f)) {
                return def; 
            }

            tmp = tmp[f];
        }

        return tmp;
    }

    /**
     * 将一个值存储到session中
     * 注意:
     *      value必须是字符串
     *
     * @example
     * this.setData('status', '1');
     * this.setData('status', '1', '8');
     *
     * @param {string} field  属性名称
     * @param {string} value  属性值
     * @param {string} def 默认值
     * @return {null}
     * @public
     **/
    setData (field, value, def = null) {
        if(field === null) {
            return this._data; 
        }

        let tmp = this._data;

        let arr = field.split('.'); 
        let lastField = arr.pop();

        for (let f of arr) {
            if(!tmp.hasOwnProperty(f)) {
                tmp[f] = {};
            }

            tmp = tmp[f];
        }

        if(def !== null && value === null) {
            value = def; 
        }

        tmp[lastField] = value;
    }
}

module.exports = Session;