Thursday, 27 June 2013

Salesforce ANT Tool (Force.com Migration Tool)

Configurations for softwares
=====================
Following are the three ways to Migrate code, objects, schema etc… from organization to another :

Change sets (From Salesforce site)
Eclipse (Using “Deploy to force.com server” option in Eclipse)
ANT (Java based tool)
We are going to discuss the ANT based migration, step by step:

Prerequisite:
JDK 1.5 or above

Step 1:
Download ANT distribution from – “http://ant.apache.org/bindownload.cgi

Step 2:
Set Environment variable “ANT_HOME”. The path should be of parent folder of “bin”. Also add the “bin” folder to your path.

Step 3:
Check whether ANT is installed or not properly by running command “ant -version”. It might be possible that you receive message something like “unable to find tools.jar”. You can copy this jar from “JDK_HOME/lib/tools.jar” to “JRE/lib” folder.


Step 4:
Login to salesforce and navigate to “Your Name |Setup | Develop | Tools” and download “Force.com Migration tool”.

Unzip the downloaded file to the directory of your choice. Copy the “ant-salesforce.jar” file from the unzipped file into the ant lib directory.

To start with deployment using ANT, we will need “build.xml” and “build.properties” file. As there is no need of “build.properties” however its good to have it so that the configuration related settings are in different file. You can copy both files from “sample” folder of unzipped content from salesforce. Following is the structure of “build.properties” file.





ANT Tool Migration
=================
1)Set path for Home_Java
2)Copy too.jar from jdk lib to jre lib
2)Set path for ANT_HOME
3)Set patth upto lib ANT
4)To test type command ant-VERSION
5)Copy "ant-salesforce.jar" into lib folder of ANT from Salesforce ANT
6)We have different folder in Sample folder of Force.com Migration tool
7)In Sample folder we have different folders lik "Unpackaged" and "retrieveOutput",removecodpkg,mypkg,codepkg.
8)Here in Unpackaged folder we have one file called "Package.xml"

in this file we can provide the structure of metadata what we need from source org as below.

eg:
===

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
            <types>
        <members>*</members>
        <name>CustomObject</name>
    </types>
    <types>
        <members>*</members>
        <name>ApexClass</name>
    </types>
    <types>
        <members>*</members>
        <name>ApexTrigger</name>
    </types>
            <types>
                        <members>*</members>
                        <name>ApexPage</name>
            </types>
    <version>27.0</version>
</Package>

===========================

9)in the same "Sample" Folder we have some files alos Build.properties,Build.xml

build.properties file
==================
# build.properties
#

# Specify the login credentials for the desired Salesforce organization
sf.username = ingenius@sfdc.com
sf.password = hijklm321TMi4AC0ouWVXpXpF45Fk63vt
#sf.username = balajilivem@gmail.com
#sf.password = hijklm321uricW52iGMVBZEX0Arii2Qjd
#sf.pkgName = <Insert comma separated package names to be retrieved>
#sf.zipFile = <Insert path of the zipfile to be retrieved>
#sf.metadataType = <Insert metadata type name for which listMetadata or bulkRetrieve operations are to be performed>

# 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

# If your network requires an HTTP proxy, see http://ant.apache.org/manual/proxy.html for configuration.
#


in the above file we need to specify User Name and Password of Source from which we want to retrieve as above.

in the above file "#" indicates  comment.

Build.xml
==============
1)in the below file which i highlighted in pink color having the directory or(folder) name called "retrieveUnpackaged" assigned to dir attribute like  <mkdir dir="retrieveUnpackaged"/>
it means we need to create an empty folder or directory like this in our "Sample" folder which is used to hold retrieved components from source org.

2) <target name="retrieve">
here whenever we want run ant tool to retrieve components from source org we need to use the following command

/sample>ant retrieve

3) <sf:retrieve username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" retrieveTarget="retrieveUnpackaged" unpackaged="unpackaged/package.xml"/>
 here Username and password,serverUrl filled with values from Build.property file

and "retrieveTarget" specifies folder name we have created to hold components from Source org

and "Unpackaged" specifies path of package.xml which contains "metadat structure" specifies what components we need to get from Source org

like

 <types>
        <members>*</members>
        <name>CustomObject</name>
    </types>
the above lines indicates total objects from source.It is specied in "package.xml" of "Unpackaged" folder

4)When you run the Command as in "2" point then all the components which are we specified in "package.xml" file of "Unpackaged" folder copied into
the directory or folder called "retrieveUnpackaged".


5)Then we need to deploy these into production

6)To deploy into the production  we need to have following in our build.xml


    <!-- Deploy the unpackaged set of metadata retrieved with retrieveUnpackaged -->
    <target name="deployUnpackaged">
      <sf:deploy username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" deployRoot="retrieveUnpackaged"/>
    </target>


