[SDC-29] rebase continue work to align source
[sdc.git] / catalog-ui / src / app / models / components / component.ts
1 'use strict';
2
3 import {AsdcComment, ArtifactModel, ArtifactGroupModel, IFileDownload, PropertyModel, PropertiesGroup, AttributeModel, AttributesGroup, ComponentInstance,
4     InputModel, DisplayModule, Module, IValidate, RelationshipModel, IMainCategory, RequirementsGroup, CapabilitiesGroup, AdditionalInformationModel,
5     Resource, IAppMenu, Product, Service} from "../../models";
6
7 import {IComponentService} from "../../services/components/component-service";
8 import {CommonUtils} from "../../utils/common-utils";
9 import {QueueUtils} from "../../utils/functions";
10 import {ArtifactGroupType} from "../../utils/constants";
11 import {ComponentMetadata} from "../component-metadata";
12
13 // import {}
14 export interface IComponent {
15
16     //---------------------------------------------- API CALLS ----------------------------------------------------//
17
18     //Component API
19     getComponent():ng.IPromise<Component>;
20     updateComponent():ng.IPromise<Component>;
21     createComponentOnServer():ng.IPromise<Component>;
22     changeLifecycleState(state:string, commentObj:AsdcComment):ng.IPromise<Component>;
23     validateName(newName:string):ng.IPromise<IValidate>;
24     updateRequirementsCapabilities():ng.IPromise<any>;
25
26     //Artifacts API
27     addOrUpdateArtifact(artifact:ArtifactModel):ng.IPromise<ArtifactModel>;
28     updateMultipleArtifacts(artifacts:Array<ArtifactModel>):ng.IPromise<any>;
29     deleteArtifact(artifactId:string, artifactLabel:string):ng.IPromise<ArtifactModel>;
30     downloadInstanceArtifact(artifactId:string):ng.IPromise<IFileDownload>;
31     downloadArtifact(artifactId:string):ng.IPromise<IFileDownload>;
32     getArtifactByGroupType(artifactGroupType:string):ng.IPromise<ArtifactGroupModel>;
33
34
35     //Property API
36     addOrUpdateProperty(property:PropertyModel):ng.IPromise<PropertyModel>;
37     deleteProperty(propertyId:string):ng.IPromise<PropertyModel>;
38     updateInstanceProperty(property:PropertyModel):ng.IPromise<PropertyModel>;
39
40     //Attribute API
41     deleteAttribute(attributeId:string):ng.IPromise<AttributeModel>;
42     addOrUpdateAttribute(attribute:AttributeModel):ng.IPromise<AttributeModel>;
43     updateInstanceAttribute(attribute:AttributeModel):ng.IPromise<AttributeModel>;
44
45
46
47
48     //Component Instance API
49     createComponentInstance(componentInstance:ComponentInstance):ng.IPromise<ComponentInstance>;
50     deleteComponentInstance(componentInstanceId:string):ng.IPromise<ComponentInstance>;
51     addOrUpdateInstanceArtifact(artifact:ArtifactModel):ng.IPromise<ArtifactModel>;
52     deleteInstanceArtifact(artifactId:string, artifactLabel:string):ng.IPromise<ArtifactModel>;
53     uploadInstanceEnvFile(artifact:ArtifactModel):ng.IPromise<ArtifactModel>;
54     changeComponentInstanceVersion(componentUid:string):ng.IPromise<Component>;
55     updateComponentInstance(componentInstance:ComponentInstance):ng.IPromise<ComponentInstance>;
56     updateMultipleComponentInstances(instances:Array<ComponentInstance>):ng.IPromise<Array<ComponentInstance>>;
57
58     //Inputs API
59     getComponentInstanceInputProperties(componentInstanceId:string, inputId:string):ng.IPromise<Array<PropertyModel>>
60     getComponentInstanceProperties(componentInstanceId:string):ng.IPromise<Array<PropertyModel>>
61     getComponentInputs(componentId:string):ng.IPromise<Array<InputModel>>;
62
63     createRelation(link:RelationshipModel):ng.IPromise<RelationshipModel>;
64     deleteRelation(link:RelationshipModel):ng.IPromise<RelationshipModel>;
65
66
67     //Modules
68     getModuleForDisplay(moduleId:string):ng.IPromise<DisplayModule>;
69     getModuleInstanceForDisplay(componentInstanceId:string, moduleId:string):ng.IPromise<DisplayModule>;
70     updateGroupMetadata(group:Module):ng.IPromise<Module>;
71     //---------------------------------------------- HELP FUNCTIONS ----------------------------------------------------//
72
73     getComponentSubType():string;
74     isAlreadyCertified():boolean;
75     isProduct():boolean;
76     isService():boolean;
77     isResource():boolean;
78     isComplex():boolean;
79     getAdditionalInformation():Array<AdditionalInformationModel>;
80     getAllVersionsAsSortedArray():Array<any>;
81     getStatus(sdcMenu:IAppMenu):string;
82 }
83
84
85 export abstract class Component implements IComponent {
86
87     //server data
88     public abstract:string;
89     public uniqueId:string;
90     public uuid:string;
91     public invariantUUID:string;
92     public name:string;
93     public version:string;
94     public creationDate:number;
95     public lastUpdateDate:number;
96     public description:string;
97     public lifecycleState:string;
98     public tags:Array<string>;
99     public icon:string;
100     public contactId:string;
101     public allVersions:any;
102     public creatorUserId:string;
103     public creatorFullName:string;
104     public lastUpdaterUserId:string;
105     public lastUpdaterFullName:string;
106     public componentType:string;
107     public deploymentArtifacts:ArtifactGroupModel;
108     public artifacts:ArtifactGroupModel;
109     public toscaArtifacts:ArtifactGroupModel;
110     public distributionStatus:string;
111     public categories:Array<IMainCategory>;
112     public componentInstancesProperties:PropertiesGroup;
113     public componentInstancesAttributes:AttributesGroup;
114     public componentInstancesRelations:Array<RelationshipModel>;
115     public componentInstances:Array<ComponentInstance>;
116     public inputs:Array<InputModel>;
117     public capabilities:CapabilitiesGroup;
118     public requirements:RequirementsGroup;
119     public additionalInformation:any;
120     public properties:Array<PropertyModel>;
121     public attributes:Array<AttributeModel>;
122     public highestVersion:boolean;
123     public vendorName:string;
124     public vendorRelease:string;
125     public derivedList:Array<any>;
126     public interfaces:any;
127     public normalizedName:string;
128     public systemName:string;
129     public projectCode:string;
130     public groups:Array<Module>;
131     //custom properties
132     public componentService:IComponentService;
133     public filterTerm:string;
134     public iconSprite:string;
135     public selectedInstance:ComponentInstance;
136     public mainCategory:string;
137     public subCategory:string;
138     public selectedCategory:string;
139     public showMenu:boolean;
140
141
142     constructor(componentService:IComponentService, protected $q:ng.IQService, component?:Component) {
143         if (component) {
144             this.abstract = component.abstract;
145             this.uniqueId = component.uniqueId;
146             this.uuid = component.uuid;
147             this.invariantUUID = component.invariantUUID;
148             this.additionalInformation = component.additionalInformation;
149             this.artifacts = new ArtifactGroupModel(component.artifacts);
150             this.toscaArtifacts = new ArtifactGroupModel(component.toscaArtifacts);
151             this.contactId = component.contactId;
152             this.categories = component.categories;
153             this.creatorUserId = component.creatorUserId;
154             this.creationDate = component.creationDate;
155             this.creatorFullName = component.creatorFullName;
156             this.description = component.description;
157             this.icon = component.icon;
158             this.lastUpdateDate = component.lastUpdateDate;
159             this.lastUpdaterUserId = component.lastUpdaterUserId;
160             this.lastUpdaterFullName = component.lastUpdaterFullName;
161             this.lifecycleState = component.lifecycleState;
162             this.componentInstancesRelations = CommonUtils.initComponentInstanceRelations(component.componentInstancesRelations);
163             this.componentInstancesProperties = new PropertiesGroup(component.componentInstancesProperties);
164             this.componentInstancesAttributes = new AttributesGroup(component.componentInstancesAttributes);
165             this.name = component.name;
166             this.version = component.version;
167             this.tags = [];
168             angular.copy(component.tags, this.tags);
169             this.capabilities = new CapabilitiesGroup(component.capabilities);
170             this.requirements = new RequirementsGroup(component.requirements);
171             this.allVersions = component.allVersions;
172             this.deploymentArtifacts = new ArtifactGroupModel(component.deploymentArtifacts);
173             this.componentType = component.componentType;
174             this.distributionStatus = component.distributionStatus;
175             this.highestVersion = component.highestVersion;
176             this.vendorName = component.vendorName;
177             this.vendorRelease = component.vendorRelease;
178             this.derivedList = component.derivedList;
179             this.interfaces = component.interfaces;
180             this.normalizedName = component.normalizedName;
181             this.systemName = component.systemName;
182             this.projectCode = component.projectCode;
183             this.inputs = component.inputs;
184             this.componentInstances = CommonUtils.initComponentInstances(component.componentInstances);
185             this.properties = CommonUtils.initProperties(component.properties, this.uniqueId);
186             this.attributes = CommonUtils.initAttributes(component.attributes, this.uniqueId);
187             this.selectedInstance = component.selectedInstance;
188             this.iconSprite = component.iconSprite;
189             this.showMenu = true;
190             this.groups = CommonUtils.initModules(component.groups);
191         }
192
193         //custom properties
194         this.componentService = componentService;
195     }
196
197     public setUniqueId = (uniqueId:string):void => {
198         this.uniqueId = uniqueId;
199     };
200
201     public setSelectedInstance = (componentInstance:ComponentInstance):void => {
202         this.selectedInstance = componentInstance;
203     };
204
205
206     //------------------------------------------ API Calls ----------------------------------------------------------------//
207     public changeLifecycleState = (state:string, commentObj:AsdcComment):ng.IPromise<Component> => {
208         let deferred = this.$q.defer();
209         let onSuccess = (componentMetadata:ComponentMetadata):void => {
210             this.setComponentMetadata(componentMetadata);
211             // this.version = componentMetadata.version;
212             this.lifecycleState = componentMetadata.lifecycleState;
213
214             deferred.resolve(this);
215         };
216         let onError = (error:any):void => {
217             deferred.reject(error);
218         };
219         this.componentService.changeLifecycleState(this, state, JSON.stringify(commentObj)).then(onSuccess, onError);
220         return deferred.promise;
221     };
222
223     public getComponent = ():ng.IPromise<Component> => {
224         return this.componentService.getComponent(this.uniqueId);
225     };
226
227     public createComponentOnServer = ():ng.IPromise<Component> => {
228         this.handleTags();
229         return this.componentService.createComponent(this);
230     };
231
232     public updateComponent = ():ng.IPromise<Component> => {
233         this.handleTags();
234         return this.componentService.updateComponent(this);
235     };
236
237     public validateName = (newName:string, subtype?:string):ng.IPromise<IValidate> => {
238         return this.componentService.validateName(newName, subtype);
239     };
240
241     public downloadArtifact = (artifactId:string):ng.IPromise<IFileDownload> => {
242         return this.componentService.downloadArtifact(this.uniqueId, artifactId);
243     };
244
245     public addOrUpdateArtifact = (artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
246         let deferred = this.$q.defer();
247         let onSuccess = (artifactObj:ArtifactModel):void => {
248             let newArtifact = new ArtifactModel(artifactObj);
249             let artifacts = this.getArtifactsByType(artifactObj.artifactGroupType);
250             artifacts[artifactObj.artifactLabel] = newArtifact;
251             deferred.resolve(newArtifact);
252         };
253         let onError = (error:any):void => {
254             deferred.reject(error);
255         };
256         this.componentService.addOrUpdateArtifact(this.uniqueId, artifact).then(onSuccess, onError);
257         return deferred.promise;
258     };
259
260     public updateMultipleArtifacts = (artifacts:Array<ArtifactModel>):ng.IPromise<any>=> {
261         let deferred = this.$q.defer();
262         let onSuccess = (response:any):void => {
263             deferred.resolve(response);
264         };
265         let onError = (error:any):void => {
266             deferred.reject(error);
267         };
268         let q = new QueueUtils(this.$q);
269
270         _.forEach(artifacts, (artifact)=> {
271             q.addBlockingUIAction(()=> this.addOrUpdateArtifact(artifact).then(onSuccess, onError));
272         });
273         return deferred.promise;
274     };
275
276
277     public deleteArtifact = (artifactId:string, artifactLabel:string):ng.IPromise<ArtifactModel> => {
278         let deferred = this.$q.defer();
279         let onSuccess = (artifactObj:ArtifactModel):void => {
280             let newArtifact = new ArtifactModel(artifactObj);
281             let artifacts = this.getArtifactsByType(artifactObj.artifactGroupType);
282             if (newArtifact.mandatory || newArtifact.serviceApi) {
283                 artifacts[newArtifact.artifactLabel] = newArtifact;
284             }
285             else {
286                 delete artifacts[artifactLabel];
287             }
288             deferred.resolve(newArtifact);
289         };
290         this.componentService.deleteArtifact(this.uniqueId, artifactId, artifactLabel).then(onSuccess);
291         return deferred.promise;
292     };
293
294     public getArtifactByGroupType = (artifactGroupType:string):ng.IPromise<ArtifactGroupModel> => {
295
296         let deferred = this.$q.defer();
297         let onSuccess = (response:ArtifactGroupModel):void => {
298             deferred.resolve(response);
299         };
300         let onFailed = (error:any):void => {
301             deferred.reject(error);
302         };
303         this.componentService.getArtifactByGroupType(this.uniqueId, artifactGroupType).then(onSuccess, onFailed);
304         return deferred.promise;
305     };
306
307     public getComponentInstanceArtifactsByGroupType = (componentInstanceId:string, artifactGroupType:string):ng.IPromise<ArtifactGroupModel> => {
308
309         let deferred = this.$q.defer();
310         let onSuccess = (response:ArtifactGroupModel):void => {
311             deferred.resolve(response);
312         };
313         let onFailed = (error:any):void => {
314             deferred.reject(error);
315         };
316         this.componentService.getComponentInstanceArtifactsByGroupType(this.uniqueId, componentInstanceId, artifactGroupType).then(onSuccess, onFailed);
317         return deferred.promise;
318     };
319
320     public addOrUpdateProperty = (property:PropertyModel):ng.IPromise<PropertyModel> => {
321         let deferred = this.$q.defer();
322
323         let onError = (error:any):void => {
324             deferred.reject(error);
325         };
326
327         if (!property.uniqueId) {
328             let onSuccess = (property:PropertyModel):void => {
329                 let newProperty = new PropertyModel(property);
330                 this.properties.push(newProperty);
331                 deferred.resolve(newProperty);
332             };
333             this.componentService.addProperty(this.uniqueId, property).then(onSuccess, onError);
334         }
335         else {
336             let onSuccess = (newProperty:PropertyModel):void => {
337                 // find exist instance property in parent component for update the new value ( find bu uniqueId )
338                 let existProperty:PropertyModel = <PropertyModel>_.find(this.properties, {uniqueId: newProperty.uniqueId});
339                 let propertyIndex = this.properties.indexOf(existProperty);
340                 newProperty.readonly = this.uniqueId != newProperty.parentUniqueId;
341                 this.properties[propertyIndex] = newProperty;
342                 deferred.resolve(newProperty);
343             };
344             this.componentService.updateProperty(this.uniqueId, property).then(onSuccess, onError);
345         }
346         return deferred.promise;
347     };
348
349     public addOrUpdateAttribute = (attribute:AttributeModel):ng.IPromise<AttributeModel> => {
350         let deferred = this.$q.defer();
351
352         let onError = (error:any):void => {
353             deferred.reject(error);
354         };
355
356         if (!attribute.uniqueId) {
357             let onSuccess = (attribute:AttributeModel):void => {
358                 let newAttribute = new AttributeModel(attribute);
359                 this.attributes.push(newAttribute);
360                 deferred.resolve(newAttribute);
361             };
362             this.componentService.addAttribute(this.uniqueId, attribute).then(onSuccess, onError);
363         }
364         else {
365             let onSuccess = (newAttribute:AttributeModel):void => {
366                 let existAttribute:AttributeModel = <AttributeModel>_.find(this.attributes, {uniqueId: newAttribute.uniqueId});
367                 let attributeIndex = this.attributes.indexOf(existAttribute);
368                 newAttribute.readonly = this.uniqueId != newAttribute.parentUniqueId;
369                 this.attributes[attributeIndex] = newAttribute;
370                 deferred.resolve(newAttribute);
371             };
372             this.componentService.updateAttribute(this.uniqueId, attribute).then(onSuccess, onError);
373         }
374         return deferred.promise;
375     };
376
377     public deleteProperty = (propertyId:string):ng.IPromise<PropertyModel> => {
378         let deferred = this.$q.defer();
379         let onSuccess = ():void => {
380             console.log("Property deleted");
381             delete _.remove(this.properties, {uniqueId: propertyId})[0];
382             deferred.resolve();
383         };
384         let onFailed = ():void => {
385             console.log("Failed to delete property");
386             deferred.reject();
387         };
388         this.componentService.deleteProperty(this.uniqueId, propertyId).then(onSuccess, onFailed);
389         return deferred.promise;
390     };
391
392     public deleteAttribute = (attributeId:string):ng.IPromise<AttributeModel> => {
393         let deferred = this.$q.defer();
394         let onSuccess = ():void => {
395             console.log("Attribute deleted");
396             delete _.remove(this.attributes, {uniqueId: attributeId})[0];
397         };
398         let onFailed = ():void => {
399             console.log("Failed to delete attribute");
400         };
401         this.componentService.deleteAttribute(this.uniqueId, attributeId).then(onSuccess, onFailed);
402         return deferred.promise;
403     };
404
405     public updateInstanceProperty = (property:PropertyModel):ng.IPromise<PropertyModel> => {
406         let deferred = this.$q.defer();
407         let onSuccess = (newProperty:PropertyModel):void => {
408             // find exist instance property in parent component for update the new value ( find bu uniqueId & path)
409             let existProperty:PropertyModel = <PropertyModel>_.find(this.componentInstancesProperties[newProperty.resourceInstanceUniqueId], {
410                 uniqueId: newProperty.uniqueId,
411                 path: newProperty.path
412             });
413             let index = this.componentInstancesProperties[newProperty.resourceInstanceUniqueId].indexOf(existProperty);
414             this.componentInstancesProperties[newProperty.resourceInstanceUniqueId][index] = newProperty;
415             deferred.resolve(newProperty);
416         };
417         let onFailed = (error:any):void => {
418             console.log('Failed to update property value');
419             deferred.reject(error);
420         };
421         this.componentService.updateInstanceProperty(this.uniqueId, property).then(onSuccess, onFailed);
422         return deferred.promise;
423     };
424
425     public updateInstanceAttribute = (attribute:AttributeModel):ng.IPromise<AttributeModel> => {
426         let deferred = this.$q.defer();
427         let onSuccess = (newAttribute:AttributeModel):void => {
428             let existAttribute:AttributeModel = <AttributeModel>_.find(this.componentInstancesAttributes[newAttribute.resourceInstanceUniqueId], {uniqueId: newAttribute.uniqueId});
429             let index = this.componentInstancesAttributes[newAttribute.resourceInstanceUniqueId].indexOf(existAttribute);
430             this.componentInstancesAttributes[newAttribute.resourceInstanceUniqueId][index] = newAttribute;
431             deferred.resolve(newAttribute);
432         };
433         let onFailed = (error:any):void => {
434             console.log('Failed to update attribute value');
435             deferred.reject(error);
436         };
437         this.componentService.updateInstanceAttribute(this.uniqueId, attribute).then(onSuccess, onFailed);
438         return deferred.promise;
439     };
440
441     public downloadInstanceArtifact = (artifactId:string):ng.IPromise<IFileDownload> => {
442         return this.componentService.downloadInstanceArtifact(this.uniqueId, this.selectedInstance.uniqueId, artifactId);
443     };
444
445     public deleteInstanceArtifact = (artifactId:string, artifactLabel:string):ng.IPromise<ArtifactModel> => {
446         let deferred = this.$q.defer();
447         let onSuccess = (artifactObj:ArtifactModel):void => {
448             let newArtifact = new ArtifactModel(artifactObj);
449             let artifacts = this.selectedInstance.deploymentArtifacts;
450             if (newArtifact.mandatory || newArtifact.serviceApi) {//?????????
451                 artifacts[newArtifact.artifactLabel] = newArtifact;
452             }
453             else {
454                 delete artifacts[artifactLabel];
455             }
456             deferred.resolve(newArtifact);
457         };
458         this.componentService.deleteInstanceArtifact(this.uniqueId, this.selectedInstance.uniqueId, artifactId, artifactLabel).then(onSuccess);
459         return deferred.promise;
460     };
461
462     public addOrUpdateInstanceArtifact = (artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
463         let deferred = this.$q.defer();
464         let onSuccess = (artifactObj:ArtifactModel):void => {
465             switch (artifactObj.artifactGroupType) {
466                 case ArtifactGroupType.DEPLOYMENT:
467                     this.selectedInstance.deploymentArtifacts[artifactObj.artifactLabel] = artifactObj;
468                     break;
469                 case ArtifactGroupType.INFORMATION:
470                     this.selectedInstance.artifacts[artifactObj.artifactLabel] = artifactObj;
471                     break;
472             }
473             deferred.resolve(artifactObj);
474         };
475         let onError = (error:any):void => {
476             deferred.reject(error);
477         };
478         if (artifact.uniqueId) {
479             this.componentService.updateInstanceArtifact(this.uniqueId, this.selectedInstance.uniqueId, artifact).then(onSuccess, onError);
480         } else {
481             this.componentService.addInstanceArtifact(this.uniqueId, this.selectedInstance.uniqueId, artifact).then(onSuccess, onError);
482         }
483         return deferred.promise;
484     };
485
486     public uploadInstanceEnvFile = (artifact:ArtifactModel):ng.IPromise<ArtifactModel> => {
487         let deferred = this.$q.defer();
488         let onSuccess = (artifactObj:ArtifactModel):void => {
489             this.selectedInstance.deploymentArtifacts[artifactObj.artifactLabel] = artifactObj;
490             deferred.resolve(artifactObj);
491         };
492         let onError = (error:any):void => {
493             deferred.reject(error);
494         };
495         this.componentService.uploadInstanceEnvFile(this.uniqueId, this.selectedInstance.uniqueId, artifact).then(onSuccess, onError);
496         return deferred.promise;
497     };
498
499     //this function will update the instance version than the function call getComponent to update the current component and return the new instance version
500     public changeComponentInstanceVersion = (componentUid:string):ng.IPromise<Component> => {
501         let deferred = this.$q.defer();
502         let onFailed = (error:any):void => {
503             deferred.reject(error);
504         };
505         let onSuccess = (componentInstance:ComponentInstance):void => {
506             let onSuccess = (component:Component):void => {
507                 component.setSelectedInstance(componentInstance);
508                 deferred.resolve(component);
509             };
510             this.getComponent().then(onSuccess, onFailed);
511         };
512         this.componentService.changeResourceInstanceVersion(this.uniqueId, this.selectedInstance.uniqueId, componentUid).then(onSuccess, onFailed);
513         return deferred.promise;
514     };
515
516     public createComponentInstance = (componentInstance:ComponentInstance):ng.IPromise<ComponentInstance> => {
517         let deferred = this.$q.defer();
518         let onSuccess = (instance:ComponentInstance):void => {
519             this.componentInstances.push(instance);
520             deferred.resolve(instance);
521         };
522         let onFailed = (error:any):void => {
523             deferred.reject(error);
524         };
525         this.componentService.createComponentInstance(this.uniqueId, componentInstance).then(onSuccess, onFailed);
526         return deferred.promise;
527     };
528
529     public updateComponentInstance = (componentInstance:ComponentInstance):ng.IPromise<ComponentInstance> => {
530         let deferred = this.$q.defer();
531         let onSuccess = (updatedInstance:ComponentInstance):void => {
532             let componentInstance:ComponentInstance = _.find(this.componentInstances, (instance:ComponentInstance) => {
533                 return instance.uniqueId === updatedInstance.uniqueId;
534             });
535
536             let index = this.componentInstances.indexOf(componentInstance);
537             this.componentInstances[index] = componentInstance;
538             deferred.resolve(updatedInstance);
539
540         };
541         let onFailed = (error:any):void => {
542             deferred.reject(error);
543         };
544         this.componentService.updateComponentInstance(this.uniqueId, componentInstance).then(onSuccess, onFailed);
545         return deferred.promise;
546     };
547
548     public updateMultipleComponentInstances = (instances:Array<ComponentInstance>):ng.IPromise<Array<ComponentInstance>> => {
549         let deferred = this.$q.defer();
550         let onSuccess = (updatedInstances:Array<ComponentInstance>):void => {
551             _.forEach(updatedInstances, (updatedComponentInstance) => {
552                 let componentInstance:ComponentInstance = _.find(this.componentInstances, (instance:ComponentInstance) => {
553                     return instance.uniqueId === updatedComponentInstance.uniqueId;
554                 });
555
556                 let index = this.componentInstances.indexOf(componentInstance);
557                 this.componentInstances[index] = componentInstance;
558
559             });
560             deferred.resolve(updatedInstances);
561
562         };
563         let onFailed = (error:any):void => {
564             deferred.reject(error);
565         };
566         this.componentService.updateMultipleComponentInstances(this.uniqueId, instances).then(onSuccess, onFailed);
567         return deferred.promise;
568     };
569
570     public deleteComponentInstance = (componentInstanceId:string):ng.IPromise<ComponentInstance> => {
571         let deferred = this.$q.defer();
572         let onSuccess = ():void => {
573             let onSuccess = (component:Component):void => {
574                 this.componentInstances = CommonUtils.initComponentInstances(component.componentInstances);
575                 this.componentInstancesProperties = new PropertiesGroup(component.componentInstancesProperties);
576                 this.componentInstancesAttributes = new AttributesGroup(component.componentInstancesAttributes);
577                 this.groups = component.groups;
578                 this.componentInstancesRelations = CommonUtils.initComponentInstanceRelations(component.componentInstancesRelations);
579                 deferred.resolve();
580             };
581             this.getComponent().then(onSuccess);
582         };
583         let onFailed = (error:any):void => {
584             deferred.reject(error);
585         };
586         this.componentService.deleteComponentInstance(this.uniqueId, componentInstanceId).then(onSuccess, onFailed);
587         return deferred.promise;
588     };
589
590
591     public createRelation = (relation:RelationshipModel):ng.IPromise<RelationshipModel> => {
592         let deferred = this.$q.defer();
593         let onSuccess = (relation:RelationshipModel):void => {
594             console.info('Link created successfully', relation);
595             if (!this.componentInstancesRelations) {
596                 this.componentInstancesRelations = [];
597             }
598             this.componentInstancesRelations.push(new RelationshipModel(relation));
599             deferred.resolve(relation);
600         };
601         let onFailed = (error:any):void => {
602             console.info('Failed to create relation', error);
603             deferred.reject(error);
604         };
605         this.componentService.createRelation(this.uniqueId, relation).then(onSuccess, onFailed);
606         return deferred.promise;
607     };
608
609     public deleteRelation = (relation:RelationshipModel):ng.IPromise<RelationshipModel> => {
610         let deferred = this.$q.defer();
611         let onSuccess = (responseRelation:RelationshipModel):void => {
612             console.log("Link Deleted In Server");
613             let relationToDelete = _.find(this.componentInstancesRelations, (item) => {
614                 return item.fromNode === relation.fromNode && item.toNode === relation.toNode && _.some(item.relationships, (relationship)=> {
615                         return angular.equals(relation.relationships[0], relationship);
616                     });
617             });
618             let index = this.componentInstancesRelations.indexOf(relationToDelete);
619             if (relationToDelete != undefined && index > -1) {
620                 if (relationToDelete.relationships.length == 1) {
621                     this.componentInstancesRelations.splice(index, 1);
622                 } else {
623                     this.componentInstancesRelations[index].relationships =
624                         _.reject(this.componentInstancesRelations[index].relationships, relation.relationships[0]);
625                 }
626             } else {
627                 console.error("Error while deleting relation - the return delete relation from server was not found in UI")
628             }
629             deferred.resolve(relation);
630         };
631         let onFailed = (error:any):void => {
632             console.error("Failed To Delete Link");
633             deferred.reject(error);
634         };
635         this.componentService.deleteRelation(this.uniqueId, relation).then(onSuccess, onFailed);
636         return deferred.promise;
637     };
638
639     public updateRequirementsCapabilities = ():ng.IPromise<any> => {
640         let deferred = this.$q.defer();
641         let onSuccess = (response:any):void => {
642             this.capabilities = response.capabilities;
643             this.requirements = response.requirements;
644             deferred.resolve(response);
645         };
646         let onFailed = (error:any):void => {
647             deferred.reject(error);
648         };
649         this.componentService.getRequirementsCapabilities(this.uniqueId).then(onSuccess, onFailed);
650         return deferred.promise;
651     };
652
653     public getModuleForDisplay = (moduleId:string):ng.IPromise<DisplayModule> => {
654
655         let deferred = this.$q.defer();
656         let onSuccess = (response:DisplayModule):void => {
657             deferred.resolve(response);
658         };
659         let onFailed = (error:any):void => {
660             deferred.reject(error);
661         };
662         this.componentService.getModuleForDisplay(this.uniqueId, moduleId).then(onSuccess, onFailed);
663         return deferred.promise;
664     };
665
666     public getModuleInstanceForDisplay = (componentInstanceId:string, moduleId:string):ng.IPromise<DisplayModule> => {
667
668         let deferred = this.$q.defer();
669         let onSuccess = (response:DisplayModule):void => {
670             deferred.resolve(response);
671         };
672         let onFailed = (error:any):void => {
673             deferred.reject(error);
674         };
675         this.componentService.getComponentInstanceModule(this.uniqueId, componentInstanceId, moduleId).then(onSuccess, onFailed);
676         return deferred.promise;
677     };
678
679
680     // this function get all instances filtered by inputs and properties (optional) - if no search string insert - this function will
681     // get all the instances of the component (in service only VF instances)
682     public getComponentInstancesFilteredByInputsAndProperties = (searchText?:string):ng.IPromise<Array<ComponentInstance>> => {
683
684         let deferred = this.$q.defer();
685         let onSuccess = (response:Array<ComponentInstance>):void => {
686             deferred.resolve(response);
687         };
688         let onFailed = (error:any):void => {
689             deferred.reject(error);
690         };
691         this.componentService.getComponentInstancesFilteredByInputsAndProperties(this.uniqueId, searchText).then(onSuccess, onFailed);
692         return deferred.promise;
693     };
694
695
696     // get inputs for instance - Pagination function
697     public getComponentInputs = ():ng.IPromise<Array<InputModel>> => {
698
699         let deferred = this.$q.defer();
700         let onSuccess = (inputsRes:Array<InputModel>):void => {
701             this.inputs = inputsRes;
702             deferred.resolve(inputsRes);
703         };
704         let onFailed = (error:any):void => {
705             deferred.reject(error);
706         };
707         this.componentService.getComponentInputs(this.uniqueId).then(onSuccess, onFailed);
708         return deferred.promise;
709     };
710
711
712     // get inputs instance - Pagination function
713     public getComponentInstanceInputs = (componentInstanceId:string, originComponentUid:string):ng.IPromise<Array<InputModel>> => {
714
715         let deferred = this.$q.defer();
716         let onSuccess = (response:Array<InputModel>):void => {
717             deferred.resolve(response);
718         };
719         let onFailed = (error:any):void => {
720             deferred.reject(error);
721         };
722         this.componentService.getComponentInstanceInputs(this.uniqueId, componentInstanceId, originComponentUid).then(onSuccess, onFailed);
723         return deferred.promise;
724     };
725
726     // get inputs inatnce - Pagination function
727     public getComponentInstanceInputProperties = (componentInstanceId:string, inputId:string):ng.IPromise<Array<PropertyModel>> => {
728
729         let deferred = this.$q.defer();
730         let onSuccess = (response:Array<PropertyModel>):void => {
731             deferred.resolve(response);
732         };
733         let onFailed = (error:any):void => {
734             deferred.reject(error);
735         };
736         this.componentService.getComponentInstanceInputProperties(this.uniqueId, componentInstanceId, inputId).then(onSuccess, onFailed);
737         return deferred.promise;
738     };
739
740     // get inputs inatnce - Pagination function
741     public getComponentInstanceProperties = (componentInstanceId:string):ng.IPromise<Array<PropertyModel>> => {
742
743         let deferred = this.$q.defer();
744         let onSuccess = (response:Array<PropertyModel>):void => {
745             deferred.resolve(response);
746         };
747         let onFailed = (error:any):void => {
748             deferred.reject(error);
749         };
750         this.componentService.getComponentInstanceProperties(this.uniqueId, componentInstanceId).then(onSuccess, onFailed);
751         return deferred.promise;
752     };
753
754
755     public updateGroupMetadata = (module:Module):ng.IPromise<Module> => {
756
757         let deferred = this.$q.defer();
758
759         let onSuccess = (updatedModule:Module):void => {
760             let groupIndex:number = _.indexOf(this.groups, _.find(this.groups, (module:Module) => {
761                 return module.uniqueId === updatedModule.uniqueId;
762             }));
763
764             if (groupIndex !== -1) {
765                 this.groups[groupIndex] = updatedModule;
766             }
767             deferred.resolve(updatedModule);
768         };
769         let onFailed = (error:any):void => {
770             deferred.reject(error);
771         };
772
773         this.componentService.updateGroupMetadata(this.uniqueId, module).then(onSuccess, onFailed);
774
775         return deferred.promise;
776     };
777
778     //------------------------------------------ Help Functions ----------------------------------------------------------------//
779
780     public isProduct = ():boolean => {
781         return this instanceof Product;
782     };
783
784     public isService = ():boolean => {
785         return this instanceof Service;
786     };
787
788     public isResource = ():boolean => {
789         return this instanceof Resource;
790     };
791
792     public getComponentSubType = ():string => {
793         return this.componentType;
794     };
795
796     public isAlreadyCertified = ():boolean => {
797         return parseInt(this.version) >= 1;
798     };
799
800     public isComplex = ():boolean => {
801         return true;
802     };
803
804     //sort string version value from hash to sorted version (i.e 1.9 before 1.11)
805     private sortVersions = (v1:string, v2:string):number => {
806         let ver1 = v1.split('.');
807         let ver2 = v2.split('.');
808         let diff = parseInt(_.first(ver1)) - parseInt(_.first(ver2));
809         if (!diff) {
810             return parseInt(_.last(ver1)) - parseInt(_.last(ver2));
811         }
812         return diff;
813     };
814
815     public getAllVersionsAsSortedArray = ():Array<any> => {
816         let res = [];
817         if (this.allVersions) {
818             let keys = Object.keys(this.allVersions).sort(this.sortVersions);
819             _.forEach(keys, (key)=> {
820                 res.push({
821                     versionNumber: key,
822                     versionId: this.allVersions[key]
823                 })
824             });
825         }
826         return res;
827     };
828
829     public isLatestVersion = ():boolean => {
830         if (this.allVersions) {
831             return this.version === _.last(Object.keys(this.allVersions).sort(this.sortVersions));
832         } else {
833             return true;
834         }
835
836     };
837
838     public getAdditionalInformation = ():Array<AdditionalInformationModel> => {
839         let additionalInformationObject:any = _.find(this.additionalInformation, (obj:any):boolean => {
840             return obj.parentUniqueId == this.uniqueId;
841         });
842         if (additionalInformationObject) {
843             return additionalInformationObject.parameters;
844         }
845         return [];
846     };
847
848     public handleTags = ():void => {
849         let isContainTag = _.find(this.tags, (tag)=> {
850             return tag === this.name;
851         });
852         if (!isContainTag) {
853             this.tags.push(this.name);
854         }
855     };
856
857     public getArtifactsByType = (artifactGroupType:string):ArtifactGroupModel => {
858         switch (artifactGroupType) {
859             case ArtifactGroupType.DEPLOYMENT:
860                 return this.deploymentArtifacts;
861             case ArtifactGroupType.INFORMATION:
862                 return this.artifacts;
863         }
864     };
865
866     public getStatus = (sdcMenu:IAppMenu):string => {
867         let status:string = sdcMenu.LifeCycleStatuses[this.lifecycleState].text;
868         if (this.lifecycleState == "CERTIFIED" && sdcMenu.DistributionStatuses[this.distributionStatus]) {
869             status = sdcMenu.DistributionStatuses[this.distributionStatus].text;
870         }
871         return status;
872     };
873
874     public abstract setComponentDisplayData():void;
875     public abstract getTypeUrl():string;
876
877     public setComponentMetadata(componentMetadata: ComponentMetadata) {
878         this.abstract = componentMetadata.abstract;
879         this.uniqueId = componentMetadata.uniqueId;
880         this.uuid = componentMetadata.uuid;
881         this.invariantUUID = componentMetadata.invariantUUID;
882         this.contactId = componentMetadata.contactId;
883         this.categories = componentMetadata.categories;
884         this.creatorUserId = componentMetadata.creatorUserId;
885         this.creationDate = componentMetadata.creationDate;
886         this.creatorFullName = componentMetadata.creatorFullName;
887         this.description = componentMetadata.description;
888         this.icon = componentMetadata.icon;
889         this.lastUpdateDate = componentMetadata.lastUpdateDate;
890         this.lastUpdaterUserId = componentMetadata.lastUpdaterUserId;
891         this.lastUpdaterFullName = componentMetadata.lastUpdaterFullName;
892         this.lifecycleState = componentMetadata.lifecycleState;
893         this.name = componentMetadata.name;
894         this.version = componentMetadata.version;
895         this.tags = angular.copy(componentMetadata.tags, this.tags);
896         this.allVersions = componentMetadata.allVersions;
897         this.componentType = componentMetadata.componentType;
898         this.distributionStatus = componentMetadata.distributionStatus;
899         this.highestVersion = componentMetadata.highestVersion;
900         this.vendorName = componentMetadata.vendorName;
901         this.vendorRelease = componentMetadata.vendorRelease;
902         this.derivedList = componentMetadata.derivedList;
903         this.normalizedName = componentMetadata.normalizedName;
904         this.systemName = componentMetadata.systemName;
905         this.projectCode = componentMetadata.projectCode;
906         this.categories = componentMetadata.categories;
907
908     }
909
910     public toJSON = ():any => {
911         this.componentService = undefined;
912         this.filterTerm = undefined;
913         this.iconSprite = undefined;
914         this.mainCategory = undefined;
915         this.subCategory = undefined;
916         this.selectedInstance = undefined;
917         this.showMenu = undefined;
918         this.$q = undefined;
919         this.selectedCategory = undefined;
920         return this;
921     };
922 }
923