1 /* 2 * Filename: Enum.js 3 * Created By: Ranando D. King 4 * License: Apache 2.0 5 * 6 * Copyright 2014 Ranando D. King 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 var Enum = function Enum(defValName, params) { 22 var $ = function EnumType(param) { 23 var self = this; 24 25 if ((param !== null) && (param !== undefined)) { 26 var n; 27 var v; 28 if ((typeof(param) == "object") && ("name" in param) && ("value" in param)) { 29 n = param.name; 30 v = param.value; 31 } 32 else { 33 n = param; 34 v = param; 35 } 36 37 try { 38 this.value = v; 39 if (n === v) 40 n = undefined; 41 } 42 catch (err1) { 43 try { 44 this.name = n; 45 if (n === v) 46 v = undefined; 47 } 48 catch (err2) { 49 throw new Error("Parameter '" + param + "' is not a name or value match for any member of this Enum!"); 50 } 51 } 52 53 if (((n === undefined) && (this.value !== v)) || 54 ((v === undefined) && (this.name != n)) || 55 ((n !== undefined) && (v !== undefined) && 56 (this.value !== v) && (this.name != n))) 57 throw new Error("Parameter '" + param + "' is not a name or value match for any member of this Enum!"); 58 else if (Object.isFrozen($)) 59 self = $[this.name]; 60 } 61 else { 62 self = $[defValName]; 63 } 64 65 return self; 66 }; 67 var validDefault = false; 68 69 var addEnum = function(key, value) { 70 Object.defineProperty($, key, { 71 enumerable: true, 72 configurable: false, 73 writable: false, 74 value: new $(value) 75 }); 76 77 Object.freeze($[key]); 78 }; 79 80 Object.defineProperties($, { 81 isMember: { 82 enumerable: true, 83 value: function isMember(obj) { 84 var retval = false; 85 86 if (obj && obj.isEnum) 87 retval = (params[obj.name] === obj.value); 88 89 return retval; 90 } 91 }, 92 isEnumType: { value: true }, 93 memberByName: { 94 enumerable: true, 95 value: function memberByName(mName) { 96 var retval = null; 97 if (params.hasOwnProperty(mName)) 98 retval = new $(mName); 99 100 return retval; 101 } 102 } 103 }); 104 105 Object.defineProperties($.prototype, { 106 "isEnum": { value: true }, 107 "valueOf": { 108 enumerable: false, 109 configurable: false, 110 writable: false, 111 value: function() { return this.value; } 112 }, 113 "_value": { 114 enumerable: false, 115 configurable: false, 116 writable: true, 117 value: null 118 }, 119 "name": { 120 enumerable: true, 121 configurable: false, 122 get: function() { 123 var retval; 124 for (var key in params) 125 if (params.hasOwnProperty(key) && (params[key] === this._value)) { 126 retval = key; 127 break; 128 } 129 130 return retval; 131 }, 132 set: function(n) { 133 if (params.hasOwnProperty(n)) 134 this._value = params[n]; 135 else 136 throw new Error("Element name '" + n + "' is not a member of this Enum!"); 137 } 138 }, 139 "value": { 140 enumerable: true, 141 configurable: false, 142 get: function() { return this._value; }, 143 set: function(v) { 144 if (this._value != v) { 145 for (var key in params) 146 if (params.hasOwnProperty(key) && (params[key] === v)) { 147 this._value = v; 148 break; 149 } 150 151 if (this._value != v) 152 throw new Error("Element value '" + v + "' is not a member of this Enum!"); 153 } 154 } 155 }, 156 "toString": { 157 enumerable: false, 158 configurable: false, 159 writable: false, 160 value: function() { 161 return this._value.toString() + " (" + this.name +")"; 162 } 163 }, 164 "toJSON": { 165 enumerable: false, 166 configurable: false, 167 writable: false, 168 value: function() { 169 return { name: this.name, value: this._value }; 170 } 171 } 172 }); 173 174 if (Array.isArray(params)) { 175 var len = params.length; 176 for (var i=0; i<len; ++i) { 177 var key = params[i]; 178 validDefault |= (key === defValName); 179 params[key] = i; //re-attach the index to params as a key:value pair. 180 delete params[i]; //remove the array element. 181 addEnum(key, i); 182 } 183 } 184 else { 185 for (var key in params) { 186 if (params.hasOwnProperty(key)) { 187 validDefault |= (key === defValName); 188 addEnum(key, params[key]); 189 } 190 } 191 } 192 193 if (!validDefault) 194 throw new Error("Default value '" + defValName + "' is not a member of this Enum!"); 195 196 Object.seal($.prototype); 197 Object.freeze($); 198 199 return $; 200 }; 201 202 //If some form of require.js exists, export the class 203 if (module && exports && module.exports === exports) 204 module.exports = Enum; 205