Wednesday, April 26, 2017

Error while submitting the Eloqua form - Value must not contain any URL

I was getting the following error while submitting the Eloqua form

<!DOCTYPE html>
<html>
<body bgcolor="#ffffff">
<div align="center" style="margin: 60px;">
<!-- CONFIRMATION PAGE TITLE -->
<div align="left" style="width: 400px; font-size: 14pt; font-family: Tahoma, Arial, Helevtica; font-weight: bold;">
<img src="/EloquaImages/ConfirmationPage/error.gif" width="32" height="50" border="0" align="left">  The Information Provided is Incomplete or Invalid. </div>
<!-- CONFIRMATION PAGE INFORMATION -->
<div align="left" style="width: 400px; font-size: 10pt; font-family: Arial, Helevtica; padding-left: 45px; padding-top: 10px; padding-right: 45px;">
<p>Reference- Value must not contain any URL&#39;s<br/></p>
</div>
</body>
</html>

The Reference filed is configured as hidden in Eloqua and also sending the URL as the input.

Based on the reading Oracle Eloqua 483 Release enabled by default "Must Not Contain URL" validation on all hidden fields but user was not able to modify this validation. But Eloqua 487 Release provided the access to users to modify the validation on hidden fields

Disable "Must Not Contain URL" validation in the hidden field that expecting the URL as input.



Sunday, April 16, 2017

how to include custom metatag headers from AEM Tags

This post explains the approach to include custom metatag headers from AEM Tags.

Customize the page properties dialog:

Customize the page properties dialog to add the field to select custom tags

Copy /libs/foundation/components/page/dialog and /libs/foundation/components/page/tab_basic under custom page rendering component e.g. /apps/training/components/page-content/

Create a node of type cq:widget under tab_basic with the following properties

Name Type Value
allowBlank Boolean true
fieldLabel String Page Type
name String ./page-type
namespaces String[] page-type
xtype String tags



Refer http://www.albinsblog.com/2017/03/how-to-customize-page-properties-dialog-dynamic-dropdownlist-aem-cq5-in-touchui-classicui.html for more details on customizing the page properties dialog.

Define new tag namespace & tags:
Create new tag namespace(page-type) through http://localhost:4502/tagging


Create required tags under page-type namespace



Override the the head.jsp if the page component is inhering from foundation/components/page. Add required logic in head.jsp to include the custom metatags from AEM tags.
e.g.
<%
%><%@ include file="/libs/foundation/global.jsp"%><%
%><%@ page contentType="text/html; charset=utf-8" import="com.albinsblog.samples.core.TagsUtil,com.day.cq.tagging.*"%><%

TagManager tagManager = resourceResolver.adaptTo(TagManager.class);
String[] pageTypeTags = properties.get("./page-type", String[].class);
String pageTypes = TagsUtil.getTagTitles(tagManager, pageTypeTags);
%><head>
 <cq:include script="/libs/wcm/core/components/init/init.jsp"/>
   <meta name="page-types" content="<%= pageTypes %>" />
</head>

TagsUtil.java - util class to fetch the tag titles and convert the titles to required formats.

import com.day.cq.tagging.Tag;
import com.day.cq.tagging.TagManager;
public class TagsUtil {
public static String getTagTitles(TagManager tagManager, String[] typeTags) {
StringBuffer typeBuffer = new StringBuffer();
if (typeTags != null) {
for (String typeTagId : typeTags) {
Tag typeTag = tagManager.resolve(typeTagId);
if (typeTag != null) {
String tagPath = typeTag.getTitlePath();
String[] splitTags = tagPath.split(":");
String tagName = splitTags[1];
if (typeTag != null)
typeBuffer.append(tagName + ";"); }
}
if (typeBuffer.length() != 0)
typeBuffer.deleteCharAt(typeBuffer.length() - 1);
}
return typeBuffer.toString();
}
}
Configure required tags in page properties dialog

The defined metatag will be added to the page 




Friday, April 14, 2017

