import * as nls from 'vscode-nls' ; const localize = nls . loadMessageBundle ( ) ; import * as vscode from 'vscode' ; import * as path from 'path' ; import { ServerManagement , Context , ServerView , ServiceView , EnvironmentView } from './serverManagement' ; import { IniManagement } from './iniManagement' ; import IDictionary from './utils/IDictionary' ; import IEnvironment from './utils/IEnvironment' ; import { advplCompile } from './advplCompile' ; export class ServerManagementView { private _provider : ServerProvider ; private get Config ( ) : vscode . WorkspaceConfiguration { return vscode . workspace . getConfiguration ( "advpl" ) ; } private get EnvironmentsConfig ( ) : Array < IEnvironment > { return this . Config . get < Array < IEnvironment > > ( "environments" ) ; } private get Dictionary ( ) : Array < IDictionary > { return this . Config . get < Array < IDictionary > > ( "dictionary" ) ; } constructor ( ) { this . _provider = new ServerProvider ( ) ; vscode . commands . registerCommand ( "advpl.serversManagement.connect" , ( element ) => this . connect ( element ) ) ; vscode . commands . registerCommand ( "advpl.serversManagement.getAllEnvironments" , ( element ) => this . getAllEnvironments ( element ) ) ; vscode . commands . registerCommand ( "advpl.serversManagement.rename" , ( element ) => this . rename ( element ) ) ; vscode . commands . registerCommand ( "advpl.serversManagement.Defrag" , ( element ) => this . defrag ( element ) ) ; vscode . commands . registerCommand ( "advpl.serversManagement.getRpoInfos" , ( element ) => this . getRpoInfos ( element ) ) ; vscode . commands . registerCommand ( "advpl.serversManagement.getRpoFunctions" , ( element ) => this . getRpoFunctions ( element ) ) ; vscode . commands . registerCommand ( "advpl.serversManagement.DeleteEnvironment" , ( element ) => this . delete ( element ) ) ; vscode . commands . registerCommand ( "advpl.serversManagement.CipherPassword" , ( element ) => this . cipherPassword ( element ) ) ; } get provider ( ) { return this . _provider ; } public connect ( element ) { let updObj = vscode . workspace . getConfiguration ( "advpl" ) ; updObj . update ( "selectedEnvironment" , element . label ) . then ( ( ) => { vscode . window . showInformationMessage ( localize ( 'src.ServerManagementView.environmentText' , 'Environment ' ) + element . label + localize ( 'src.ServerManagementView.environmentSelectedText' , ' selection was successful.' ) ) ; } ) ; } public getAllEnvironments ( element ) { let serverManagement = new ServerManagement ( false ) ; let ini = new IniManagement ( ) ; if ( element . context !== Context . ServiceConnected ) { vscode . window . showErrorMessage ( localize ( 'src.ServerManagementView.CONTEXTVALID' , "This option can only be used for a Service type item." ) ) ; return ; } vscode . window . withProgress ( { location : vscode . ProgressLocation . Window , title : localize ( 'src.ServerManagementView.CARREGANDO' , "Loading environments..." ) , cancellable : false } , ( progress , token ) => { token . onCancellationRequested ( ( ) => { console . log ( "User canceled the long running operation" ) ; } ) ; return new Promise ( resolve => { ini . GetIniContent ( ) . then ( ( ) => { ini . GetEnvironments ( ) ; ini . Environments . map ( env => { let service = < ServiceView > element . subject ; if ( ! service . environments . find ( _env => _env . environment . toUpperCase ( ) === env . Environment . toUpperCase ( ) ) ) { serverManagement . AddEnvironment ( { environment : env . Environment , name : env . Environment , server : service . parent . serverIP , port : service . servicePort , serverVersion : service . serverVersion , passwordCipher : service . passwordCipher , includeList : service . includeList , user : service . user , smartClientPath : service . smartClientPath , enable : true } ) ; } } ) ; resolve ( ) ; } ) ; } ) ; } ) ; } rename ( element ) { let config = this . Config ; let dictionary = this . Dictionary ; let environments = this . EnvironmentsConfig ; let oldLabel = element . label ; let options = { prompt : localize ( 'src.ServerManagementView.RENAME' , "Rename" ) , placeHolder : localize ( 'src.ServerManagementView.INFORMELABEL' , "Enter the Label to change." ) , value : oldLabel , validateInput : function ( newLabel ) { if ( ! newLabel ) { return localize ( 'src.ServerManagementView.INFORMELABEL' , "Enter the Label to change." ) ; } if ( dictionary . find ( dic => dic . label . toUpperCase ( ) . trim ( ) === newLabel . toUpperCase ( ) . trim ( ) ) ) { return localize ( 'src.ServerManagementView.LABELINUSE' , "This Label is already in use." ) ; } if ( environments . find ( env => retEnv ( env ) . toUpperCase ( ) . trim ( ) === newLabel . toUpperCase ( ) . trim ( ) ) ) { return localize ( 'src.ServerManagementView.NAMEINUSE' , "This Label is already being used in an environment." ) ; } /**
                 * Verifica se no ambiente está informado o atributo nome,
                 * trata desta forma para evitar erros caso essa propriedade
                 * seja null.
                 */ function retEnv ( env ) { if ( env . name ) return env . name ; else return env . environment ; } return "" ; } } ; vscode . window . showInputBox ( options ) . then ( newLabel => { if ( newLabel ) { if ( element . subject instanceof ServerView ) { let obj = < ServerView > element . subject ; let dictionaryPos = dictionary . findIndex ( dic => dic . name === obj . serverIP ) ; if ( dictionaryPos > - 1 ) { dictionary [ dictionaryPos ] . label = newLabel ; } else { dictionary . push ( { "label" : newLabel , "name" : obj . serverIP } ) ; } config . update ( 'dictionary' , dictionary ) ; } else if ( element . subject instanceof ServiceView ) { let obj = < ServiceView > element . subject ; let dictionaryPos = dictionary . findIndex ( dic => validParent ( dic ) && dic . name === obj . servicePort . toString ( ) ) ; /**
                     * Valida o atributo parent dessa forma para evitar erros
                     * caso essa propriedade seja null.
                     */ function validParent ( dic ) { if ( dic . parent ) return dic . parent . trim ( ) === obj . parent . serverIP . trim ( ) ; else return true ; } if ( dictionaryPos > - 1 ) { dictionary [ dictionaryPos ] . label = newLabel ; } else { dictionary . push ( { "label" : newLabel , "name" : obj . servicePort . toString ( ) , "parent" : obj . parent . serverIP } ) ; } config . update ( 'dictionary' , dictionary ) ; } else if ( element . subject instanceof EnvironmentView ) { let obj = < EnvironmentView > element . subject ; environments . find ( env => env . environment === obj . environment && env . port === obj . parent . servicePort && env . server === obj . parent . parent . serverIP ) . name = newLabel ; config . update ( 'environments' , environments ) ; if ( obj . isConnected ) { let newElement = new Dependency ( newLabel , element . description , element . tooltip , element . collapsibleState , element . context , element . isConnected , element . owner , element . subject ) ; this . connect ( newElement ) ; } } } } ) ; } defrag ( element ) { vscode . commands . executeCommand ( "advpl.monitor.defragRpo" ) ; } getRpoInfos ( element ) { vscode . commands . executeCommand ( "advpl.monitor.getRpoInfos" ) ; } getRpoFunctions ( element ) { vscode . commands . executeCommand ( "advpl.monitor.getRpoFunctions" ) ; } cipherPassword ( element ) { const compile = new advplCompile ( ) ; let options = { prompt : localize ( 'src.advplCompile.passwordQueryText' , 'Type in the password:' ) , password : true } ; var password = vscode . window . showInputBox ( options ) . then ( newPass => { let environments = this . EnvironmentsConfig ; let config = this . Config ; let obj = < EnvironmentView > element . subject ; if ( newPass != undefined ) { compile . runCipherPassword ( newPass , cipher => { cipher = cipher . replace ( /\r?\n?/g , '' ) ; environments . find ( env => env . environment === obj . environment && env . port === obj . parent . servicePort && env . server === obj . parent . parent . serverIP ) . passwordCipher = cipher ; config . update ( 'environments' , environments ) . then ( ( ) => { let message = localize ( 'src.ServerManagementView.passwordChangedSuccess' , 'Environment password %ENV_NAME% successfully changed.' ) ; vscode . window . showInformationMessage ( message . replace ( "%ENV_NAME%" , obj . environmentLabel ) ) ; } ) ; } ) ; } } ) ; } delete ( element ) { let config = this . Config ; let environments = this . EnvironmentsConfig ; vscode . window . showQuickPick ( [ localize ( 'src.ServerManagementView.yesText' , 'Yes' ) , localize ( 'src.ServerManagementView.noText' , 'No' ) ] ) . then ( option => { if ( option === localize ( 'src.ServerManagementView.yesText' , 'Yes' ) ) { if ( element . subject instanceof EnvironmentView ) { let obj = < EnvironmentView > element . subject ; environments = environments . filter ( env => ! ( env . environment === obj . environment && env . port === obj . parent . servicePort && env . server === obj . parent . parent . serverIP ) ) ; config . update ( 'environments' , environments ) . then ( ( ) => { vscode . window . showInformationMessage ( localize ( 'src.ServerManagementView.environmentText' , "Environment " ) + element . label + localize ( 'src.ServerManagementView.DELETED' , " deleted" ) ) ; } ) ; } } } ) ; } } export class ServerProvider implements vscode . TreeDataProvider < Dependency > { private _onDidChangeTreeData : vscode . EventEmitter < Dependency | undefined > = new vscode . EventEmitter < Dependency | undefined > ( ) ; readonly onDidChangeTreeData : vscode . Event < Dependency | undefined > = this . _onDidChangeTreeData . event ; refresh ( ) { this . _onDidChangeTreeData . fire ( undefined ) ; } getTreeItem ( element ) { return element ; } getChildren ( element ? ) { if ( element ) { return Promise . resolve ( this . getEnvironments ( element , element . context ) ) ; } else { return Promise . resolve ( this . getEnvironments ( ) ) ; } } private getEnvironments ( childElement ? , context ? ) { let environments = Array < Dependency > ( ) ; let servers = new ServerManagement ( true ) . servers ; let objectParent ; const toDep = ( label , description , tooltip , isConnected , context , owner , subject ) : Dependency => { if ( context === Context . Environment || context === Context . EnvironmentConnected ) { return new Dependency ( label , description , tooltip , vscode . TreeItemCollapsibleState . None , context , isConnected , owner , subject ) ; } else { return new Dependency ( label , description , tooltip , vscode . TreeItemCollapsibleState . Expanded , context , isConnected , owner , subject ) ; } } ; if ( childElement ) { if ( childElement . context == Context . Server || childElement . context == Context . ServerConnected ) { objectParent = < ServerView > servers . find ( server => server . serverName === childElement . label ) ; objectParent . services . map ( service => environments . push ( toDep ( service . serviceName , service . servicePort , service . serviceName . toUpperCase ( ) . trim ( ) == service . servicePort . toUpperCase ( ) . trim ( ) ? service . serviceName : service . serviceName + " • " + service . servicePort , service . isConnected , service . isConnected ? Context . ServiceConnected : Context . Service , childElement . label , service ) ) ) ; } else if ( childElement . context == Context . Service || childElement . context == Context . ServiceConnected ) { objectParent = < ServiceView > servers . find ( server => server . serverName === childElement . owner ) . services . find ( service => service . serviceName === childElement . label ) ; objectParent . environments . map ( environment => environments . push ( toDep ( environment . environmentLabel , environment . environment , environment . environmentLabel . toUpperCase ( ) . trim ( ) == environment . environment . toUpperCase ( ) . trim ( ) ? environment . environmentLabel : environment . environmentLabel + " • " + environment . environment , environment . isConnected , environment . isConnected ? Context . EnvironmentConnected : Context . Environment , childElement . label , environment ) ) ) ; } } else { servers . map ( server => environments . push ( toDep ( server . serverName , server . serverIP , server . serverName . toUpperCase ( ) . trim ( ) == server . serverIP . toUpperCase ( ) . trim ( ) ? server . serverName : server . serverName + " • " + server . serverIP , server . isConnected , server . isConnected ? Context . ServerConnected : Context . Server , "" , server ) ) ) ; } return environments ; } } export class Dependency extends vscode . TreeItem { constructor ( public readonly label , public readonly description , public readonly tooltip , public readonly collapsibleState , public readonly context ? , public readonly isConnected ? , public readonly owner ? , public readonly subject ? ) { super ( label , collapsibleState ) ; } get contextValue ( ) : string { return Context [ this . context ] ; } iconPath = { light : path . join ( __filename , '..' , '..' , '..' , 'images' , 'light' , this . getIcon ( ) ) , dark : path . join ( __filename , '..' , '..' , '..' , 'images' , 'dark' , this . getIcon ( ) ) } ; private getIcon ( ) { if ( this . context === Context . Environment || this . context === Context . EnvironmentConnected ) { return this . isConnected ? "server_green.svg" : "server.svg" ; } else { return this . isConnected ? "dependency_green.svg" : "dependency.svg" ; } } }