Here in the above deployRoot="retrieveUnpackaged" indicates Root folder folde which contains the component which are ready to deploy


7)we need to specify Username and password of Production in Build.properties file

8)Then run command

/sample>ant deployUnpackaged

Then deployment will be successfull if there is no issues with componets we retrieved from source org





<project name="Sample usage of Salesforce Ant tasks" default="test" basedir="." xmlns:sf="antlib:com.salesforce">

    <property file="build.properties"/>
    <property environment="env"/>

    <!-- Test out deploy and retrieve verbs for package 'mypkg' -->
    <target name="test">
      <!-- Upload the contents of the "mypkg" package -->
      <sf:deploy username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" deployRoot="mypkg"/>
      <mkdir dir="retrieveOutput"/>
      <!-- Retrieve the contents into another directory -->
      <sf:retrieve username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" retrieveTarget="retrieveOutput" packageNames="MyPkg"/>
    </target>

    <!-- Retrieve an unpackaged set of metadata from your org -->
    <!-- The file unpackaged/package.xml lists what is to be retrieved -->
    <target name="retrieve">
      <mkdir dir="retrieveUnpackaged"/>
      <!-- Retrieve the contents into another directory -->
      <sf:retrieve username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" retrieveTarget="retrieveUnpackaged" unpackaged="unpackaged/package.xml"/>
    </target>

    <!-- Retrieve all the items of a particular metadata type -->
    <target name="bulkRetrieve">
      <sf:bulkRetrieve username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" metadataType="${sf.metadataType}" retrieveTarget="retrieveUnpackaged"/>
    </target>

    <!-- Retrieve metadata for all the packages specified under packageNames -->
    <target name="retrievePkg">
      <sf:retrieve username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" retrieveTarget="retrieveOutput" packageNames="${sf.pkgName}"/>
    </target>

    <!-- Deploy the unpackaged set of metadata retrieved with retrieveUnpackaged -->
    <target name="deployUnpackaged">
      <sf:deploy username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" deployRoot="retrieveUnpackaged"/>
    </target>

    <!-- Deploy a zip of metadata files to the org -->
    <target name="deployZip">
      <sf:deploy username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" zipFile="${sf.zipFile}" pollWaitMillis="1000"/>
    </target>

    <!-- Shows deploying code & running tests for code in directory -->
    <target name="deployCode">
      <!-- Upload the contents of the "codepkg" directory, running the tests for just 1 class -->
      <sf:deploy username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" deployRoot="codepkg">
        <runTest>SampleDeployClass</runTest>
      </sf:deploy>
    </target>

    <!-- Shows removing code; only succeeds if done after deployCode -->
    <target name="undeployCode">
      <sf:deploy username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" deployRoot="removecodepkg"/>
    </target>

    <!-- Shows retrieving code; only succeeds if done after deployCode -->
    <target name="retrieveCode">
      <!-- Retrieve the contents listed in the file codepkg/package.xml into the codepkg directory -->
      <sf:retrieve username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" retrieveTarget="codepkg" unpackaged="codepkg/package.xml"/>
    </target>

    <!-- Shows deploying code, running all tests, and running tests (1 of which fails), and logging. -->
    <target name="deployCodeFailingTest">
      <!-- Upload the contents of the "codepkg" package, running all tests -->
      <sf:deploy username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" deployRoot="codepkg" runAllTests="true" logType="Debugonly"/>
    </target>

    <!-- Shows check only; never actually saves to the server -->
    <target name="deployCodeCheckOnly">
      <sf:deploy username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" deployRoot="codepkg" checkOnly="true"/>
    </target>

            <!-- Retrieve the information of all items of a particular metadata type -->
    <target name="listMetadata">
      <sf:listMetadata username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}" metadataType="${sf.metadataType}"/>
    </target>

            <!-- Retrieve the information on all supported metadata type -->
    <target name="describeMetadata">
      <sf:describeMetadata username="${sf.username}" password="${sf.password}" serverurl="${sf.serverurl}"/>
    </target></project>





Monday, 3 June 2013

XML Parsing

Hi,
I am going to give a brief explanation on xml parsing.we have DOM parser to parse xml.
Before we are going to parse an xml file we need to look its strcture and we should expect how many we may need for parsing the "XML" which have to avoid number of  script statemements limitation in Apex.
Use the XmlNode class to work with a node in an XML document. The DOM represents an XML document as a hierarchy of nodes. Some nodes may be branch nodes and have child nodes, while others are leaf nodes with no children.
Node Types
There are different types of DOM nodes available in Apex. XmlNodeType is an enum of these different types. The values are:
COMMENT
ELEMENT
TEXT
It is important to distinguish between elements and nodes in an XML document. The following is a simple XML example:
<name>
    <firstName>Balaji</firstName>
    <lastName>Malemarpuram</lastName>
