Revision: 40303
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at January 29, 2011 07:15 by d3developer
Initial Code
/* * Make sure your class is using the latest API version. Some features in this class * will only work with API v19 or higher. */ public class CsvToSObjectParser { private final String RESOURCE_NAME = 'object_csv'; private List<String> lines = new List<String>(); // Map instead of list since I need the .remove() method AND // Map instead of set since DML can't be performed on set of SObject private Map objsToInsert = new Map(); // A map to associate our external Ids as defined in the CSV with SObject Ids. // This helps the code associate related objects. Using two similar maps // since this one will hold ALL records (think reference-Map) but the one // above holds a running list of uncommited records (think action-Map) private Map extIdMap = new Map(); public StaticResource theStaticResource{get;set;} public CsvToSObjectParser(){ fetchResource(RESOURCE_NAME); } public CsvToSObjectParser(String resourceName){ fetchResource(resourceName); } // Run over the lines in the files public List parseCsv(){ String bodyText = theStaticResource.body.toString(); // Break the body into it's constituent lines List bodyLines = bodyText.split('\n'); for(String line: bodyLines){ // Ignore comment and empty lines if(line.trim().length() == 0){ continue; } System.debug('Key-value pair: '+line); SObject s = munch(line); } List objs = objsToInsert.values(); return objs; } // Robotic muncher. Eats CSV lines and poops // SObjects. private SObject munch(String s){ SObject obj; // Rearrange the CSV line into a list of string values List keyValuePairs = s.split(','); String eId; for(String pairString: keyValuePairs){ // Some boilerplate splitting List<String> pairs = pairString.split(':'); String key = pairs[0].trim(); // Don't forget to Trim! String value = pairs[1].trim(); // Waste not, want not. // Reserved keyword in the CSV markup - used // to denote the object name if(key == 'object'){ obj = createSObject(value); // Reserved keyword - denotes the parent record Id } else if(key == 'relatedTo'){ // More boilerplate List referenceFields = value.split('#'); String fieldName = referenceFields[0]; String extId = referenceFields[1]; // Find the parent record. Now here we violate the // 'No DML in a loop' golden rule because the parent // record Id is required for the association. There is // way to get around this by using a few lists and a map // or two. I don't deem it necessary since I have direct // control over the number of records in the sample file, // but it'll make a fun exercise for y'all in your spare // time SObject parentObj = extIdMap.get(extId); if(parentObj.id == null){ insert parentObj; objsToInsert.remove(extId); } obj.put(fieldName, parentObj.id); // Reserved keyword - used to associate my CSV record // Id and the salesforce record Id } else if( key == 'extId' ){ eId = value; // Everything else i.e. the real field values } else { obj.put(key, value); } } objsToInsert.put(eId, obj); extIdMap.put(eId, obj); return obj; } // Helper that instantiates a generic SObject private SObject createSObject(String objectName){ Schema.SObjectType t = Schema.getGlobalDescribe().get(objectName); SObject s = t.newSObject(); return s; } private void fetchResource(String resourceName){ try{ theStaticResource = [SELECT id, Body FROM StaticResource WHERE name = :resourceName]; }catch(System.QueryException e){ System.debug(e); // You should always let the admins/devs know if // something unexpected happened. // e.g. ExceptionUtils.mail(Administrator); } } }
Initial URL
Initial Description
Initial Title
@wesnolte CvsToSObject Parser
Initial Tags
Initial Language
Other