This article describes a sample integration between Inforama and Apex code (hosted on the force.com platform). The goal is to create a document/documents (by calling Inforama web service) populated with data retrieved from the force.com platform, e.g. with account's details and deliver the document to the end user.
The steps below describe a sample way of achieving that by performing a number of callouts to the Inforama server from the Apex code.
1. Retrieve a list of available documents along with required parameters
The HTTP request
InforamaServer/rest/templates.htm returns an xml describing the default project's available document templates and the parameters that should be provided in order to generate the result documents. The sample response may look like shown below:
<project name="TestProject">
<document name="document1">
<parameter name="Account.Business_City__c" />
<parameter name="Account.Business_Zip__c" />
<parameter name="Contact.Cell_Phone__c" />
<parameter name="Account.Business_State__c" />
<parameter name="Account.Business_Address__c" />
<parameter name="Contact.City__c" />
</document>
</project>
In the description below we will follow the convention: parameters whose names are prefixed with Account. word refer to the current account on the force.com page (i.e. an account which is active/selected when the callout to the Inforama server is performed from the Apex code.). The same rules applies to parameters prefixed with Contact. word.
The snipped below shows an Apex code performing the request and consuming the response. The XMLDom class is a standard implementation of the wc3 XML Dom model. The tempaltesMap maps a template name to a set of required parameters.
// Apex code retrieve available templates along with required parameters
Map<String,Set<String>> templatesMap = new Map<String, Set<String>>();
Http http = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('http://inforamaserver/rest/templates.htm');
req.setMethod('GET');
HttpResponse res = http.send(req);
XMLDom d = new XMLDom(res.getBody());
// templates
for (XMLdom.Element de : d.getElementsByTagName('document')) {
String templateName = de.getAttribute('name');
Set<String> templateParams = new Set<String>();
templatesMap.put(templateName, templateParams);
// parameters
for (XMLdom.Element pe : de.getElementsByTagName('parameter')) {
String parameterName = pe.getAttribute('name');
// check if this is an account parameter
if (parameterName.startsWith('Account.')) {
templateParams.add(parameterName.substring(8));
}
}
}
Once we obtained the required parameter names we can match them with relevant
Account/Contact fields retrieved from the
force.com platform's data store. The
Apex method shown below buidl an
Account object populated with the fields whose names are specified in the
requiredParams set.
/** Gets a current Account object */
private Account buildAccount(Set<String> requiredParams) {
if (requiredParams.size() == 0) {
return null;
}
String query = 'SELECT ';
Boolean first = true;
for (String param : requiredParams) {
if (first) {
query += param;
first = false;
} else {
query += ', ' + param;
}
}
String accountId = ApexPages.currentPage().getParameters().get('id');
query += ' FROM account WHERE id=\'' + accountId + '\'';
return (Account)Database.query(query);
}
3. Call the Inforama service in order to generate the output documents.
The HTTP Request that needs to be performed in order to generate output documents should follow the form:
InforamaServer/rest/generator.html?docs=requested_documents¶ms=provided_parameters where
requested_documents is a semicolon separated list of documents that should be generated (e.g. doc1:doc2:doc3) and
provided_parameters is a semicolon separated list of parameters with their values (e.g. Account.First_Name=John:Account.Last_Name=Doe).
The sample
Inforama Server response to this call can look like shown on the snippet below:
<response>
<status value="ok"/>
<file id="1240330360357" name="documents.zip"/>
</response>
The name is the name of the file that has been generated and stored on the Inforama Server while the id is the unique identifier of this file. In case of multiple document request the Inforama Server will compress them to a ZIP file, the single-document request outcomes are be stored directly as PDF files.
4. Retrieving the generated documents from the Inforama Server.
Once the documents (or a single document) have been generated and stored in the
Inforama Server they can be retrieved by performing the HTTP Request in a form:
inforamaServer/rest/documents.htm?id=document_id where
document_id is the identifier retrieved previously.
One possible scenario of using that
HTTP Request could be in a custom
VisualForce controller which, say, redirects the browser to the
Inforama Server so that the generated file is delivered directly to the client. The sample
Apex code shown below illustrates this:
// this is a controller method, invoked when, for example, a button on the VisualForce is pressed
public PageReference generate() {
// retrieve the required parameters by invoking the relevant Inforama Service
Set<String> requiredParams = gatherRequiredParams();
// retrieve the account from the force.com data store, the account is populated with
// the fields specified by the requiredParams
Account account = buildAccount(requiredParams);
// build the HTTP Request url which will generated and stored required documents
// on the Inforama server.
String generatorUrl = buildGeneratorUrl(account, requiredParams);
// retrieve the unique identifier of the document that has been generated
// and stored on the Inforama server.
String docId = retrieveId(generatorUrl);
// build HTTP Request URL that will return the generated document/documents
String documentUrl = buildDocumentUril(docId);
// redirect the browser so the file is delivered to the client directly
// from the Inforama server.
return new PageReference(documentUrl);
}