1 // The Antville Project 2 // http://code.google.com/p/antville 3 // 4 // Copyright 2007-2011 by Tobi Schäfer. 5 // 6 // Copyright 2001–2007 Robert Gaggl, Hannes Wallnöfer, Tobi Schäfer, 7 // Matthias & Michael Platzer, Christoph Lincke. 8 // 9 // Licensed under the Apache License, Version 2.0 (the ``License''); 10 // you may not use this file except in compliance with the License. 11 // You may obtain a copy of the License at 12 // 13 // http://www.apache.org/licenses/LICENSE-2.0 14 // 15 // Unless required by applicable law or agreed to in writing, software 16 // distributed under the License is distributed on an ``AS IS'' BASIS, 17 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 // See the License for the specific language governing permissions and 19 // limitations under the License. 20 // 21 // $Revision$ 22 // $Author$ 23 // $Date$ 24 // $URL$ 25 26 /** 27 * @fileoverview Defines the Feature prototype. 28 * Another trial to implement modular features. 29 */ 30 31 /** 32 * Renders the main() method of a feature, if available. 33 * @param {Object} param The default Helma macro parameter object 34 * @param {String} id The identifier of the desired feature. 35 */ 36 global.feature_macro = function(param, id) { 37 var func, feature = Feature.get(id); 38 if (feature && (func = feature.main)) { 39 func.constructor === Function && func(param); 40 } 41 return; 42 } 43 44 /** 45 * @constructor 46 * @property {String} id The feature’s unique identifier. 47 * @param {String} id A unique identifier for the feature. 48 * @param {String} url The URL of the website providing further information about the feature. 49 * @param {Object} feature The initial properties of the feature. 50 */ 51 var Feature = function(id, url, feature) { 52 var self = this; 53 54 this.__defineGetter__("id", function() {return id}); 55 56 for (let i in feature) { 57 this[i] = feature[i]; 58 } 59 60 this.toString = function() { 61 return "[Feature: " + html.linkAsString({href: url}, id) + "]"; 62 } 63 64 return this; 65 } 66 67 /** 68 * Adds a feature to the registry. 69 * @see Feature 70 * @returns {Feature} 71 */ 72 Feature.add = function(id, url, feature) { 73 if (!id || !url) { 74 throw Error("Insufficient arguments"); 75 } 76 77 var existingFeature = Feature.get(id); 78 if (existingFeature) { 79 app.log("Warning! Overwriting already present feature with ID " + id); 80 Feature.remove(existingFeature); 81 } 82 83 Feature.list().push(new Feature(id, url, feature)); 84 return this; 85 } 86 87 /** 88 * Removes a feature from the registry. 89 * @param {Feature} feature The feature object to be removed. 90 * @returns {Number} The resulting number of features still in the registry. 91 */ 92 Feature.remove = function(feature) { 93 var features = Feature.list(); 94 if (feature === "*") { 95 features.length = 0; 96 } else if (feature) { 97 var index = features.indexOf(feature); 98 (index > -1) && features.splice(index, 1); 99 } 100 return features.length; 101 } 102 103 /** 104 * Lists all available features in the registry. 105 * @returns {Feature[]} 106 */ 107 Feature.list = function() { 108 return app.data.features; 109 } 110 111 /** 112 * Retrieves a feature from the registry. 113 * @param {String} id The identifier of the desired feature. 114 * @returns {Feature} 115 */ 116 Feature.get = function(id) { 117 for each (let feature in Feature.list()) { 118 if (feature.id === id) { 119 return feature; 120 } 121 } 122 return; 123 } 124 125 /** 126 * Invokes a (callback) function for a feauture. 127 * @param {String} id The identifier of the desired feature. '*' can be used to address all available features. 128 * @param {Function|String} callback The callback function or the name of method of the feature. 129 * @returns {Object} 130 */ 131 Feature.invoke = function(id, callback) { 132 id || (id = "*"); 133 if (callback) { 134 var feature, method, result; 135 var args = Array.prototype.slice.call(arguments, 2); 136 if (id === "*") { 137 for each (feature in Feature.list()) { 138 method = feature[String(callback)]; 139 if (method && method.constructor === Function) { 140 result = method.apply(feature, args); 141 } 142 } 143 } else { 144 feature = Feature.get(id); 145 if (feature) { 146 if (callback.constructor === Function) { 147 result = callback.apply(feature, args); 148 } else { 149 method = feature[callback]; 150 if (method && method.constructor === Function) { 151 result = method.apply(feature, args); 152 } 153 } 154 } 155 } 156 } 157 return result; 158 } 159 160 /** 161 * Wrapper for the Feature._getPermission method. All registered features will be evaluated. 162 * @param {String} action The desired action to be invoked. 163 * @returns {Boolean} 164 */ 165 Feature.getPermission = function(action) { 166 for each (let feature in Feature.list()) { 167 let method = feature._getPermission; 168 if (method && method.constructor === Function && method.call(this, action)) { 169 return true; 170 } 171 } 172 return false; 173 }