RIFT-14874: Allow deny of duplicate events in loggin
[osm/UI.git] / skyquake / plugins / composer / src / src / libraries / model / DescriptorModel.js
1
2 /*
3 *
4 * Copyright 2016 RIFT.IO Inc
5 *
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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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.
17 *
18 */
19 /**
20 * Created by onvelocity on 8/23/15.
21 */
22
23 import _ from 'lodash'
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'
29
30 /**
31 * Abstract base class for the CONFD MANO Descriptors as defined by the Rift.ware YANG configuration files.
32 *
33 * Sub-classes should specify the type and qualified-type properties.
34 */
35 export default class DescriptorModel {
36
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(),
43 children: new Set(),
44 values: {},
45 model: model
46 });
47 this.className = 'DescriptorModel';
48 this.uid = this.uid || guid();
49 if (parent instanceof DescriptorModel) {
50 parent.addChild(this);
51 }
52 }
53
54 get fieldNames() {
55 return DescriptorModelMetaFactory.getModelFieldNamesForType(this.uiState['qualified-type'] || this.type);
56 }
57
58 get property() {
59 return DescriptorModelMetaFactory.getModelMetaForType(this.uiState['qualified-type'] || this.type);
60 }
61
62 get model() {
63 let model = this._props_.get(this).model;
64 if (!model) {
65 model = this.model = {uiState: {}};
66 }
67 return model;
68 }
69
70 set model(model) {
71 this._props_.get(this).model = model;
72 return this;
73 }
74
75 get uiState() {
76 return this.model.uiState = this.model.uiState || {};
77 }
78
79 set uiState(uiState) {
80 this.model.uiState = uiState;
81 return this;
82 }
83
84 get uid() {
85 return this.uiState[':uid'];
86 }
87
88 set uid(uid) {
89 this.uiState[':uid'] = uid;
90 return this;
91 }
92
93 get key() {
94 return this.id;
95 }
96
97 // key is read only by design
98
99 get id() {
100 return this.model.id;
101 }
102
103 set id(id) {
104 this.model.id = id;
105 return this;
106 }
107
108 get title() {
109 return this.model['short-name'] || this.model.name || this.key;
110 }
111
112 // title is read only by design
113
114 get name() {
115 return this.model.name;
116 }
117
118 set name(name) {
119 this.model.name = name;
120 }
121
122 get 'short-name'() {
123 return this.model['short-name'];
124 }
125
126 set 'short-name'(name) {
127 this.model['short-name'] = name;
128 }
129
130 get type() {
131 return this.uiState.type;
132 }
133
134 set type(type) {
135 this.uiState.type = type;
136 return this;
137 }
138
139 get qualifiedType() {
140 return this.uiState['qualified-type'] || this.type;
141 }
142
143 set qualifiedType(type) {
144 this.uiState['qualified-type'] = type;
145 }
146
147 get position() {
148 return this._props_.get(this).position;
149 }
150
151 set position(position) {
152 if (!(position instanceof Position)) {
153
154 }
155 this._props_.get(this).position = position;
156 return this;
157 }
158
159 get location() {
160 return this.uiState.location;
161 }
162
163 set location(v) {
164 this.uiState.location = v;
165 }
166
167 get children() {
168 return Array.from(this._props_.get(this).children);
169 }
170
171 addProp(name, value) {
172 this._props_.get(this).values[name] = value;
173 return this;
174 }
175
176 getProp(name) {
177 return this._props_.get(this).values[name];
178 }
179
180 addChild(child) {
181 if (!child instanceof DescriptorModel) {
182 throw new ReferenceError('child must be an instance of DescriptorModel class');
183 }
184 if (this.findChildByUid(child.uid)) {
185 throw new ReferenceError('child already exists');
186 }
187 if (child.parent instanceof DescriptorModel) {
188 throw new ReferenceError('child already has a parent');
189 }
190 child.parent = this;
191 this._props_.get(this).children.add(child);
192 }
193
194 findChildByUid(uid) {
195 // uid can be a DescriptorModel instance, JSON model object, or a uid string
196 if (typeof uid === 'object') {
197 uid = uid.uiState && uid.uiState[':uid'];
198 }
199 if (typeof uid === 'string') {
200 return this.children.filter(d => d.uid === uid)[0];
201 }
202 }
203
204 removeChild(child) {
205 let uid;
206 // warn don't clear parent so that removed ones can get to root for updating the catalog json model
207 //child.parent = null;
208 // uid can be a DescriptorModel instance, JSON model object, or a uid string
209 if (typeof uid === 'object') {
210 uid = uid.uiState && uid.uiState[':uid'];
211 }
212 if (typeof uid === 'string') {
213 this.children.filter(d => d.uid === uid).forEach(d => this._props_.get(this).children.delete(d));
214 } else {
215 this._props_.get(this).children.delete(child);
216 }
217 }
218
219 getRoot() {
220 let root = this;
221 while (root && root.parent) {
222 root = root.parent;
223 }
224 return root;
225 }
226
227 getRootNSDContainer() {
228 let container = this.parent;
229 while(container) {
230 if (container.type === 'nsd') {
231 return container;
232 }
233 container = container.parent;
234 }
235 }
236
237 setPosition(position) {
238 this.position = new Position(position);
239 }
240
241 get selected() {
242 return SelectionManager.isSelected(this);
243 }
244
245 get colors() {
246 return this.uiState.colors || {primary: 'black', secondary: 'white'};
247 }
248
249 set colors(colors) {
250 this.uiState.colors = colors;
251 }
252
253 get icon() {
254 return IconFactory.getIconForType(this.type);
255 }
256
257 get width() {
258 return this.position.width;
259 }
260
261 get height() {
262 return this.position.height;
263 }
264
265 get displayData() {
266 return {
267 title: this.title,
268 type: this.model.type,
269 cpNumber: this.cpNumber
270 };
271 }
272
273 valueOf() {
274 return this.model;
275 }
276
277 updateModelList(modelFieldName, modelFieldValue, descriptorClass = DescriptorModel, newItemAddedSuccessCallback = () => {}) {
278 // value can be Array of (DescriptorModel | json model), DescriptorModel, or json model
279 if (_.isArray(modelFieldValue)) {
280 this.model[modelFieldName] = modelFieldValue.map(d => d instanceof descriptorClass ? d.model : d);
281 return true;
282 }
283 const size = this.model[modelFieldName].length;
284 if (modelFieldValue instanceof descriptorClass) {
285 this.model[modelFieldName].push(modelFieldValue.valueOf());
286 newItemAddedSuccessCallback(modelFieldValue);
287 } else if (typeof modelFieldValue === 'object') {
288 this.model[modelFieldName].push(modelFieldValue);
289 newItemAddedSuccessCallback(new descriptorClass(modelFieldValue, this));
290 } else {
291 throw new ReferenceError(`expect object to be either an Array, ${descriptorClass.name} or JSON object`);
292 }
293 return size !== this.model[modelFieldName].length;
294 }
295
296 removeModelListItem(propertyName, child) {
297 // ensure child is a DescriptorModel instance
298 child = this.findChildByUid(child) || child;
299 if (!child) {
300 return false;
301 }
302 this.removeChild(child);
303 const uid = child.uid;
304 const length = this[propertyName].length;
305 this[propertyName] = this[propertyName].filter(d => d.uid !== uid);
306 return length !== this[propertyName].length;
307 }
308
309 }