1
18 package net.bull.javamelody.internal.web.pdf;
19
20 import java.io.IOException;
21 import java.io.OutputStream;
22 import java.util.HashMap;
23 import java.util.Locale;
24 import java.util.Map;
25
26 import com.lowagie.text.BadElementException;
27 import com.lowagie.text.ChapterAutoNumber;
28 import com.lowagie.text.Chunk;
29 import com.lowagie.text.Document;
30 import com.lowagie.text.DocumentException;
31 import com.lowagie.text.Element;
32 import com.lowagie.text.Font;
33 import com.lowagie.text.HeaderFooter;
34 import com.lowagie.text.Image;
35 import com.lowagie.text.PageSize;
36 import com.lowagie.text.Paragraph;
37 import com.lowagie.text.Phrase;
38 import com.lowagie.text.Rectangle;
39 import com.lowagie.text.pdf.BaseFont;
40 import com.lowagie.text.pdf.PdfContentByte;
41 import com.lowagie.text.pdf.PdfPageEventHelper;
42 import com.lowagie.text.pdf.PdfTemplate;
43 import com.lowagie.text.pdf.PdfWriter;
44
45 import net.bull.javamelody.internal.common.I18N;
46 import net.bull.javamelody.internal.common.Parameters;
47 import net.bull.javamelody.internal.model.Range;
48
49
53 class PdfDocumentFactory {
54 private final String application;
55 private final Range range;
56 private final OutputStream output;
57 private final Map<String, Image> paragraphImagesByResourceName = new HashMap<>();
58 private final Map<String, Image> smallImagesByResourceName = new HashMap<>();
59 private final Font paragraphTitleFont = PdfFonts.PARAGRAPH_TITLE.getFont();
60
61 private static class PdfAdvancedPageNumberEvents extends PdfPageEventHelper {
62
63 private PdfContentByte cb;
64
65
66 private PdfTemplate template;
67
68
69 private final BaseFont bf;
70
71 PdfAdvancedPageNumberEvents() throws DocumentException, IOException {
72 super();
73 bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
74 }
75
76
77
78 @Override
79 public void onGenericTag(PdfWriter writer, Document document, Rectangle rect, String text) {
80
81 }
82
83
84
85 @Override
86 public void onOpenDocument(PdfWriter writer, Document document) {
87 cb = writer.getDirectContent();
88 template = cb.createTemplate(50, 50);
89 }
90
91
92
93 @Override
94 public void onChapter(PdfWriter writer, Document document, float paragraphPosition,
95 Paragraph title) {
96
97 }
98
99
100
101 @Override
102 public void onEndPage(PdfWriter writer, Document document) {
103 final int pageN = writer.getPageNumber();
104 final String text = pageN + " / ";
105 final float len = bf.getWidthPoint(text, 8);
106 cb.beginText();
107 cb.setFontAndSize(bf, 8);
108 final float width = document.getPageSize().getWidth();
109 cb.setTextMatrix(width / 2, 30);
110 cb.showText(text);
111 cb.endText();
112 cb.addTemplate(template, width / 2 + len, 30);
113 }
114
115
116
117 @Override
118 public void onCloseDocument(PdfWriter writer, Document document) {
119 template.beginText();
120 template.setFontAndSize(bf, 8);
121 template.showText(String.valueOf(writer.getPageNumber() - 1));
122 template.endText();
123 }
124 }
125
126 PdfDocumentFactory(String application, Range range, OutputStream output) {
127 super();
128 assert application != null;
129 assert output != null;
130
131 this.application = application;
132 this.range = range;
133 this.output = output;
134 }
135
136 Document createDocument() throws DocumentException, IOException {
137 return createDocument(false);
138 }
139
140 Document createDocument(boolean landscape) throws DocumentException, IOException {
141
142 final Rectangle pageSize = getPageSize(landscape);
143
144
145
146 final Document document = new Document(pageSize, 20, 20, 20, 40);
147
148 final String title;
149 if (range == null) {
150 title = I18N.getFormattedString("Monitoring_sur", application);
151 } else {
152 title = I18N.getFormattedString("Monitoring_sur", application) + " - "
153 + range.getLabel();
154 }
155 createWriter(document, title);
156
157
158 document.addAuthor(application);
159 document.addCreator(
160 "JavaMelody par E. Vernat, https:);
161 document.addTitle(title);
162 return document;
163 }
164
165 private Rectangle getPageSize(boolean landscape) {
166 Rectangle pageSize;
167 if (Locale.US.getCountry().equals(I18N.getCurrentLocale().getCountry())) {
168
169 pageSize = PageSize.LETTER;
170 } else {
171 pageSize = PageSize.A4;
172 }
173 if (landscape) {
174 pageSize = pageSize.rotate();
175 }
176 return pageSize;
177 }
178
179
180 private void createWriter(Document document, String title)
181 throws DocumentException, IOException {
182 final PdfWriter writer = PdfWriter.getInstance(document, output);
183
184
185
186 final HeaderFooter header = new HeaderFooter(new Phrase(title), false);
187 header.setAlignment(Element.ALIGN_LEFT);
188 header.setBorder(Rectangle.NO_BORDER);
189 document.setHeader(header);
190
191
192
193
194
195
196
197
198 writer.setPageEvent(new PdfAdvancedPageNumberEvents());
199 }
200
201 Element createParagraphElement(String paragraphTitle, String iconName)
202 throws DocumentException, IOException {
203 final Paragraph paragraph = new Paragraph("", paragraphTitleFont);
204 paragraph.setSpacingBefore(5);
205 paragraph.setSpacingAfter(5);
206 if (iconName != null) {
207 paragraph.add(new Chunk(getParagraphImage(iconName), 0, -5));
208 }
209 final Phrase element = new Phrase(' ' + paragraphTitle, paragraphTitleFont);
210 element.setLeading(12);
211 paragraph.add(element);
212
213 final ChapterAutoNumber chapter = new ChapterAutoNumber(paragraph);
214
215 chapter.setNumberDepth(0);
216 chapter.setBookmarkOpen(false);
217 chapter.setTriggerNewPage(false);
218 return chapter;
219 }
220
221 private Image getParagraphImage(String resourceFileName) throws DocumentException, IOException {
222 Image image = paragraphImagesByResourceName.get(resourceFileName);
223 if (image == null) {
224 image = getImage(resourceFileName);
225 image.scaleAbsolute(16, 16);
226 paragraphImagesByResourceName.put(resourceFileName, image);
227 }
228 return image;
229 }
230
231 Image getSmallImage(String resourceFileName) throws DocumentException, IOException {
232 Image image = smallImagesByResourceName.get(resourceFileName);
233 if (image == null) {
234 image = getImage(resourceFileName);
235 image.scaleAbsolute(8, 8);
236 smallImagesByResourceName.put(resourceFileName, image);
237 }
238 return image;
239 }
240
241 static Image getImage(String resourceFileName) throws BadElementException, IOException {
242 return Image.getInstance(
243 PdfDocumentFactory.class.getResource(Parameters.getResourcePath(resourceFileName)));
244 }
245 }
246