You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2021/04/27 23:45:53 UTC

[brooklyn-ui] 02/05: nicer id generation, ensures uniqueness and is customisable

This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-ui.git

commit 9b8c18bb34e69e647c848ff14b3c2a8d203e79c2
Author: Alex Heneveld <al...@cloudsoftcorp.com>
AuthorDate: Tue Apr 27 22:21:19 2021 +0100

    nicer id generation, ensures uniqueness and is customisable
---
 .../app/components/dsl-editor/dsl-editor.js        |  4 +-
 .../providers/blueprint-service.provider.js        | 46 +++++++++++++++++++---
 .../app/components/quick-fix/quick-fix.js          | 17 ++++----
 .../spec-editor/spec-editor.directive.js           |  2 +-
 .../app/components/util/model/issue.model.js       |  1 +
 .../app/views/main/graphical/graphical.state.js    |  2 +-
 6 files changed, 53 insertions(+), 19 deletions(-)

diff --git a/ui-modules/blueprint-composer/app/components/dsl-editor/dsl-editor.js b/ui-modules/blueprint-composer/app/components/dsl-editor/dsl-editor.js
index 63d687a..3b0cd20 100644
--- a/ui-modules/blueprint-composer/app/components/dsl-editor/dsl-editor.js
+++ b/ui-modules/blueprint-composer/app/components/dsl-editor/dsl-editor.js
@@ -364,9 +364,7 @@ export function dslEditorDirective($rootScope, $filter, $log, brUtilsGeneral, bl
             if (brUtilsGeneral.isNonEmpty(state.entityId)) {
                 targetEntity.id = state.entityId;
             } else {
-                targetEntity.id = targetEntity.hasName() ?
-                    targetEntity.name.replace(/\W/g, '-').toLowerCase() :
-                    targetEntity._id;
+                blueprintService.populateId(targetEntity);
             }
         }
 
diff --git a/ui-modules/blueprint-composer/app/components/providers/blueprint-service.provider.js b/ui-modules/blueprint-composer/app/components/providers/blueprint-service.provider.js
index 47e7fa3..1784ed8 100644
--- a/ui-modules/blueprint-composer/app/components/providers/blueprint-service.provider.js
+++ b/ui-modules/blueprint-composer/app/components/providers/blueprint-service.provider.js
@@ -36,14 +36,14 @@ export const DSL_ENTITY_SPEC = '$brooklyn:entitySpec';
 
 export function blueprintServiceProvider() {
     return {
-        $get: ['$log', '$q', '$sce', 'paletteApi', 'iconGenerator', 'dslService',
-            function ($log, $q, $sce, paletteApi, iconGenerator, dslService) {
-            return new BlueprintService($log, $q, $sce, paletteApi, iconGenerator, dslService);
-        }]
+        $get: ['$log', '$q', '$sce', 'paletteApi', 'iconGenerator', 'dslService', 'brBrandInfo',
+            function ($log, $q, $sce, paletteApi, iconGenerator, dslService, brBrandInfo) {
+                return new BlueprintService($log, $q, $sce, paletteApi, iconGenerator, dslService, brBrandInfo);
+            }]
     }
 }
 
-function BlueprintService($log, $q, $sce, paletteApi, iconGenerator, dslService) {
+function BlueprintService($log, $q, $sce, paletteApi, iconGenerator, dslService, brBrandInfo) {
     let blueprint = new Entity();
 
     return {
@@ -72,6 +72,7 @@ function BlueprintService($log, $q, $sce, paletteApi, iconGenerator, dslService)
         addConfigKeyDefinition: addConfigKeyDefinition,
         addParameterDefinition: addParameterDefinition,
         getRelationships: getRelationships,
+        populateId: populateId,
     };
 
     function setBlueprintFromJson(jsonBlueprint) {
@@ -773,4 +774,39 @@ function BlueprintService($log, $q, $sce, paletteApi, iconGenerator, dslService)
         }, relationships);
     }
 
+    function populateId(entity) {
+        if (entity.id) return;
+
+        let defaultSalterFn = (candidateId, index) => candidateId+"-"+index;
+        let uniqueSuffixFn = (candidateId, root, salterFn) => {
+            let matches = {};
+            root.visitWithDescendants(e => {
+                if (e.id && e.id.startsWith(candidateId)) {
+                    matches[e.id] = true;
+                }
+            });
+            if (!matches[candidateId]) return candidateId;
+            let i=2;
+            while (true) {
+                let newCandidateId = (salterFn || defaultSalterFn)(candidateId, i);
+                if (!matches[newCandidateId]) return newCandidateId;
+                i++;
+            }
+        };
+
+        entity.id = (brBrandInfo.blueprintComposerIdGenerator || blueprintComposerIdGenerator)(entity, uniqueSuffixFn);
+    }
+
+    function blueprintComposerIdGenerator(entity, uniqueSuffixFn) {
+        let candidate = entity.hasName()
+            ? entity.name.replace(/\W/g, '-').toLowerCase()
+            : entity.type ? entity.type.replace(/\W/g, '-').toLowerCase()
+            : !entity.parent ? "root"
+            : entity._id;
+        return uniqueSuffixFn(
+                candidate,
+                entity.getApplication() /* unique throughout blueprint */,
+                null /* use default salter */ );
+    }
+
 }
