Friday 2 March 2012

Tool for SalesForce Profile Comparison, Field Level Security

Hi many a time while working in Salesforce we get the boring and mechanical task of comparing profiles, and out of this worst part is field level security. This task gets worse when we have some objects with large number of custom fields. So to sort this out I have written a java code that will read files from two different folders(Download profiles in your eclipse and pass the path of the Profile folders from two different project) or if you want to compare just two files, put them in two folders and provide the path of those two folders.

After comparison, the code will generate a parent directory, containing children directories named on the profile, the children directories will contain two csv files each one for object comparison and other for Field level security comparison.

To execute this code, you just need eclipse of core java libraries, and change the path mentioned in the class to that of your system specific path, and get the results.

please find the code below.






package com.utility;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class CompareSFDCProfiles {

public static final String pathOfFile1 = "C://Documents and Settings//varun.vatsa//Desktop//src//profiles1";//directory one containing profiles.
public static final String pathOfFile2 = "C://Documents and Settings//varun.vatsa//Desktop/src//profiles2";//directory two containing profiles to be compared.
public static String directoryRootPath = "C://Documents and Settings//varun.vatsa//Desktop//ProfileComparisionMedtronic";//This is the parent directory that will hold the directories with comparison data.
public static String comparingProfileName ="";
public static String csv="";

public static void main(String[] args){
File folder = new File(pathOfFile1);
File folderCVG = new File(pathOfFile2);
List<File> listCC = new ArrayList<File>();
List<File> listCVG = new ArrayList<File>();
Map<File, File> ccCvgFileMap = new HashMap<File, File>();
getFiles(folder, listCC);
getFiles(folderCVG, listCVG);
//getCSVofFilesinTwoFolders(listCC,listCVG);System.exit(0);//Please un-comment this line if a CSV of files in different folders is required.
getListOfCommonFiles(ccCvgFileMap,listCC,listCVG);

System.out.println("::::Contents of common File Map"+ccCvgFileMap);


for(File f:ccCvgFileMap.keySet()){
if(f!=null){
System.out.println("CC File Name ::"+f.getPath()+"---CVG File Name ::" +ccCvgFileMap.get(f).getPath());
}
}
getNodesWithDifferentValues(ccCvgFileMap);
}

public static void getCSVofFilesinTwoFolders(List<File> listCC,List<File> listCVG){
String csv = "File from Folder1,File from Folder2\n";
List<String> tempList  =new ArrayList<String>();
Map<String,String> fieldMap = new HashMap<String, String>();
for(File f1:listCC){
Boolean foundMatch = false;
for(File f2:listCVG){
if((f1.getName()).equals(f2.getName())){
foundMatch=true;
fieldMap.put(f1.getName(), f2.getName());
}
}

if(!foundMatch){
fieldMap.put(f1.getName(), " ");
}
}

for(File f2:listCVG){
Boolean foundMatch = false;
for(String s:fieldMap.values()){
if((f2.getName()).equals(s)){
foundMatch = true;
}
}
if(!foundMatch){
tempList.add(f2.getName());
}
}

for(String s:fieldMap.keySet()){
csv += s+","+fieldMap.get(s)+"\n";
}
if(tempList!=null && tempList.size()>0){
for(String s:tempList){
csv += " "+","+s+"\n";
}

}

try{
 String file_name = "C://Documents and Settings//varun.vatsa//Desktop//"+"FilesInFolders.csv";
         FileWriter file = new FileWriter(file_name);
         BufferedWriter out = new BufferedWriter (file);
         out.write(csv);
         out.close();

}catch(Exception e){

}
}
public static void getFiles(File folder, List<File> list) {
         File[] files = folder.listFiles();
         for(int j = 0; j < files.length; j++) {
             list.add(files[j]);
             if(files[j].isDirectory())
                 getFiles(files[j], list);
         }
     }

public static void getListOfCommonFiles( Map<File, File> fileMap, List<File> listCC,List<File> listCVG){
        Map<String,File> ccFileMAp = new HashMap<String, File>();
        Map<String,File> cvgFileMAp = new HashMap<String, File>();
       
        for(File f:listCC){
            ccFileMAp.put(f.getName(), f);
        }
       
        for(File f:listCVG){
            cvgFileMAp.put(f.getName(),f);
        }
       
        for(String s:cvgFileMAp.keySet()){
            fileMap.put(ccFileMAp.get(s), cvgFileMAp.get(s));
        }
    }

public static void getNodesWithDifferentValues(Map<File, File> fileMap){
new File(directoryRootPath).mkdirs();
        for(File f:fileMap.keySet()){
            try{
            comparingProfileName=f.getName();
                compareFiles(f,fileMap.get(f));
            }catch(Exception e){
                System.out.println(e.getMessage());
            }
         }
    }

public static void compareFiles(File f1,File f2) throws ParserConfigurationException,IOException,SAXException,TransformerConfigurationException{
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        Document docc = docBuilder.parse(f1);
        Document docv = docBuilder.parse(f2);
     
        TransformerFactory tFactory = TransformerFactory.newInstance();
        Transformer tFormer = tFactory.newTransformer();
     
        Element rootcc = docc.getDocumentElement();
        Element rootcv = docv.getDocumentElement();
     
        NodeList nlcObj = rootcc.getElementsByTagName("objectPermissions");
        NodeList nlvObj = rootcv.getElementsByTagName("objectPermissions");
        NodeList nlcField = rootcc.getElementsByTagName("fieldPermissions");
        NodeList nlvField = rootcv.getElementsByTagName("fieldPermissions");
     
        getObjectMapForComparasions(nlcObj,nlvObj);
        CompareFieldPermissions(nlcField,nlvField);
   
}


public static void getObjectMapForComparasions(NodeList nlc,NodeList nlv){

Map<String,Node> nlMapcc  = getObjectMapOnName(nlc);
         Map<String,Node> nlMapcv  = getObjectMapOnName(nlv);
       
         Map<String,Map<String,String>> objectValuesMapcc = new HashMap<String, Map<String,String>>();
         Map<String,Map<String,String>> objectValuesMapcv = new HashMap<String, Map<String,String>>();
       
         for(String s:nlMapcv.keySet()){
          Map<String,String> ccValsMap = new HashMap<String, String>();
          Map<String,String> cvValsMap = new HashMap<String, String>();
       
          if( nlMapcv.get(s)!=null){
            NodeList n =  nlMapcv.get(s).getChildNodes();
           
            for(int i = 0 ; i < n.getLength();i++){
            Node el = n.item(i);
            if( el.getTextContent()!=null || el.getTextContent()!=""){
            cvValsMap.put(el.getNodeName(), el.getTextContent());
            }
                }
            }
           
            if( nlMapcc.get(s)!=null){
            NodeList n =  nlMapcc.get(s).getChildNodes();
           
            for(int i = 0 ; i < n.getLength();i++){
            Node el = n.item(i);
            if( el.getTextContent()!=null || el.getTextContent()!=""){
            ccValsMap.put(el.getNodeName(), el.getTextContent());
            }
                }
            }
            objectValuesMapcc.put(s, ccValsMap);
            objectValuesMapcv.put(s, cvValsMap);
         }
         compareObjectPermissions(objectValuesMapcc, objectValuesMapcv,"objectPermissions");

}

public static void CompareFieldPermissions(NodeList nlc,NodeList nlv){

      Map<String,Node> nlMapccFields  = getFieldMapOnName(nlc);
         Map<String,Node> nlMapcvFields  = getFieldMapOnName(nlv);
       
         Map<String,Map<String,String>> fieldValuesMapcc = new HashMap<String, Map<String,String>>();
         Map<String,Map<String,String>> fieldValuesMapcv = new HashMap<String, Map<String,String>>();
       
         for(String s:nlMapcvFields.keySet()){
          Map<String,String> ccValsMap = new HashMap<String, String>();
          Map<String,String> cvValsMap = new HashMap<String, String>();
       
          if( nlMapcvFields.get(s)!=null){
            NodeList n =  nlMapcvFields.get(s).getChildNodes();
           
            for(int i = 0 ; i < n.getLength();i++){
            Node el = n.item(i);
            if( el.getTextContent()!=null || el.getTextContent()!=""){
            cvValsMap.put(el.getNodeName(), el.getTextContent());
            }
               }
             }
           
             if( nlMapccFields.get(s)!=null){
            NodeList n =  nlMapccFields.get(s).getChildNodes();
           
            for(int i = 0 ; i < n.getLength();i++){
            Node el = n.item(i);
            if( el.getTextContent()!=null || el.getTextContent()!=""){
            ccValsMap.put(el.getNodeName(), el.getTextContent());
            }
                 }
             }
             fieldValuesMapcc.put(s, ccValsMap);
             fieldValuesMapcv.put(s, cvValsMap);
         
          }
         compareObjectPermissions(fieldValuesMapcc, fieldValuesMapcv,"fieldPermissions");
}

public static Map<String,Node> getObjectMapOnName(NodeList nl){
         Map<String,Node> nlMap = new HashMap<String, Node>();
         if(nl!=null && nl.getLength()>0){
             for(int i = 0 ; i < nl.getLength();i++){
                Element el = (Element)nl.item(i);
                 if(el.getElementsByTagName("object")!=null){
                     NodeList RT = el.getElementsByTagName("object");
                     nlMap.put(RT.item(0).getTextContent(), nl.item(i));
                 }
             }
         }
       
         return nlMap;
     }


public static Map<String,Node> getFieldMapOnName(NodeList nl){
         Map<String,Node> nlMap = new HashMap<String, Node>();
         if(nl!=null && nl.getLength()>0){
             for(int i = 0 ; i < nl.getLength();i++){
                Element el = (Element)nl.item(i);
                 if(el.getElementsByTagName("field")!=null){
                     NodeList RT = el.getElementsByTagName("field");
                     nlMap.put(RT.item(0).getTextContent(), nl.item(i));
                 }
             }
         }
       
         return nlMap;
     }


public static void compareObjectPermissions(Map<String,Map<String,String>> oMap1,Map<String,Map<String,String>> oMap2,String comparingNode){

Map<String,Map<String,String>> mapOfObjectsWithDiffFieldPermissions = new HashMap<String, Map<String,String>>();

for(String s:oMap1.keySet()){
Map<String,String> map1 = oMap1.get(s);
Map<String,String> map2 = oMap2.get(s);
mapOfObjectsWithDiffFieldPermissions.put(s,copmareObjPermissionForSingleObject(map1, map2));

}
writeCsvOfDifferences(mapOfObjectsWithDiffFieldPermissions,comparingNode);
 }

public static Map<String,String> copmareObjPermissionForSingleObject(Map<String,String> map1, Map<String,String> map2){
Map<String,String> tempMap = new HashMap<String, String>();

for(String s:map1.keySet()){
if(s!="object" && !map1.get(s).trim().equalsIgnoreCase(map2.get(s).trim())){
tempMap.put(s+"::"+map1.get(s), map2.get(s));
}
}
return tempMap;
}

public static void writeCsvOfDifferences(Map<String,Map<String,String>> diffMap,String comparingNode){
String file_name="";

 try
     {   String toWrite="";

 if(comparingNode=="objectPermissions"){
 toWrite = "Object Permissions\n\n";
 toWrite += "\""+"Object Name"+"\""+","+"\""+"Property"+"\""+","+"\""+"Profile 1 Value"+"\""+","+"\""+"Profile 2 Value"+"\"\n";
     }else if(comparingNode=="fieldPermissions"){
     toWrite = "Field Permissions\n\n";
     toWrite +="\""+"Object Name"+"\""+","+"\""+"Field Name"+"\""+","+"\""+"Property"+"\""+","+"\""+"Profile 1 Value"+"\""+","+"\""+"Profile 2 Value"+"\"\n";
    }

         if(diffMap!=null){
             for(String s:diffMap.keySet()){
           
             if(comparingNode=="objectPermissions"){
               for(String s2:diffMap.get(s).keySet()){
               String[] keyVal = s2.split("::");
             
               if(keyVal.length==2){
               toWrite +="\""+s+"\""+","+"\""+keyVal[0]+"\""+","+"\""+keyVal[1]+"\""+","+"\""+diffMap.get(s).get(s2)+"\"\n";
               }
               }
         }else if(comparingNode=="fieldPermissions"){
        String[] objNameArr = s.split("\\.");
              String objNAme = objNameArr[0];
              String fieldName = objNameArr[1];
             
               for(String s2:diffMap.get(s).keySet()){
               String[] keyVal = s2.split("::");
             
               if(keyVal.length==2){
               toWrite +="\""+objNAme+"\""+","+"\""+fieldName+"\""+","+"\""+keyVal[0]+"\""+","+"\""+keyVal[1]+"\""+","+"\""+diffMap.get(s).get(s2)+"\"\n";
               }
               }
        }
             }
           
         System.out.println(toWrite);
         Boolean dirExists = new File(directoryRootPath+"//"+comparingProfileName).exists();
         if(dirExists){
         file_name = directoryRootPath+"//"+comparingProfileName+"//"+comparingProfileName+"-"+comparingNode+".csv";
         }else{
         new File(directoryRootPath+"//"+comparingProfileName).mkdirs();
         file_name = directoryRootPath+"//"+comparingProfileName+"//"+comparingProfileName+"-"+comparingNode+".csv";
         }
         
         FileWriter file = new FileWriter(file_name);
         BufferedWriter out = new BufferedWriter (file);
         out.write(toWrite);
         out.close();
         }
     }
     catch (IOException e)
     {
         System.out.println(e.getMessage());
     }
}
}




No comments:

Post a Comment