0e21f033bedb2fefd8087eceac27c54e733e1dd1
[sdc.git] /
1 import {Requirement, CompositionCiLinkBase, ComponentInstance, CapabilitiesGroup, RequirementsGroup, MatchReqToCapability, MatchBase,
2     MatchReqToReq,CompositionCiNodeBase, Component, Capability} from "app/models";
3 /**
4  * Created by obarda on 1/1/2017.
5  */
6
7 export class MatchCapabilitiesRequirementsUtils {
8
9     constructor() {
10     }
11
12     public static linkable(requirement1:Requirement, requirement2:Requirement, vlCapability:Capability):boolean {
13         return MatchCapabilitiesRequirementsUtils.isMatch(requirement1, vlCapability) && MatchCapabilitiesRequirementsUtils.isMatch(requirement2, vlCapability);
14     };
15
16
17     /**
18      * Shows + icon in corner of each node passed in
19      * @param filteredNodesData
20      * @param cy
21      */
22     public highlightMatchingComponents(filteredNodesData, cy:Cy.Instance) {
23         _.each(filteredNodesData, (data:any) => {
24             let node = cy.getElementById(data.id);
25             cy.emit('showhandle', [node]);
26         });
27     }
28
29     /**
30      * Adds opacity to each node that cannot be linked to hovered node
31      * @param filteredNodesData
32      * @param nodesData
33      * @param cy
34      * @param hoveredNodeData
35      */
36     public fadeNonMachingComponents(filteredNodesData, nodesData, cy:Cy.Instance, hoveredNodeData?) {
37         let fadeNodes = _.xorWith(nodesData, filteredNodesData, (node1, node2) => {
38             return node1.id === node2.id;
39         });
40         if (hoveredNodeData) {
41             _.remove(fadeNodes, hoveredNodeData);
42         }
43         cy.batch(()=> {
44             _.each(fadeNodes, (node) => {
45                 cy.getElementById(node.id).style({'background-image-opacity': 0.4});
46             });
47         })
48     }
49
50     /**
51      * Resets all nodes to regular opacity
52      * @param cy
53      */
54     public resetFadedNodes(cy:Cy.Instance) {
55         cy.batch(()=> {
56             cy.nodes().style({'background-image-opacity': 1});
57         })
58     }
59
60     // -------------------------------------------ALL FUNCTIONS NEED REFACTORING---------------------------------------------------------------//
61
62     private static requirementFulfilled(fromNodeId:string, requirement:any, links:Array<CompositionCiLinkBase>):boolean {
63         return _.some(links, {
64             'relation': {
65                 'fromNode': fromNodeId,
66                 'relationships': [{
67                     'requirementOwnerId': requirement.ownerId,
68                     'requirement': requirement.name,
69                     'relationship': {
70                         'type': requirement.relationship
71                     }
72                 }
73                 ]
74             }
75         });
76     };
77
78     private static isMatch(requirement:Requirement, capability:Capability):boolean {
79         if (capability.type === requirement.capability) {
80             if (requirement.node) {
81                 if (_.includes(capability.capabilitySources, requirement.node)) {
82                     return true;
83                 }
84             } else {
85                 return true;
86             }
87         }
88         return false;
89     };
90
91     private getFromToMatches(requirements1:RequirementsGroup,
92                              requirements2:RequirementsGroup,
93                              capabilities:CapabilitiesGroup,
94                              links:Array<CompositionCiLinkBase>,
95                              fromId:string,
96                              toId:string,
97                              vlCapability?:Capability):Array<MatchBase> {
98         let matches:Array<MatchBase> = new Array<MatchBase>();
99         _.forEach(requirements1, (requirementValue:Array<Requirement>, key) => {
100             _.forEach(requirementValue, (requirement:Requirement) => {
101                 if (requirement.name !== "dependency" && !MatchCapabilitiesRequirementsUtils.requirementFulfilled(fromId, requirement, links)) {
102                     _.forEach(capabilities, (capabilityValue:Array<Capability>, key) => {
103                         _.forEach(capabilityValue, (capability:Capability) => {
104                             if (MatchCapabilitiesRequirementsUtils.isMatch(requirement, capability)) {
105                                 let match:MatchReqToCapability = new MatchReqToCapability(requirement, capability, true, fromId, toId);
106                                 matches.push(match);
107                             }
108                         });
109                     });
110                     if (vlCapability) {
111                         _.forEach(requirements2, (requirement2Value:Array<Requirement>, key) => {
112                             _.forEach(requirement2Value, (requirement2:Requirement) => {
113                                 if (!MatchCapabilitiesRequirementsUtils.requirementFulfilled(toId, requirement2, links) && MatchCapabilitiesRequirementsUtils.linkable(requirement, requirement2, vlCapability)) {
114                                     let match:MatchReqToReq = new MatchReqToReq(requirement, requirement2, true, fromId, toId);
115                                     matches.push(match);
116                                 }
117                             });
118                         });
119                     }
120                 }
121             });
122         });
123         return matches;
124     }
125
126     private getToFromMatches(requirements:RequirementsGroup, capabilities:CapabilitiesGroup, links:Array<CompositionCiLinkBase>, fromId:string, toId:string):Array<MatchReqToCapability> {
127         let matches:Array<MatchReqToCapability> = [];
128         _.forEach(requirements, (requirementValue:Array<Requirement>, key) => {
129             _.forEach(requirementValue, (requirement:Requirement) => {
130                 if (requirement.name !== "dependency" && !MatchCapabilitiesRequirementsUtils.requirementFulfilled(toId, requirement, links)) {
131                     _.forEach(capabilities, (capabilityValue:Array<Capability>, key) => {
132                         _.forEach(capabilityValue, (capability:Capability) => {
133                             if (MatchCapabilitiesRequirementsUtils.isMatch(requirement, capability)) {
134                                 let match:MatchReqToCapability = new MatchReqToCapability(requirement, capability, false, toId, fromId);
135                                 matches.push(match);
136                             }
137                         });
138                     });
139                 }
140             });
141         });
142         return matches;
143     }
144
145     public getMatchedRequirementsCapabilities(fromComponentInstance:ComponentInstance,
146                                               toComponentInstance:ComponentInstance,
147                                               links:Array<CompositionCiLinkBase>,
148                                               vl?:Component):Array<MatchBase> {//TODO allow for VL array
149         let linkCapability;
150         if (vl) {
151             let linkCapabilities:Array<Capability> = vl.capabilities.findValueByKey('linkable');
152             if (linkCapabilities) {
153                 linkCapability = linkCapabilities[0];
154             }
155         }
156         let fromToMatches:Array<MatchBase> = this.getFromToMatches(fromComponentInstance.requirements,
157             toComponentInstance.requirements,
158             toComponentInstance.capabilities,
159             links,
160             fromComponentInstance.uniqueId,
161             toComponentInstance.uniqueId,
162             linkCapability);
163         let toFromMatches:Array<MatchReqToCapability> = this.getToFromMatches(toComponentInstance.requirements,
164             fromComponentInstance.capabilities,
165             links,
166             fromComponentInstance.uniqueId,
167             toComponentInstance.uniqueId);
168
169         return fromToMatches.concat(toFromMatches);
170     }
171
172
173     /**
174      * Step I: Check if capabilities of component match requirements of nodeDataArray
175      * 1. Get component capabilities and loop on each capability
176      * 2. Inside the loop, perform another loop on all nodeDataArray, and fetch the requirements for each one
177      * 3. Loop on the requirements, and verify match (see in code the rules)
178      *
179      * Step II: Check if requirements of component match capabilities of nodeDataArray
180      * 1. Get component requirements and loop on each requirement
181      * 2.
182      *
183      * @param component         - this is the hovered resource of the left panel of composition screen
184      * @param nodeDataArray     - Array of resource instances that are on the canvas
185      * @param links             -getMatchedRequirementsCapabilities
186      * @param vl                -
187      * @returns {any[]|T[]}
188      */
189     public findByMatchingCapabilitiesToRequirements(component:Component,
190                                                     nodeDataArray:Array<CompositionCiNodeBase>,
191                                                     links:Array<CompositionCiLinkBase>,
192                                                     vl?:Component):Array<any> {//TODO allow for VL array
193         let res = [];
194
195         // STEP I
196         {
197             let capabilities:any = component.capabilities;
198             _.forEach(capabilities, (capabilityValue:Array<any>, capabilityKey)=> {
199                 _.forEach(capabilityValue, (capability)=> {
200                     _.forEach(nodeDataArray, (node:CompositionCiNodeBase)=> {
201                         if (node && node.componentInstance) {
202                             let requirements:any = node.componentInstance.requirements;
203                             let fromNodeId:string = node.componentInstance.uniqueId;
204                             _.forEach(requirements, (requirementValue:Array<any>, requirementKey)=> {
205                                 _.forEach(requirementValue, (requirement)=> {
206                                     if (requirement.name !== "dependency" && MatchCapabilitiesRequirementsUtils.isMatch(requirement, capability)
207                                         && !MatchCapabilitiesRequirementsUtils.requirementFulfilled(fromNodeId, requirement, links)) {
208                                         res.push(node);
209                                     }
210                                 });
211                             });
212                         }
213                     });
214                 });
215             });
216         }
217
218         // STEP II
219         {
220             let requirements:any = component.requirements;
221             let fromNodeId:string = component.uniqueId;
222             let linkCapability:Array<Capability> = vl ? vl.capabilities.findValueByKey('linkable') : undefined;
223
224             _.forEach(requirements, (requirementValue:Array<any>, requirementKey)=> {
225                 _.forEach(requirementValue, (requirement)=> {
226                     if (requirement.name !== "dependency" && !MatchCapabilitiesRequirementsUtils.requirementFulfilled(fromNodeId, requirement, links)) {
227                         _.forEach(nodeDataArray, (node:any)=> {
228                             if (node && node.componentInstance && node.category !== 'groupCp') {
229                                 let capabilities:any = node.componentInstance.capabilities;
230                                 _.forEach(capabilities, (capabilityValue:Array<any>, capabilityKey)=> {
231                                     _.forEach(capabilityValue, (capability)=> {
232                                         if (MatchCapabilitiesRequirementsUtils.isMatch(requirement, capability)) {
233                                             res.push(node);
234                                         }
235                                     });
236                                 });
237                                 if (linkCapability) {
238                                     let linkRequirements = node.componentInstance.requirements;
239                                     _.forEach(linkRequirements, (value:Array<any>, key)=> {
240                                         _.forEach(value, (linkRequirement)=> {
241                                             if (!MatchCapabilitiesRequirementsUtils.requirementFulfilled(node.componentInstance.uniqueId, linkRequirement, links)
242                                                 && MatchCapabilitiesRequirementsUtils.linkable(requirement, linkRequirement, linkCapability[0])) {
243                                                 res.push(node);
244                                             }
245                                         });
246                                     });
247                                 }
248                             }
249                         });
250                     }
251                 });
252             });
253         }
254
255         return _.uniq(res);
256     };
257 }
258
259 MatchCapabilitiesRequirementsUtils.$inject = [];