+const uiStateToSave = ['containerPositionMap'];
+
+//////
+// Data serialization will be done on a meta model basis. That is,
+// given a schema and data, retrieve from the data only that which is
+// defined by the schema.
+//
+
+// serialize data for a list of properties
+function serializeAll(properties, data) {
+ if (data) {
+ return properties.reduce((obj, p) => {
+ return Object.assign(obj, p.serialize(data));
+ }, {});
+ }
+ return null;
+}
+
+function serialize_container(data) {
+ data = data[this.name];
+ if (_isEmpty(data)) {
+ return null;
+ }
+ let obj = {};
+ obj[this.name] = serializeAll(this.properties, data);
+ return obj;
+}
+
+function serialize_list(data) {
+ data = data[this.name];
+ if (data) {
+ if (!Array.isArray(data)) {
+ return serializeAll(this.properties, data);
+ } else if (data.length) {
+ let list = data.reduce((c, d) => {
+ let obj = serializeAll(this.properties, d);
+ if (!_isEmpty(obj)) {
+ c.push(obj);
+ }
+ return c;
+ }, []);
+ if (!_isEmpty(list)){
+ let obj = {};
+ obj[this.name] = list;
+ return obj;
+ }
+ }
+ }
+ return null;
+}
+
+function serialize_leaf(data) {
+ let value = data[this.name];
+ if (value === null || typeof value === 'undefined' || value === '') {
+ return null;
+ }
+ let obj = {};
+ if (this['data-type'] === 'empty') {
+ value = ''; // empty string does get sent as value
+ }
+ obj[this.name] = value;
+ return obj;
+}
+
+function serialize_leaf_empty(data) {
+ let value = data[this.name];
+ if (value) {
+ let obj = {};
+ obj[this.name] = "";
+ return obj;
+ }
+ return null;
+}
+
+function serialize_leaf_list(data) {
+ data = data[this.name];
+ if (data) {
+ commaSeparatedValues = data.reduce((d, v) => {
+ let leaf = Serializer.leaf.call(this, d);
+ let value = leaf & leaf[this.name];
+ if (value && value.length) {
+ if (v.length) {
+ v += ', ';
+ }
+ v += value;
+ }
+ }, "");
+ if (commaSeparatedValues.length) {
+ let obj = {};
+ obj[this.name] = commaSeparatedValues;
+ return obj;
+ }
+ }
+ return null;
+}
+
+function serialize_choice(data) {
+ let keys = Object.keys(data);
+ if (keys) {
+ const chosen = this.properties.find(
+ c => c.type === 'case' && c.properties && c.properties.some(p => keys.indexOf(p.name) > -1));
+ return chosen && serializeAll(chosen.properties, data);
+ }
+ return null;
+}
+
+function serialize_case(data) {
+ return Serializer.container.call(this, data);
+}
+
+// special ui data handler for leaf of type string named 'meta'
+function serialize_meta(data) {
+ let uiState = data['uiState'];
+ let meta = uiState && _pick(uiState, uiStateToSave);
+ // if there is no uiState to save perhaps this was not a ui state property
+ return _isEmpty(meta) ? null : {meta: JSON.stringify(meta)};
+}
+
+function serialize_unsupported(data) {
+ console.error('unsupported property', property);
+ return null;
+}
+
+function getSerializer(property) {
+ switch (property.name) {
+ case 'rw-nsd:meta':
+ case 'rw-vnfd:meta':
+ return serialize_meta.bind(property);
+ }
+ switch (property.type) {
+ case 'list':
+ return serialize_list.bind(property);
+ case 'container':
+ return serialize_container.bind(property);
+ case 'choice':
+ return serialize_choice.bind(property);
+ case 'case':
+ return serialize_case.bind(property);
+ case 'leaf_list':
+ return serialize_leaf_list.bind(property);
+ case 'leaf':
+ switch (property['data-type']){
+ case 'empty':
+ return serialize_leaf_empty.bind(property);
+ }
+ return serialize_leaf.bind(property);
+ }
+ return serialize_unsupported.bind(property);
+}
+