diff --git a/ui-modules/blueprint-composer/app/components/quick-fix/quick-fix.js b/ui-modules/blueprint-composer/app/components/quick-fix/quick-fix.js
index 27f175a..12c09af 100644
--- a/ui-modules/blueprint-composer/app/components/quick-fix/quick-fix.js
+++ b/ui-modules/blueprint-composer/app/components/quick-fix/quick-fix.js
@@ -26,7 +26,8 @@ angular.module(MODULE_NAME, []);
 export default MODULE_NAME;
 
 
-export function computeQuickFixes(allIssues) {
+export function computeQuickFixes(blueprintService, allIssues) {
+    if (!allIssues) allIssues = blueprintService.getAllIssues();
     if (!allIssues) allIssues = {};
     if (!allIssues.errors) allIssues.errors = {};
 
@@ -51,20 +52,20 @@ export function computeQuickFixes(allIssues) {
             }
             v.issues.push(issueO);
 
-            computeQuickFixesForIssue(issue, issue.entity, v.quickFixes)
+            computeQuickFixesForIssue(issue, issue.entity, blueprintService, v.quickFixes)
         });
     });
     return allIssues;
 }
 
-export function computeQuickFixesForIssue(issue, entity, proposalHolder) {
+export function computeQuickFixesForIssue(issue, entity, blueprintService, proposalHolder) {
     let qfs = getQuickFixHintsForIssue(issue, entity);
     (qfs || []).forEach(qf => {
         let qfi = getQuickFixProposer(qf['fix']);
         if (!qfi) {
             console.log("Skipping unknown quick fix", qf);
         } else {
-            qfi.propose(qf, issue, entity, proposalHolder);
+            qfi.propose(qf, issue, entity, blueprintService, proposalHolder);
             // we could offer the fix per-issue, but no need as they can get that by navigating to the entity
             //qfi.propose(issue, issueO.quickFixes);  // issueO from previous method
         }
@@ -74,7 +75,7 @@ export function computeQuickFixesForIssue(issue, entity, proposalHolder) {
 const QUICK_FIX_PROPOSERS = {
     clear_config: {
         // the propose function updates the proposals object
-        propose: (qfdef, issue, entity, proposals) => {
+        propose: (qfdef, issue, entity, blueprintService, proposals) => {
             if (!issue.ref) return;
             if (!proposals) proposals = {};
 
@@ -111,7 +112,7 @@ const QUICK_FIX_PROPOSERS = {
 };
 
 function proposeSetFrom() {
-    return function (qfdef, issue, entity, proposals) {
+    return function (qfdef, issue, entity, blueprintService, proposals) {
         if (!issue.ref) return;
 
         let ckey_exact = qfdef['source-key'];
@@ -217,9 +218,7 @@ function proposeSetFrom() {
                                     ));
                                 }
                             }
-                            if (!sourceNode.entity.id) {
-                                sourceNode.entity.id = sourceNode.entity._id;
-                            }
+                            blueprintService.populateId(sourceNode.entity);
 
                             entity = (entity || issue.entity);
                             entity.addConfig(issue.ref, '$brooklyn:component("' + sourceNode.entity.id + '").config("' + ckey + '")');
diff --git a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
index 1f71e62..a32f222 100644
--- a/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
+++ b/ui-modules/blueprint-composer/app/components/spec-editor/spec-editor.directive.js
@@ -259,7 +259,7 @@ export function specEditorDirective($rootScope, $templateCache, $injector, $sani
                     let issueWithFixes = Object.assign({}, issueCopy, {
                         quickFixes: {},
                     });
-                    computeQuickFixesForIssue(issueCopy, scope.model, issueWithFixes.quickFixes);
+                    computeQuickFixesForIssue(issueCopy, scope.model, blueprintService, issueWithFixes.quickFixes);
                     scope.model.issuesWithFixes.push(issueWithFixes);
                 });
             });
diff --git a/ui-modules/blueprint-composer/app/components/util/model/issue.model.js b/ui-modules/blueprint-composer/app/components/util/model/issue.model.js
index f00bd7d..0d87dd1 100644
--- a/ui-modules/blueprint-composer/app/components/util/model/issue.model.js
+++ b/ui-modules/blueprint-composer/app/components/util/model/issue.model.js
@@ -104,6 +104,7 @@ class Builder {
 
     phase(phase) {
         this.issue.phase = phase;
+        return this;
     }
 
     ref(ref) {
diff --git a/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.js b/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.js
index 16cf7f8..142f1f8 100644
--- a/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.js
+++ b/ui-modules/blueprint-composer/app/views/main/graphical/graphical.state.js
@@ -49,7 +49,7 @@ function graphicalController($scope, $state, $filter, blueprintService, paletteS
     $scope.$watch('blueprint', () => vm.computeIssues(), true);
 
     this.computeIssues = () => {
-        $scope.allIssues = computeQuickFixes(blueprintService.getAllIssues());
+        $scope.allIssues = computeQuickFixes(blueprintService);
     }
     this.onCanvasSelection = (item) => {
         $scope.canvasSelectedItem = item;