4 * Copyright 2016 RIFT.IO Inc
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 * Created by onvelocity on 8/23/15.
23 import _isArray
from 'lodash/isArray'
24 import _set
from 'lodash/set'
25 import _get
from 'lodash/get'
26 import guid
from '../guid'
27 import Position
from '../graph/Position'
28 import IconFactory
from './IconFactory'
29 import SelectionManager
from '../SelectionManager'
30 import DescriptorModelMetaFactory
from './DescriptorModelMetaFactory'
33 * Abstract base class for the CONFD MANO Descriptors as defined by the Rift.ware YANG configuration files.
35 * Sub-classes should specify the type and qualified-type properties.
37 export default class DescriptorModel
{
39 constructor(model
= {uiState
: {}}, parent
= null, readonly
= false) {
40 // when our instance has no more strong references
41 // then our properties will get garbage collected.
42 this._props_
= new WeakMap();
43 this._props_
.set(this, {
44 position
: new Position(),
49 this.className
= 'DescriptorModel';
50 this.uid
= this.uid
|| guid();
51 if (parent
instanceof DescriptorModel
) {
52 parent
.addChild(this);
54 this.isReadOnly
= readonly
;
58 return DescriptorModelMetaFactory
.getModelFieldNamesForType(this.uiState
['qualified-type'] || this.type
);
62 return DescriptorModelMetaFactory
.getModelMetaForType(this.uiState
['qualified-type'] || this.type
);
66 let model
= this._props_
.get(this).model
;
68 model
= this.model
= {uiState
: {}};
74 this._props_
.get(this).model
= model
;
79 return this.model
.uiState
= this.model
.uiState
|| {};
82 set uiState(uiState
) {
83 this.model
.uiState
= uiState
;
88 return this.uiState
[':uid'];
92 this.uiState
[':uid'] = uid
;
100 // key is read only by design
103 return this.model
.id
;
112 return this.model
['short-name'] || this.model
.name
|| this.key
;
115 // title is read only by design
118 return this.model
.name
;
122 this.model
.name
= name
;
126 return this.model
['short-name'];
129 set 'short-name'(name
) {
130 this.model
['short-name'] = name
;
134 return this.uiState
.type
;
138 this.uiState
.type
= type
;
142 get qualifiedType() {
143 return this.uiState
['qualified-type'] || this.type
;
146 set qualifiedType(type
) {
147 this.uiState
['qualified-type'] = type
;
151 return this._props_
.get(this).position
;
154 set position(position
) {
155 if (!(position
instanceof Position
)) {
158 this._props_
.get(this).position
= position
;
163 return this.uiState
.location
;
167 this.uiState
.location
= v
;
171 return Array
.from(this._props_
.get(this).children
);
174 addProp(name
, value
) {
175 this._props_
.get(this).values
[name
] = value
;
180 return this._props_
.get(this).values
[name
];
184 if (!child
instanceof DescriptorModel
) {
185 throw new ReferenceError('child must be an instance of DescriptorModel class');
187 if (this.findChildByUid(child
.uid
)) {
188 console
.warn('Child already exists');
189 // NOTE: Commented out this line because it was causing issues with Internal VLD.
190 // TODO: Check why it caused issues with Internal VLD
191 // throw new ReferenceError('child already exists');
193 if (child
.parent
instanceof DescriptorModel
) {
194 throw new ReferenceError('child already has a parent');
197 this._props_
.get(this).children
.add(child
);
200 findChildByUid(uid
) {
201 // uid can be a DescriptorModel instance, JSON model object, or a uid string
202 if (typeof uid
=== 'object') {
203 uid
= uid
.uiState
&& uid
.uiState
[':uid'];
205 if (typeof uid
=== 'string') {
206 return this.children
.filter(d
=> d
.uid
=== uid
)[0];
212 // warn don't clear parent so that removed ones can get to root for updating the catalog json model
213 //child.parent = null;
214 // uid can be a DescriptorModel instance, JSON model object, or a uid string
215 if (typeof uid
=== 'object') {
216 uid
= uid
.uiState
&& uid
.uiState
[':uid'];
218 if (typeof uid
=== 'string') {
219 this.children
.filter(d
=> d
.uid
=== uid
).forEach(d
=> this._props_
.get(this).children
.delete(d
));
221 this._props_
.get(this).children
.delete(child
);
227 while (root
&& root
.parent
) {
233 getRootNSDContainer() {
234 let container
= this.parent
;
236 if (container
.type
=== 'nsd') {
239 container
= container
.parent
;
243 setPosition(position
) {
244 this.position
= new Position(position
);
248 return SelectionManager
.isSelected(this);
252 return this.uiState
.colors
|| {primary
: 'black', secondary
: 'white'};
256 this.uiState
.colors
= colors
;
260 return IconFactory
.getIconForType(this.type
);
264 return this.position
.width
;
268 return this.position
.height
;
274 type
: this.model
.type
,
275 cpNumber
: this.cpNumber
283 updateModelList(modelFieldName
, modelFieldValue
, descriptorClass
= DescriptorModel
, newItemAddedSuccessCallback
= () => {}) {
284 // value can be Array of (DescriptorModel | json model), DescriptorModel, or json model
285 if (_isArray(modelFieldValue
)) {
286 this.model
[modelFieldName
] = modelFieldValue
.map(d
=> d
instanceof descriptorClass
? d
.model
: d
);
289 const size
= this.model
[modelFieldName
].length
;
290 if (modelFieldValue
instanceof descriptorClass
) {
291 this.model
[modelFieldName
].push(modelFieldValue
.valueOf());
292 newItemAddedSuccessCallback(modelFieldValue
);
293 } else if (typeof modelFieldValue
=== 'object') {
294 this.model
[modelFieldName
].push(modelFieldValue
);
295 newItemAddedSuccessCallback(new descriptorClass(modelFieldValue
, this));
297 throw new ReferenceError(`expect object to be either an Array, ${descriptorClass.name} or JSON object`);
299 return size
!== this.model
[modelFieldName
].length
;
302 removeModelListItem(propertyName
, child
) {
303 // ensure child is a DescriptorModel instance
304 child
= this.findChildByUid(child
) || child
;
308 this.removeChild(child
);
309 const uid
= child
.uid
;
310 const length
= this[propertyName
].length
;
311 this[propertyName
] = this[propertyName
].filter(d
=> d
.uid
!== uid
);
312 return length
!== this[propertyName
].length
;
315 setUiState(setting
, path
, value
){
316 _set(this.uiState
, [setting
].concat(path
), value
);
319 getUiState(setting
, path
, defaultValue
){
320 return _get(this.uiState
, [setting
].concat(path
), defaultValue
);