0

I want to build an java application where my code take package.xml and retrieve all metadata. Well this one is done using Java Example code given by Salesforce. Now I need to unzip that zip and do changes in metadata programatically like set Validation, Workflows to Inactive. and then zip the file back with base64 encode.

I used programatically zipped file and deploy it to SFDC using file base Metadata deploy call. Server gives success message but changes are not reflecting in SFDC org.

According to my analysis the issue is with editing the metadata and creating zip file. Looks some encoding issue. Below is the code I use to create zip.

< package wsc;
import org.apache.commons.codec.binary.Base64;
public class ZipUtils {
private List <String> fileList;
public static  String OUTPUT_ZIP_FILE;
public static  String SOURCE_FOLDER ; // SourceFolder path

public ZipUtils(String SourceFolder, String TargetZip) {
   fileList = new ArrayList < String > ();
   OUTPUT_ZIP_FILE = TargetZip;
   SOURCE_FOLDER = SourceFolder;

}

public static void main(String[] args) {
  // ZipUtils appZip = new ZipUtils();
 //  appZip.generateFileList(new File(SOURCE_FOLDER));
 //  appZip.zipIt(OUTPUT_ZIP_FILE);

}

 public void zipIt(String zipFile) {
   byte[] buffer = new byte[1024];
   String source = new File(SOURCE_FOLDER).getName();
   FileOutputStream fos = null;
   ZipOutputStream zos = null;
   try {
       fos = new FileOutputStream(zipFile);
       zos = new ZipOutputStream(fos);

       System.out.println("Output to Zip : " + zipFile);
       FileInputStream in = null;

       for (String file: this.fileList) {
           System.out.println("File Added : " + file);
          // ZipEntry ze = new ZipEntry(source + File.separator + file);

           ZipEntry ze = new ZipEntry(file);
           zos.putNextEntry(ze);
           try {
               in = new FileInputStream(SOURCE_FOLDER + File.separator + file);
             //  in = new FileInputStream(file);
               int len;
               while ((len = in .read(buffer)) > 0) {
                   byte [] enc = Base64.encodeBase64(Arrays.copyOf(buffer, len));
                   zos.write(enc, 0, enc.length);
               }
           } finally {
               in.close();
           }
       }

       zos.closeEntry();
       System.out.println("Folder successfully compressed");

   } catch (IOException ex) {
       ex.printStackTrace();
   } finally {
       try {
           zos.close();
       } catch (IOException e) {
           e.printStackTrace();
       }
   }

}

 public void generateFileList(File node) {
   // add file only
   if (node.isFile()) {
       fileList.add(generateZipEntry(node.toString()));
   }
   System.out.println("fileList---"+fileList);
   if (node.isDirectory()) {
       String[] subNote = node.list();
       for (String filename: subNote) {
           generateFileList(new File(node, filename));
       }
   }

}

 private String generateZipEntry(String file) {
   System.out.println("file---"+file);
    System.out.println("SourceFolder---"+SOURCE_FOLDER);
   return file.substring(SOURCE_FOLDER.length() + 1, file.length());
 }}

Appreciate any help or suggestions. Thanks in Advance, Jitendra

2
  • Check the deployment status page from setup.
    – ManishG
    Feb 6, 2018 at 12:34
  • Hi @ManishG , Thanks for taking out time for this. I checked the same the Deployment is showing succeeded but the Deploy Components is 0. If I manually zip the file then It works properly but if I zip with program that's not working. So the problem is with zipping code.
    – Jeet
    Feb 7, 2018 at 12:59

1 Answer 1

0

To update/Inactive the Validation, Workflows you can use the tooling API. With tooling API you can update Validation/Workflows within the code and no need to update XML files.

Here is the example:

public static void inactivateValidationRules(ToolingConnection toolingConnection, String queryStr) throws Exception {
    ArrayList<SObject> listRecordsToUpdate = new ArrayList<SObject>();
    List<SObject> listValidationRules = ToolingApiCommon.querySfdcObjectToList(toolingConnection, queryStr);
    System.out.println("listValidationRules.size(): " + listValidationRules.size());
    for(SObject sObject : listValidationRules) {
        ValidationRule validationRule = (ValidationRule) sObject;
        System.out.println("ValidationRule Metadata: " + validationRule);
        // Updating only the ones that are active
        if(validationRule.getActive() == true) {
            validationRule.setActive(false);
            listRecordsToUpdate.add(validationRule);
        }
    }

    ToolingApiCommon.createUpdateSfdcRecords(toolingConnection, listRecordsToUpdate, 50);   
}

If you want to use the approach of retrieving the package, updating the XML files for Validation/Workflows and deploying while using Metadata API and need to make sure the package files are zipped correctly you may non need to encode (Base64.encodeBase64) you may only need to add the bytes into the zip file. Here is a working example to zip the files:

//  ------------------------------------------------------------------------------------------------
    /**
     * @Desc:   
     */ 
    public static void getAllFiles(File dir, List<File> fileList) {
        try {
            File[] files = dir.listFiles();
            for (File file : files) {
                fileList.add(file);
                if (file.isDirectory()) {
                    System.out.println("directory:" + file.getCanonicalPath());
                    getAllFiles(file, fileList);
                } else {
                    System.out.println("     file:" + file.getCanonicalPath());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

//  ------------------------------------------------------------------------------------------------
    /**
     * @Desc:   
     */ 
    public static void writeZipFile(File directoryToZip, List<File> fileList, String zipFilePathName) {

    try {
        FileOutputStream fos = new FileOutputStream(zipFilePathName);
        ZipOutputStream zos = new ZipOutputStream(fos);

        for (File file : fileList) {
            if (!file.isDirectory()) { // we only zip files, not directories
                addToZip(directoryToZip, file, zos);
            }
        }
        zos.close();
        fos.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

//  ------------------------------------------------------------------------------------------------
    /**
     * @Desc:   
     */ 
    public static void addToZip(File directoryToZip, File file, ZipOutputStream zos) throws FileNotFoundException,
            IOException {

    FileInputStream fis = new FileInputStream(file);

    // we want the zipEntry's path to be a relative path that is relative
    // to the directory being zipped, so chop off the rest of the path
    String zipFilePath = file.getCanonicalPath().substring(directoryToZip.getCanonicalPath().length() + 1,
            file.getCanonicalPath().length());
    System.out.println("Writing '" + zipFilePath + "' to zip file");
    ZipEntry zipEntry = new ZipEntry(zipFilePath);
    zos.putNextEntry(zipEntry);

    byte[] bytes = new byte[1024];
    int length;
    while ((length = fis.read(bytes)) >= 0) {
        zos.write(bytes, 0, length);
    }

    zos.closeEntry();
    fis.close();
}

Let me know is this helps.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .