package fi.otavanopisto.pyramus.binary.reports;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import fi.internetix.smvc.SmvcRuntimeException;
import fi.internetix.smvc.controllers.BinaryRequestContext;
import fi.otavanopisto.pyramus.dao.DAOFactory;
import fi.otavanopisto.pyramus.dao.base.MagicKeyDAO;
import fi.otavanopisto.pyramus.dao.reports.ReportDAO;
import fi.otavanopisto.pyramus.domainmodel.base.MagicKey;
import fi.otavanopisto.pyramus.domainmodel.base.MagicKeyScope;
import fi.otavanopisto.pyramus.domainmodel.reports.Report;
import fi.otavanopisto.pyramus.framework.BinaryRequestController;
import fi.otavanopisto.pyramus.framework.UserRole;
import fi.otavanopisto.pyramus.util.ReportUtils;
/** A binary request controller responsible for serving reports
* in various binary file formats.
*
*/
public class DownloadReportBinaryRequestController extends BinaryRequestController {
/** Processes a binary request for a report in binary format.
* The request should contain the following parameters:
* <dl>
* <dt><code>reportId</code></dt>
* <dd>The ID of the report to download.</dd>
* <dt><code>format</code></dt>
* <dd>The file format of the report. Possible values:
* <ul>
* <li><code>html</code></li>
* <li><code>pdf</code></li>
* <li><code>rtf</code></li>
* <li><code>doc</code></li>
* <li><code>xml</code></li>
* </ul>
* </dd>
* </dl>
*
* @param binaryRequestContext The context of the binary request.
*/
public void process(BinaryRequestContext binaryRequestContext) {
ReportDAO reportDAO = DAOFactory.getInstance().getReportDAO();
MagicKeyDAO magicKeyDAO = DAOFactory.getInstance().getMagicKeyDAO();
Long reportId = binaryRequestContext.getLong("reportId");
String formatParameter = binaryRequestContext.getString("format");
ReportOutputFormat outputFormat = Enum.valueOf(ReportOutputFormat.class, formatParameter);
StringBuilder magicKeyBuilder = new StringBuilder()
.append(Long.toHexString(reportId))
.append('-')
.append(Long.toHexString(System.currentTimeMillis()))
.append('-')
.append(Long.toHexString(Thread.currentThread().getId()));
MagicKey magicKey = magicKeyDAO.create(magicKeyBuilder.toString(), MagicKeyScope.REQUEST);
Report report = reportDAO.findById(reportId);
String reportName = report.getName().toLowerCase().replaceAll("[^a-z0-9\\.]", "_");
String localeAdd = "";
Locale locale = binaryRequestContext.getRequest().getLocale();
if (locale != null) {
localeAdd = "&__locale=";
localeAdd += locale.getLanguage();
if (!StringUtils.isEmpty(locale.getCountry())) {
localeAdd += "_";
localeAdd += locale.getCountry();
}
}
StringBuilder urlBuilder = new StringBuilder()
.append(ReportUtils.getReportsUrl(binaryRequestContext.getRequest()))
.append("/preview")
.append("?magicKey=")
.append(magicKey.getName())
.append(localeAdd)
.append("&__report=reports/")
.append(reportId)
.append(".rptdesign")
.append("&__format=")
.append(outputFormat.name());
Map<String, String[]> parameterMap = binaryRequestContext.getRequest().getParameterMap();
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
if (!reservedParameters.contains(entry.getKey())) {
String[] values = entry.getValue();
for (String value : values) {
// TODO ISO-8859-1 should be UTF-8, once Birt's parameter dialog form has its accept-charset="UTF-8" set
try {
urlBuilder.append('&').append(entry.getKey()).append('=').append(URLEncoder.encode(value, "ISO-8859-1"));
}
catch (UnsupportedEncodingException e) {
throw new SmvcRuntimeException(e);
}
}
}
}
binaryRequestContext.setFileName(reportName + '.' + outputFormat.getExt());
binaryRequestContext.setContentUrl(urlBuilder.toString());
}
/** Returns the user roles allowed to access this controller.
*
* @return The user roles allowed to access this controller.
*/
public UserRole[] getAllowedRoles() {
return new UserRole[] { UserRole.USER, UserRole.STUDY_PROGRAMME_LEADER, UserRole.MANAGER, UserRole.ADMINISTRATOR };
}
private enum ReportOutputFormat {
HTML ("html"),
PDF ("pdf"),
RTF ("rtf"),
DOC ("doc"),
XLS ("xml");
ReportOutputFormat (String ext) {
this.ext = ext;
}
public String getExt() {
return ext;
}
private String ext;
}
private static Set<String> reservedParameters = new HashSet<>();
static {
reservedParameters.add("reportId");
reservedParameters.add("magicKey");
reservedParameters.add("format");
reservedParameters.add("__format");
reservedParameters.add("__report");
}
}