11import * as fs from 'fs' ;
2- // import { RetrieveResult } from '@salesforce/source-deploy-retrieve';
3- // import { sfcclicommand } from '../../utils/sfcli/commands/sfclicommand';
42import * as shell from 'shelljs' ;
53import { Org } from '@salesforce/core' ;
6- import { ApexASTParser , MethodCall } from '../../utils/apex/parser/apexparser' ;
4+ import {
5+ ApexASTParser ,
6+ InsertAfterTokenUpdate ,
7+ InterfaceImplements ,
8+ MethodCall ,
9+ MethodParameter ,
10+ ParameterType ,
11+ RangeTokenUpdate ,
12+ SingleTokenUpdate ,
13+ TokenUpdater ,
14+ } from '../../utils/apex/parser/apexparser' ;
715import { MigrationResult , RelatedObjectsMigrate } from '../interfaces' ;
816import { sfProject } from '../../utils/sfcli/project/sfProject' ;
917import { fileutil , File } from '../../utils/file/fileutil' ;
18+ import { Logger } from '../../utils/logger' ;
1019import { BaseRelatedObjectMigration } from './BaseRealtedObjectMigration' ;
20+
1121const APEXCLASS = 'Apexclass' ;
1222const APEX_CLASS_PATH = '/force-app/main/default/classes' ;
23+ const CALLABLE = 'Callable' ;
24+ const VLOCITY_OPEN_INTERFACE2 = 'VlocityOpenInterface2' ;
25+ const VLOCITY_OPEN_INTERFACE = 'VlocityOpenInterface' ;
26+
1327export class ApexMigration extends BaseRelatedObjectMigration implements RelatedObjectsMigrate {
28+ private readonly callableInterface : InterfaceImplements ;
29+ private readonly vlocityOpenInterface2 : InterfaceImplements ;
30+ private readonly vlocityOpenInterface : InterfaceImplements ;
31+ private updatedNamespace = this . namespace ;
32+ public constructor ( projectPath : string , namespace : string , org : Org ) {
33+ super ( projectPath , namespace , org ) ;
34+ this . callableInterface = new InterfaceImplements ( CALLABLE , this . namespace ) ;
35+ this . vlocityOpenInterface2 = new InterfaceImplements ( VLOCITY_OPEN_INTERFACE2 , this . namespace ) ;
36+ this . vlocityOpenInterface = new InterfaceImplements ( VLOCITY_OPEN_INTERFACE , this . namespace ) ;
37+ }
1438 public identifyObjects ( migrationResults : MigrationResult [ ] ) : Promise < JSON [ ] > {
1539 throw new Error ( 'Method not implemented.' ) ;
1640 }
@@ -32,23 +56,98 @@ export class ApexMigration extends BaseRelatedObjectMigration implements Related
3256 files = fileutil . readFilesSync ( dir ) ;
3357 for ( const file of files ) {
3458 if ( file . ext !== '.cls' ) continue ;
35- this . processApexFile ( file ) ;
59+ try {
60+ this . processApexFile ( file ) ;
61+ } catch ( err ) {
62+ Logger . logger . error ( `Error processing ${ file . name } ` ) ;
63+ Logger . logger . error ( err ) ;
64+ }
3665 }
3766 return files ;
3867 }
3968
4069 public processApexFile ( file : File ) : void {
4170 const fileContent = fs . readFileSync ( file . location , 'utf8' ) ;
42- const interfaces = new Set < string > ( [ 'VlocityOpenInterface' , 'VlocityOpenInterface2' , 'Callable' ] ) ;
71+ const interfaces : InterfaceImplements [ ] = [ ] ;
72+ interfaces . push ( this . vlocityOpenInterface , this . vlocityOpenInterface2 , this . callableInterface ) ;
4373 const methodCalls = new Set < MethodCall > ( ) ;
44- methodCalls . add ( new MethodCall ( 'process' , 'DRGlobal' , this . namespace ) ) ;
45- methodCalls . add ( new MethodCall ( 'processObjectsJSON' , 'DRGlobal' , this . namespace ) ) ;
74+ const drNameParameter = new MethodParameter ( 2 , ParameterType . DR_NAME ) ;
75+ const ipNameParameter = new MethodParameter ( 1 , ParameterType . IP_NAME ) ;
76+ methodCalls . add ( new MethodCall ( 'DRGlobal' , 'process' , this . namespace , drNameParameter ) ) ;
77+ methodCalls . add ( new MethodCall ( 'DRGlobal' , 'processObjectsJSON' , this . namespace , drNameParameter ) ) ;
78+ methodCalls . add ( new MethodCall ( 'DRGlobal' , 'processString' , this . namespace , drNameParameter ) ) ;
79+ methodCalls . add ( new MethodCall ( 'DRGlobal' , 'processFromApex' , this . namespace , drNameParameter ) ) ;
80+ methodCalls . add (
81+ new MethodCall ( 'IntegrationProcedureService' , 'runIntegrationService' , this . namespace , ipNameParameter )
82+ ) ;
4683 const parser = new ApexASTParser ( fileContent , interfaces , methodCalls , this . namespace ) ;
4784 parser . parse ( ) ;
48- this . processApexFileforDRCalls ( file , fileContent ) ;
85+ const tokenUpdates : TokenUpdater [ ] = [ ] ;
86+ const tokenUpdatesForRemoteCalls = this . processApexFileForRemotecalls ( file , parser ) ;
87+ const tokeUpdatesForMethodCalls = this . processApexFileForMethodCalls ( file , parser ) ;
88+ const updateMessages : string [ ] = [ ] ;
89+
90+ if ( tokenUpdatesForRemoteCalls && tokenUpdatesForRemoteCalls . length > 0 ) {
91+ tokenUpdates . push ( ...tokenUpdatesForRemoteCalls ) ;
92+ updateMessages . push ( 'File has been updated to allow remote calls from the Omnistudio components' ) ;
93+ }
94+ if ( tokeUpdatesForMethodCalls && tokeUpdatesForMethodCalls . length > 0 ) {
95+ updateMessages . push ( 'File has been updated to allow calls to Omnistudio components' ) ;
96+ tokenUpdates . push ( ...tokeUpdatesForMethodCalls ) ;
97+ }
98+ if ( tokenUpdates && tokenUpdates . length > 0 ) {
99+ fs . writeFileSync ( file . location , parser . rewrite ( tokenUpdates ) ) ;
100+ }
101+ const warningMessage : string [ ] = this . processNonReplacableMethodCalls ( file , parser ) ;
102+ Logger . logger . warn ( warningMessage ) ;
49103 }
50- public processApexFileforDRCalls ( file : File , fileContent : string ) : void {
51- // fileContent = fileContent.replace(this.namespace + '.', 'omnistudio.');
52- fs . writeFileSync ( file . location , fileContent , 'utf-8' ) ;
104+
105+ private processApexFileForRemotecalls ( file : File , parser : ApexASTParser ) : TokenUpdater [ ] {
106+ const implementsInterface = parser . implementsInterfaces ;
107+ const tokenUpdates : TokenUpdater [ ] = [ ] ;
108+ if ( implementsInterface . has ( this . callableInterface ) ) {
109+ Logger . logger . info ( 'file ${file.name} already implements callable no changes will be applied' ) ;
110+ } else if ( implementsInterface . has ( this . vlocityOpenInterface2 ) ) {
111+ const tokens = implementsInterface . get ( this . vlocityOpenInterface2 ) ;
112+ tokenUpdates . push ( new RangeTokenUpdate ( CALLABLE , tokens [ 0 ] , tokens [ 1 ] ) ) ;
113+ tokenUpdates . push ( new InsertAfterTokenUpdate ( this . callMethodBody ( ) , parser . classDeclaration ) ) ;
114+ } else if ( implementsInterface . has ( this . vlocityOpenInterface ) ) {
115+ Logger . logger . error ( 'file ${file.name} implements VlocityOpenInterface please implement Callable' ) ;
116+ }
117+ return tokenUpdates ;
118+ }
119+
120+ private processApexFileForMethodCalls ( file : File , parser : ApexASTParser ) : TokenUpdater [ ] {
121+ const namespaceChanges = parser . namespaceChanges ;
122+ const tokenUpdates : TokenUpdater [ ] = [ ] ;
123+ if ( namespaceChanges && namespaceChanges . has ( this . namespace ) ) {
124+ for ( const tokenChange of namespaceChanges . get ( this . namespace ) )
125+ tokenUpdates . push ( new SingleTokenUpdate ( this . updatedNamespace , tokenChange ) ) ;
126+ }
127+ return tokenUpdates ;
128+ }
129+
130+ private processNonReplacableMethodCalls ( file : File , parser : ApexASTParser ) : string [ ] {
131+ const methodCalls = parser . nonReplacableMethodParameters ;
132+ const messages : string [ ] = [ ] ;
133+ if ( methodCalls . length === 0 ) return messages ;
134+ for ( const methodCall of methodCalls ) {
135+ messages . push (
136+ `${ file . name } has method call ${ methodCall . className } ${ methodCall . methodName } for which bundleName could have been updated please check and replace with new value if updated.`
137+ ) ;
138+ }
139+ return messages ;
140+ }
141+ private callMethodBody ( ) : string {
142+ return `
143+ public Object call(String action, Map<String,Object> args)
144+ {
145+ Map<String,Object> inputMap = (Map<String,Object>)args.get('input');
146+ Map<String,Object> outMap = (Map<String,Object>)args.get('output');
147+ Map<String,Object> options = (Map<String,Object>)args.get('options');
148+
149+ return invokeMethod(action, inputMap, outMap, options);
150+ }
151+ ` ;
53152 }
54153}
0 commit comments