Integration of AEM with Salesforce - Part4

This post will explain the approach to extend the basic AEM Salesforce connector to create/update the Salesforce objects.

Refer the following post for details on integrating Salesforce with AEM
http://www.albinsblog.com/2017/03/integrationofaemcq5withsalesforcepart1.html
http://www.albinsblog.com/2017/04/integrationofaemcq5withsalesforcepart2.html
http://www.albinsblog.com/2017/04/integration-of-aem-with-salesforce-part3.html

Prerequisite  - Configure the Salesforce cloud connection, refer the above mentioned post for more details.
Enable the Salesforce cloud configuration for the Home page of the websites.


Dependency:

Add the below Maven dependency to the project
For 6.0 and 6.1
<dependency>
    <groupId>com.adobe.aem</groupId>
    <artifactId>aem-api</artifactId>
    <version>6.0.0.1</version>
    <scope>provided</scope>
</dependency>

For 6.2
<dependency>
    <groupId>com.adobe.aem</groupId>
    <artifactId>uber-jar</artifactId>
    <version>6.2.0</version>
    <classifier>apis</classifier>
    <scope>provided</scope>
</dependency>

Change the version based on your server

Create a Java Class (SalesforceUpdateProcess.java) that will use the base connector to create/update Salesforce objects - This code provides the support to OPPORTUNITY, change the code accordingly to enable the support for other objects.

import javax.jcr.Node;
import javax.jcr.RepositoryException;

import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.cq.mcm.salesforce.SalesforceClient;
import com.adobe.cq.mcm.salesforce.SalesforceResponse;
import com.adobe.granite.crypto.CryptoException;
import com.adobe.granite.crypto.CryptoSupport;
import com.day.cq.wcm.webservicesupport.Configuration;

@Component
@Service({SalesforceUpdateProcess.class})
public class SalesforceUpdateProcess  
{
  private static final Logger log = LoggerFactory.getLogger(SalesforceUpdateProcess.class);

  @Reference
  private CryptoSupport cryptoSupport;
  
  public void update(Configuration cloudConfig, SalesforceUpdateParameters parameters, ResourceResolver resolver)
   throws Exception
 {
 
   if (cloudConfig != null)
   {
     String instanceUrl = (String)cloudConfig.get("instanceurl", "");
     String accessToken = (String)cloudConfig.get("accesstoken", "");
     String clientId = (String)cloudConfig.get("customerkey", "");
     String encryptedCustomerSecret = (String)cloudConfig.get("customersecret", "");
     String encryptedRefereshToken = (String)cloudConfig.get("refreshtoken", "");
     try
     {
       String customerSecret = encryptedCustomerSecret;
       String refreshToken = encryptedRefereshToken;
       if (this.cryptoSupport.isProtected(encryptedCustomerSecret)) {
         customerSecret = this.cryptoSupport.unprotect(encryptedCustomerSecret);
       }
       if (this.cryptoSupport.isProtected(encryptedRefereshToken)) {
         refreshToken = this.cryptoSupport.unprotect(encryptedRefereshToken);
       }
       
       JSONObject requestData = new JSONObject(parameters.getInputData());
                String requestDataString = requestData.toString();
       
       SalesforceClient salesforceClient = new SalesforceClient();
                salesforceClient.setAccessToken(accessToken);
                salesforceClient.setRefreshToken(refreshToken);
                salesforceClient.setClientId(clientId);
                salesforceClient.setClientSecret(customerSecret);
                
                salesforceClient.setInstanceURL(instanceUrl);
                salesforceClient.setContentType("application/json");
                String sObjectName="";
                if (SalesforceUpdateParameters.SalesforceObjectType.OPPORTUNITY.equals(parameters.getObjectType())) {
                sObjectName="OPPORTUNITY";
                }
                StringBuilder salesforcePath = new StringBuilder("/services/data/v20.0/sobjects/"+sObjectName+"/");
                if (SalesforceUpdateParameters.SalesforceOperationType.UPDATE.equals(parameters.getOperationType())) 
                {
                salesforcePath=salesforcePath.append(parameters.getSalesforceObjectId());
                salesforceClient.setStringMethod("PATCH");
                }else if (SalesforceUpdateParameters.SalesforceOperationType.CREATE.equals(parameters.getOperationType())) {
                salesforceClient.setStringMethod("POST");
               }     
   
                salesforceClient.setPath(salesforcePath.toString());
                salesforceClient.setData(requestDataString);
                
                SalesforceResponse salesforceResponse = salesforceClient.executeRequest();
       if (salesforceResponse.getAccessTokenUpdated().booleanValue())
       {
         String configPath = cloudConfig.getPath();
         Resource configResource = resolver.getResource(configPath);
         Node configNode = ((Node)configResource.adaptTo(Node.class)).getNode("jcr:content");
         configNode.setProperty("accesstoken", salesforceClient.getAccessToken());
         configNode.getSession().save();
       }   
               
       if (salesforceResponse.getCode()!=204 && salesforceResponse.getCode()!=201)
                {
        throw new Exception("Error in Update"+salesforceResponse.getBody());
                }
     }
     catch (RepositoryException e)
     {
       log.error("Repository Exception in Update " + e.getMessage());
       throw new Exception("Repository Exception in Update " + e.getMessage());
     }
     catch (CryptoException e)
     {
       log.error("Cryto Exception in Update " + e.getMessage());
       throw new Exception("Crypto Exception in Update " + e.getMessage());
     }
     catch (JSONException e)
     {
       log.error("JSON Exception in Update " + e.getMessage());
       throw new Exception("JSON Exception in Update " + e.getMessage());
     }
     catch (Exception e)
     {
       log.error("Exception in Update " + e.getMessage());
       throw new Exception("Exception in Update " + e.getMessage());
     }
   }     
 }  
  
