Skip to content

Instantly share code, notes, and snippets.

@kiran-machhewar
Last active October 6, 2018 12:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kiran-machhewar/da6ec2e8d65bf41ec2a4 to your computer and use it in GitHub Desktop.
Save kiran-machhewar/da6ec2e8d65bf41ec2a4 to your computer and use it in GitHub Desktop.
Controller for SFCompare.page
/**
* @ApexClass : SFCompareController
* @Description : This provides services to SFCompare page, which can be accessed by js remoting. It provides below services.
* 1. Logging into SF orgs for obtaining session and instance url.
* 2. Fetches code from the SF org.
* */
public class SFCompareController {
/**
* @description : This method does the login to sf orgs and provides session id and
* instance url wrapped in SFOrgLogin wrapper instances.
*/
@RemoteAction
public static List<SFOrgLogin> doSFLogins(String sorgType,String susername,String spassword,String torgType,String tusername,String tpassword){
List<SFOrgLogin> sfOrgLogins = new List<SFOrgLogin>();
sforgLogins.add(getSessionId(susername,spassword,sorgType));
sforgLogins.add(getSessionId(tusername,tpassword,torgType));
return sforgLogins;
}
/**
* @description : This gets the sesssion id and instance url from any SF org based on
* username, password and orgType(Production/Sandbox)
*/
public static SFOrgLogin getSessionId(String username, String password,String orgType){
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
Http http = new Http();
req.setEndpoint('https://'+orgType+'.salesforce.com/services/oauth2/token');
req.setMethod('POST');
req.setBody('grant_type=password&client_id=<yourclientid>&client_secret=<yourclientsecretekey>&username='+EncodingUtil.urlEncode(username, 'UTF-8')+'&password='+EncodingUtil.urlEncode(password, 'UTF-8'));
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
try {
res = http.send(req);
System.debug(res.getBody());
Map<String,Object> response = (Map<String,Object>)JSON.deserializeUntyped(res.getBody());
SFOrgLogin sforg = new SFOrgLogin();
sforg.sessionId = ''+response.get('access_token');
sforg.instanceURL = ''+response.get('instance_url');
if(sforg.sessionId == '' || sforg.sessionId == 'null'
|| sforg.instanceURL == '' || sforg.instanceURL == 'null'){
throw new SFCompareException('Username/Password is incorrect - Please check details for '+username);
}
return sforg;
} catch(System.CalloutException e) {
System.debug('Callout error: '+ e);
System.debug(res.toString());
}
return null;
}
/**
* @ApexClass : SFOrgLogin
* @Description : Wrapper to hold session id and instance url.
*/
public class SFOrgLogin{
String sessionId;
String instanceURL;
}
/**
* @Returns the metadata options for selected metadata types.
*/
@RemoteAction
public static Map<String,Object> getMetadata(SFOrgLogin sforgLogin){
List<String> metadataItems = new List<String>();
metadataItems.add('ApexClass');
metadataItems.add('ApexPage');
metadataItems.add('ApexTrigger');
//metadataItems.add('CustomObject');
Map<String,Object> result = new Map<String,Object>();
for(String metadata : metadataItems){
result.put(metadata,getOptions(sforgLogin,metadata));
}
return result;
}
/**
*@Description : For selected metadata type it returns all the entries in the org wrapped in Option(Wrapper class).
*/
private static List<Option> getOptions(SFOrgLogin sforgLogin,String metadataItem){
String query = ' SELECT Id, Name FROM '+metadataItem + ' Order By Name ';
query = EncodingUtil.urlEncode(query, 'UTF-8');
String response = makeToolingApiRequest(sforglogin.instanceURL+'/services/data/v28.0/tooling/query/?q='+query,sforglogin.sessionid);
List<Option> result = new List<Option>();
Map<String,Object> responseMap = (Map<String,Object>)JSON.deserializeUntyped(response);
List<Object> records = (List<Object>)responseMap.get('records');
for(Object record : records){
Map<String,Object> recordObj = (Map<String,Object>) record;
result.add(new Option(metadataItem + '/'+recordObj.get('Id'),''+recordObj.get('Name')));
}
return result;
}
/**
*@description : Helps making tooling api call.
*/
private static String makeToolingApiRequest(String endpoint,String sessionId){
HttpRequest req = new HttpRequest();
//Set the tooling api endpoint
req.setEndpoint(endpoint);
/*Set authorization by using current users session Id*/
req.setHeader('Authorization', 'Bearer ' + sessionId);
req.setHeader('Content-Type', 'application/json');
req.setMethod('GET');
Http http = new Http();
HTTPResponse res = http.send(req);
return res.getBody();
}
/**
* @description : It returns the id of selected metadata element from target org.
*/
private static String getTargetOrgMetadataItemId(SFOrgLogin sforgLogin,String metadataItem,String metadataType){
String query = ' SELECT Id, Name FROM '+metadataType+' WHERE Name =\''+metadataItem+'\' ';
query = EncodingUtil.urlEncode(query, 'UTF-8');
String response = makeToolingApiRequest(sforglogin.instanceURL+'/services/data/v28.0/tooling/query/?q='+query,sforglogin.sessionid);
Map<String,Object> responseMap = (Map<String,Object>)JSON.deserializeUntyped(response);
List<Object> records = (List<Object>)responseMap.get('records');
for(Object record : records){
Map<String,Object> recordObj = (Map<String,Object>) record;
return ''+recordObj.get('Id');
}
return null;
}
/**
* @description : It returns the code of metadata element(ApexClass,ApexTrigger or ApexPages)
*/
private static String getCode(SFOrgLogin sforgLogin,String metadataURL){
String result=null;
String response = makeToolingApiRequest(sforglogin.instanceURL+'/services/data/v28.0/tooling/sobjects/'+metadataURL,sforglogin.sessionid);
Map<String,Object> responseMap = (Map<String,Object>)JSON.deserializeUntyped(response);
if(responseMap.get('Body') != null){
result = ''+responseMap.get('Body');
}else if(responseMap.get('Markup') != null){
result = ''+responseMap.get('Markup');
}
return result;
}
@RemoteAction
public static Code getCode(SFOrgLogin source,SFOrgLogin target,String metadataURL,String metadataItem){
Code result = new Code();
String metadataType = metadataURL.split('/')[0];
String targetMetadataURL = metadataType + '/'+ getTargetOrgMetadataItemId(target,metadataItem,metadataType);
result.sourceCode = getCode(source,metadataURL);
result.targetCode = getCode(target,targetMetadataURL);
return result;
}
/**
*@ApexClass : Code
*@Description : Wrapper class to hold source code and target org used for comparison
*/
public class Code{
String sourceCode;
String targetCode;
public Code(){}
public Code(String sourceCode,String targetCode){
this.sourceCode = sourceCode;
this.targetCode = targetCode;
}
}
/**
*@ApexClass : Option
*@Description : Wrapper class to hold value and label of metadata element
*/
public class Option{
String value;
String label;
public Option(String value,String label){
this.value = value;
this.label = label;
}
}
/**
* @ApexClass : SFCompareException
* @Description : Custom Exception
*/
public class SFCompareException extends Exception {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment