/** * ============================================================================= * * ORCID (R) Open Source * http://orcid.org * * Copyright (c) 2012-2014 ORCID, Inc. * Licensed under an MIT-Style License (MIT) * http://orcid.org/open-source-license * * This copyright and license information (including a link to the full license) * shall be included in its entirety in all copies or substantial portion of * the software. * * ============================================================================= */ package org.orcid.core.salesforce.adapter; import static org.orcid.core.utils.JsonUtils.extractObject; import static org.orcid.core.utils.JsonUtils.extractString; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import javax.annotation.Resource; import org.apache.commons.lang3.StringUtils; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.orcid.core.salesforce.model.Consortium; import org.orcid.core.salesforce.model.Contact; import org.orcid.core.salesforce.model.ContactRole; import org.orcid.core.salesforce.model.Integration; import org.orcid.core.salesforce.model.Member; import org.orcid.core.salesforce.model.Opportunity; import org.orcid.core.utils.JsonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ma.glasnost.orika.MapperFacade; /** * * @author Will Simpson * */ public class SalesForceAdapter { private static final Logger LOGGER = LoggerFactory.getLogger(SalesForceAdapter.class); @Resource(name = "salesForceMemberMapperFacade") private MapperFacade mapperFacade; public void setMapperFacade(MapperFacade mapperFacade) { this.mapperFacade = mapperFacade; } public Consortium createConsortiumFromJson(JSONObject results) { try { int numFound = JsonUtils.extractInt(results, "totalSize"); if (numFound == 0) { return null; } Consortium consortium = new Consortium(); List<Opportunity> opportunityList = new ArrayList<>(); consortium.setOpportunities(opportunityList); JSONArray records = results.getJSONArray("records"); JSONObject firstRecord = records.getJSONObject(0); JSONObject opportunities = extractObject(firstRecord, "ConsortiaOpportunities__r"); if (opportunities != null) { JSONArray opportunityRecords = opportunities.getJSONArray("records"); for (int i = 0; i < opportunityRecords.length(); i++) { Opportunity salesForceOpportunity = new Opportunity(); JSONObject opportunity = opportunityRecords.getJSONObject(i); salesForceOpportunity.setId(extractOpportunityId(opportunity)); JSONObject account = extractObject(opportunity, "Account"); salesForceOpportunity.setTargetAccountId(extractAccountId(account)); // salesForceOpportunity.setAccountName(JsonUtils.extractString(account, // "Name")); salesForceOpportunity.setAccountName(JsonUtils.extractString(account, "Public_Display_Name__c")); opportunityList.add(salesForceOpportunity); } return consortium; } } catch (JSONException e) { throw new RuntimeException("Error getting consortium record from SalesForce JSON", e); } return null; } Contact createContactFromJson(JSONObject record) { return mapperFacade.map(record, Contact.class); } public List<Contact> createContactsFromJson(JSONObject object) { try { List<JSONObject> objectsList = extractObjectListFromRecords(object); return objectsList.stream().map(e -> mapperFacade.map(e, Contact.class)).collect(Collectors.toList()); } catch (JSONException e) { throw new RuntimeException("Error getting all contacts list from SalesForce JSON", e); } } public List<Contact> createContactsWithRolesFromJson(JSONObject object) { try { JSONObject firstRecord = extractFirstRecord(object); JSONObject contactRoles = firstRecord.getJSONObject("Membership_Contact_Roles__r"); List<JSONObject> objectsList = extractObjectListFromRecords(contactRoles); return objectsList.stream().map(e -> mapperFacade.map(e, Contact.class)).collect(Collectors.toList()); } catch (JSONException e) { throw new RuntimeException("Error getting contacts with roles list from SalesForce JSON", e); } } public JSONObject createSaleForceRecordFromContact(Contact contact) { return mapperFacade.map(contact, JSONObject.class); } public List<ContactRole> createContactRolesFromJson(JSONObject object) { try { List<JSONObject> contactRoles = extractObjectListFromRecords(object); return contactRoles.stream().map(e -> mapperFacade.map(e, ContactRole.class)).collect(Collectors.toList()); } catch (JSONException e) { throw new RuntimeException("Error getting contact roles list from SalesForce JSON", e); } } public JSONObject createSaleForceRecordFromContactRole(ContactRole contactRole) { return mapperFacade.map(contactRole, JSONObject.class); } public List<Member> createMembersListFromJson(JSONObject results) { List<Member> members = new ArrayList<>(); try { JSONArray records = results.getJSONArray("records"); for (int i = 0; i < records.length(); i++) { members.add(createMemberFromSalesForceRecord(records.getJSONObject(i))); } } catch (JSONException e) { throw new RuntimeException("Error getting member records from SalesForce JSON", e); } return members; } public List<Integration> createIntegrationsListFromJson(JSONObject results) { List<Integration> integrations = new ArrayList<>(); try { JSONArray records = results.getJSONArray("records"); if (records.length() > 0) { JSONObject firstRecord = records.getJSONObject(0); JSONObject integrationsObject = extractObject(firstRecord, "Integrations__r"); if (integrationsObject != null) { JSONArray integrationRecords = integrationsObject.getJSONArray("records"); for (int i = 0; i < integrationRecords.length(); i++) { integrations.add(createIntegrationFromSalesForceRecord(integrationRecords.getJSONObject(i))); } } } } catch (JSONException e) { throw new RuntimeException("Error getting integrations records from SalesForce JSON", e); } return integrations; } public String extractParentOrgNameFromJson(JSONObject results) { try { JSONArray records = results.getJSONArray("records"); if (records.length() > 0) { // return extractString(records.getJSONObject(0), "Name"); return extractString(records.getJSONObject(0), "Public_Display_Name__c"); } } catch (JSONException e) { throw new RuntimeException("Error getting parent org from SalesForce JSON", e); } return null; } private String extractOpportunityId(JSONObject opportunity) throws JSONException { JSONObject opportunityAttributes = extractObject(opportunity, "attributes"); String opportunityUrl = extractString(opportunityAttributes, "url"); return extractIdFromUrl(opportunityUrl); } private String extractAccountId(JSONObject account) throws JSONException { JSONObject accountAttributes = extractObject(account, "attributes"); String accountUrl = extractString(accountAttributes, "url"); String accountId = extractIdFromUrl(accountUrl); return accountId; } Member createMemberFromSalesForceRecord(JSONObject record) throws JSONException { return mapperFacade.map(record, Member.class); } public JSONObject createSaleForceRecordFromMember(Member member) { return mapperFacade.map(member, JSONObject.class); } private Integration createIntegrationFromSalesForceRecord(JSONObject integrationRecord) throws JSONException { Integration integration = new Integration(); String name = extractString(integrationRecord, "Name"); integration.setName(name); integration.setDescription(extractString(integrationRecord, "Description__c")); integration.setStage(extractString(integrationRecord, "Integration_Stage__c")); try { integration.setResourceUrl(extractURL(integrationRecord, "Integration_URL__c")); } catch (MalformedURLException e) { LOGGER.info("Malformed resource URL for member: {}", name, e); } return integration; } public Opportunity createOpportunityFromSalesForceRecord(JSONObject jsonObject) { return mapperFacade.map(jsonObject, Opportunity.class); } public JSONObject createSaleForceRecordFromOpportunity(Opportunity opportunity) { JSONObject jsonObject = mapperFacade.map(opportunity, JSONObject.class); return jsonObject; } private URL extractURL(JSONObject record, String key) throws JSONException, MalformedURLException { String urlString = tidyUrl(extractString(record, key)); return urlString != null ? new URL(urlString) : null; } private String tidyUrl(String urlString) { if (StringUtils.isBlank(urlString)) { return null; } // We were getting a // http://www.fileformat.info/info/unicode/char/feff/index.htm at the // beginning of one logo URL from SF. urlString = urlString.replaceAll("\\p{C}", ""); urlString = urlString.trim(); if (!urlString.matches("^.*?://.*")) { urlString = "http://" + urlString; } return urlString; } private List<JSONObject> extractObjectListFromRecords(JSONObject object) throws JSONException { List<JSONObject> objects = new ArrayList<>(); JSONArray records = object.getJSONArray("records"); for (int i = 0; i < records.length(); i++) { objects.add(records.getJSONObject(i)); } return objects; } private JSONObject extractFirstRecord(JSONObject object) throws JSONException { JSONArray records = object.getJSONArray("records"); return records.getJSONObject(0); } public String extractIdFromFirstRecord(JSONObject object) { JSONObject firstRecord; try { firstRecord = extractFirstRecord(object); return firstRecord.optString("Id"); } catch (JSONException e) { throw new RuntimeException("Error getting ID from first record", e); } } public static String extractIdFromUrl(String url) { if (url == null) { return null; } int slashIndex = url.lastIndexOf('/'); if (slashIndex == -1) { throw new IllegalArgumentException("Unable to extract ID, url = " + url); } return url.substring(slashIndex + 1); } }