added ansible server functionality
[appc/cdt.git] / src / app / shared / services / mapping-editor.service.ts
1 /*
2 ============LICENSE_START==========================================
3 ===================================================================
4 Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
5 ===================================================================
6
7 Unless otherwise specified, all software contained herein is licensed
8 under the Apache License, Version 2.0 (the License);
9 you may not use this software except in compliance with the License.
10 You may obtain a copy of the License at
11
12     http://www.apache.org/licenses/LICENSE-2.0
13
14 Unless required by applicable law or agreed to in writing, software
15 distributed under the License is distributed on an "AS IS" BASIS,
16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 See the License for the specific language governing permissions and
18 limitations under the License.
19
20 ============LICENSE_END============================================
21 */
22
23
24 import {Injectable} from '@angular/core';
25 import {ConfigMapping} from '../models/index';
26 import {Observable} from 'rxjs/Observable';
27 import {Observer} from 'rxjs/Observer';
28 import 'rxjs/add/operator/share';
29
30
31 @Injectable()
32 export class MappingEditorService {
33
34     editor: any;
35     session: any;
36     editorContent: string;
37     configMappings: Array<ConfigMapping> = [];
38     paramContent: string = '{}';
39
40     KEY_EXPRESSION: string = '\\${\\(.+?\\)}';//new RegExp('${.+?}'); // \${.+?}
41     KEY_START: string = '${(';
42     KEY_MID: string = ')=(';
43     KEY_END: string = ')}';
44     KEY_START_LENGTH: number = 3;
45     KEY_MID_LENGTH: number = 3;
46     KEY_END_LENGTH: number = 2;
47     SYNC_T_KEY_EXPRESSION: string = '\\${.+?\\}';
48     T_KEY_EXPRESSION: string = '\\${.+?}';//new RegExp('${.+?}'); // \${.+?}
49     T_KEY_START: string = '${';
50     T_KEY_END: string = '}';
51     T_KEY_START_LENGTH: number = 2;
52     T_KEY_END_LENGTH: number = 1;
53     checkSpecialCharsReg: RegExp = /[^\w\s-_]/gi;
54     public paramData = [];
55     public referenceNameObjects: any;
56     prmName: string = '';
57     prmValue: string = '';
58     navChange$: Observable<any>;
59     public fromScreen: any = '';
60     public storedTemplateData: any;
61     public storedTemplateMappingData: any;
62     public fileType: any;
63     public hasErrorCode: boolean = false;
64     public appDataObject: any;
65     public downloadDataObject: any;
66     public markedarr: any;
67     public tempAllData: any;
68     public latestAction: any;
69     public selectedWord: any;
70     identifier: any;
71     private selectedVNFCType;
72     private _navItem = {};
73     private _observer: Observer<any>;
74     private referenceList = [];
75     newObject: any
76     constructor() {
77         this.navChange$ = new Observable(observer =>
78             this._observer = observer).share();
79     }
80
81     setSelectedWord(selectedWord: any) {
82         this.selectedWord = selectedWord;
83     }
84
85     getSelectedWord() {
86         return this.selectedWord;
87     }
88
89     changeNav(object) {
90         this._navItem = object;
91         this.referenceNameObjects = object;
92     }
93
94     changeNavAppData(object) {
95         this._navItem = object;
96         this.appDataObject = object;
97     }
98
99     changeNavDownloadData(object) {
100         this._navItem = object;
101         this.downloadDataObject = object;
102     }
103
104     saveLatestAction(data) {
105         this.latestAction = data;
106     }
107     selectedObj(data) {
108         this.newObject = data;
109         
110     }
111     saveLatestIdentifier(identifier) {
112         this.identifier = identifier;
113     }
114
115     setSelectedVNFCType(vnfcType) {
116         this.selectedVNFCType = vnfcType;
117     }
118
119     getSelectedVNFCType() {
120         return this.selectedVNFCType;
121     }
122
123     public getParamContent() {
124         return this.paramContent;
125     }
126
127     saveTempAllData(data) {
128         this.tempAllData = data;
129     }
130
131     navItem() {
132         return this._navItem;
133     }
134
135     public setParamContent(paramContent: string): void {
136         this.paramContent = paramContent;
137         
138     }
139
140     public initialise(editor: any, editorContent: string): void {
141         this.editor = editor;
142         this.editor.session = editor.session;
143         this.editor.selection.session.$backMarkers = {};
144         this.editorContent = editorContent;
145         this.editor.$blockScrolling = Infinity;
146         this.editor.$blockSelectEnabled = false;
147         //this.initialiseCommands(modal);
148         //this.editor.setValue(this.editorContent);
149         this.refreshEditor();
150     }
151
152
153     public initialiseCommands(modal): void {
154         this.editor.commands.addCommand({
155             name: 'keyCompletionCommand',
156             bindKey: {win: 'Ctrl-s', mac: 'Command-s'},
157             exec: (editor: any) => {
158                 this.handlekeyCompletion();
159             }
160         });
161
162         this.editor.commands.addCommand({
163             name: 'autoAnnotateCommand',
164             bindKey: {win: 'Ctrl-2', mac: 'Command-2'},
165             exec: (editor: any) => {
166                 this.autoAnnotateDataForParams();
167             }
168         });
169
170         this.editor.commands.addCommand({
171             name: 'autoAnnotateCommand',
172             bindKey: {win: 'Ctrl-shift-z', mac: 'Command-shift-z'},
173             exec: (editor: any) => {
174                 this.removeTheSelectedMarkers();
175             }
176         });
177     }
178
179     public getStartBeforeAfterSelection(selection: any, beforeCount: number, afterCount: number) {
180         let newSelctionRange: any = JSON.parse(JSON.stringify(selection));
181         if (selection) {
182             let newBeforeColumn: number = selection.start.column - beforeCount;
183             let newAfterColumn: number = selection.end.column + afterCount;
184             newSelctionRange.start.column = newBeforeColumn;
185             newSelctionRange.end.column = newAfterColumn;
186         }
187         return newSelctionRange;
188     }
189
190     public checkToDataAdd(value: string): boolean {
191         let toAdd = false;
192         if (value && (value.startsWith('"') || value.startsWith('>'))
193             && (value.endsWith('"') || value.endsWith('<'))
194             && !value.startsWith('"${')
195         ) {
196             toAdd = true;
197         }
198         return toAdd;
199     }
200
201     public autoAnnotateDataForParams(): boolean {
202         this.paramContent = localStorage['paramsContent'];
203         var mergeStatus: boolean = false;
204         if (this.paramContent) {
205             var paramJson: JSON = JSON.parse(this.paramContent);
206             for (var prop in paramJson) {
207                 let value: string = paramJson[prop];
208                 if (value) {
209                     var occurances = this.editor.findAll(value, { regExp: false });
210                     var ranges = this.editor.getSelection().getAllRanges();
211                     if (ranges && occurances && occurances > 0) {
212
213                         for (var r = 0; r < ranges.length; r++) {
214                             let selectedRange: any = ranges[r];
215                             let selectedWord: string = this.editor.session.getTextRange(selectedRange);
216                             let prefixSuffixselectedWord: string = this.editor.session.getTextRange(this.getStartBeforeAfterSelection(selectedRange, 1, 1));
217                             if (selectedWord && this.checkComments(selectedRange) && this.checkDelimiters(selectedRange) && this.checkApplied(selectedRange)) {
218                                 let replaceWord: any = this.KEY_START + selectedWord + this.KEY_MID + prop + this.KEY_END;
219                                 this.editor.session.replace(selectedRange, replaceWord);
220                                 mergeStatus = true;
221                             }
222                         }
223                     }
224                 }
225             }
226         }
227         return mergeStatus;
228     }
229
230     checkComments(selectedRange: any) {
231         var tempStartColumn = selectedRange.start.column;
232         var result = false;
233         selectedRange.start.column = 0;
234         if (this.editor.session.getTextRange(selectedRange).trim().startsWith('//')) {
235             result = false;
236         } else {
237             result = true;
238         }
239         selectedRange.start.column = tempStartColumn;
240         return result;
241     }
242
243     checkApplied(selectedRange: any) {
244         var tempStartColumn = selectedRange.start.column;
245         for (var i = selectedRange.start.column; i >= 0; i--) {
246             selectedRange.start.column = i;
247             if (this.editor.session.getTextRange(selectedRange).startsWith(this.KEY_START)
248                 || this.editor.session.getTextRange(selectedRange).startsWith(this.T_KEY_START)) {
249                 selectedRange.start.column = tempStartColumn;
250                 return false;
251             } else if (this.editor.session.getTextRange(selectedRange).startsWith(this.KEY_END)
252                 || this.editor.session.getTextRange(selectedRange).startsWith(this.T_KEY_END)) {
253                 selectedRange.start.column = tempStartColumn;
254                 return true;
255             }
256
257         }
258         selectedRange.start.column = tempStartColumn;
259         return true;
260
261     }
262
263     checkDelimiters(selectedRange: any) {
264         let result = false;
265         let actualText = this.editor.session.getTextRange(selectedRange);
266         var tempStartColumn = selectedRange.start.column;
267         var tempEndcolumn = selectedRange.end.column;
268
269         selectedRange.start.column = selectedRange.start.column - 1;
270         selectedRange.end.column = selectedRange.end.column + 1;
271         if ((this.editor.session.getTextRange(selectedRange).startsWith(' ')
272             || this.editor.session.getTextRange(selectedRange).startsWith('"')
273             || this.editor.session.getTextRange(selectedRange).startsWith('>'))
274             && (this.editor.session.getTextRange(selectedRange).endsWith(' ')
275                 || this.editor.session.getTextRange(selectedRange).endsWith('"')
276                 || this.editor.session.getTextRange(selectedRange).endsWith(',')
277                 || this.editor.session.getTextRange(selectedRange).endsWith(actualText)
278                 || this.editor.session.getTextRange(selectedRange).endsWith('<'))) {
279             result = true;
280         }
281
282         //Ignore the JSON key names(which ends with :)
283         selectedRange.end.column = selectedRange.end.column + 1;
284         if (this.editor.session.getTextRange(selectedRange).endsWith('":')) {
285             result = false;
286         } else {
287             selectedRange.end.column = selectedRange.end.column + 1;
288             if (this.editor.session.getTextRange(selectedRange).endsWith('" :')) {
289                 result = false;
290             }
291         }
292         selectedRange.start.column = tempStartColumn;
293         selectedRange.end.column = tempEndcolumn;
294         return result;
295     }
296
297     checkAppliedForNamesOnly(selectedRange: any) {
298         var tempStartColumn = selectedRange.start.column;
299         for (var i = selectedRange.start.column; i >= 0; i--) {
300             selectedRange.start.column = i;
301             if (this.editor.session.getTextRange(selectedRange).startsWith(this.KEY_START)) {
302                 selectedRange.start.column = tempStartColumn;
303                 return false;
304             } else if (this.editor.session.getTextRange(selectedRange).startsWith(this.KEY_END)) {
305                 selectedRange.start.column = tempStartColumn;
306                 return true;
307             }
308
309         }
310         selectedRange.start.column = tempStartColumn;
311         return true;
312
313     }
314
315     checkToDataAddForJson(value: string): boolean {
316         let toAdd = false;
317         if (value && !value.startsWith('"${') && !value.startsWith('(')) {
318             toAdd = true;
319         }
320         return toAdd;
321     }
322
323     public autoAnnotateTemplateForParam(): void {
324         var occurances = this.editor.findAll(this.T_KEY_EXPRESSION, { regExp: true });
325         var ranges = this.editor.getSelection().getAllRanges();
326         if (ranges) {
327             for (var r = 0; r < ranges.length; r++) {
328                 let selectedRange: any = ranges[r];
329                 let selectedWord: string = this.editor.session.getTextRange(selectedRange);
330                 if (selectedWord) {
331                     let key: string = selectedWord.substring(this.T_KEY_START_LENGTH, selectedWord.lastIndexOf(this.T_KEY_END));
332                     let value: string = this.getValueForKey(key);
333                     let replaceWord: any = this.KEY_START + value + this.KEY_MID + key + this.KEY_END;
334                     this.editor.session.replace(selectedRange, replaceWord);
335                 }
336             }
337         }
338
339     }
340
341     /*
342      * Once you save command is triggered, We need to re populate all the params, which may be defined new
343      * and auto populate the key if any of the values maps to the keys
344      */
345     public handlekeyCompletion(): void {
346         this.refreshEditor();
347     }
348
349     public checkMethodCall(modal): void {
350     //this.handleAnnotation(modal)
351     }
352
353     public refreshEditor(): void {
354         if (this.editor) {
355
356             var occurances = this.editor.findAll(this.KEY_EXPRESSION, {regExp: true});
357             var ranges = this.editor.getSelection().getAllRanges();
358             if (ranges) {
359                 this.refreshParams(ranges);
360             }
361
362             occurances = this.editor.findAll(this.KEY_EXPRESSION, {regExp: true});
363             ranges = this.editor.getSelection().getAllRanges();
364             if (ranges) {
365                 this.populateMissingKeys(ranges);
366             }
367             this.refreshMarker();
368         }
369         
370     }
371
372     replaceNamesWithBlankValues() {
373         var occurances = this.editor.findAll(this.SYNC_T_KEY_EXPRESSION, { regExp: true });
374         var ranges = this.editor.getSelection().getAllRanges();
375         if (occurances > 0) {
376             if (ranges) {
377                 for (var r = 0; r < ranges.length; r++) {
378                     let selectedRange: any = ranges[r];
379                     // console.log("Selected range == " + selectedRange)
380                     let selectedWord: string = this.editor.session.getTextRange(selectedRange);
381                     let specialKeys = (selectedWord.substring(2, selectedWord.length - 1)).match(this.checkSpecialCharsReg);
382                     // console.log("Selected word == " + selectedWord.length)
383                     //if (!selectedWord.startsWith('<') || !selectedWord.startsWith('{')) {
384                     if (specialKeys && specialKeys.length) {
385                     }
386
387                     else if (selectedWord && this.checkAppliedForNamesOnly(selectedRange) && !specialKeys && this.checkComments(selectedRange)) {
388                         let replaceWord: any = this.KEY_START + '' + this.KEY_MID + selectedWord.substring(2, selectedWord.length - 1) + this.KEY_END;
389                         this.editor.session.replace(selectedRange, replaceWord);
390                     }
391                     // }
392                 }
393             }
394         }
395     }
396
397     public refreshParams(ranges: any): void {
398         var paramData = [];
399         if (this.paramContent === undefined) this.paramContent = '{}';
400         if (this.editor && ranges) {
401             var paramJson: JSON = JSON.parse(this.paramContent);
402             this.hasErrorCode = false;
403             for (var r = 0; r < ranges.length; r++) {
404                 let keyValue: string = this.editor.session.getTextRange(ranges[r]);
405                 //console.log("keyValues==="+keyValue)
406                 if (this.checkComments(ranges[r]) && keyValue && keyValue.startsWith(this.KEY_START) && keyValue.endsWith(this.KEY_END) && keyValue.includes(this.KEY_MID)) {
407                     let key: string = keyValue.substring(keyValue.indexOf(this.KEY_MID) + this.KEY_MID_LENGTH, keyValue.indexOf(this.KEY_END));
408                     let value: string = keyValue.substring(this.KEY_START_LENGTH, keyValue.indexOf(this.KEY_MID));
409                     let specialKeys = key.match(this.checkSpecialCharsReg);
410                     if (specialKeys && specialKeys.length) {
411                       
412                     } else {
413                         if (this.fromScreen === 'TemplateScreen') {
414                             if (key) {
415                                 paramJson[key] = value;
416                                 var obj: any = { 'paramName': '', 'paramValue': '' };
417                                 obj.paramName = key;
418                                 obj.paramValue = value;
419                                 paramData.push(obj);
420                             }
421
422                         }
423                         else if (this.fromScreen === 'MappingScreen') {
424                             if (key) {
425                                 paramJson[key] = value;
426                                 var obj: any = { 'paramName': '', 'paramValue': '' };
427                                 obj.paramName = key;
428                                 obj.paramValue = value;
429
430                                 paramData.push(obj);
431
432                             }
433                         }
434                     }
435                 }
436             }
437             this.paramData = paramData;
438             this.paramContent = JSON.stringify(paramJson);
439
440         }
441     }
442
443     public populateMissingKeys(ranges: any): void {
444         if (this.editor && ranges) {
445             // Populate missing keys
446             for (var r = 0; r < ranges.length; r++) {
447                 let keyValue: string = this.editor.session.getTextRange(ranges[r]);
448                 if (keyValue && keyValue.startsWith(this.KEY_START) && keyValue.endsWith(this.KEY_END) && keyValue.includes(this.KEY_MID)) {
449                     let key: string = keyValue.substring(keyValue.indexOf(this.KEY_MID) + this.KEY_MID_LENGTH, keyValue.indexOf(this.KEY_END));
450                     let value: string = keyValue.substring(this.KEY_START_LENGTH, keyValue.indexOf(this.KEY_MID));
451                     if (!key && value) {
452                         let keyFromStore = '';
453                         if (keyFromStore) {
454                             let replaceWord: string = '${(' + value + ')=(' + keyFromStore + ')}';
455                             this.editor.session.replace(ranges[r], replaceWord);
456                         }
457                     }
458                 }
459             }
460
461         }
462     }
463
464     public refreshMarker(): void {
465         if (this.editor) {
466             this.hasErrorCode = false;
467             var occurances = this.editor.findAll(this.KEY_EXPRESSION, { regExp: true });
468             var ranges = this.editor.getSelection().getAllRanges();
469             var keysList = [];
470             // Populate missing keys
471             for (var r = 0; r < ranges.length; r++) {
472                 let keyValue: string = this.editor.session.getTextRange(ranges[r]);
473                 if (this.checkComments(ranges[r]) && keyValue && keyValue.startsWith(this.KEY_START) && keyValue.endsWith(this.KEY_END) && keyValue.includes(this.KEY_MID)) {
474                     let key: string = keyValue.substring(keyValue.indexOf(this.KEY_MID) + this.KEY_MID_LENGTH, keyValue.indexOf(this.KEY_END));
475                     let value: string = keyValue.substring(this.KEY_START_LENGTH, keyValue.indexOf(this.KEY_MID));
476                     let specialKeys = key.match(this.checkSpecialCharsReg);
477                     if (specialKeys && specialKeys.length) {
478                         this.hasErrorCode = true;
479                         break;
480                     }
481                     if (!key && value) {
482                         this.editor.session.addMarker(ranges[r], 'warningMarker', 'text');
483                     } else {
484                         if (keysList.indexOf(key) > -1) {
485                             this.editor.session.addMarker(ranges[r], 'warningMarker', 'text');
486                         } else {
487                             this.editor.session.addMarker(ranges[r], 'keyedMarker', 'text');
488                         }
489                         keysList.push(key);
490                     }
491                     // Refresh Markers
492                 }
493             }
494             this.editor.clearSelection();
495             this.editor.exitMultiSelectMode();
496         }
497     }
498
499     public getKeysForValues(value: string): string {
500         var key: string = undefined;
501         if (this.paramContent && value) {
502             var paramJson: JSON = JSON.parse(this.paramContent);
503             for (var prop in paramJson) {
504                 if (value === paramJson[prop]) {
505                     key = prop;
506                 }
507             }
508         }
509         return key;
510     }
511
512     public getValueForKey(key: string): string {
513         var value: string = undefined;
514         if (key) {
515             var paramJson: JSON = JSON.parse(this.paramContent);
516             if (paramJson) {
517                 value = paramJson[key];
518             }
519         }
520         return value;
521     }
522
523     public generateTemplate(templateEditor: any): void {
524         if (templateEditor) {
525             templateEditor.setValue(this.editor.getValue());
526             var occurances = templateEditor.findAll(this.KEY_EXPRESSION, { regExp: true });
527             var ranges = templateEditor.getSelection().getAllRanges();
528             if (ranges) {
529                 for (var r = 0; r < ranges.length; r++) {
530                     let keyValue: string = templateEditor.session.getTextRange(ranges[r]);
531                     if (keyValue && keyValue.startsWith(this.KEY_START) && keyValue.endsWith(this.KEY_END) && keyValue.includes(this.KEY_MID)) {
532                         let key: string = keyValue.substring(keyValue.indexOf(this.KEY_MID) + this.KEY_MID_LENGTH, keyValue.indexOf(this.KEY_END));
533                         let value: string = keyValue.substring(this.KEY_START_LENGTH, keyValue.indexOf(this.KEY_MID));
534                         if (key && value) {
535                             let replaceWord: string = '${' + key + '}';
536                             templateEditor.session.replace(ranges[r], replaceWord);
537                         }
538                     }
539                 }
540                 templateEditor.clearSelection();
541                 templateEditor.exitMultiSelectMode();
542                 templateEditor.session.$backMarkers = {};
543
544             }
545         }
546     }
547
548     public generateParams(paramsEditor: any, paramsKeyValueEditor: any): JSON {
549         if (paramsEditor && paramsKeyValueEditor) {
550             var occurances = this.editor.findAll(this.KEY_EXPRESSION, { regExp: true });
551             var ranges = this.editor.getSelection().getAllRanges();
552             if (ranges) {
553                 let paramsJSON: JSON = JSON.parse('{}');
554                 for (var r = 0; r < ranges.length; r++) {
555                     let keyValue: string = this.editor.session.getTextRange(ranges[r]);
556                     if (keyValue && keyValue.startsWith(this.KEY_START) && keyValue.endsWith(this.KEY_END) && keyValue.includes(this.KEY_MID)) {
557                         let key: string = keyValue.substring(keyValue.indexOf(this.KEY_MID) + this.KEY_MID_LENGTH, keyValue.indexOf(this.KEY_END));
558                         let value: string = keyValue.substring(this.KEY_START_LENGTH, keyValue.indexOf(this.KEY_MID));
559                         if (key) {
560                             paramsJSON[key] = value;
561                         }
562                     }
563                 }
564
565                 var propertyContent = [];
566                 for (var prop in paramsJSON) {
567                     propertyContent.push(prop + '=' + paramsJSON[prop]);
568                 }
569                 this.editor.clearSelection();
570                 this.editor.exitMultiSelectMode();
571                 return paramsJSON;
572             }
573         }
574     }
575
576     setTemplateDataForStore(templateData: any) {
577         this.storedTemplateData = templateData;
578     }
579
580     getTemplateDataFromStore() {
581         return this.storedTemplateData;
582     }
583
584     removeTheSelectedMarkers() {
585         var arr: any = [];
586         arr = this.markedarr;
587         this.editor.selection.session.$backMarkers = {};
588     }
589
590     getsaveMarkers() {
591         this.markedarr = [...this.editor.selection.session.$selectionMarkers];
592     }
593
594     getTemplateMappingDataFromStore() {
595         return this.storedTemplateMappingData;
596     }
597
598     setTemplateMappingDataFromStore(templateMappingData: any) {
599         this.storedTemplateMappingData = templateMappingData;
600     }
601
602     public setReferenceList(references) {
603         this.referenceList = references;
604     }
605
606     public getReferenceList() {
607         return this.referenceList;
608     }
609
610
611 }