zanata/config.js

'use strict';

/**
 * The configuration definition
 * @exports zanata/config
 *
 * @requires xml2json
 * @requires fs
 * @requires zanata/ini
 */
const xml2json = require('xml2json');
const fs = require('fs');
const ini = require('./ini.js').Ini;

/**
 * @class
 * @classdesc The configuration class capsulating zanata.xml and zanata.ini file.
 */
class Config {

  /**
   * This class provides a reader only. even if you change something with {@link module:zanata/config~Config#set} method,
   * it won't be saved into the files.
   * To access values in zanata.xml, 'config.' is prefixed to the key. otherwise will be a value in zanata.ini.
   *
   * @param {string} [file='./zanata.xml'] - the place of zanata.xml.
   */
  constructor(file) {
    this.ini = new ini();
    this.tbl = {'url': 'config.url',
                'project': 'config.project',
                'project-version': 'config.project-version',
                'project-type': 'config.project-type',
                'src-dir': 'config.src-dir',
                'trans-dir': 'config.trans-dir',
                'api-key': 'key',
                'rules': 'config.rules'
               };
    if (file == undefined)
      file = './zanata.xml';
    try {
      this.resource = xml2json.toJson(fs.readFileSync(file, 'utf-8'),
                                      {object: true,
                                       reversible: false,
                                       coerce: true,
                                       trim: true,
                                       arrayNotation: false,
                                       sanitize: true});
    } catch (e) {
    };
  }

  _init(obj) {
    if (this.resource == undefined)
      this.resource = {};
    let ref = this.resource;
    obj.split('.').slice(0, -1).forEach(function(k) {
      if (ref[k] == undefined)
        ref[k] = {};
      ref = ref[k];
    });
  }

  _ref(name) {
    let ret = this.resource;

    name.split('.').slice(0, -1).forEach(function(k) {
      ret = ret[k];
    });
    return ret;
  }

  /**
   * Set the value corresponding to the name
   *
   * @param {string} name - the key name
   * @param {*} v - the value
   */
  set(name, v) {
    let n = this.tbl[name] || name;
    this._init(n);
    let o = this._ref(n);
    let a = n.split('.');
    o[a[a.length-1]] = v;

    return this;
  }

  _get(name) {
    this._init(name);
    let o = this._ref(name);
    let a = name.split('.');
    return o[a[a.length-1]];
  }

  /**
   * Obtain the value corresponding to the name
   *
   * @param {string} name - the key name
   */
  get(name) {
    let n = this.tbl[name] || name;
    let r = this._get(n);
    if (r == undefined) {
      if (!n.match(/^config\./)) {
        let url = this._get('config.url');
        return this.ini.getServerResource(url, n);
      }
    }
    return r;
  }

}

exports.Config = Config;