Friday, March 22, 2013

Handle Session Timeout on Visual Force Page

One of my fellow developer recently faced a strange requirement related to handling session timeout on visualforce page. They have quite large Visual force page with lot of data entry fields. Sometime it take hours to fill that large form.

Although Salesforce session timeout duration can be increased and salesforce give option to continue your previous session also. But still there are chances that user doesn't notice session timeout popup or may be they have popup blocker enable in their browser. In such cases session timeout popup will not appear at all, and this vary browser to browser.

So he wanted to do something when user hit submit/save button to verify if session is active otherwise give error message and stay on page. Although once session has expired there is no way to post the data entered on that form even if you relogin in same browser. But if we give a error message in javascript and stay on page data is still there that they can copy/paste on a new form.

A practical use case for this problem is when you are capturing from client on phone, so you would not like to bother client again complaining that my session expired. Here is a workaround to this problem.

<apex:page standardController="Account">
  <script src="/soap/ajax/27.0/connection.js" />
    <script>
      function saveRecord(){
        try{
          sforce.connection.sessionId = "{!$Api.Session_ID}";
          var result = sforce.connection.query("Select Name, Id from User Limit 1");
          if(result)
            return true;
          else
            return false;      
        }
        catch(ex){
          if(ex.faultcode == 'sf:INVALID_SESSION_ID')
            alert('Your session has expired, data will not be saved.');
          else
            alert(ex);
          return false;
        }
      }
    </script>
  <apex:form >
    <apex:inputField value="{!Account.Name}" />
    <apex:commandButton action="{!save}" value="Save" onclick="return saveRecord();" />
  </apex:form>
</apex:page>

Saturday, March 16, 2013

Ant Deploy to permanently remove custom objects

Ant and Force.com Migration tool (ant-salesforce.jar) are very powerful command line tools to manage deployments in salesforce.

I have been using this for a long time and it has proved very productive for deployment tasks. Recently I was trying to remove custom objects from one of my developer org using migration tool when I faced a problem. When we delete a object from salesforce user interface it is not deleted permanently. It remain there in list of "Deleted objects" and you can undelete it. I wanted to delete my objects permanently as those were not needed. Salesforce Ant Deploy task has an attribute "purgeOnDelete" which is expected to delete custom objects permanently. But when I tried to use this I got following error:

sf:deploy doesn't support the "purgeOnDelete" attribute.

As per salesforce documentation if we set purgeOnDelete to true, the deleted components in the destructiveChanges.xml manifest file aren't stored in the Recycle Bin. Instead, they become immediately eligible for deletion.

But this feature doesn't work as documented. So Let's see how we are going to overcome this. If you are new to Force.com Migration tool refer salesforce documentation for getting started with this fantastic tool. I am expecting that you have prior knowledge of Salesforce Migration tool.


Step 1. First step it to make purgeOnDelete available for use. For this we have to extend DeployTask class from com.salesforce.ant package that comes in ant-salesforce.jar. Here are detailed steps to do this and create a new "DeployPurge.jar"

  1. Start Eclipse and select File | New | Java Project. In New Java Project dialog box enter name of your project and optionally Location. Click "Next".

  2. Click "Libraries" tab on next screen.
  3. Click "Add External JARs..." button and locate ant.jar and ant-salesforce.jar. You can find ant.jar and ant-salesforce.jar in lib directory under Ant installation folder. If you don't find ant-salesforce.jar in lib folder you need to follow instruction in Force.com Migration Tool Guide to install Ant and Salesforce migration tool on your machine.
  4. Click "Open", on next screen click "Finish"
  5. Right Click src folder in eclipse package explorer and select New | Class
  6. Enter "com.salesforce.ant" in package field and "DeployPurge" in name field.
  7. Replace your class code with following code.
    package com.salesforce.ant;
    import com.salesforce.ant.DeployTask;
    public class DeployPurge extends DeployTask
    {
        public DeployPurge()
        {
            this.deployOptions.setPurgeOnDelete(false);
        }
    
        public void setPurgeOnDelete(boolean purgeOnDelete) 
        {
            this.deployOptions.setPurgeOnDelete(purgeOnDelete);
        }
    }
    
  8. We have simply created a new class by extending DeployTask class and created a new method in this to set purgeOnDelete.
  9. Now we need to export our project as a jar file. Right click on your project in package explorer and select "Export"
  10. Expend Java and select "JAR file", click next. Make selection as per below screenshot.

  11. Click Finish. Our customized jar file is ready. Place this jar in ant\lib directory where you already have ant-salesforce.jar file.
Step 2. Next step is to use our jar file and purgeOnDelete option. We need following files in a folder.
build.xml
build.properties
removecode\package.xml
removecode\destructiveChanges.xml

build.xml
<project basedir="." default="undeploy" name="Sample usage of DeployPurge" xmlns:sf="antlib:com.salesforce">
    <property file="build.properties" />
    <property environment="env" />
    <taskdef classname="com.salesforce.ant.DeployPurge" name="deploypurge"/>
    <target name="undeploy">
     <deploypurge username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" deployroot="removecode"  purgeondelete="true" />
     </target>
  </project>
build.properties
# build.properties
# Specify the login credentials for the desired Salesforce organization
sf.username = username@mydomain.com
sf.password = passwordtoken
# Use 'https://login.salesforce.com' for production or developer edition (the default if not specified).
# Use 'https://test.salesforce.com for sandbox.
sf.serverurl = https://login.salesforce.com
package.xml
<package xmlns="http://soap.sforce.com/2006/04/metadata">
    <version>25.0</version>
</package>
destructiveChanges.xml
<package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>testobj__c</members>
        <name>CustomObject</name>
    </types>
    <version>25.0</version>
</package>

In build.properties file enter your salesforce username, password and security token.

In destructiveChanges.xml repalce testobj__c with your object name. You can repeat this <members> tag multiple time to delete multiple objects in one go.


Step 3. Next step is to fire the ant task from command line. Use this step carefully as this will delete object and all its data and you will not be able to recover it. 

  1. Start command prompt and move to folder where you have created above files.
  2. Run following command : ant undeploy
  3. Login to salesforce and check that your objects are delete permanently.
You can find source code for all this on github.