diff options
Diffstat (limited to 'node_modules/montage/core/serializer.js')
-rwxr-xr-x | node_modules/montage/core/serializer.js | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/node_modules/montage/core/serializer.js b/node_modules/montage/core/serializer.js new file mode 100755 index 00000000..129c3e80 --- /dev/null +++ b/node_modules/montage/core/serializer.js | |||
@@ -0,0 +1,452 @@ | |||
1 | /* <copyright> | ||
2 | This file contains proprietary software owned by Motorola Mobility, Inc.<br/> | ||
3 | No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> | ||
4 | (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. | ||
5 | </copyright> */ | ||
6 | /** | ||
7 | @module montage/core/serializer | ||
8 | @requires montage | ||
9 | @requires montage/core/uuid | ||
10 | @requires montage/core/deserializer | ||
11 | */ | ||
12 | var Montage = require("montage").Montage; | ||
13 | var Uuid = require("core/uuid").Uuid; | ||
14 | var Deserializer = require("core/deserializer").Deserializer; | ||
15 | |||
16 | /** | ||
17 | @class module:montage/core/serializer.Serializer | ||
18 | @classdesc Serialized objects are indexed by uuid. | ||
19 | @extends module:montage/core/core.Montage | ||
20 | */ | ||
21 | var Serializer = Montage.create(Montage, /** @lends module:montage/serializer.Serializer# */ { | ||
22 | _serializedObjects: {value: {}}, // uuid -> string | ||
23 | _serializedReferences: {value: {}}, // uuid -> string | ||
24 | _externalObjects: {value: null}, // label -> object | ||
25 | _externalElements: {value: null}, | ||
26 | _objectStack: {value: null}, | ||
27 | _objectReferences: {value: null}, // uuid -> object with properies | ||
28 | // last used index of an objectName to create a label | ||
29 | _objectNamesIndex: {value: null}, | ||
30 | _objectLabels: {value: null}, // uuid -> label | ||
31 | _serializationUnits: {value: []}, | ||
32 | |||
33 | serializeNullValues: {value: false}, | ||
34 | |||
35 | /** | ||
36 | Defines a serialization unit for an object. | ||
37 | @function | ||
38 | @param {string} name The unit name. | ||
39 | @param {function} funktion The delegate function that creates the serialization unit. This function accepts the object being serialized as an argument and should return an object to be be JSON'd. | ||
40 | */ | ||
41 | defineSerializationUnit: {value: function(name, funktion) { | ||
42 | this._serializationUnits.push({ | ||
43 | name: name, | ||
44 | funktion: funktion | ||
45 | }); | ||
46 | }}, | ||
47 | |||
48 | /** | ||
49 | Defines the require function to be used. | ||
50 | @function | ||
51 | @param {function} require The require function to be used to identify module ids of the objects being serialized. | ||
52 | */ | ||
53 | initWithRequire: { | ||
54 | value: function(require) { | ||
55 | this._require = require; | ||
56 | return this; | ||
57 | } | ||
58 | }, | ||
59 | |||
60 | /** | ||
61 | Serializes a single object. | ||
62 | @function | ||
63 | @param {object} object The object to be serialized. | ||
64 | @returns {string} The serialized object. | ||
65 | */ | ||
66 | serializeObject: { | ||
67 | value: function(object) { | ||
68 | return this.serialize({root: object}); | ||
69 | } | ||
70 | }, | ||
71 | |||
72 | /** | ||
73 | Serialize several objects under specific labels. | ||
74 | @function | ||
75 | @param {object} objects A label->object mapping of the objects to be serialized. | ||
76 | @returns {string} The serialized objects. | ||
77 | */ | ||
78 | serialize: { | ||
79 | value: function(objects) { | ||
80 | var serialization, | ||
81 | valueSerialization, | ||
82 | label; | ||
83 | |||
84 | this._serializedObjects = {}; | ||
85 | this._serializedReferences = {}; | ||
86 | this._externalObjects = {}; | ||
87 | this._externalElements = []; | ||
88 | this._objectNamesIndex = {}; | ||
89 | this._objectLabels = {}; | ||
90 | this._objectReferences = {}; | ||
91 | |||
92 | for (label in objects) { | ||
93 | this._objectLabels[objects[label].uuid] = label; | ||
94 | } | ||
95 | |||
96 | for (label in objects) { | ||
97 | valueSerialization = this._serializeValue(objects[label], null, 2); | ||
98 | // objects are automatically inserted as top level objects after calling _serializeValue, but native objects have to be manually inserted them. | ||
99 | if (!(label in this._serializedObjects)) { | ||
100 | this._serializedObjects[label] = {value: valueSerialization}; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | serialization = this._getSerialization(this._serializedObjects); | ||
105 | //console.log(serialization); | ||
106 | // save the require used for this serialization | ||
107 | this._require = require; | ||
108 | this._serialization = serialization; | ||
109 | return serialization; | ||
110 | } | ||
111 | }, | ||
112 | |||
113 | /** | ||
114 | This function is to be used in the context of serializeSelf delegate used for custom object serializations. | ||
115 | It adds an entry to the "properties" serialization unit of the object being serialized. | ||
116 | @function | ||
117 | @param {string} name The name of the entry to be added. | ||
118 | @param {string} value The value to be serialized. | ||
119 | */ | ||
120 | set: {value: function(name, value) { | ||
121 | var stack = this._objectStack; | ||
122 | |||
123 | return (stack[stack.length - 1][name] = value); | ||
124 | }}, | ||
125 | |||
126 | /** | ||
127 | This function is to be used in the context of serializeSelf delegate used for custom object serializations. | ||
128 | It adds an entry to the "properties" serialization unit of the object being serialized. The value for this entry will be stored as a reference only and not the value itself. | ||
129 | @function | ||
130 | @param {string} name The name of the entry to be added. | ||
131 | @param {string} value The value to be referenced. | ||
132 | */ | ||
133 | setReference: {value: function(name, value) { | ||
134 | var stack = this._objectStack, | ||
135 | stackElement = stack[stack.length - 1], | ||
136 | objectReferences = this._objectReferences, | ||
137 | uuid = stackElement.uuid; | ||
138 | |||
139 | if (!(uuid in objectReferences)) { | ||
140 | objectReferences[uuid] = {}; | ||
141 | objectReferences[uuid][name] = true; | ||
142 | } | ||
143 | |||
144 | return (stackElement[name] = value); | ||
145 | }}, | ||
146 | |||
147 | /** | ||
148 | This function is to be used in the context of serializeSelf delegate used for custom object serializations. | ||
149 | It serializes all properties specified as part of the "properties" serialization unit. | ||
150 | @function | ||
151 | @param {array} propertyNames The array with the property names to be serialized. | ||
152 | */ | ||
153 | setProperties: {value: function(propertyNames) { | ||
154 | var ix = this._objectStack.length - 2, | ||
155 | object = this._objectStack[ix]; | ||
156 | |||
157 | for (var i = 0, l = propertyNames.length; i < l; i++) { | ||
158 | var propertyName = propertyNames[i]; | ||
159 | if (Montage.getPropertyAttribute(object, propertyName, "serializable") === "reference") { | ||
160 | this.setReference(propertyName, object[propertyName]); | ||
161 | } else { | ||
162 | this.set(propertyName, object[propertyName]); | ||
163 | } | ||
164 | } | ||
165 | }}, | ||
166 | |||
167 | /** | ||
168 | This function is to be used in the context of serializeSelf delegate used for custom object serializations. | ||
169 | It adds an object to be serialized into the current serialization. | ||
170 | @function | ||
171 | @param {object} object The object to be serialized. | ||
172 | */ | ||
173 | addObject: {value: function(object) { | ||
174 | var valueSerialization = this._serializeValue(object, null, 2); | ||
175 | var label = this._getObjectLabel(object); | ||
176 | // objects are automatically inserted as top level objects after calling _serializeValue, but native objects have to be manually inserted them. | ||
177 | if (!(label in this._serializedObjects)) { | ||
178 | this._serializedObjects[label] = {value: valueSerialization}; | ||
179 | } | ||
180 | }}, | ||
181 | |||
182 | /** | ||
183 | @private | ||
184 | */ | ||
185 | _pushContextObject: {value: function(object) { | ||
186 | if (this._objectStack === null) { | ||
187 | this._objectStack = [object]; | ||
188 | } else { | ||
189 | this._objectStack.push(object); | ||
190 | } | ||
191 | }}, | ||
192 | |||
193 | /** | ||
194 | @private | ||
195 | */ | ||
196 | _popContextObject: {value: function() { | ||
197 | return this._objectStack.pop(); | ||
198 | }}, | ||
199 | |||
200 | /** | ||
201 | Returns a dictionary of the external objects that were referenced in the last serialization. | ||
202 | @function | ||
203 | @returns {object} The dictionary of external objects {label: object} | ||
204 | */ | ||
205 | getExternalObjects: {value: function() { | ||
206 | var externalObjects = this._externalObjects; | ||
207 | |||
208 | for (var label in externalObjects) { | ||
209 | var object = externalObjects[label]; | ||
210 | if (this._serializedObjects[object.uuid]) { | ||
211 | delete externalObjects[label]; | ||
212 | } | ||
213 | } | ||
214 | |||
215 | return externalObjects; | ||
216 | }}, | ||
217 | |||
218 | /** | ||
219 | Returns a list of the external elements that were referenced in the last serialization. | ||
220 | @function | ||
221 | @returns {array} The arrat of external elements. | ||
222 | */ | ||
223 | getExternalElements: {value: function() { | ||
224 | return this._externalElements; | ||
225 | }}, | ||
226 | |||
227 | /** | ||
228 | @private | ||
229 | */ | ||
230 | _getSerialization: {value: function(objects) { | ||
231 | var objectsString = [], | ||