NO TICKET: Support for leaf lists in composer
[osm/UI.git] / skyquake / plugins / composer / src / src / libraries / model / DescriptorModelMetaProperty.js
1 /*
2 *
3 * Copyright 2016 RIFT.IO Inc
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18 /**
19 * Created by onvelocity on 1/27/16.
20 *
21 * This class provides utility methods for interrogating an instance of model uiState object.
22 */
23
24 'use strict';
25
26 import _ from 'lodash'
27 import guid from './../guid'
28 import changeCase from 'change-case'
29 import InstanceCounter from './../InstanceCounter'
30 import DescriptorModelFields from './DescriptorModelFields'
31 import DescriptorTemplateFactory from './DescriptorTemplateFactory'
32
33 export default {
34 isLeaf(property = {}) {
35 return /leaf|choice/.test(property.type);
36 },
37 isList(property = {}) {
38 return /list|leaf_list/.test(property.type);
39 },
40 isLeafList(property = {}) {
41 return property.type === 'leaf_list';
42 },
43 isArray(property = {}) {
44 // give '1' or '0..N' or '0..1' or '0..5' determine if represents an array
45 // '0..1' is not an array
46 // '0..2' is an array
47 // '0..N' is an array
48 const cardinality = String(property.cardinality).toUpperCase();
49 const pos = cardinality.lastIndexOf('.') + 1;
50 const val = cardinality.substr(pos);
51 return val === 'N' || parseInt(val, 10) > 1;
52 },
53 isEnumeration(property = {}) {
54 const type = property['data-type'] || {};
55 return type.hasOwnProperty('enumeration');
56 },
57 isRequired(property = {}) {
58 return /^1/.test(property.cardinality);
59 },
60 isObject(property = {}) {
61 return !/^(leaf|leaf_list)$/.test(property.type);
62 },
63 isSimpleList(property = {}) {
64 return _.contains(DescriptorModelFields.simpleList, property.name);
65 },
66 isPrimativeDataType(property = {}) {
67 const Property = this;
68 return /string|int/.test(property['data-type']) || Property.isEnumeration(property) || Property.isGuid(property);
69 },
70 defaultValue(property = {}) {
71 if (property.defaultValue) {
72 return property.defaultValue;
73 }
74 if (this.isObject(property)) {
75 return {};
76 }
77 return '';
78 },
79 getContainerMethod(property, container, methodName) {
80 const name = changeCase.camel(methodName + '-' + property.name);
81 if (typeof container[name] === 'function') {
82 return container[name].bind(container);
83 }
84 },
85 getContainerCreateMethod(property, container) {
86 const name = changeCase.camel('create-' + property.name);
87 if (typeof container[name] === 'function') {
88 return container[name].bind(container);
89 }
90 },
91 containerHasCreateMethod(container, property = {}) {
92 const find = changeCase.camel('create-' + property.name);
93 return typeof container[find] === 'function';
94 },
95 getEnumeration(property = {}, value) {
96 const enumeration = property['data-type'].enumeration.enum;
97 if (typeof enumeration === 'string') {
98 return [{name: enumeration, value: enumeration, isSelected: String(value) === enumeration}];
99 }
100 return Object.keys(enumeration).map(enumName => {
101 let enumValue = enumName;
102 // warn we only support named enums and systematically ignore enum values
103 //const enumObj = enumeration[enumName];
104 //if (enumObj) {
105 // enumValue = enumObj.value || enumName;
106 //}
107 return {name: enumName, value: enumValue, isSelected: String(enumValue) === String(value)};
108 });
109 },
110 isGuid(property = {}) {
111 const type = property['data-type'];
112 if (typeof type === 'object' && type.leafref && type.leafref.path) {
113 return /\bid$/.test(type.leafref.path);
114 }
115 return /uuid/.test(property['data-type']);
116 },
117 createModelInstance(property) {
118 const Property = this;
119 const defaultValue = Property.defaultValue.bind(this);
120 function createModel(uiState, parentMeta) {
121 const model = {};
122 if (Property.isLeaf(uiState)) {
123 if (uiState.name === 'name') {
124 return changeCase.param(parentMeta.name) + '-' + InstanceCounter.count(parentMeta[':qualified-type']);
125 }
126 if (_.isArray(parentMeta.key) && _.contains(parentMeta.key, uiState.name)) {
127 if (/uuid/.test(uiState['data-type'])) {
128 return guid();
129 }
130 if (uiState['data-type'] === 'string') {
131 const prefix = uiState.name.replace('id', '');
132 return (prefix ? changeCase.param(prefix) + '-' : '') + guid(5);
133 }
134 if (/int/.test(uiState['data-type'])) {
135 return InstanceCounter.count(uiState[':qualified-type']);
136 }
137 }
138 return defaultValue(uiState);
139 } else if (Property.isList(uiState)) {
140 return [];
141 } else {
142 uiState.properties.forEach(p => {
143 model[p.name] = createModel(p, uiState);
144 });
145 }
146 return model;
147 }
148 if (property) {
149 if (Property.isPrimativeDataType(property)) {
150 return defaultValue(property);
151 }
152 if (property.type === 'leaf') {
153 return defaultValue(property);
154 }
155 if (/list/.test(property.type)) {
156 property.type = 'container';
157 }
158 const modelInstance = createModel(property, property);
159 modelInstance.uiState = {type: property.name};
160 const modelFragment = DescriptorTemplateFactory.createModelForType(property[':qualified-type'] || property.name) || {};
161 Object.assign(modelInstance, modelFragment);
162 return modelInstance;
163 }
164 }
165 }