  protected void bindCryptoSupport(CryptoSupport paramCryptoSupport)
  {
    this.cryptoSupport = paramCryptoSupport;
  }
  
  protected void unbindCryptoSupport(CryptoSupport paramCryptoSupport)
  {
    if (this.cryptoSupport == paramCryptoSupport) {
      this.cryptoSupport = null;
    }
  }
}


Create a Java class(SalesforceUpdateParameters.java) that will provide the support for required Salesforce objects -  - This code provides the support to OPPORTUNITY, change the code accordingly to enable the support for other objects.

import java.util.HashMap;

public class SalesforceUpdateParameters
{
  private HashMap<String,String> inputData;
  private SalesforceObjectType objectType;  
  private SalesforceOperationType opeationType;
  private String salesforceObjectId;
  
  public static enum SalesforceOperationType
  {
 UPDATE,CREATE;
    
    private SalesforceOperationType() {}
  }  
  public SalesforceOperationType getOperationType()
  {
    return this.opeationType;
  }  
  public void setOpeationType(SalesforceOperationType opeationType)
  {
    this.opeationType = opeationType;
  }  
  public void setOpeationType(String opeationType)
  {
    if (SalesforceOperationType.UPDATE.name().equalsIgnoreCase(opeationType)) {
      this.opeationType = SalesforceOperationType.UPDATE;
    } else if (SalesforceOperationType.CREATE.name().equalsIgnoreCase(opeationType)) {
        this.opeationType = SalesforceOperationType.CREATE;
      }
  }  
  public static enum SalesforceObjectType
  {
 OPPORTUNITY;    
    private SalesforceObjectType() {}
  }  
  public SalesforceObjectType getObjectType()
  {
    return this.objectType;
  }  
  public void setObjectType(SalesforceObjectType objectType)
  {
    this.objectType = objectType;
  }  
  public void setObjectType(String objectType)
  {
    if (SalesforceObjectType.OPPORTUNITY.name().equalsIgnoreCase(objectType)) {
      this.objectType = SalesforceObjectType.OPPORTUNITY;
    } 
  }  
  public HashMap<String,String> getInputData()
  {
    return this.inputData;
  }  
  public void setInputData(HashMap<String,String> inputData)
  {
    this.inputData = inputData;
  }
public String getSalesforceObjectId() {
return salesforceObjectId;
}
public void setSalesforceObjectId(String salesforceObjectId) {
this.salesforceObjectId = salesforceObjectId;
}
}

