package controllers;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.codec.binary.Base64InputStream;
import org.apache.commons.lang3.SerializationUtils;
import org.codehaus.jackson.JsonNode;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import play.Logger;
import play.libs.Json;
import play.mvc.Controller;
import play.mvc.Http.MultipartFormData;
import play.mvc.Http.MultipartFormData.FilePart;
import play.mvc.Result;
import com.appirio.PDFCombinerArguments;
import com.appirio.PDFCombinerFile;
import com.appirio.report.Reporter;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class Application extends Controller {
private static final String CLOUDAMQP_URL = System.getenv("CLOUDAMQP_URL");
private static final String GENERATED_PDFS_DIR = System.getenv("GENERATED_PDFS_DIR");
public static Result index() {
return ok(views.html.index.render());
}
/**
* Stream PDF File
* @throws Exception
*/
public static Result getPdf(String pdfFile) throws Exception {
// stream generated PDF content
pdfFile = System.getenv("GENERATED_PDFS_DIR") + File.separator + pdfFile;
return ok(new File(pdfFile));
}
private final static String QUEUE_NAME = "pdfcombiner";
/**
* Handles uploading of files. Launch PDF combiner.
* @return Url to the generated PDF file
* @throws Exception
*/
public static Result upload() throws Exception {
// create connection
ConnectionFactory factory = new ConnectionFactory();
factory.setUri(CLOUDAMQP_URL);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// get json and fill pdfCombinerArguments object
JsonNode json = request().body().asJson();
PDFCombinerArguments pdfCombinerArguments = Json.fromJson(json, PDFCombinerArguments.class);
// broadcast message containing pdfCombinerArguments
byte[] data = SerializationUtils.serialize(pdfCombinerArguments);
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.basicPublish("", QUEUE_NAME, null, data);
// debug info
System.out.println(" title: " + pdfCombinerArguments.getTitle());
System.out.println(" subTitle: " + pdfCombinerArguments.getSubTitle());
System.out.println(" email: " + pdfCombinerArguments.getEmail());
System.out.println(" [x] Message sent to queue");
channel.close();
connection.close();
return redirect(routes.Application.index());
}
/**
* Handles the report preview generation. Stream the generated file.
* @return stream of generated file
* @throws Exception
*/
public static Result outputPreview() throws Exception {
System.out.println("outputPreview(): begin");
// get uploaded json and fill pdfCombinerArguments object
JsonNode json = request().body().asJson();
PDFCombinerArguments pdfCombinerArguments = Json.fromJson(json, PDFCombinerArguments.class);
// get first contents as pdf combiner file
PDFCombinerFile file = pdfCombinerArguments.getContents().get(0);
// set filename for this datasource
String fileName = "/tmp/" + file.getPathOnClient();
// download datasource
generateEmptyXml(file, fileName);
// download disclaimer
String disclaimerXmlFilename = "/tmp/disclaimers.xml";
downloadFile(pdfCombinerArguments.getDisclaimerUrl(), pdfCombinerArguments.getSessionId(), disclaimerXmlFilename);
// download map panel order preferences
String mapPanelOrderPrefXmlFilename = "/tmp/mapPanelOrderPref" + pdfCombinerArguments.getSessionId() + ".xml";
downloadFile(pdfCombinerArguments.getMapPanelOrderPrefUrl(), pdfCombinerArguments.getSessionId(), mapPanelOrderPrefXmlFilename);
//download package summary file
String packageSummaryXmlFilename = "/tmp/packageSummary" + pdfCombinerArguments.getSessionId() + ".xml";
downloadFile(pdfCombinerArguments.getPackageSummaryUrl(), pdfCombinerArguments.getSessionId(), packageSummaryXmlFilename);
// process report
Reporter reporter = new Reporter(fileName, disclaimerXmlFilename, mapPanelOrderPrefXmlFilename, null, packageSummaryXmlFilename, pdfCombinerArguments.isShowTotalProgramSummary(), pdfCombinerArguments.isShowIndividualMarketSummary(), pdfCombinerArguments.isShowIndividualFlightSummary(), file, pdfCombinerArguments.isExportToPdf(), pdfCombinerArguments.isExportToXls(),
null);
// prepare response
String fileExtension = pdfCombinerArguments.isExportToXls() ? "xls" : "pdf";
// get generated report file
String fileDownloadParameter = reporter.getUniqueId() + File.separator + reporter.getUniqueId() + "." + fileExtension;
System.out.println(" fileDownloadParameter: " + fileDownloadParameter);
// return url to pdf
String baseUrl = routes.Application.index().absoluteURL(request());
if(baseUrl.endsWith("/")) {
baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
}
// download url
String downloadUrl = baseUrl + controllers.routes.Application.getPdf(fileDownloadParameter).url();
System.out.println(" downloadUrl: " + downloadUrl);
System.out.println("outputPreview(): end");
return ok(downloadUrl);
}
public static Result getReportFile(String fileName) throws Exception {
// stream generated PDF content
fileName = System.getenv("GENERATED_PDFS_DIR") + File.separator + fileName + File.separator + fileName + ".pdf";
return ok(new File(fileName));
}
public static Result showSystemStatus() {
return ok("System Status...");
}
/**
* Decodes a base64 encoded file to binary.
* @param base64FileName
* @param newFileName
* @throws Exception
*/
public static void decodeBase64File(String base64FileName, String newFileName) throws Exception {
int BUFFER_SIZE = 4096;
byte[] buffer = new byte[BUFFER_SIZE];
Logger.info(" open input stream");
InputStream input = new Base64InputStream(new FileInputStream(base64FileName));
Logger.info(" open output stream");
OutputStream output = new FileOutputStream(newFileName);
int n = input.read(buffer, 0, BUFFER_SIZE);
while (n >= 0) {
Logger.info(" reading");
output.write(buffer, 0, n);
n = input.read(buffer, 0, BUFFER_SIZE);
}
Logger.info(" closing streams");
input.close();
output.close();
}
private static void downloadFile(String url, String sessionId, String outputFileName) {
System.out.println("downloadFile(): begin");
System.out.println(" url : " + url);
System.out.println(" sessionId : " + sessionId);
System.out.println(" outputFileName: " + outputFileName);
System.out.println(" curl command : curl -H \"Authorization: Bearer " + sessionId + "\" -H \"Accept: application/xml\"" + url);
int size=1024;
InputStream is = null;
OutputStream outStream = null;
URLConnection uCon = null;
try {
URL Url;
byte[] buf;
int ByteRead,ByteWritten=0;
Url= new URL(url);
outStream = new BufferedOutputStream(new FileOutputStream(outputFileName));
uCon = Url.openConnection();
uCon.setRequestProperty("Authorization", "Bearer " + sessionId);
uCon.setRequestProperty("Accept", "application/xml");
is = uCon.getInputStream();
buf = new byte[size];
while ((ByteRead = is.read(buf)) != -1) {
outStream.write(buf, 0, ByteRead);
ByteWritten += ByteRead;
}
System.out.println(" Downloaded Successfully.");
System.out.println(" File name:\""+outputFileName+ "\"\nNo ofbytes :" + ByteWritten);
}catch (Exception e) {
e.printStackTrace();
}
finally {
try {
is.close();
outStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Generate an empty xml that will serve as dataset for report preview
*/
public static void generateEmptyXml(PDFCombinerFile pdfCombinerFile, String outputFileName) {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("QueryResult");
doc.appendChild(rootElement);
// staff elements
Element staff = doc.createElement("records");
rootElement.appendChild(staff);
// split fields
String[] fieldNamesArray = pdfCombinerFile.getFieldNamesPipeDelimited().get(0).split("\\|");
// for each field name
for(Integer fieldIndex = 0; fieldIndex < fieldNamesArray.length; fieldIndex++) {
// add element
Element recordElement = doc.createElement(fieldNamesArray[fieldIndex]);
staff.appendChild(recordElement);
}
/*
<Package_Flight__r>
<Id>1</Id>
<Type__c>Audience</Type__c>
<Campaign_Start_Date__c>2013-01-01</Campaign_Start_Date__c>
<Campaign_End_Date__c>2013-01-01</Campaign_End_Date__c>
</Package_Flight__r>
*/
// add empty flight record
Element flightElement = doc.createElement("Package_Flight__r");
staff.appendChild(flightElement);
Element idElement = doc.createElement("Id");
idElement.setTextContent("1");
flightElement.appendChild(idElement);
Element typeElement = doc.createElement("Type__c");
typeElement.setTextContent("Audience");
flightElement.appendChild(typeElement);
Element campaignStartDateElement = doc.createElement("Campaign_Start_Date__c");
campaignStartDateElement.setTextContent("2013-01-01");
flightElement.appendChild(campaignStartDateElement);
Element campaignEndDateElement = doc.createElement("Campaign_End_Date__c");
campaignEndDateElement.setTextContent("2013-12-31");
flightElement.appendChild(campaignEndDateElement);
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(outputFileName));
// Output to console for testing
//StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
System.out.println("File saved!");
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
}