aboutsummaryrefslogtreecommitdiff
path: root/src/js/fiveui/js/rules.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js/fiveui/js/rules.js')
-rw-r--r--src/js/fiveui/js/rules.js292
1 files changed, 292 insertions, 0 deletions
diff --git a/src/js/fiveui/js/rules.js b/src/js/fiveui/js/rules.js
new file mode 100644
index 0000000..314d50b
--- /dev/null
+++ b/src/js/fiveui/js/rules.js
@@ -0,0 +1,292 @@
+/*
+ * Module : rules.js
+ * Copyright : (c) 2011-2012, Galois, Inc.
+ *
+ * Maintainer :
+ * Stability : Provisional
+ * Portability: Portable
+ *
+ * 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.
+ */
+
+var fiveui = fiveui || {};
+
+(function() {
+
+/**
+ * @constructor
+ * @param {!string} module A Javascript module that defines the rule.
+ */
+fiveui.Rule = function(module) {
+ this.module = module;
+};
+
+fiveui.Rule.defaults = function(obj) {
+ return _.defaults(obj, {
+ module: '',
+ });
+};
+
+/**
+ * Create a Rule from a JSON object.
+ *
+ * @param {!Object} obj The object to take settings from.
+ * @return {!fiveui.Rule} A populated Rule object.
+ */
+fiveui.Rule.fromJSON = function(obj) {
+ return new fiveui.Rule(obj.module);
+};
+
+/**
+ * @constructor
+ * @param {!number} id The unique RuleSet identifier.
+ * @param {!string} name A human-readable name for this RuleSet.
+ * @param {!string} desc A human-readable description of the Rule Set.
+ * @param {!string} source The url where the manifest can be retrieved
+ * @param {!Array.<fiveui.Rule>} rules An Array of Rules.
+ * @param {?Array.<string>} deps Dependencies that this RuleSet requires.
+ */
+fiveui.RuleSet = function(id, name, desc, source, rules, deps) {
+ this.id = id;
+ this.name = name;
+ this.description = desc;
+ this.source = source;
+ this.rules = rules || [];
+ this.dependencies = deps || [];
+};
+
+/**
+ * Create a Rule Setfrom a JSON object.
+ *
+ * @param {!number} id A unique id for the rehydrated Rule.
+ * @param {!Object} obj The object to take settings from.
+ * @return {!fiveui.RuleSet} A populated RuleSet object.
+ */
+fiveui.RuleSet.fromJSON = function(id, obj) {
+ var rules = (/** @type {!Array.<!fiveui.Rule>} */
+ _.map(obj.rules, fiveui.Rule.fromJSON));
+
+ return new fiveui.RuleSet(id, obj.name, obj.description, obj.source,
+ rules, obj.dependencies);
+};
+
+
+fiveui.RuleSet.defaults = function(obj) {
+ return _.defaults(obj, {
+ name: '',
+ description: '',
+ rules: [],
+ dependencies: []
+ });
+};
+
+
+/**
+ * Options is an object that can contain a success and error continuation.
+ */
+fiveui.RuleSet.load = function(manifest_url, options) {
+
+ _.defaults(options, {
+ success: function() {},
+ error: function() { throw "failed when loading url"; }
+ });
+
+ var match = manifest_url.match(/\/[^\/]*$/);
+
+ if(match) {
+ var base_url = manifest_url.substring(0,match.index);
+
+ // iterate over rules, retrieving the
+ var loadRules = function(manifest, rules) {
+
+ if(rules.length == 0) {
+ options.success(manifest);
+ } else {
+
+ // XXX there's likely problems here, how should we make sure that the
+ // url is what we expect?
+ var rule_file = fiveui.Rule.defaults(rules.pop());
+ var rule_url = base_url + '/' + rule_file;
+
+ fiveui.ajax.get(rule_url, {
+
+ success: function(text) {
+ manifest.rules.push(new fiveui.Rule(text));
+ loadRules(manifest, rules);
+ },
+
+ error: options.error
+ });
+
+ }
+ };
+
+ // fetch the manifest, and load its rules
+ fiveui.ajax.get(manifest_url, {
+
+ success: function(text) {
+ try {
+ var sanitized = fiveui.utils.filterJSON(text,'json');
+ var manifest = JSON.parse(sanitized);
+
+ } catch(e) {
+ // XXX incoming error continuation is empty
+ // (and we may have syntax error details in e)
+ options.error('failed to parse manifest');
+ return;
+ }
+
+ fiveui.RuleSet.defaults(manifest);
+
+ var rules = manifest.rules;
+ manifest.rules = [];
+ loadRules(manifest, rules);
+ },
+
+ error: function() {
+ options.error('failed to retrieve manifest');
+ },
+ });
+
+
+ } else {
+ options.error("unable to parse manifest url");
+ }
+
+};
+
+
+/*******************************************************************************
+ * Models for RuleSet
+ ******************************************************************************/
+
+/**
+ * The model for an single set of rules.
+ */
+fiveui.RuleSetModel = Backbone.Model.extend({
+
+ defaults: {
+ id: null,
+ name: '',
+ description: '',
+ source: '',
+ rules: [],
+ dependencies: [],
+ },
+
+ sync: function(method, model, options) {
+
+ _.defaults(options, {
+ success:function() {},
+ error: function() {}
+ });
+
+ var msg = this.url;
+ var id = model.get('id');
+ var source = model.get('source');
+
+ switch(method) {
+
+ case 'update':
+ case 'create':
+ var rsMethod = method == 'update' ? 'updateRuleSet' : 'addRuleSet';
+
+ msg.send('loadRuleSet', source, function(obj) {
+ if(!obj.error) {
+ obj.id = id;
+ obj.source = source;
+
+ msg.send(rsMethod, obj, options.success);
+ } else {
+ options.error(obj.error);
+ }
+ });
+ break;
+
+ case 'delete':
+ msg.send('remRuleSet', id, function(obj) {
+ if(obj.removed) {
+ options.success();
+ } else {
+ options.error();
+ }
+ });
+ break;
+
+ case 'read':
+ msg.send('getRuleSet', id, function(rs) {
+ model.set({
+ title: rs.name,
+ descr: rs.description,
+ source: rs.source,
+ });
+ });
+ break;
+
+ default:
+ break;
+ }
+ }
+
+}, {
+
+ /**
+ * Generate a RuleSetModel from a RuleSet
+ */
+ fromRuleSet: function(ruleSet,msg) {
+ return new fiveui.RuleSetModel({
+ id: ruleSet.id,
+ name: ruleSet.name,
+ description: ruleSet.description,
+ rules: ruleSet.rules,
+ dependencies:ruleSet.dependencies,
+ source: ruleSet.source,
+ }, { url : msg });
+ },
+
+});
+
+
+/**
+ * The model for a collection of rule sets
+ */
+fiveui.RuleSets = Backbone.Collection.extend({
+
+ model: fiveui.RuleSetModel,
+
+ sync: function(method, collection, options) {
+ _.defaults(options, {
+ success:function() {},
+ error:function() {}
+ });
+
+ var self = this;
+ var msg = this.url;
+
+ switch(method) {
+
+ case 'read':
+ msg.send('getRuleSets', null, function(ruleSets) {
+ options.success(_.map(ruleSets, function(rs) {
+ return fiveui.RuleSetModel.fromRuleSet(rs, msg);
+ }));
+ });
+ break;
+
+ }
+ }
+
+});
+
+
+})();