Create a components that will invoke SalesforceUpdateProcess.java to create/update the Salesforce objects by providing required parameters.

<% 

           try{
            String[] cloudConfigs = pageProperties.getInherited("cq:cloudserviceconfigs", new String[]{});
            ConfigurationManager configurationManager = resourceResolver.adaptTo(ConfigurationManager.class);

            if(cloudConfigs.length>0){
                Configuration salesforceConfig = configurationManager.getConfiguration("salesforce",cloudConfigs);

SalesforceUpdateProcess updateClient = sling.getService(SalesforceUpdateProcess.class);
                SalesforceUpdateParameters updateParameters = new SalesforceUpdateParameters();
                                                      updateParameters.setObjectType(SalesforceUpdateParameters.SalesforceObjectType.OPPORTUNITY);

                HashMap<String,String> inputData=new HashMap<String,String>();//Send only the required field for update
                inputData.put("Description","Test Description");
                inputData.put("Name","TestOpportunity");
                inputData.put("StageName","Prospecting");   
                inputData.put("CloseDate","2017-04-30");   

                updateParameters.setInputData(inputData);
                updateParameters.setOpeationType(SalesforceUpdateParameters.SalesforceOperationType.CREATE);//Create New Object
                //updateParameters.setOpeationType(SalesforceUpdateParameters.SalesforceOperationType.UPDATE);//Update the existing object by providong the id
                //updateParameters.setSalesforceObjectId("0069000000rjArf");//Object id to update

                updateClient.update(salesforceConfig, updateParameters, resource.getResourceResolver());

                }else
                {%>
 <div id="cloudconfigerror">
                    Salesforce Cloud Service Configuration could not be found for this page.
                </div>
                <%}
                }catch(Exception e)
                {%>
 <div id="error">
     Exception occurred while Create/Update. Please contact Administrator.
            </div>
            <%}

                %>





Wednesday, April 12, 2017

Integration of AEM with Salesforce - Part3

This post will explain the approach to extend the basic AEM Salesforce connector to search for the Salesforce objects other than Lead/Contact.

Refer the following post for details on integrating Salesforce with AEM
 http://www.albinsblog.com/2017/03/integrationofaemcq5withsalesforcepart1.html
http://www.albinsblog.com/2017/04/integrationofaemcq5withsalesforcepart2.html

Prerequisite  - Configure the Salesforce cloud connection, refer the above mentioned post for more details.
Enable the Salesforce cloud configuration for the Home page of the websites.
Dependency:

Add the below Maven dependency to the project
For 6.0 and 6.1
<dependency>
    <groupId>com.adobe.aem</groupId>
    <artifactId>aem-api</artifactId>
    <version>6.0.0.1</version>
    <scope>provided</scope>
</dependency>

For 6.2
<dependency>
    <groupId>com.adobe.aem</groupId>
    <artifactId>uber-jar</artifactId>
    <version>6.2.0</version>
    <classifier>apis</classifier>
    <scope>provided</scope>
</dependency>

Change the version based on your server

Create a Java Class (SalesforceSearchProcess.java) that will use the base connector to search for Salesforce objects - This code provides the support to OPPORTUNITY, change the code accordingly to enable the support for other objects.

