Skip to content

Commit

Permalink
Retreive CaseComment CustomObject and Workflow
Browse files Browse the repository at this point in the history
Salesforce does not return a `FileProperties` instance for
`CaseComment` when 'listMetadata` query is sent for `CustomObject` or
`Workflow` types, resulting in a backup that is missing these metadata
components.

This fix works around that by manually adding stub `FileProperties`
instances for `CaseComment` object and workflow, so that the metadata can
be retrieved.

Fixes #46
  • Loading branch information
alan-morey committed Jul 21, 2016
1 parent 8e3f2ac commit 9b6e973
Showing 1 changed file with 102 additions and 41 deletions.
143 changes: 102 additions & 41 deletions force-meta-backup.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,19 @@ class ForceService {
fileProperties
}

def listMetadataForTypes(types) {
def queries = types.collect { type ->
withValidMetadataType(type) {
def query = new ListMetadataQuery()
query.type = it
query
}
}
queries.removeAll([null])

listMetadata(queries)
}

private buildConnectionUrl = { serverUrl, username, password ->
def encode = { URLEncoder.encode(it, 'UTF-8') }

Expand Down Expand Up @@ -517,28 +530,18 @@ class MiscMetadataManifestBuilder {


private getGroupedFileProperties() {
def queries = TYPES.collect { type ->
forceService.withValidMetadataType(type) {
def query = new ListMetadataQuery()
query.type = it
query
}
}
queries.removeAll([null])

def grouped = [:]

forceService.listMetadata(queries).each { fileProperties ->
def type = fileProperties.type

if (!grouped.containsKey(type)) {
grouped[type] = []
}
def grouped = new GroupedFileProperties(
forceService.listMetadataForTypes(TYPES)
)

grouped[type] << fileProperties
}
// XXX - Hack to always retrieve the CaseComment SObject & Workflow.
//
// For some reason CaseComment is not returned in listMetadata()
// calls for CustomObject and Workflow but if we explicitly put
// these in package.xml for retrieve we can download them.
grouped.addIfMissingStandard('Workflow', 'CaseComment')

grouped
grouped.filePropertiesByType
}

def writePackageXml() {
Expand Down Expand Up @@ -575,6 +578,73 @@ class MiscMetadataManifestBuilder {
}
}

class GroupedFileProperties {
static final String NO_NAMESPACE = null;
static final String STANDARD_NAMESPACE = '';

def filePropertiesByType = [:]

GroupedFileProperties() {
}

GroupedFileProperties(List<FileProperties> fileProperties) {
addAll(fileProperties)
}

GroupedFileProperties addAll(List<FileProperties> fileProperties) {
fileProperties.each { fp ->
add(fp)
}

this
}

GroupedFileProperties add(FileProperties fp) {
if (!containsGroup(fp.type)) {
filePropertiesByType[fp.type] = []
}

filePropertiesByType[fp.type] << fp

this
}

GroupedFileProperties addIfMissingStandard(String type, String fullName) {
addIfMissing(type, fullName, STANDARD_NAMESPACE)
}

GroupedFileProperties addIfMissingCustom(String type, String fullName) {
addIfMissing(type, fullName, NO_NAMESPACE)
}

GroupedFileProperties addIfMissing(String type, String fullName, String namespacePrefix) {
addIfMissing([
type: type,
fullName: fullName,
namespacePrefix: namespacePrefix
] as FileProperties)
}

GroupedFileProperties addIfMissing(FileProperties fp) {
if (!contains(fp.type, fp.fullName, fp.namespacePrefix)) {
add(fp)
}

this
}

Boolean containsGroup(String type) {
filePropertiesByType.containsKey(type)
}

Boolean contains(String type, String fullName, String namespacePrefix) {
containsGroup(type) && filePropertiesByType[type].find {
it.fullName == fullName &&
it.namespacePrefix == namespacePrefix
}
}
}

class ProfilesMetadataManifestBuilder {
def forceService
def config
Expand Down Expand Up @@ -604,40 +674,31 @@ class ProfilesMetadataManifestBuilder {

private getGroupedFileProperties() {
if (groupedFileProps == null) {

def queries = TYPES.collect { type ->
forceService.withValidMetadataType(type) {
def query = new ListMetadataQuery()
query.type = it
query
}
}
queries.removeAll([null])
def grouped = new GroupedFileProperties(
forceService.listMetadataForTypes(TYPES)
)

def grouped = [:]
// XXX - Hack to always retrieve the CaseComment SObject & Workflow.
//
// For some reason CaseComment is not returned in listMetadata()
// calls for CustomObject and Workflow but if we explicitly put
// these in package.xml for retrieve we can download them.
grouped.addIfMissingStandard('CustomObject', 'CaseComment')

forceService.listMetadata(queries).each { fileProperties ->
def type = fileProperties.type

if (!grouped.containsKey(type)) {
grouped[type] = []
}

grouped[type] << fileProperties
}

grouped.each { k, v ->
grouped.filePropertiesByType.each { k, v ->
v.sort { a, b ->
a.namespacePrefix <=> b.namespacePrefix ?: a.fullName <=> b.fullName
}
}

groupedFileProps = grouped
groupedFileProps = grouped.filePropertiesByType
}

groupedFileProps
}


def writePackageXmlForType(type, fileProperties) {
def builder = new StreamingMarkupBuilder()
builder.encoding = 'UTF-8'
Expand Down

0 comments on commit 9b6e973

Please sign in to comment.