Saturday, 15 March 2014

Attempt to de-reference a null object salesforce

Thought of posting about a very common error we come across in apex. You must have seen this a number of times.
Visualforce Error: System.NullPointerException: Attempt to de-reference a null object

This error occurs whenever you try to access value/values from a variable/collection whose new new instance has not been created or is null in other words.

for example: if you have a list of accounts (List<account> accList) defined and you have not created a new instance of this list. And then, accidentally you try to access record from this list; then you will get the above error.

As can be seen from this example:

Visualforce Page


?
1
2
3
4
5
<apex:page controller="DeferenceDemoController">
 <apex:form >
   <apex:commandButton value="Call Method" action="{!Demo_method}"/>
 </apex:form>
</apex:page>

Controller
?
1
2
3
4
5
6
7
8
9
10
Public with sharing class DeferenceDemoController {
List<account> accList;
   Public DeferenceDemoController(){
     
   }
  Public void Demo_method(){
   for(Account ac:accList )
       system.debug('****'+ac.name);
  
}




A list "accList" of accounts has been defined but a new instance of this list has not been created. So when we press the button "Call Method" we get the error "Attempt to deference a null object" as in the called method we are trying to access the "accList" list.

This error can be avoided by creating a new instance of the accList before trying to access it as below:

Modified controller:

?
1
2
3
4
5
6
7
8
9
10
Public with sharing class DeferenceDemoController {
List<account> accList;
   Public DeferenceDemoController(){
      accList =New List<account>();
    }
  Public void Demo_method(){
   for(Account ac:accList )
       system.debug('****'+ac.name);
  
}

Tuesday, 11 March 2014

Authentication (Get Accesss token and Signature) of Salesforce using Apex

Authentication of Salesforce to perform an action on behalf of the User from out side the system or from the different Salesforce Org.
To retrieve records or perform an action in Salesforce on behalf of a user then we need to get connect with Salesforce there are several ways to connect with Salesforce, One and important method is OAuth using username and password to get access token and call out on the Salesforce org.

An autonomous client can obtain an access token by simply providing username, password and (depending on configuration) security token in an access token request. Again the request is POSTed (1) to https://login.salesforce.com/services/oauth2/token or https://test.salesforce.com/services/oauth2/token, but the payload now has the form

grant_type=password&client_id=<your_client_id>&client_secret=<your_client_secret>&username=<your_username>&password=<your_password>

The following parameters are required:
grant_type Set this to password.
client_id         Your application's client identifier (How to generate consumer key).
client_secret Your application's client secret (How to generate secret key).
username The API user's Salesforce.com username, of the form user@example.com.
password The API user's Salesforce.com password. If the client's IP address has not been white listed in your org, you must concatenate the security
token with the password.

You will receive a similar response to the authorization code case: Demo 

{
    "id":"https://login.salesforce.com/id/00D50000000IZ3ZEAW/00550000001fg5OAAQ",
    "issued_at":"1296509381665",
    "instance_url":"https://ap1.salesforce.com",
    "signature":"aNbl5EOl/DlsvUZ4NbGDno6vn935XsWGVbwoKyXHayo=",
    "access_token":"120D50000000IZ3Z!AQgAQH0Yd9M51BU_rayzAdmZ6NmT3pXZBgzkc3JTwDOGBl8BP2AREOiZzL
                    _A2zg7etH81kTuuQPljJVsX4CPt3naL7qustlb"
}
You will notice that there is no refresh token in the response. Since the user is not redirected to login at Salesforce, there is no opportunity
for the user to authorize the application. Such an authorization is required for a refresh token to be issued. If your application requires a
refresh token, you should carefully consider moving to either the web server or user agent flow if at all possible.

Generic Apex Class to get Authentication Detail(Just copy and paste in your org and you are ready to use the class) :

/*
    @Author: Mohammad Usman
    @Description: Class is used to get Authentication of salesforce
    @version:1.0
*/
public with sharing class AuthenticationDetail{
    /*End point Url to web service callout*/
    private final static String ENP_POINT_URL = 'https://login.salesforce.com/services/oauth2/token';
    //For development and production https://login.salesforce.com/services/oauth2/token
    //And for sandbox https://test.salesforce.com/services/oauth2/token
    private final static String REQUEST_BODY = 'grant_type=password&client_id={0}&client_secret=
                                                {1}&username={2}&password={3}';
    private final static String USERNAME = 'Your_Username';
    private final static String PASSWORD = 'Your_Password';
    private final static String CONSUMER_KEY = 'Your_Org_Consumer_Key';
    private final static String CONSUMER_SECRET = 'Your_Org_Consumer_Secret';
    
    /*To generate Access token Method*/
    private static OAuth getAccessToken(){
        try{
            HttpRequest req = new HttpRequest();
            req.setEndpoint(ENP_POINT_URL);
            req.setMethod('POST');          
            Blob headerValue = Blob.valueOf(USERNAME + ':' + PASSWORD);
            String authorizationHeader = 'BASIC ' +
            EncodingUtil.base64Encode(headerValue);
            req.setHeader('Authorization', authorizationHeader); 
            req.setBody(String.format(REQUEST_BODY ,new string[]{CONSUMER_KEY,CONSUMER_SECRET,
                                                                 USERNAME,PASSWORD}));
            req.setTimeout(60000);
            Http http = new Http();
            HttpResponse res = http.send(req);
            OAuth objAuthenticationInfo = (OAuth)JSON.deserialize(res.getbody(), OAuth.class);
            return objAuthenticationInfo;
        }catch(CallOutException ce){
            throw ce;
        }
        return null;
    }
    
    /*To get Access token property*/
    public static OAuth authenticationDetail{
        get{
            if(authenticationDetail == null){
                authenticationDetail = getAccessToken();
            }
            return authenticationDetail;
        }set;
    }
        
    /*To get aouthentication detail Wrapper*/
    public class OAuth{
        public String id{get;set;}
        public String issued_at{get;set;}
        public String instance_url{get;set;}
        public String signature{get;set;}
        public String access_token{get;set;}    
    }   
}
Output of the above Class:

Authentication Detail for the above apex class
Summary :
Force.com's implementation of OAuth 2.0 allows client applications to access resources on behalf of end users without sharing credentials such as passwords with those client applications, enhancing both privacy and security. This article provides a description of OAuth as well as the various authentication flows supported by OAuth.

Reference :
http://wiki.developerforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com

Monday, 24 February 2014

Outbound Emails in salesforce

To send individual and mass email with Apex, use the following classes:
SingleEmailMessage
Instantiates an email object used for sending a single email message. The syntax is:
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
MassEmailMessage
Instantiates an email object used for sending a mass email message. The syntax is:
Messaging.MassEmailMessage mail = new Messaging.MassEmailMessage();
Messaging
Includes the static sendEmail method, which sends the email objects you instantiate with either the SingleEmailMessage or MassEmailMessage classes, and returns a SendEmailResult object.
The syntax for sending an email is:
Messaging.sendEmail(new Messaging.Email[] { mail } , opt_allOrNone);
where Email is either Messaging.SingleEmailMessage or Messaging.MassEmailMessage.
The optional opt_allOrNone parameter specifies whether sendEmail prevents delivery of all other messages when any of the messages fail due to an error (true), or whether it allows delivery of the messages that don't have errors (false). The default is true.
Includes the static reserveMassEmailCapacity and reserveSingleEmailCapacity methods, which can be called before sending any emails to ensure that the sending organization won't exceed its daily email limit when the transaction is committed and emails are sent. The syntax is:
Messaging.reserveMassEmailCapacity(count);
and
Messaging.reserveSingleEmailCapacity(count);
where count indicates the total number of addresses that emails will be sent to.
Note the following:
  • The email is not sent until the Apex transaction is committed.
  • The email address of the user calling the sendEmail method is inserted in the From Address field of the email header. All email that is returned, bounced, or received out-of-office replies goes to the user calling the method.
  • Maximum of 10 sendEmail methods per transaction. Use the Limits methods to verify the number of sendEmail methods in a transaction.
  • Single email messages sent with the sendEmail method count against the sending organization's daily single email limit. When this limit is reached, calls to the sendEmail method using SingleEmailMessage are rejected, and the user receives a SINGLE_EMAIL_LIMIT_EXCEEDED error code. However, single emails sent through the application are allowed.
  • Mass email messages sent with the sendEmail method count against the sending organization's daily mass email limit. When this limit is reached, calls to the sendEmail method using MassEmailMessage are rejected, and the user receives a MASS_MAIL_LIMIT_EXCEEDED error code.
  • Any error returned in the SendEmailResult object indicates that no email was sent.

Example

// First, reserve email capacity for the current Apex transaction to ensure
                        
// that we won't exceed our daily email limits when sending email after
                        
// the current transaction is committed.
Messaging.reserveSingleEmailCapacity(2);

// Processes and actions involved in the Apex transaction occur next,
// which conclude with sending a single email.

// Now create a new single email message object
// that will send out a single email to the addresses in the To, CC & BCC list.
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

// Strings to hold the email addresses to which you are sending the email.
String[] toAddresses = new String[] {'user@acme.com'}; 
String[] ccAddresses = new String[] {'smith@gmail.com'};
  

// Assign the addresses for the To and CC lists to the mail object.
mail.setToAddresses(toAddresses);
mail.setCcAddresses(ccAddresses);

// Specify the address used when the recipients reply to the email. 
mail.setReplyTo('support@acme.com');

// Specify the name used as the display name.
mail.setSenderDisplayName('Salesforce Support');

// Specify the subject line for your email address.
mail.setSubject('New Case Created : ' + case.Id);
 
//Required if using a template, optional otherwise. The ID of the contact, lead, or user to 
//which the email will be sent. The ID you specify sets the context and 
//ensures that merge fields in the template contain the correct data.
mail.SetTargetObjectId(userId); 
 
 // Set to True if you want to BCC yourself on the email.
mail.setBccSender(false);

// Optionally append the salesforce.com email signature to the email.
// The email address of the user executing the Apex Code will be used.
mail.setUseSignature(false);

// Specify the text content of the email.
mail.setPlainTextBody('Your Case: ' + case.Id +' has been created.');

mail.setHtmlBody('Your case:<b> ' + case.Id +' </b>has been created.<p>'+
     'To view your case <a href=https://na1.salesforce.com/'+case.Id+'>click here.</a>');

// Send the email you have created.
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

How to send mass emails to users in salesforce

In the below sample code "lstPortalUser" is a list of partner users.Now I need to sent them an email with different body.

  1. List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();  
  2. for(User portalUser :lstPortalUser)  
  3. {     
  4.    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();  
  5.    string body = 'Hi '+ portalUser.LastName;    
  6.    mail.setSubject('Test Subject');  
  7.    mail.setTargetObjectId(portalUser.Id);  
  8.    mail.setSaveAsActivity(false);  
  9.    mail.setHtmlBody(body);  
  10.    mails.add(mail);  
  11. }  
  12. Messaging.sendEmail(mails);  

Link to download Force.com Explorer

Note: Before downloading Force.com Explorer, kindly download and install Adobe AIR.

Use the below link to download Force.com Explorer

http://wiki.developerforce.com/page/ForceExplorer


Thursday, 6 February 2014

How Salesforce 18 Digit Id Is Calculated

As we know that each record Id represents a unique record within an organization. There are two versions of every record Id in salesforce :
  • 15 digit case-sensitive version which is referenced in the UI
  • 18 digit case-insensitive version which is referenced through the API
The last 3 digits of the 18 digit Id is a checksum of the capitalization of the first 15 characters, this Id length was created as a workaround to legacy system which were not compatible with case-sensitive Ids. The API will accept the 15 digit Id as input but will always return the 18 digit Id.
Now how we can calculate the 18 digit Id from 15 digit Id ??? Just copy paste the below code in system logs and pass your 15 digit id in String id
//Your 15 Digit Id
String id= '00570000001ZwTi' ;

string suffix = '';
integer flags;

for (integer i = 0; i < 3; i++)
{
 flags = 0;
 for (integer j = 0; j < 5; j++)
 {
  string c = id.substring(i * 5 + j,i * 5 + j + 1);
  //Only add to flags if c is an uppercase letter:
  if (c.toUpperCase().equals(c) && c >= 'A' && c <= 'Z')
  {
   flags = flags + (1 << j);
  }
 }
 if (flags <= 25)
 {
  suffix = suffix + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.substring(flags,flags+1);
 }
 else
 {
  suffix = suffix + '012345'.substring(flags-25,flags-24);
 }
}

//18 Digit Id with checksum
System.debug(' ::::::: ' + id + suffix) ;
This debug will return the 18 digit Id.
 If you don’t mind using up a field per object….you can create a formula field to show the 18 digit ID as well.
Implementing 15-to-18-character ID converter through a formula field is below. No code needed! 
Id & 
MID( 
"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345", 
MIN(FIND(MID(Id, 5, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 16 + 
MIN(FIND(MID(Id, 4, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 8 + 
MIN(FIND(MID(Id, 3, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 4 + 
MIN(FIND(MID(Id, 2, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 2 + 
MIN(FIND(MID(Id, 1, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 1 + 1, 
1) & 
MID( 
"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345", 
MIN(FIND(MID(Id, 10, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 16 + 
MIN(FIND(MID(Id, 9, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 8 + 
MIN(FIND(MID(Id, 8, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 4 + 
MIN(FIND(MID(Id, 7, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 2 + 
MIN(FIND(MID(Id, 6, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 1 + 1, 
1) & 
MID( 
"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345", 
MIN(FIND(MID(Id, 15, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 16 + 
MIN(FIND(MID(Id, 14, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 8 + 
MIN(FIND(MID(Id, 13, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 4 + 
MIN(FIND(MID(Id, 12, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 2 + 
MIN(FIND(MID(Id, 11, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"), 1) * 1 + 1, 
1)