import com.adobe.cq.mcm.salesforce.SalesforceClient;
import com.adobe.cq.mcm.salesforce.SalesforceResponse;
import com.albinsblog.samples.core.SalesforceSearchParameters;
import com.adobe.granite.crypto.CryptoException;
import com.adobe.granite.crypto.CryptoSupport;
import com.day.cq.wcm.webservicesupport.Configuration;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
@Service({SalesforceSearchProcess.class})
public class SalesforceSearchProcess
{
  private static final Logger log = LoggerFactory.getLogger(SalesforceSearchProcess.class);
  @Reference
  private CryptoSupport cryptoSupport;
  public JSONObject search(Configuration cloudConfig, SalesforceSearchParameters parameters, ResourceResolver resolver) throws Exception
  {
    if (cloudConfig != null)
    {
      String instanceUrl = (String)cloudConfig.get("instanceurl", "");
      String accessToken = (String)cloudConfig.get("accesstoken", "");
      String clientId = (String)cloudConfig.get("customerkey", "");
      String encryptedCustomerSecret = (String)cloudConfig.get("customersecret", "");
      String encryptedRefereshToken = (String)cloudConfig.get("refreshtoken", "");
      try
      {
        String customerSecret = encryptedCustomerSecret;
        String refreshToken = encryptedRefereshToken;
        if (this.cryptoSupport.isProtected(encryptedCustomerSecret)) {
          customerSecret = this.cryptoSupport.unprotect(encryptedCustomerSecret);
        }
        if (this.cryptoSupport.isProtected(encryptedRefereshToken)) {
          refreshToken = this.cryptoSupport.unprotect(encryptedRefereshToken);
        }
        SalesforceClient client = new SalesforceClient();
        client.setAccessToken(accessToken);
        client.setInstanceURL(instanceUrl);
        client.setRefreshToken(refreshToken);
        client.setClientId(clientId);
        client.setClientSecret(customerSecret);
        client.setMethod(SalesforceClient.AvailableMethods.GET);
        client.setContentType("application/json");
        client.setPath("/services/data/v20.0/query/");
        client.addParameter("q", buildSOSL(parameters));
    
        SalesforceResponse response = client.executeRequest();
        if (response.getAccessTokenUpdated().booleanValue())
        {
          String configPath = cloudConfig.getPath();
          Resource configResource = resolver.getResource(configPath);
          Node configNode = ((Node)configResource.adaptTo(Node.class)).getNode("jcr:content");
          configNode.setProperty("accesstoken", client.getAccessToken());
          configNode.getSession().save();
        }    
        return response.getBodyAsJSON();
      }
      catch (RepositoryException e)
      {
        log.error("Repository Exception in Searching SFDC Opportunity " + e.getMessage());
        throw new Exception("Repository Exception in Searching SFDC Opportunity " + e.getMessage());
      }
      catch (CryptoException e)
      {
        log.error("Cryto Exception in searching SFDC Opportunity " + e.getMessage());
        throw new Exception("Crypto Exception in searching SFDC Opportunity " + e.getMessage());
      }
      catch (JSONException e)
      {
        log.error("JSON Exception in searching SFDC Opportunity " + e.getMessage());
        throw new Exception("JSON Exception in searching SFDC Opportunity " + e.getMessage());
      }
    }
    return null;
  }

  protected String buildSOSL(SalesforceSearchParameters parameters) throws Exception
  {
    StringBuilder query = new StringBuilder();
    query.append("SELECT ");
    if ((parameters.getResultProperties() != null) && (parameters.getResultProperties().length > 0))
    {
      for (int i = 0; i < parameters.getResultProperties().length; i++) {
        if (parameters.getResultProperties()[i] != null) {
          query.append(parameters.getResultProperties()[i] + ", ");
        }
      }
      query.deleteCharAt(query.lastIndexOf(","));
    }
   
    if (SalesforceSearchParameters.SalesforceObjectType.OPPORTUNITY.equals(parameters.getObjectType())) {//Add the support for required objects
    query.append(" FROM OPPORTUNITY ");
    }  
    if ((parameters.getSearchOperator() != null) && (parameters.getSearchType() != null) && (parameters.getSearchVal() != null)) {
      query.append("WHERE " + parameters.getSearchType() + " " + parameters.getSearchOperator() + " " + getEncodedSearchVal(parameters.getSearchOperator(), parameters.getSearchVal()));
    }
    return query.toString();
  }

