Java tutorial
/***************************************************************** * This file is part of Managing Agricultural Research for Learning & * Outcomes Platform (MARLO). * MARLO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * at your option) any later version. * MARLO 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 General Public License for more details. * You should have received a copy of the GNU General Public License * along with MARLO. If not, see <http://www.gnu.org/licenses/>. *****************************************************************/ package org.cgiar.ccafs.marlo.action.summaries; import org.cgiar.ccafs.marlo.config.APConstants; import org.cgiar.ccafs.marlo.data.manager.GlobalUnitManager; import org.cgiar.ccafs.marlo.data.manager.PhaseManager; import org.cgiar.ccafs.marlo.data.manager.ProjectHighligthManager; import org.cgiar.ccafs.marlo.data.manager.ProjectManager; import org.cgiar.ccafs.marlo.data.model.ProjectHighlight; import org.cgiar.ccafs.marlo.data.model.ProjectHighlightCountry; import org.cgiar.ccafs.marlo.data.model.ProjectHighlightType; import org.cgiar.ccafs.marlo.data.model.ProjectHighligthsTypeEnum; import org.cgiar.ccafs.marlo.utils.APConfig; import org.cgiar.ccafs.marlo.utils.FileManager; import org.cgiar.ccafs.marlo.utils.HTMLParser; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.text.SimpleDateFormat; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.stream.Collectors; import javax.inject.Inject; import com.lowagie.text.BadElementException; import com.lowagie.text.Image; import org.apache.commons.lang3.StringUtils; import org.apache.struts2.dispatcher.Parameter; import org.pentaho.reporting.engine.classic.core.CompoundDataFactory; import org.pentaho.reporting.engine.classic.core.Element; import org.pentaho.reporting.engine.classic.core.ItemBand; import org.pentaho.reporting.engine.classic.core.MasterReport; import org.pentaho.reporting.engine.classic.core.SubReport; import org.pentaho.reporting.engine.classic.core.TableDataFactory; import org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PdfReportUtil; import org.pentaho.reporting.engine.classic.core.modules.output.table.xls.ExcelReportUtil; import org.pentaho.reporting.engine.classic.core.util.TypedTableModel; import org.pentaho.reporting.libraries.resourceloader.Resource; import org.pentaho.reporting.libraries.resourceloader.ResourceManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Andrs Valencia - CIAT/CCAFS */ public class ProjectHighlightsSummaryAction extends BaseSummariesAction implements Summary { private static final long serialVersionUID = 1L; private static Logger LOG = LoggerFactory.getLogger(ProjectHighlightsSummaryAction.class); // Managers private final ProjectHighligthManager projectHighLightManager; private final ResourceManager resourceManager; private final HTMLParser HTMLParser; // Parameters private long startTime; private String selectedFormat; // XLSX bytes private byte[] bytesPDF; // XLSX bytes private byte[] bytesXLSX; // Streams InputStream inputStream; @Inject public ProjectHighlightsSummaryAction(APConfig config, GlobalUnitManager crpManager, ProjectHighligthManager projectHighLightManager, PhaseManager phaseManager, ResourceManager resourceManager, HTMLParser HTMLParser, ProjectManager projectManager) { super(config, crpManager, phaseManager, projectManager); this.projectHighLightManager = projectHighLightManager; this.resourceManager = resourceManager; this.HTMLParser = HTMLParser; } /** * Method to add i8n parameters to masterReport in Pentaho * * @param masterReport * @return masterReport with i8n parameters added */ private MasterReport addi8nParameters(MasterReport masterReport) { masterReport.getParameterValues().put("i8nMainTitle", this.getText("projectHighlights.title")); masterReport.getParameterValues().put("i8nNoData", this.getText("projectHighlight.noData")); masterReport.getParameterValues().put("i8nSingular", this.getText("projectHighlight.singular")); masterReport.getParameterValues().put("i8nTitle", this.getText("highlight.title")); masterReport.getParameterValues().put("i8nAuthor", this.getText("highlight.author")); masterReport.getParameterValues().put("i8nSubject", this.getText("highlight.subject")); masterReport.getParameterValues().put("i8nPublisher", this.getText("highlight.publisher")); masterReport.getParameterValues().put("i8nYear", this.getText("highlight.year")); masterReport.getParameterValues().put("i8nTypes", this.getText("highlight.types")); masterReport.getParameterValues().put("i8nIsGlobal", this.getText("highlight.isGlobal.readText")); masterReport.getParameterValues().put("i8nStartDate", this.getText("highlight.startDate")); masterReport.getParameterValues().put("i8nEndDate", this.getText("highlight.endDate")); masterReport.getParameterValues().put("i8nProjectId", this.getText("searchTerms.projectId")); masterReport.getParameterValues().put("i8nCountries", this.getText("highlight.countries")); masterReport.getParameterValues().put("i8nKeywords", this.getText("highlight.keywords")); masterReport.getParameterValues().put("i8nDescripition", this.getText("highlight.descripition.readText")); masterReport.getParameterValues().put("i8nObjectives", this.getText("highlight.objectives.readText")); masterReport.getParameterValues().put("i8nResults", this.getText("highlight.results.readText")); masterReport.getParameterValues().put("i8nPartners", this.getText("highlight.partners.readText")); masterReport.getParameterValues().put("i8nLinks", this.getText("highlight.links.readText")); masterReport.getParameterValues().put("i8nProjectHighlightsId", this.getText("projectHighlights.projectHighlightsId")); masterReport.getParameterValues().put("i8nImage", this.getText("highlight.image.readText")); return masterReport; } @Override public String execute() throws Exception { ByteArrayOutputStream os = new ByteArrayOutputStream(); try { Resource reportResource; if (this.getSelectedFormat().equals(APConstants.SUMMARY_FORMAT_EXCEL)) { reportResource = resourceManager.createDirectly( this.getClass().getResource("/pentaho/crp/ProjectHighlightsExcel.prpt"), MasterReport.class); } else { reportResource = resourceManager.createDirectly( this.getClass().getResource("/pentaho/crp/ProjectHighlightsPDF.prpt"), MasterReport.class); } MasterReport masterReport = (MasterReport) reportResource.getResource(); String center = this.getLoggedCrp().getAcronym(); // Get datetime ZonedDateTime timezone = ZonedDateTime.now(); DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-d 'at' HH:mm "); String zone = timezone.getOffset() + ""; if (zone.equals("Z")) { zone = "+0"; } String date = timezone.format(format) + "(GMT" + zone + ")"; // Set Main_Query CompoundDataFactory cdf = CompoundDataFactory.normalize(masterReport.getDataFactory()); String masterQueryName = "main"; TableDataFactory sdf = (TableDataFactory) cdf.getDataFactoryForQuery(masterQueryName); TypedTableModel model = this.getMasterTableModel(center, date, String.valueOf(this.getSelectedYear())); sdf.addTable(masterQueryName, model); masterReport.setDataFactory(cdf); // Set i8n for pentaho masterReport = this.addi8nParameters(masterReport); // Get details band ItemBand masteritemBand = masterReport.getItemBand(); // Create new empty subreport hash map HashMap<String, Element> hm = new HashMap<String, Element>(); // method to get all the subreports in the prpt and store in the HashMap this.getAllSubreports(hm, masteritemBand); // Uncomment to see which Subreports are detecting the method getAllSubreports // System.out.println("Pentaho SubReports: " + hm); this.fillSubreport((SubReport) hm.get("project_highlight"), "project_highlight"); if (this.getSelectedFormat().equals(APConstants.SUMMARY_FORMAT_EXCEL)) { ExcelReportUtil.createXLSX(masterReport, os); bytesXLSX = os.toByteArray(); } else { PdfReportUtil.createPDF(masterReport, os); bytesPDF = os.toByteArray(); } os.close(); } catch (Exception e) { LOG.error("Error generating ProjectHighlights" + this.getSelectedFormat() + ": " + e.getMessage()); throw e; } // Calculate time of generation long stopTime = System.currentTimeMillis(); stopTime = stopTime - startTime; LOG.info("Downloaded successfully: " + this.getFileName() + ". User: " + this.getCurrentUser().getComposedCompleteName() + ". CRP: " + this.getLoggedCrp().getAcronym() + ". Time to generate: " + stopTime + "ms."); return SUCCESS; } private void fillSubreport(SubReport subReport, String query) { CompoundDataFactory cdf = CompoundDataFactory.normalize(subReport.getDataFactory()); TableDataFactory sdf = (TableDataFactory) cdf.getDataFactoryForQuery(query); TypedTableModel model = null; switch (query) { case "project_highlight": model = this.getProjectHighligthsTableModel(); break; } sdf.addTable(query, model); subReport.setDataFactory(cdf); } public byte[] getBytesPDF() { return bytesPDF; } public byte[] getBytesXLSX() { return bytesXLSX; } @Override public int getContentLength() { if (this.getSelectedFormat().equals(APConstants.SUMMARY_FORMAT_EXCEL)) { return bytesXLSX.length; } else { return bytesPDF.length; } } @Override public String getContentType() { if (this.getSelectedFormat().equals(APConstants.SUMMARY_FORMAT_EXCEL)) { return "application/xlsx"; } else { return "application/pdf"; } } @SuppressWarnings("unused") private File getFile(String fileName) { // Get file from resources folder ClassLoader classLoader = this.getClass().getClassLoader(); File file = new File(classLoader.getResource(fileName).getFile()); return file; } @Override public String getFileName() { StringBuffer fileName = new StringBuffer(); fileName.append("ProjectHighlightsSummary-"); fileName.append(this.getLoggedCrp().getAcronym() + "-"); fileName.append(this.getSelectedYear() + "_"); fileName.append(new SimpleDateFormat("yyyyMMdd-HHmm").format(new Date())); if (this.getSelectedFormat().equals(APConstants.SUMMARY_FORMAT_EXCEL)) { fileName.append(".xlsx"); } else { fileName.append(".pdf"); } return fileName.toString(); } public String getHighlightsImagesUrl(String projectId) { return config.getDownloadURL() + "/" + this.getHighlightsImagesUrlPath(projectId).replace('\\', '/'); } public String getHighlightsImagesUrlPath(long projectID) { return config.getProjectsBaseFolder(this.getCrpSession()) + File.separator + projectID + File.separator + "hightlightsImage" + File.separator; } public String getHighlightsImagesUrlPath(String projectId) { return config.getProjectsBaseFolder(this.getCrpSession()) + File.separator + projectId + File.separator + "hightlightsImage" + File.separator; } private String getHightlightImagePath(long projectID) { return config.getUploadsBaseFolder() + File.separator + this.getHighlightsImagesUrlPath(projectID) + File.separator; } @Override public InputStream getInputStream() { if (inputStream == null) { if (this.getSelectedFormat().equals(APConstants.SUMMARY_FORMAT_EXCEL)) { inputStream = new ByteArrayInputStream(bytesXLSX); } else { inputStream = new ByteArrayInputStream(bytesPDF); } } return inputStream; } private TypedTableModel getMasterTableModel(String center, String date, String year) { // Initialization of Model TypedTableModel model = new TypedTableModel(new String[] { "center", "date", "year" }, new Class[] { String.class, String.class, String.class }); model.addRow(new Object[] { center, date, year }); return model; } private TypedTableModel getProjectHighligthsTableModel() { TypedTableModel model = new TypedTableModel( new String[] { "id", "title", "author", "subject", "publisher", "year_reported", "highlights_types", "highlights_is_global", "start_date", "end_date", "keywords", "countries", "image", "highlight_desc", "introduction", "results", "partners", "links", "width", "heigth", "project_id", "imageurl", "imageName", "phaseID" }, new Class[] { Long.class, String.class, String.class, String.class, String.class, Long.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, Integer.class, Integer.class, String.class, String.class, String.class, Long.class }, 0); SimpleDateFormat formatter = new SimpleDateFormat("MMM yyyy"); for (ProjectHighlight projectHighlight : projectHighLightManager.findAll().stream() .filter(ph -> ph.isActive() && ph.getProject() != null && ph.getProject().isActive() && ph.getProjectHighlightInfo(this.getSelectedPhase()) != null && ph.getProjectHighlightInfo().getYear() != null && ph.getProjectHighlightInfo().getYear() == this.getSelectedYear() && ph.getProject().getProjecInfoPhase(this.getSelectedPhase()) != null) .sorted((ph1, ph2) -> Long.compare(ph1.getProject().getId(), ph2.getProject().getId())) .collect(Collectors.toList())) { String title = null, author = null, subject = null, publisher = null, highlightsTypes = "", highlightsIsGlobal = null, startDate = null, endDate = null, keywords = null, countries = "", highlightDesc = null, introduction = null, results = null, partners = null, links = null, projectId = null, image = "", imageurl = null, imageName = null; Long yearReported = null; int width = 244; int heigth = 163; if (projectHighlight.getProjectHighlightInfo().getTitle() != null && !projectHighlight.getProjectHighlightInfo().getTitle().isEmpty()) { title = projectHighlight.getProjectHighlightInfo().getTitle(); } if (projectHighlight.getProjectHighlightInfo().getAuthor() != null && !projectHighlight.getProjectHighlightInfo().getAuthor().isEmpty()) { author = projectHighlight.getProjectHighlightInfo().getAuthor(); } if (projectHighlight.getProjectHighlightInfo().getSubject() != null && !projectHighlight.getProjectHighlightInfo().getSubject().isEmpty()) { subject = projectHighlight.getProjectHighlightInfo().getSubject(); } if (projectHighlight.getProjectHighlightInfo().getPublisher() != null && !projectHighlight.getProjectHighlightInfo().getPublisher().isEmpty()) { publisher = projectHighlight.getProjectHighlightInfo().getPublisher(); } if (projectHighlight.getProjectHighlightInfo().getYear() != null) { yearReported = projectHighlight.getProjectHighlightInfo().getYear(); } for (ProjectHighlightType projectHighlightType : projectHighlight.getProjectHighligthsTypes().stream() .filter(pht -> pht.isActive()).collect(Collectors.toList())) { if (ProjectHighligthsTypeEnum.getEnum(projectHighlightType.getIdType() + "") != null) { if (this.getSelectedFormat().equals(APConstants.SUMMARY_FORMAT_EXCEL)) { highlightsTypes += "\n? " + ProjectHighligthsTypeEnum .getEnum(projectHighlightType.getIdType() + "").getDescription(); } else { highlightsTypes += "<br>? " + ProjectHighligthsTypeEnum .getEnum(projectHighlightType.getIdType() + "").getDescription(); } } } if (highlightsTypes.isEmpty()) { highlightsTypes = null; } if (projectHighlight.getProjectHighlightInfo().isGlobal() == true) { highlightsIsGlobal = "Yes"; } else { highlightsIsGlobal = "No"; } if (projectHighlight.getProjectHighlightInfo().getStartDate() != null) { startDate = formatter.format(projectHighlight.getProjectHighlightInfo().getStartDate()); } if (projectHighlight.getProjectHighlightInfo().getEndDate() != null) { endDate = formatter.format(projectHighlight.getProjectHighlightInfo().getEndDate()); } if (projectHighlight.getProjectHighlightInfo().getKeywords() != null && !projectHighlight.getProjectHighlightInfo().getKeywords().isEmpty()) { keywords = projectHighlight.getProjectHighlightInfo().getKeywords(); } int countriesFlag = 0; for (ProjectHighlightCountry projectHighlightCountry : projectHighlight.getProjectHighlightCountries() .stream().filter(phc -> phc.isActive()).collect(Collectors.toList())) { if (projectHighlightCountry.getLocElement() != null) { if (countriesFlag == 0) { countries += projectHighlightCountry.getLocElement().getName(); countriesFlag++; } else { countries += ", " + projectHighlightCountry.getLocElement().getName(); countriesFlag++; } } } if (countries.isEmpty()) { countries = null; } if (projectHighlight.getProjectHighlightInfo().getDescription() != null && !projectHighlight.getProjectHighlightInfo().getDescription().isEmpty()) { if (this.getSelectedFormat().equals(APConstants.SUMMARY_FORMAT_EXCEL)) { highlightDesc = projectHighlight.getProjectHighlightInfo().getDescription(); } else { highlightDesc = HTMLParser .plainTextToHtml(projectHighlight.getProjectHighlightInfo().getDescription()); } } if (projectHighlight.getProjectHighlightInfo().getObjectives() != null && !projectHighlight.getProjectHighlightInfo().getObjectives().isEmpty()) { if (this.getSelectedFormat().equals(APConstants.SUMMARY_FORMAT_EXCEL)) { introduction = projectHighlight.getProjectHighlightInfo().getObjectives(); } else { introduction = HTMLParser .plainTextToHtml(projectHighlight.getProjectHighlightInfo().getObjectives()); } } if (projectHighlight.getProjectHighlightInfo().getResults() != null && !projectHighlight.getProjectHighlightInfo().getResults().isEmpty()) { if (this.getSelectedFormat().equals(APConstants.SUMMARY_FORMAT_EXCEL)) { results = projectHighlight.getProjectHighlightInfo().getResults(); } else { results = HTMLParser.plainTextToHtml(projectHighlight.getProjectHighlightInfo().getResults()); } } if (projectHighlight.getProjectHighlightInfo().getPartners() != null && !projectHighlight.getProjectHighlightInfo().getPartners().isEmpty()) { if (this.getSelectedFormat().equals(APConstants.SUMMARY_FORMAT_EXCEL)) { partners = projectHighlight.getProjectHighlightInfo().getPartners(); } else { partners = HTMLParser.plainTextToHtml(projectHighlight.getProjectHighlightInfo().getPartners()); } } if (projectHighlight.getProjectHighlightInfo().getLinks() != null && !projectHighlight.getProjectHighlightInfo().getLinks().isEmpty()) { if (this.getSelectedFormat().equals(APConstants.SUMMARY_FORMAT_EXCEL)) { links = projectHighlight.getProjectHighlightInfo().getLinks(); } else { links = HTMLParser.plainTextToHtml(projectHighlight.getProjectHighlightInfo().getLinks()); } } if (projectHighlight.getProject() != null) { projectId = projectHighlight.getProject().getId().toString(); } if (projectHighlight.getProjectHighlightInfo().getFile() != null) { double pageWidth = 612 * 0.4; double pageHeigth = 792 * 0.4; double imageWidth = 244; double imageHeigth = 163; image = this.getHightlightImagePath(projectHighlight.getProject().getId()) + projectHighlight.getProjectHighlightInfo().getFile().getFileName(); imageurl = this.getHighlightsImagesUrl(projectHighlight.getProject().getId().toString()) + projectHighlight.getProjectHighlightInfo().getFile().getFileName(); imageName = projectHighlight.getProjectHighlightInfo().getFile().getFileName(); Image imageFile = null; LOG.info("image.getURL.replace " + image); File url; try { url = new File(image); } catch (Exception e) { LOG.warn("Failed to get image File. Url was set to null. Exception: " + e.getMessage()); url = null; image = ""; imageurl = null; imageName = null; } if (url != null && url.exists()) { try { imageFile = Image.getInstance(FileManager.readURL(url)); // System.out.println("W: " + imageFile.getWidth() + " \nH: " + imageFile.getHeight()); if (imageFile.getWidth() >= imageFile.getHeight()) { imageWidth = pageWidth; imageHeigth = imageFile.getHeight() * (((pageWidth * 100) / imageFile.getWidth()) / 100); } else { imageHeigth = pageHeigth; imageWidth = imageFile.getWidth() * (((pageHeigth * 100) / imageFile.getHeight()) / 100); } // System.out.println("New W: " + imageWidth + " \nH: " + imageHeigth); width = (int) imageWidth; heigth = (int) imageHeigth; // If successful, process the message } catch (BadElementException e) { LOG.warn("BadElementException getting image: " + e.getMessage()); image = ""; imageurl = null; imageName = null; } catch (MalformedURLException e) { LOG.warn("MalformedURLException getting image: " + e.getMessage()); image = ""; imageurl = null; imageName = null; } catch (IOException e) { LOG.warn("IOException getting image: " + e.getMessage()); image = ""; imageurl = null; imageName = null; } } else { image = ""; imageurl = null; imageName = null; } } Long phaseID = this.getSelectedPhase().getId(); model.addRow(new Object[] { projectHighlight.getId(), title, author, subject, publisher, yearReported, highlightsTypes, highlightsIsGlobal, startDate, endDate, keywords, countries, image, highlightDesc, introduction, results, partners, links, width, heigth, projectId, imageurl, imageName, phaseID }); } return model; } public String getSelectedFormat() { return selectedFormat; } @Override public void prepare() throws Exception { Map<String, Parameter> parameters = this.getParameters(); this.setGeneralParameters(); this.setSelectedFormat( (StringUtils.trim(parameters.get(APConstants.SUMMARY_FORMAT).getMultipleValues()[0]))); // Calculate time to generate report startTime = System.currentTimeMillis(); LOG.info("Start report download: " + this.getFileName() + ". User: " + this.getCurrentUser().getComposedCompleteName() + ". CRP: " + this.getLoggedCrp().getAcronym()); } public void setBytesPDF(byte[] bytesPDF) { this.bytesPDF = bytesPDF; } public void setBytesXLSX(byte[] bytesXLSX) { this.bytesXLSX = bytesXLSX; } public void setInputStream(InputStream inputStream) { this.inputStream = inputStream; } public void setSelectedFormat(String selectedFormat) { this.selectedFormat = selectedFormat; } }