</name>
This example contains three XML elements: name, firstName, and lastName. It contains five nodes: the three name, firstName, and lastNameelement nodes, as well as two text nodes—Balaji and Marpuram. Note that the text within an element node is considered to be a separate text node.
Example:
======
public  class Xmlparsercls {
    public String xmlstring{get;set;}
    public String outxmlstring{get;set;}
    public String rootElement{get;set;}
    public String filename{get;set;}
    public blob body{get;set;}
    public List<Account> lstaccount{get;set;}
    public Xmlparsercls(){
      lstaccount=new List<Account>();
    }
//Parsing xml what you entered in the left text area
    public pagereference Parsexml(){
       DOM.Document xmlDOC = new DOM.Document(); 
       xmlDOC.load(xmlstring); 
       DOM.XMLNode rootElement = xmlDOC.getRootElement();
       outxmlstring=String.valueof(xmlDOC.getRootElement().getName());
       for(DOM.XMLNode xmlnodeobj:xmlDOC.getRootElement().getChildElements()){
          if(xmlnodeobj.getName()=='Name')
            outxmlstring+='\nAccount Name:'+xmlnodeobj.getText();
          if(xmlnodeobj.getName()=='Type')
            outxmlstring+='\nAccount Type:'+xmlnodeobj.getText();  
          if(xmlnodeobj.getName()=='Industry')
            outxmlstring+='\nAccount Industry:'+xmlnodeobj.getText();
       }
       
      return null;
    }
//This is for parsing xml file what you selected
  public pagereference Parsexmlfile(){
       DOM.Document xmlDOC = new DOM.Document(); 
       xmlstring=body.tostring();
       system.debug('****xmlstring'+xmlstring);
      // xmlstring=xmlstring.Substring(1,xmlstring.length());
       //outxmlstring=xmlstring;
       xmlDOC.load(xmlstring); 
       DOM.XMLNode rootElement = xmlDOC.getRootElement();
       outxmlstring=String.valueof(xmlDOC.getRootElement().getName());//gives you root element Name
       for(DOM.XMLNode xmlnodeobj:xmlDOC.getRootElement().getChildElements()){ //gives you all childnodes list
          if(xmlnodeobj.getName()=='Name')
            outxmlstring+='\nAccount Name:'+xmlnodeobj.getText();// it gives you text node
          if(xmlnodeobj.getName()=='Type')
            outxmlstring+='\nAccount Type:'+xmlnodeobj.getText();  
          if(xmlnodeobj.getName()=='Industry')
            outxmlstring+='\nAccount Industry:'+xmlnodeobj.getText();
       }
       
      return null;
    }
}
Vpage:
======
<apex:page controller="Xmlparsercls" sidebar="false">
    <apex:form >
        <apex:pageBlock >
            <apex:pageBlockButtons location="bottom">
                <apex:commandButton value="Parse Xml" action="{!Parsexml}"/>    
                <apex:commandButton value="ParseXML File" action="{!Parsexmlfile}"/>
            </apex:pageBlockButtons>
            <apex:inputTextArea value="{!xmlstring}" style="width:336px;height:260px;"/> &nbsp;&nbsp;
            <apex:inputTextArea value="{!outxmlstring}" style="width:336px;height:260px;" id="response"/><br/>

            <apex:outputLabel value="Select Xml File" for="file"/>
            <apex:inputFile fileName="{!fileName}" value="{!body}"/>
        </apex:pageBlock>
    </apex:form>
</apex:page>

Here i am choosing XML format in Text area or in xml file as shown below .According to the file we need to write and parse.

XML format:
===========
<Account>
   <Name>Balaji</Name>
   <Type>Customer</Type>
   <Industry>It</Industry>
</Account>

when you work with this example and want to test with xml file copy the same xml format as above into your notepad and save with ".xml" extension.


Ouput:
=====
When you are selecting file then click on ParseXML file button.
When you type as shown above in the textarea then click on "Parse Xml" button then you can parse the xml.


Making Startswith() and Endswith() in javascript

Hi,

By using prototypes in Javascript we can build our own methods with our own logic.Here in the following code i made two methods for comparing the string with starwith and endwith.
<script>
if ( typeof String.prototype.startsWith != 'function' ) {
  String.prototype.startsWith = function( str ) {
    return this.substring( 0, str.length ) === str;
  }
};

alert( "hello world".startsWith( "hello" ) );

if ( typeof String.prototype.endsWith != 'function' ) {
  String.prototype.endsWith = function( str ) {
    return this.substring( this.length - str.length, this.length ) === str;
  }
};

alert( "hello world".endsWith( "world" ) );
</script>