  private String getEncodedSearchVal(String operator, String searchVal)
  {
    Double searchValue = null;
    try
    {
      searchValue = Double.valueOf(Double.parseDouble(searchVal));
      return searchValue.toString();
    }
    catch (NumberFormatException e) {}
    return "'" + searchVal + "'";
  }
  protected void bindCryptoSupport(CryptoSupport paramCryptoSupport)
  {
    this.cryptoSupport = paramCryptoSupport;
  }
  protected void unbindCryptoSupport(CryptoSupport paramCryptoSupport)
  {
    if (this.cryptoSupport == paramCryptoSupport) {
      this.cryptoSupport = null;
    }
  }
}

Create a Java class(SalesforceSearchParameters.java) that will provide the support for required Salesforce objects -  - This code provides the support to OPPORTUNITY, change the code accordingly to enable the support for other objects.

import java.util.HashMap;
public class SalesforceSearchParameters
{
  private String searchOperator;
  private String searchVal;
  private String searchType;
  private String[] resultProperties;
  private HashMap<String,String> inputData;
  private SalesforceObjectType objectType;

  public static enum SalesforceObjectType
  {
 OPPORTUNITY;//Add the required objects
    private SalesforceObjectType() {}
  }
  public SalesforceObjectType getObjectType()
  {
    return this.objectType;
  }
  public void setObjectType(SalesforceObjectType objectType)
  {
    this.objectType = objectType;
  }
  public void setObjectType(String objectType)
  {
    if (SalesforceObjectType.OPPORTUNITY.name().equalsIgnoreCase(objectType)) {// Add the support required objects
      this.objectType = SalesforceObjectType.OPPORTUNITY;
    }
  }
  public String getSearchOperator()
  {
    return this.searchOperator;
  }
  public void setSearchOperator(String searchOperator)
  {
    this.searchOperator = searchOperator;
  }
  public String getSearchVal()
  {
    return this.searchVal;
  }
  public void setSearchVal(String searchVal)
  {
    this.searchVal = searchVal;
  }
  public String getSearchType()
  {
    return this.searchType;
  }
  public void setSearchType(String searchType)
  {
    this.searchType = searchType;
  }
  public String[] getResultProperties()
  {
    return this.resultProperties;
  }
  public void setResultProperties(String[] resultProperties)
  {
    this.resultProperties = resultProperties;
  }
  public HashMap<String,String> getInputData()
  {
    return this.inputData;
  }
  public void setInputData(HashMap<String,String> inputData)
  {
    this.inputData = inputData;
  }
}

Create a components that will invoke SalesforceSearchProcess.search to get the data by providing required parameters.

<%@include file="/libs/foundation/global.jsp"%><%
%><cq:defineObjects />
<%@page session="false"
        import="com.albinsblog.samples.core.SalesforceSearchProcess,
    com.day.cq.wcm.webservicesupport.Configuration,
