ReportsManager.java
/*
** Module : ReportsManager.java
** Abstract : ReportsManager provides external API to generate reports.
**
** Copyright (c) 2017-2023, Golden Code Development Corporation.
**
** -#- -I- --Date-- ----------------Description----------------------
** 001 SBI 20170601 Created initial version.
** 002 TJD 20220504 Java 11 compatibility related minor changes
** 003 GBB 20230512 Logging methods replaced by CentralLogger/ConversionStatus.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.admin.server.reports;
import java.io.*;
import java.util.*;
import com.goldencode.p2j.util.logging.*;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.common.*;
import org.apache.pdfbox.pdmodel.font.*;
import com.goldencode.p2j.admin.AdminServerImpl;
import com.goldencode.p2j.admin.server.reports.PdfReportBuilder.*;
import com.goldencode.p2j.admin.server.reports.ReportBuilder.*;
import com.goldencode.p2j.admin.server.reports.TextReportBuilder.*;
import com.goldencode.p2j.admin.shared.*;
/**
* Reports manager hides internal reports implementations. Provides external api to generate
* reports.
*/
public class ReportsManager
{
/** Logger */
private static final CentralLogger LOG = CentralLogger.get(ReportsManager.class);
/** The standard reports factory */
private static ReportsFactory reportsFactory;
/** The reports factory to build extended reports */
private static ReportsFactory extReportsFactory;
/** The extended reports factory class */
private static Class<? extends ReportsFactory> extReportFactoryClass;
/**
* Gets the standard reports factory.
*
* @return The standard reports factory
*/
private static ReportsFactory getReportsFactory()
{
if (reportsFactory == null)
{
reportsFactory = new ReportsFactoryImpl();
}
return reportsFactory;
}
/**
* Gets the extended reports factory.
*
* @return The extended reports factory
*/
private static ReportsFactory getExtReportsFactory()
{
if (extReportsFactory == null && extReportFactoryClass != null)
{
try
{
extReportsFactory = (ReportsFactory) extReportFactoryClass.getDeclaredConstructor().newInstance();
}
catch (ReflectiveOperationException e)
{
LOG.severe("Get ext reports factory exception", e);
}
}
return extReportsFactory;
}
/**
* Sets the report factory class to instantiate the extended report factory.
*
* @param reportFactoryClass
* The report factory class
*/
public static synchronized void setExtReportFactoryClass(Class<? extends ReportsFactory> reportFactoryClass)
{
ReportsManager.extReportFactoryClass = reportFactoryClass;
}
/**
* Gets the requested report factory.
*
* @param request
* The given report request
*
* @return The requested report factory
*/
public static synchronized ReportsFactory getReportsFactory(ReportRequest request)
{
String ext = request.getReportParameters().getOrDefault(
ReportParameters.EXTENSION.getParameter(), "");
ReportsFactory factory;
if (ext.isEmpty())
{
factory = getReportsFactory();
}
else
{
factory = getExtReportsFactory();
}
if (factory == null)
{
factory = getReportsFactory();
}
return factory;
}
/**
* Builds the requested PDF report.
*
* @param request
* The report request
*
* @return The pdf document given by PDDocument
*
* @throws IOException
* Throws this exception iff this IO operation is failed
*/
public static PDDocument buildPDFReport(ReportRequest request)
throws IOException
{
PdfDocument doc = buildPDFReportDocument(request);
return doc.getDocument();
}
/**
* Builds the requested PDF report.
*
* @param request
* The report request
*
* @return The pdf document holder
*
* @throws IOException
* Throws this exception iff this IO operation is failed
*/
private static PdfDocument buildPDFReportDocument(ReportRequest request)
throws IOException
{
ReportsFactory factory = getReportsFactory(request);
return factory.createPDFReportBuilder(request).buildReport(
buildReportParameters(request));
}
/**
* Builds the requested PDF page report.
*
* @param request
* The report request
* @param pageNumber
* The page number to preview its pdf report
*
* @return The pdf document given by PDDocument
*
* @throws IOException
* Throws this exception iff this IO operation is failed
*/
public static PdfDocument buildPDFPagePreview(ReportRequest request, int pageNumber)
throws IOException
{
request.getReportParameters().put(ReportParameters.PREVIEW_PAGE.getParameter(),
String.valueOf(pageNumber));
return buildPDFReportDocument(request);
}
/**
* Builds the requested report.
*
* @param request
* The report request
*
* @return The report document
*
* @throws IOException
* Throws this exception iff this IO operation is failed
*/
public static Document buildReport(ReportRequest request)
throws IOException
{
ReportsFactory factory = getReportsFactory(request);
String type = request.getReportParameters().getOrDefault(
ReportParameters.REPORT_TYPE.getParameter(), DocumentType.PDF.name());
if (DocumentType.get(type) == DocumentType.PDF)
{
return factory.createPDFReportBuilder(request).buildReport(buildReportParameters(request));
}
else
{
return factory.createTextReportBuilder(request).buildReport(buildTextReportParameters(request));
}
}
/**
* Builds the requested report settings for the text report type.
*
* @param request
* The text report request
*
* @return The text report settings
*/
public static TextReportSettings buildTextReportParameters(ReportRequest request)
{
return new TextReportSettings()
{
};
}
/**
* Builds the requested report settings for the PDF report type.
*
* @param request
* The PDF report request
*
* @return The PDF report settings
*/
public static PdfReportSettings buildReportParameters(ReportRequest request)
{
final Map<String, String> parameters = request.getReportParameters();
final PaperOrientation orient = PaperOrientation.valueOf(
parameters.get(ReportParameters.PAPER_ORIENT.getParameter()));
final PaperFormat format = PaperFormat.valueOf(
parameters.get(ReportParameters.PAPER_FORMAT.getParameter()));
// these server report parameters can't be changed on the client side
Map<String, Object> map = AdminServerImpl.getReportParametersMap();
Integer maxPagesNumber = (Integer) map.get(ReportParameters.MAX_PAGES_NUMBER.getParameter());
//report geometry settings
float[] margin = new float[4];
margin[0] = (Float) map.get(ReportParameters.LEFT_PAGE_MARGIN.getParameter());
margin[1] = (Float) map.get(ReportParameters.TOP_PAGE_MARGIN.getParameter());
margin[2] = (Float) map.get(ReportParameters.RIGHT_PAGE_MARGIN.getParameter());
margin[3] = (Float) map.get(ReportParameters.BOTTOM_PAGE_MARGIN.getParameter());
Float cellMargin = (Float) map.get(ReportParameters.CELL_MARGIN.getParameter());
Float cellPadding = (Float) map.get(ReportParameters.CELL_PADDING.getParameter());
Float headerMargin = (Float) map.get(ReportParameters.HEADER_MARGIN.getParameter());
Float footerMargin = (Float) map.get(ReportParameters.FOOTER_MARGIN.getParameter());
//report font settings
Integer fontSize = (Integer) map.get(ReportParameters.FONT_SIZE.getParameter());
Integer columnFontSize = (Integer) map.get(ReportParameters.COLUMN_FONT_SIZE.getParameter());
Integer headerFontSize = (Integer) map.get(ReportParameters.HEADER_FONT_SIZE.getParameter());
Integer footerFontSize = (Integer) map.get(ReportParameters.FOOTER_FONT_SIZE.getParameter());
//TODO the font family selection
//String fontName = (String) map.get(ReportParameters.FONT_NAME.getParameter());
//String boldFontName = (String) map.get(ReportParameters.BOLD_FONT_NAME.getParameter());
/**
* The anonymous implementation of PDF report settings
*/
return new PdfReportSettings() {
/**
* Gets the report rectangle.
*
* @return The report rectangle
*/
@Override
public PDRectangle getReportSize()
{
switch(format)
{
case LETTER:
return PDRectangle.LETTER;
case LEGAL:
return PDRectangle.LEGAL;
case A0:
return PDRectangle.A0;
case A1:
return PDRectangle.A1;
case A2:
return PDRectangle.A2;
case A3:
return PDRectangle.A3;
case A4:
return PDRectangle.A4;
case A5:
return PDRectangle.A5;
case A6:
return PDRectangle.A6;
default:
return PDRectangle.A4;
}
}
/**
* Gets the report paper orientation.
*
* @return The paper orientation
*/
@Override
public PaperOrientation getPaperOrientation()
{
return orient;
}
/**
* Gets the normal report font.
*
* @return The normal report font
*/
@Override
public PDFont getFont()
{
return PDType1Font.COURIER;
}
/**
* Gets the bold report font.
*
* @return The bold report font
*/
@Override
public PDFont getBoldFont()
{
return PDType1Font.COURIER_BOLD;
}
/**
* Gets the base font size.
*
* @return The base font size
*/
@Override
public int getFontSize()
{
return fontSize.intValue();
}
/**
* Gets the column header font size.
*
* @return The column header font size
*/
@Override
public int getColumnFontSize()
{
return columnFontSize.intValue();
}
/**
* Gets the cell font size.
*
* @return The cell font size
*/
@Override
public int getCellFontSize()
{
return getFontSize();
}
/**
* Gets the page header font size.
*
* @return The page header font size
*/
@Override
public int getHeaderFontSize()
{
return headerFontSize.intValue();
}
/**
* Gets the page footer font size.
*
* @return The page footer font size
*/
@Override
public int getFooterFontSize()
{
return footerFontSize.intValue();
}
/**
* Gets the page margin in this order: left, top, right and bottom. The values are
* measured by points relative to the user space.
*
* @return The page margin
*/
@Override
public float[] getPageMargin()
{
return margin;
}
/**
* Gets the header margin measured by points relative to the user space.
*
* @return The header margin
*/
@Override
public float getHeaderMargin()
{
return headerMargin.floatValue();
}
/**
* Gets the footer margin measured by points relative to the user space.
*
* @return The footer margin
*/
@Override
public float getFooterMargin()
{
return footerMargin.floatValue();
}
/**
* Gets the cell margin measured by points relative to the user space.
*
* @return The cell margin
*/
@Override
public float getCellMargin()
{
return cellMargin.floatValue();
}
/**
* Gets the cell padding measured by points relative to the user space.
*
* @return The cell padding
*/
@Override
public float getCellPadding()
{
return cellPadding.floatValue();
}
/**
* Gets the maximal pages number.
*
* @return The maximal pages number
*/
@Override
public int getMaxPagesNumber()
{
return maxPagesNumber;
}
};
}
}