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 guid
from '../guid'
25 import Position
from '../graph/Position'
26 import IconFactory
from './IconFactory'
27 import SelectionManager
from '../SelectionManager'
28 import DescriptorModelMetaFactory
from './DescriptorModelMetaFactory'
31 * Abstract base class for the CONFD MANO Descriptors as defined by the Rift.ware YANG configuration files.
33 * Sub-classes should specify the type and qualified-type properties.
35 export default class DescriptorModel
{
37 constructor(model
= {uiState
: {}}, parent
= null) {
38 // when our instance has no more strong references
39 // then our properties will get garbage collected.
40 this._props_
= new WeakMap();
41 this._props_
.set(this, {
42 position
: new Position(),
47 this.className
= 'DescriptorModel';
48 this.uid
= this.uid
|| guid();
49 if (parent
instanceof DescriptorModel
) {
50 parent
.addChild(this);
55 return DescriptorModelMetaFactory
.getModelFieldNamesForType(this.uiState
['qualified-type'] || this.type
);
59 return DescriptorModelMetaFactory
.getModelMetaForType(this.uiState
['qualified-type'] || this.type
);
63 let model
= this._props_
.get(this).model
;
65 model
= this.model
= {uiState
: {}};
71 this._props_
.get(this).model
= model
;
76 return this.model
.uiState
= this.model
.uiState
|| {};
79 set uiState(uiState
) {
80 this.model
.uiState
= uiState
;
85 return this.uiState
[':uid'];
89 this.uiState
[':uid'] = uid
;
97 // key is read only by design
100 return this.model
.id
;
109 return this.model
['short-name'] || this.model
.name
|| this.key
;
112 // title is read only by design
115 return this.model
.name
;
119 this.model
.name
= name
;
123 return this.model
['short-name'];
126 set 'short-name'(name
) {
127 this.model
['short-name'] = name
;
131 return this.uiState
.type
;
135 this.uiState
.type
= type
;
139 get qualifiedType() {
140 return this.uiState
['qualified-type'] || this.type
;
143 set qualifiedType(type
) {
144 this.uiState
['qualified-type'] = type
;
148 return this._props_
.get(this).position
;
151 set position(position
) {
152 if (!(position
instanceof Position
)) {
155 this._props_
.get(this).position
= position
;
160 return this.uiState
.location
;
164 this.uiState
.location
= v
;
168 return Array
.from(this._props_
.get(this).children
);
171 addProp(name
, value
) {
172 this._props_
.get(this).values
[name
] = value
;
177 return this._props_
.get(this).values
[name
];
181 if (!child
instanceof DescriptorModel
) {
182 throw new ReferenceError('child must be an instance of DescriptorModel class');
184 if (this.findChildByUid(child
.uid
)) {
185 console
.warn('Child already exists');
186 // NOTE: Commented out this line because it was causing issues with Internal VLD.
187 // TODO: Check why it caused issues with Internal VLD
188 // throw new ReferenceError('child already exists');
190 if (child
.parent
instanceof DescriptorModel
) {
191 throw new ReferenceError('child already has a parent');
194 this._props_
.get(this).children
.add(child
);
197 findChildByUid(uid
) {
198 // uid can be a DescriptorModel instance, JSON model object, or a uid string
199 if (typeof uid
=== 'object') {
200 uid
= uid
.uiState
&& uid
.uiState
[':uid'];
202 if (typeof uid
=== 'string') {
203 return this.children
.filter(d
=> d
.uid
=== uid
)[0];
209 // warn don't clear parent so that removed ones can get to root for updating the catalog json model
210 //child.parent = null;
211 // uid can be a DescriptorModel instance, JSON model object, or a uid string
212 if (typeof uid
=== 'object') {
213 uid
= uid
.uiState
&& uid
.uiState
[':uid'];
215 if (typeof uid
=== 'string') {
216 this.children
.filter(d
=> d
.uid
=== uid
).forEach(d
=> this._props_
.get(this).children
.delete(d
));
218 this._props_
.get(this).children
.delete(child
);
224 while (root
&& root
.parent
) {
230 getRootNSDContainer() {
231 let container
= this.parent
;
233 if (container
.type
=== 'nsd') {
236 container
= container
.parent
;
240 setPosition(position
) {
241 this.position
= new Position(position
);
245 return SelectionManager
.isSelected(this);
249 return this.uiState
.colors
|| {primary
: 'black', secondary
: 'white'};
253 this.uiState
.colors
= colors
;
257 return IconFactory
.getIconForType(this.type
);
261 return this.position
.width
;
265 return this.position
.height
;
271 type
: this.model
.type
,
272 cpNumber
: this.cpNumber
280 updateModelList(modelFieldName
, modelFieldValue
, descriptorClass
= DescriptorModel
, newItemAddedSuccessCallback
= () => {}) {
281 // value can be Array of (DescriptorModel | json model), DescriptorModel, or json model
282 if (_isArray(modelFieldValue
)) {
283 this.model
[modelFieldName
] = modelFieldValue
.map(d
=> d
instanceof descriptorClass
? d
.model
: d
);
286 const size
= this.model
[modelFieldName
].length
;
287 if (modelFieldValue
instanceof descriptorClass
) {
288 this.model
[modelFieldName
].push(modelFieldValue
.valueOf());
289 newItemAddedSuccessCallback(modelFieldValue
);
290 } else if (typeof modelFieldValue
=== 'object') {
291 this.model
[modelFieldName
].push(modelFieldValue
);
292 newItemAddedSuccessCallback(new descriptorClass(modelFieldValue
, this));
294 throw new ReferenceError(`expect object to be either an Array, ${descriptorClass.name} or JSON object`);
296 return size
!== this.model
[modelFieldName
].length
;
299 removeModelListItem(propertyName
, child
) {
300 // ensure child is a DescriptorModel instance
301 child
= this.findChildByUid(child
) || child
;
305 this.removeChild(child
);
306 const uid
= child
.uid
;
307 const length
= this[propertyName
].length
;
308 this[propertyName
] = this[propertyName
].filter(d
=> d
.uid
!== uid
);
309 return length
!== this[propertyName
].length
;