2

We are trying to retrieve zip file of metadata in Salesforce. After trying in several ways we are able to get the metadata in a zip file but, it only has "package.xml" not the folder detail file as explained in http://www.salesforce.com/us/developer/docs/api_meta/Content/meta_folder.htm

<?xml version="1.0" encoding="UTF-8"?>
<DocumentFolder xmlns="http://soap.sforce.com/2006/04/metadata">
    <accessType>Public</accessType>
    <name>sampleFolder</name>
    <publicFolderAccess>ReadWrite</publicFolderAccess>
</DocumentFolder>

This above xml we can not get.

We are querying this way:

//Query Code

String session = 'session';
String instance = 'https://na17.salesforce.com';
MetadataService.MetadataPort service = MetadataUtils.createService(session, instance);
List<MetadataService.ListMetadataQuery> queries = new List<MetadataService.ListMetadataQuery>();
MetadataService.ListMetadataQuery queryLayout = new MetadataService.ListMetadataQuery();

queryLayout.folder = '';
queryLayout.type_x = 'DocumentFolder';

queries.add(queryLayout);
// return all folders name in xml
MetadataService.FileProperties[] fileProperties = new List<MetadataService.FileProperties>();

// query metadata items by callout
fileProperties = service.listMetadata(queries, '30.0');

Here we get all folder names.

Retrieval method. It is not working for folders:

// But we are getting a zip file with "package.xml" only. It must have other files also.
for(MetadataService.FileProperties fileinfo :fileProperties)
{
    // insert all folder names received in above query ex: Test_Document_Folder
    li.add(fileinfo.fullname);
}
typeAndItemMap.put('DocumentFolder',li);

// Creating AsyncResult by callout. Insert all type names in list to retrieve
MetadataService.AsyncResult asyncResult = MetadataUtils.retrieveMetadataItem(types, session, instance);
String asyncId;
if(asyncResult.Id != null)
{
 asyncId = asyncResult.Id;
}

Folder retrieval is listed in metadata type but not getting retrieved. Only "package.xml" is received.

Update: Here is the way to retrieve folder-meta.xml but it doesn't return document file.

Map<String,List<String>> typeAndItemMap = new Map<String,List<String>>();
List<String> li = new List<String>();
// Set up Document file retrieve
li.add('Test/AnyFile.txt');
typeAndItemMap.put('Document',li);

// clear the list to add folder to retrieve
li.clear();
// Add folder
li.add('My_Folder');

// combine folder and document to retrieve at once
typeAndItemMap.put('DocumentFolder',li);
MetadataService.AsyncResult asyncResult = MetadataUtils.retrieveMetadataItem(typeAndItemMap, session, instance);
if(asyncResult.Id != null)
{
  System.debug('asyncResult.Id------:'+asyncResult.Id);
}

Any help will be appreciated.

  • Are you using Apex Metadata API? – Andrew Fawcett Sep 19 '14 at 12:59
  • Yes, we are using parsed wsdl in apex @AndrewFawcett – Ashwani Sep 19 '14 at 13:00
  • Ok, i'm having a look, i also provide a library for using this API in Apex, here, github.com/financialforcedev/apex-mdapi. – Andrew Fawcett Sep 19 '14 at 13:04
  • @AndrewFawcett I tried with your library but some how I couldn't get folder zip file. It get retrieved with "package.xml" only. Thanks for looking into it. – Ashwani Sep 19 '14 at 13:07
  • 1
    Yes, it's not the library, its that the Salesforce Metadata API retrieve its wrapping does not support what you want. I've found the answer another way though! :-) – Andrew Fawcett Sep 19 '14 at 13:30
4

Folders are strange things indeed, there are four types of folders, document, email, report and dashboard, they do not exist as a physical Metadata Type, hence you don't see them listed here. Most of the time they don't work like regular Metadata components with the rest of the API either. The Folder documentation also further hints at their slightly 'special' nature!

Folders are stored in the corresponding component directory of the package. These directories are named documents, email, reports, and dashboards. Folders do not have a text file representation—they are containers for files. For each folder, an accompanying metadata file named FolderName-meta.xml is created at the same directory level. The FolderName-meta.xml metadata file contains the metadata information for that folder, such as the accessType. For example, for a documents folder named sampleFolder, there’s a sampleFolder-meta.xml within the documents folder of the package.

You cannot retrieve just the folder itself with the Metadata API retrieve operation, you have to request at least one file for it to create the folder and the associated metadata XML file for the folder. In my testing just now i can see that you can effectively put anything you like as the type when using retrieve and it just ignores (unlike other operations that throw errors) invalid ones, most misleading!

Fortunately you can use the latest readMetadata operation combined with the listMetadata to retrieve them instead! Here is an example using the Apex Metadata API to do just that...

MetadataService.MetadataPort service = new MetadataService.MetadataPort();
List<MetadataService.ListMetadataQuery> queries = new List<MetadataService.ListMetadataQuery>();
service.SessionHeader = new MetadataService.SessionHeader_element();
service.SessionHeader.sessionId = UserInfo.getSessionId();

MetadataService.ListMetadataQuery queryDocumentFolder = new MetadataService.ListMetadataQuery();
queryDocumentFolder.type_x = 'DocumentFolder';
queries.add(queryDocumentFolder);       
MetadataService.FileProperties[] fileProperties = service.listMetadata(queries, 30);
List<String> folderNames = new List<String>();
for(MetadataService.FileProperties fileProperty : fileProperties)
    folderNames.add(fileProperty.fileName.replace('documents/', ''));

List<MetadataService.DocumentFolder> folder = 
    (List<MetadataService.DocumentFolder>) 
        service.readMetadata('DocumentFolder', folderNames).getRecords();

Retrieve Metadata Demo Further Info

This screenshot shows the Retrieve Demo from the Apex Metadata API retrieving a document file and the document folder, you can see it retrieves the document metadata file. Again this only works IF you also retrieve a file as well sadly.

enter image description here

NOTE: Take a look at this code to see how the above works, to try it out enter the name of your folder in the Folder field, select Document from the drop down, select any file in the folder and click Retrieve.

  • Thanks for the response. It returns a Metadata type class. It is polymorphic in nature. Can we get deployable zip file as a response of folder retrieve request? – Ashwani Sep 19 '14 at 13:38
  • When we try to retrieve either it returns folder-meta.xml or the document itselt but not both. – Ashwani Sep 19 '14 at 13:41
  • It may extend the Metadata base class yes, but in regards to retrieving it via 'retrieve' its a no go, without also retrieving a file within the folder. I'll attach an example from the Retrieve Metadata Demo from my library to illustrate that does work. – Andrew Fawcett Sep 19 '14 at 13:45
  • I have updated my answer with a sample code which return folder-meta.xml. We provide both document file and folder in package. So, it should return the folder and document file but it returns folder (meta.xml) only. – Ashwani Sep 19 '14 at 13:54
  • Thanks for the great help and unveiling the hidden part of API. Hope it will definitely help others if they reach to this problem. – Ashwani Sep 29 '14 at 17:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.