163 lines, 83 LOC, 69 covered (83%)
14 | 1 | /* ***** BEGIN LICENSE BLOCK ***** |
2 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
|
3 | * |
|
4 | * The contents of this file are subject to the Mozilla Public License Version |
|
5 | * 1.1 (the "License"); you may not use this file except in compliance with |
|
6 | * the License. You may obtain a copy of the License at |
|
7 | * http://www.mozilla.org/MPL/ |
|
8 | * |
|
9 | * Software distributed under the License is distributed on an "AS IS" basis, |
|
10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
|
11 | * for the specific language governing rights and limitations under the |
|
12 | * License. |
|
13 | * |
|
14 | * The Original Code is Weave. |
|
15 | * |
|
16 | * The Initial Developer of the Original Code is Mozilla. |
|
17 | * Portions created by the Initial Developer are Copyright (C) 2008 |
|
18 | * the Initial Developer. All Rights Reserved. |
|
19 | * |
|
20 | * Contributor(s): |
|
21 | * Dan Mills <thunder@mozilla.com> |
|
22 | * |
|
23 | * Alternatively, the contents of this file may be used under the terms of |
|
24 | * either the GNU General Public License Version 2 or later (the "GPL"), or |
|
25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
|
26 | * in which case the provisions of the GPL or the LGPL are applicable instead |
|
27 | * of those above. If you wish to allow use of your version of this file only |
|
28 | * under the terms of either the GPL or the LGPL, and not to allow others to |
|
29 | * use your version of this file under the terms of the MPL, indicate your |
|
30 | * decision by deleting the provisions above and replace them with the notice |
|
31 | * and other provisions required by the GPL or the LGPL. If you do not delete |
|
32 | * the provisions above, a recipient may use your version of this file under |
|
33 | * the terms of any one of the MPL, the GPL or the LGPL. |
|
34 | * |
|
35 | * ***** END LICENSE BLOCK ***** */ |
|
36 | ||
182 | 37 | const EXPORTED_SYMBOLS = ['WBORecord', 'RecordManager', 'Records']; |
38 | ||
56 | 39 | const Cc = Components.classes; |
56 | 40 | const Ci = Components.interfaces; |
56 | 41 | const Cr = Components.results; |
56 | 42 | const Cu = Components.utils; |
43 | ||
70 | 44 | Cu.import("resource://weave/log4moz.js"); |
70 | 45 | Cu.import("resource://weave/resource.js"); |
70 | 46 | Cu.import("resource://weave/util.js"); |
47 | ||
3744 | 48 | function WBORecord(uri) { |
14864 | 49 | this.data = {}; |
14864 | 50 | this.payload = {}; |
7432 | 51 | if (uri) |
3755 | 52 | this.uri = uri; |
53 | } |
|
28 | 54 | WBORecord.prototype = { |
28 | 55 | _logName: "Record.WBO", |
56 | ||
57 | // NOTE: baseUri must have a trailing slash, or baseUri.resolve() will omit |
|
58 | // the collection name |
|
3694 | 59 | get uri() { |
40326 | 60 | return Utils.makeURI(this.baseUri.resolve(encodeURI(this.id))); |
61 | }, |
|
84 | 62 | set uri(value) { |
224 | 63 | if (typeof(value) != "string") |
8 | 64 | value = value.spec; |
280 | 65 | let foo = value.split('/'); |
280 | 66 | this.id = foo.pop(); |
672 | 67 | this.baseUri = Utils.makeURI(foo.join('/') + '/'); |
68 | }, |
|
69 | ||
28 | 70 | get sortindex() { |
71 | if (this.data.sortindex) |
|
72 | return this.data.sortindex; |
|
73 | return 0; |
|
74 | }, |
|
75 | ||
1306 | 76 | deserialize: function deserialize(json) { |
16614 | 77 | this.data = json.constructor.toString() == String ? JSON.parse(json) : json; |
78 | ||
1278 | 79 | try { |
80 | // The payload is likely to be JSON, but if not, keep it as a string |
|
8944 | 81 | this.payload = JSON.parse(this.payload); |
82 | } |
|
1283 | 83 | catch(ex) {} |
84 | }, |
|
85 | ||
2409 | 86 | toJSON: function toJSON() { |
87 | // Copy fields from data to be stringified, making sure payload is a string |
|
7143 | 88 | let obj = {}; |
66580 | 89 | for (let [key, val] in Iterator(this.data)) |
61834 | 90 | obj[key] = key == "payload" ? JSON.stringify(val) : val; |
4762 | 91 | return obj; |
92 | }, |
|
93 | ||
70 | 94 | toString: function WBORec_toString() "{ " + [ |
95 | "id: " + this.id, |
|
96 | "index: " + this.sortindex, |
|
97 | "modified: " + this.modified, |
|
98 | "payload: " + JSON.stringify(this.payload) |
|
99 | ].join("\n ") + " }", |
|
100 | }; |
|
101 | ||
280 | 102 | Utils.deferGetSet(WBORecord, "data", ["id", "modified", "sortindex", "payload"]); |
103 | ||
98 | 104 | Utils.lazy(this, 'Records', RecordManager); |
105 | ||
77 | 106 | function RecordManager() { |
343 | 107 | this._log = Log4Moz.repository.getLogger(this._logName); |
245 | 108 | this._records = {}; |
109 | } |
|
28 | 110 | RecordManager.prototype = { |
28 | 111 | _recordType: WBORecord, |
28 | 112 | _logName: "RecordMgr", |
113 | ||
48 | 114 | import: function RecordMgr_import(url) { |
203 | 115 | this._log.trace("Importing record: " + (url.spec ? url.spec : url)); |
40 | 116 | try { |
117 | // Clear out the last response with empty object if GET fails |
|
80 | 118 | this.response = {}; |
140 | 119 | this.response = new Resource(url).get(); |
120 | ||
121 | // Don't parse and save the record on failure |
|
100 | 122 | if (!this.response.success) |
8 | 123 | return null; |
124 | ||
72 | 125 | let record = new this._recordType(); |
90 | 126 | record.deserialize(this.response); |
54 | 127 | record.uri = url; |
128 | ||
144 | 129 | return this.set(url, record); |
130 | } |
|
131 | catch(ex) { |
|
132 | this._log.debug("Failed to import record: " + Utils.exceptionStr(ex)); |
|
133 | return null; |
|
134 | } |
|
135 | }, |
|
136 | ||
10870 | 137 | get: function RecordMgr_get(url) { |
138 | // Use a url string as the key to the hash |
|
46977 | 139 | let spec = url.spec ? url.spec : url; |
32526 | 140 | if (spec in this._records) |
43288 | 141 | return this._records[spec]; |
100 | 142 | return this.import(url); |
143 | }, |
|
144 | ||
54 | 145 | set: function RegordMgr_set(url, record) { |
112 | 146 | let spec = url.spec ? url.spec : url; |
130 | 147 | return this._records[spec] = record; |
148 | }, |
|
149 | ||
28 | 150 | contains: function RegordMgr_contains(url) { |
151 | if ((url.spec || url) in this._records) |
|
152 | return true; |
|
153 | return false; |
|
154 | }, |
|
155 | ||
49 | 156 | clearCache: function recordMgr_clearCache() { |
105 | 157 | this._records = {}; |
158 | }, |
|
159 | ||
71 | 160 | del: function RegordMgr_del(url) { |
5 | 161 | delete this._records[url]; |
162 | } |
|
14 | 163 | }; |