/* * Copyright 2008-2014 by Emeric Vernat * * This file is part of Java Melody. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.bull.javamelody; import java.io.IOException; import java.text.DateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; import net.bull.javamelody.PdfJavaInformationsReport.Bar; import com.lowagie.text.Anchor; import com.lowagie.text.BadElementException; import com.lowagie.text.Chunk; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.Image; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.pdf.PdfPCell; /** * Partie du rapport pdf pour les jobs. * @author Emeric Vernat */ class PdfJobInformationsReport extends PdfAbstractTableReport { private static final long ONE_DAY_MILLIS = 24L * 60 * 60 * 1000; private final List<JobInformations> jobInformationsList; private final Counter jobCounter; private final DateFormat fireTimeFormat = I18N.createDateAndTimeFormat(); private final DateFormat durationFormat = I18N.createDurationFormat(); private final Font cellFont = PdfFonts.TABLE_CELL.getFont(); PdfJobInformationsReport(List<JobInformations> jobInformationsList, Counter rangeJobCounter, Document document) { super(document); assert jobInformationsList != null; assert rangeJobCounter != null; this.jobInformationsList = jobInformationsList; this.jobCounter = rangeJobCounter; } @Override void toPdf() throws DocumentException, IOException { writeHeader(); for (final JobInformations jobInformations : jobInformationsList) { nextRow(); writeJobInformations(jobInformations); } addTableToDocument(); addConfigurationReference(); } private void addConfigurationReference() throws DocumentException { final Anchor quartzAnchor = new Anchor("Configuration reference", PdfFonts.BLUE.getFont()); quartzAnchor.setName("Quartz configuration reference"); quartzAnchor.setReference("http://www.quartz-scheduler.org/docs/index.html"); quartzAnchor.setFont(PdfFonts.BLUE.getFont()); final Paragraph quartzParagraph = new Paragraph(); quartzParagraph.add(quartzAnchor); quartzParagraph.setAlignment(Element.ALIGN_RIGHT); addToDocument(quartzParagraph); } private void writeHeader() throws DocumentException { final List<String> headers = createHeaders(); final int[] relativeWidths = new int[headers.size()]; Arrays.fill(relativeWidths, 0, headers.size(), 2); relativeWidths[1] = 3; // nom relativeWidths[2] = 5; // nom de la classe relativeWidths[headers.size() - 1] = 1; // paused initTable(headers, relativeWidths); } private List<String> createHeaders() { final List<String> headers = new ArrayList<String>(); headers.add(getString("JobGroup")); headers.add(getString("JobName")); headers.add(getString("JobClassName")); headers.add(getString("JobMeanTime")); headers.add(getString("JobElapsedTime")); headers.add(getString("JobPreviousFireTime")); headers.add(getString("JobNextFireTime")); headers.add(getString("JobPeriodOrCronExpression")); headers.add(getString("JobPaused")); return headers; } private void writeJobInformations(JobInformations jobInformations) throws BadElementException, IOException { final PdfPCell defaultCell = getDefaultCell(); defaultCell.setHorizontalAlignment(Element.ALIGN_LEFT); addCell(jobInformations.getGroup()); addCell(jobInformations.getName()); addCell(jobInformations.getJobClassName()); defaultCell.setHorizontalAlignment(Element.ALIGN_RIGHT); final CounterRequest counterRequest = getCounterRequest(jobInformations); // counterRequest ne peut pas être null ici if (counterRequest.getMean() >= 0) { addCell(formatDuration(counterRequest.getMean())); } else { addCell(""); } // rq: on n'affiche pas ici le nb d'exécutions, le maximum, l'écart-type // ou le pourcentage d'erreurs, uniquement car cela ferait trop de colonnes dans la page writeJobTimes(jobInformations, counterRequest); defaultCell.setHorizontalAlignment(Element.ALIGN_CENTER); if (jobInformations.isPaused()) { addCell(getString("oui")); } else { addCell(getString("non")); } } private String formatDuration(int durationAsMillis) { // int to long sans cast pour findbugs final long duration = 1L * durationAsMillis; return durationFormat.format(new Date(duration)); } private void writeJobTimes(JobInformations jobInformations, CounterRequest counterRequest) throws BadElementException, IOException { final long elapsedTime = jobInformations.getElapsedTime(); if (elapsedTime >= 0) { final Phrase elapsedTimePhrase = new Phrase(durationFormat.format(elapsedTime), cellFont); final Image memoryImage = Image.getInstance( Bar.toBar(100d * elapsedTime / counterRequest.getMean()), null); memoryImage.scalePercent(47); elapsedTimePhrase.add("\n"); elapsedTimePhrase.add(new Chunk(memoryImage, 0, 0)); addCell(elapsedTimePhrase); } else { addCell(""); } if (jobInformations.getPreviousFireTime() != null) { addCell(fireTimeFormat.format(jobInformations.getPreviousFireTime())); } else { addCell(""); } if (jobInformations.getNextFireTime() != null) { addCell(fireTimeFormat.format(jobInformations.getNextFireTime())); } else { addCell(""); } // on n'affiche pas la période si >= 1 jour car ce formateur ne saurait pas l'afficher if (jobInformations.getRepeatInterval() > 0 && jobInformations.getRepeatInterval() < ONE_DAY_MILLIS) { addCell(durationFormat.format(new Date(jobInformations.getRepeatInterval()))); } else if (jobInformations.getCronExpression() != null) { addCell(jobInformations.getCronExpression()); } else { addCell(""); } } private CounterRequest getCounterRequest(JobInformations jobInformations) { final String jobFullName = jobInformations.getGroup() + '.' + jobInformations.getName(); // rq: la méthode getCounterRequestByName prend en compte l'éventuelle utilisation du paramètre // job-transform-pattern qui peut faire que jobFullName != counterRequest.getName() final CounterRequest result = jobCounter.getCounterRequestByName(jobFullName); // getCounterRequestByName ne peut pas retourner null actuellement assert result != null; return result; } }