2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 import { Injectable } from '@angular/core';
22 CapabilitiesGroup, Capability, ComponentInstance, CompositionCiLinkBase,
23 CompositionCiNodeBase, Match, Requirement, RequirementsGroup
25 import * as _ from 'lodash';
28 * Created by obarda on 1/1/2017.
31 export class MatchCapabilitiesRequirementsUtils {
34 * Shows + icon in corner of each node passed in
35 * @param filteredNodesData
38 public highlightMatchingComponents(filteredNodesData, cy: Cy.Instance) {
39 _.each(filteredNodesData, (data: any) => {
40 const node = cy.getElementById(data.id);
41 cy.emit('showhandle', [node]);
46 * Adds opacity to each node that cannot be linked to hovered node
47 * @param filteredNodesData
50 * @param hoveredNodeData
52 public fadeNonMachingComponents(filteredNodesData, nodesData, cy: Cy.Instance, hoveredNodeData?) {
53 const fadeNodes = _.xorWith(nodesData, filteredNodesData, (node1, node2) => {
54 return node1.id === node2.id;
56 if (hoveredNodeData) {
57 _.remove(fadeNodes, hoveredNodeData);
60 _.each(fadeNodes, (node) => {
61 cy.getElementById(node.id).style({'background-image-opacity': 0.4});
67 * Resets all nodes to regular opacity
70 public resetFadedNodes(cy: Cy.Instance) {
72 cy.nodes().style({'background-image-opacity': 1});
76 public getMatchedRequirementsCapabilities(fromComponentInstance: ComponentInstance,
77 toComponentInstance: ComponentInstance,
78 links: CompositionCiLinkBase[]): Match[] {
79 const fromToMatches: Match[] = this.getMatches(fromComponentInstance.requirements,
80 toComponentInstance.capabilities,
82 fromComponentInstance.uniqueId,
83 toComponentInstance.uniqueId, true);
84 const toFromMatches: Match[] = this.getMatches(toComponentInstance.requirements,
85 fromComponentInstance.capabilities,
87 toComponentInstance.uniqueId,
88 fromComponentInstance.uniqueId, false);
90 return fromToMatches.concat(toFromMatches);
93 /***** REFACTORED FUNCTIONS START HERE *****/
95 public getMatches(requirements: RequirementsGroup, capabilities: CapabilitiesGroup, links: CompositionCiLinkBase[],
96 fromId: string, toId: string, isFromTo: boolean): Match[] {
97 const matches: Match[] = [];
98 const unfulfilledReqs = this.getUnfulfilledRequirements(fromId, requirements, links);
99 _.forEach(unfulfilledReqs, (req) => {
100 _.forEach(_.flatten(_.values(capabilities)), (capability: Capability) => {
101 if (this.isMatch(req, capability)) {
103 matches.push(new Match(req, capability, isFromTo, fromId, toId));
105 matches.push(new Match(req, capability, isFromTo, toId, fromId));
113 public getUnfulfilledRequirements = (fromNodeId: string, requirements: RequirementsGroup, links: CompositionCiLinkBase[]): Requirement[] => {
114 const requirementArray: Requirement[] = [];
115 _.forEach(_.flatten(_.values(requirements)), (requirement: Requirement) => {
116 const reqFulfilled = this.isRequirementFulfilled(fromNodeId, requirement, links);
117 if (requirement.name !== 'dependency' && requirement.parentName !== 'dependency' && !reqFulfilled) {
118 requirementArray.push(requirement);
121 return requirementArray;
125 * Returns true if there is a match between the capabilities and requirements that are passed in
126 * @param requirements
127 * @param capabilities
130 public containsMatch = (requirements: Requirement[], capabilities: CapabilitiesGroup): boolean => {
131 return _.some(requirements, (req: Requirement) => {
132 return _.some(_.flatten(_.values(capabilities)), (capability: Capability) => {
133 return this.isMatch(req, capability);
138 public hasUnfulfilledRequirementContainingMatch = (node: CompositionCiNodeBase, componentRequirements: Requirement[], capabilities: CapabilitiesGroup, links: CompositionCiLinkBase[]) => {
139 if (node && node.componentInstance) {
140 // Check if node has unfulfilled requirement that can be filled by component (#2)
141 const nodeRequirements: Requirement[] = this.getUnfulfilledRequirements(node.componentInstance.uniqueId, node.componentInstance.requirements, links);
142 if (!nodeRequirements.length) {
145 if (this.containsMatch(nodeRequirements, capabilities)) {
152 * Returns array of nodes that can connect to the component.
153 * In order to connect, one of the following conditions must be met:
154 * 1. component has an unfulfilled requirement that matches a node's capabilities
155 * 2. node has an unfulfilled requirement that matches the component's capabilities
156 * 3. vl is passed in which has the capability to fulfill requirement from component and requirement on node.
158 public findMatchingNodesToComponentInstance(componentInstance: ComponentInstance, nodeDataArray: CompositionCiNodeBase[], links: CompositionCiLinkBase[]): any[] {
159 return _.filter(nodeDataArray, (node: CompositionCiNodeBase) => {
160 const matchedRequirementsCapabilities = this.getMatchedRequirementsCapabilities(node.componentInstance, componentInstance, links);
161 return matchedRequirementsCapabilities && matchedRequirementsCapabilities.length > 0;
165 public isMatch(requirement: Requirement, capability: Capability): boolean {
166 if (capability.type === requirement.capability) {
167 if (requirement.node) {
168 if (_.includes(capability.capabilitySources, requirement.node)) {
178 private isRequirementFulfilled(fromNodeId: string, requirement: any, links: CompositionCiLinkBase[]): boolean {
179 return _.some(links, {
181 fromNode: fromNodeId,
184 requirementOwnerId: requirement.ownerId,
185 requirement: requirement.name,
187 type: requirement.relationship