com.day.cq.wcm.webservicesupport.ConfigurationManager" %>
<%@page import="com.albinsblog.samples.core.SalesforceSearchParameters" %>
<%@page import="com.day.cq.i18n.I18n" %>
<%@page import="org.apache.sling.commons.json.JSONObject" %>
<%@page import="org.apache.sling.commons.json.JSONArray" %>
<%@ page import="org.apache.sling.commons.json.JSONException" %>
<%
    final String searchType = "";
    final String searchVal = "";
    final String searchOperator = "=";
    I18n i18n = new I18n(slingRequest.getResourceBundle(currentPage.getLanguage(false)));
    boolean cloudConfigFound = false;
    boolean opportunityFound = false;
    boolean errorsInSearch = false;
           try{
            SalesforceSearchProcess searchClient = sling.getService(SalesforceSearchProcess.class);
            SalesforceSearchParameters searchParameters = new SalesforceSearchParameters();            searchParameters.setObjectType(SalesforceSearchParameters.SalesforceObjectType.OPPORTUNITY);    //Configure the required object    
  if(!searchVal.equals(""))
  {
searchParameters.setSearchVal(searchVal);
  }
     if(!searchType.equals(""))
  {
searchParameters.setSearchType(searchType);
  }
  if(!searchOperator.equals(""))
  {
searchParameters.setSearchOperator(searchOperator);
  }
   
searchParameters.setResultProperties(new String[]{"Name","StageName","Probability"});// Configured the required fields
String[] cloudConfigs = pageProperties.getInherited("cq:cloudserviceconfigs", new String[]{});
            ConfigurationManager configurationManager = resourceResolver.adaptTo(ConfigurationManager.class);
            if(cloudConfigs.length>0){
                Configuration salesforceConfig = configurationManager.getConfiguration("salesforce",cloudConfigs);
                if(salesforceConfig!=null){
                    cloudConfigFound = true;
                    JSONObject opportunityJSON = searchClient.search(salesforceConfig, searchParameters, resource.getResourceResolver());
                   if(opportunityJSON!=null){
                        log.info("OpportunityJSON "+opportunityJSON.toString());
                        if(!hasErrors(opportunityJSON)){
                            Integer totalOpportunity = Integer.parseInt(opportunityJSON.getString("totalSize"));
                            log.info("Total Opportunity searched ----> "+totalOpportunity);
                            if(totalOpportunity > 0 ){
                                opportunityFound = true;
                                JSONArray opportunity = opportunityJSON.getJSONArray("records"); %>
                                <div id="opportunity-grid">
                                    <table>
                                        <thead>
                                        <tr>
                                         <td width="150"> <%= i18n.get("Name") %> </td>
                                         <td width="150"> <%= i18n.get("Probability") %> </td>
                                         <td width="150"> <%= i18n.get("StageName") %> </td>
                                        </tr>
                                        </thead>
                                        <%
                                        for(int i=0; i<opportunity.length(); i++){
                                            JSONObject opr = opportunity.getJSONObject(i);
                                            %>
                                                <tr>
                                                    <td> <%= xssAPI.encodeForHTML( (String)opr.get("Name") ) %> </td>
                                                    <td> <%= opr.get("Probability")  %> </td>
                                                    <td> <%= xssAPI.encodeForHTML( (String)opr.get("StageName") ) %> </td>
                                                </tr>
                                            <%
                                        }
                                        %>
                                    </table>
                                </div>
                                <%
                            }
                        }
                        else {
                            errorsInSearch = true;
                        }
                    }
                }
            }
            if(!cloudConfigFound){
                %>
                <div id="emptyOpportunity">
                    <%= i18n.get("Salesforce Cloud Service Configuration could not be found for this page.")%>
                </div>
                <%
            }
            else if(errorsInSearch){
                %>
                <div id="emptyOpportunity">
                    <%= i18n.get("Errors in Search Criteria. Search Again !")%>
                </div>
                <%
            }
            else if(!opportunityFound){
                %>
                <div id="emptyOpportunity">
                    <%= i18n.get("No Results Found for given Search Criteria. Search Again !")%>
                </div>
                <%
            }
        }catch (Exception se){
            %>
            <div id="emptyOpportunity">
                <%= i18n.get("Exception occurred while Searching. Please contact Administrator. ")%>
            </div>
            <%
            log.error("Exception in Searching Opportunity: "+se.getMessage());
        } %>
<%!
    boolean hasErrors(JSONObject opportunity){
        boolean hasErrors = false;
        try {
            if(opportunity.get("errorCode")!=null)
                hasErrors = true;
        } catch (JSONException e) {
            hasErrors = false;
        }
        return hasErrors;
    }
%>

This will display all the available OPPORTUNITIES in the system


Provide values to searchType,searchVal and searchOperator to restrict the search - make this fields configureable via dialog
e.g
searchType = "Name";
searchVal = "TestPost";
searchOperator = "=";



Integration of AEM with Salesforce - Part4





Contact Form

Name

Email *

Message *