baja/tag/entityDecoder.js

/**
 * @copyright 2015 Tridium, Inc. All Rights Reserved.
 * @author Gareth Johnson
 */

/**
 * @module baja/tag/entityDecoder
 */
define(["bajaScript/sys",
        "bajaScript/baja/tag/Id",
        "bajaScript/baja/tag/Tag",
        "bajaScript/baja/tag/TagSet",
        "bajaScript/baja/tag/RelationSet",
        "bajaScript/baja/tag/Relation",
        "bajaScript/baja/tag/BasicEntity"], function (
        baja,
        Id,
        Tag,
        TagSet,
        RelationSet,
        Relation,
        BasicEntity) {
  
  "use strict";

  function decodeTag(val, name) {
    var type = name[name.length - 1],
        Float = baja.Float,
        Double = baja.Double;

    name = name.substring(0, name.length - 1);

    switch(type) {
      case "M": return new Tag(name);
      case "B": return new Tag(name, baja.$("baja:Boolean", val));
      case "D": return new Tag(name, baja.$("baja:Double", val));
      case "I": return new Tag(name, baja.$("baja:Integer", val));
      case "F": return new Tag(name, baja.$("baja:Float", val));
      case "L": return new Tag(name, baja.$("baja:Long", val));
      case "S":
      case "J":
        return new Tag(name, baja.$("baja:String").decodeFromString(val));
      case "A": return new Tag(name, baja.$("baja:AbsTime").decodeFromString(val));
      case "O": return new Tag(name, baja.$("baja:Ord").decodeFromString(val));
      case "Y": return new Tag(name, baja.$("baja:DynamicEnum").decodeFromString(val));
      case "G": return new Tag(name, baja.$("baja:EnumRange").decodeFromString(val));
      case "R": return new Tag(name, baja.$("baja:RelTime").decodeFromString(val));
      case "U": return new Tag(name, baja.$("baja:Unit").decodeFromString(val));
      case "Z": return new Tag(name, baja.$("baja:TimeZone").decodeFromString(val));
      case "N":
        switch(val) {
          case "fNaN":  return new Tag(name, Float.NaN);
          case "fpInf": return new Tag(name, Float.POSITIVE_INFINITY);  
          case "fnInf": return new Tag(name, Float.NEGATIVE_INFINITY);  
          case "dNaN":  return new Tag(name, Double.make(Number.NaN));
          case "dpInf": return new Tag(name, Double.POSITIVE_INFINITY);  
          case "dnInf": return new Tag(name, Double.NEGATIVE_INFINITY);  
        }
        break;
      default: throw new Error("Unknown value type: " + type);
    }
  }

  function decodeTags(tags) {
    var tagsArray = [];

    baja.iterate(tags, function (val, name) {
      tagsArray.push(decodeTag(val, name));
    });

    return new TagSet(tagsArray);
  }

  function decodeRelations(relations) {
    var relationsArray = [];

    baja.iterate(relations, function (relationJson) {
      var rtags = [];

      if (relationJson.rtags) {
        baja.iterate(relationJson.rtags, function (val, name) {
          rtags.push(decodeTag(val, name));
        });
      }   
      
      relationsArray.push(new Relation(relationJson.rId, relationJson.entityOrd, new TagSet(rtags)));
    });

    return new RelationSet(relationsArray);
  }
     
  function decodeEntity(entityJson) {
    var tagSet,
        relationSet;

    tagSet = entityJson.tags ? decodeTags(entityJson.tags) : new TagSet();
    relationSet = entityJson.relations ? decodeRelations(entityJson.relations) : new RelationSet();

    return new BasicEntity(entityJson.ord, tagSet, relationSet);
  }

  return {
    decodeEntity: decodeEntity,
    decodeTags: decodeTags,
    decodeRelations: decodeRelations
  };
});