1 /*
2  * Copyright 2008-2019 by Emeric Vernat
3  *
4  *     This file is part of Java Melody.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package net.bull.javamelody.internal.web.pdf;
19
20 import java.io.IOException;
21 import java.text.DateFormat;
22 import java.text.DecimalFormat;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28
29 import com.lowagie.text.BadElementException;
30 import com.lowagie.text.Chunk;
31 import com.lowagie.text.Document;
32 import com.lowagie.text.DocumentException;
33 import com.lowagie.text.Element;
34 import com.lowagie.text.Font;
35 import com.lowagie.text.Image;
36 import com.lowagie.text.Paragraph;
37 import com.lowagie.text.Phrase;
38 import com.lowagie.text.pdf.PdfPCell;
39
40 import net.bull.javamelody.internal.common.I18N;
41 import net.bull.javamelody.internal.common.Parameters;
42 import net.bull.javamelody.internal.model.SessionInformations;
43 import net.bull.javamelody.internal.web.html.HtmlSessionInformationsReport;
44
45 /**
46  * Rapport pdf pour les sessions http.
47  * @author Emeric Vernat
48  */

49 class PdfSessionInformationsReport extends PdfAbstractTableReport {
50     private final List<SessionInformations> sessionsInformations;
51     private final boolean displayUser;
52     private final DecimalFormat integerFormat = I18N.createIntegerFormat();
53     private final DateFormat durationFormat = I18N.createDurationFormat();
54     private final DateFormat expiryFormat = I18N.createDateAndTimeFormat();
55     private final Font cellFont = PdfFonts.TABLE_CELL.getFont();
56     private final Font severeCellFont = PdfFonts.SEVERE_CELL.getFont();
57     private final Map<String, Image> imagesByFileName = new HashMap<>();
58
59     PdfSessionInformationsReport(List<SessionInformations> sessionsInformations,
60             Document document) {
61         super(document);
62         assert sessionsInformations != null;
63         this.sessionsInformations = sessionsInformations;
64
65         this.displayUser = isDisplayUser();
66     }
67
68     private boolean isDisplayUser() {
69         for (final SessionInformations sessionInformations : sessionsInformations) {
70             if (sessionInformations.getRemoteUser() != null) {
71                 return true;
72             }
73         }
74         return false;
75     }
76
77     @Override
78     void toPdf() throws IOException, DocumentException {
79
80         if (sessionsInformations.isEmpty()) {
81             addToDocument(new Phrase(getString("Aucune_session"), cellFont));
82             return;
83         }
84
85         writeHeader();
86         writeSessions();
87
88         long totalSerializedSize = 0;
89         int nbSerializableSessions = 0;
90         for (final SessionInformations sessionInformations : sessionsInformations) {
91             final int size = sessionInformations.getSerializedSize();
92             if (size >= 0) {
93                 totalSerializedSize += size;
94                 nbSerializableSessions++;
95             }
96         }
97         final long meanSerializedSize;
98         if (nbSerializableSessions > 0) {
99             meanSerializedSize = totalSerializedSize / nbSerializableSessions;
100         } else {
101             meanSerializedSize = -1;
102         }
103         final Paragraph paragraph = new Paragraph("", cellFont);
104         paragraph.add(new Chunk(getFormattedString("nb_sessions", sessionsInformations.size())
105                 + "\n\n" + getFormattedString("taille_moyenne_sessions", meanSerializedSize)));
106         paragraph.setAlignment(Element.ALIGN_RIGHT);
107         addToDocument(paragraph);
108     }
109
110     private void writeHeader() throws DocumentException {
111         final List<String> headers = createHeaders();
112         final int[] relativeWidths = new int[headers.size()];
113         Arrays.fill(relativeWidths, 0, headers.size(), 1);
114         relativeWidths[0] = 3; // sessionId
115
116         initTable(headers, relativeWidths);
117     }
118
119     private List<String> createHeaders() {
120         final List<String> headers = new ArrayList<>();
121         headers.add(getString("Session_id"));
122         headers.add(getString("Dernier_acces"));
123         headers.add(getString("Age"));
124         headers.add(getString("Expiration"));
125         headers.add(getString("Nb_attributs"));
126         headers.add(getString("Serialisable"));
127         headers.add(getString("Taille_serialisee"));
128         headers.add(getString("Adresse_IP"));
129         headers.add(getString("Pays"));
130         headers.add(getString("Navigateur"));
131         headers.add(getString("OS"));
132         if (displayUser) {
133             headers.add(getString("Utilisateur"));
134         }
135         return headers;
136     }
137
138     private void writeSessions() throws IOException, DocumentException {
139         for (final SessionInformations session : sessionsInformations) {
140             nextRow();
141             writeSession(session);
142         }
143         addTableToDocument();
144     }
145
146     private void writeSession(SessionInformations session) throws IOException, BadElementException {
147         final PdfPCell defaultCell = getDefaultCell();
148         defaultCell.setHorizontalAlignment(Element.ALIGN_LEFT);
149         addCell(session.getId());
150         defaultCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
151         addCell(durationFormat.format(session.getLastAccess()));
152         addCell(durationFormat.format(session.getAge()));
153         addCell(expiryFormat.format(session.getExpirationDate()));
154         addCell(integerFormat.format(session.getAttributeCount()));
155         defaultCell.setHorizontalAlignment(Element.ALIGN_CENTER);
156         if (session.isSerializable()) {
157             addCell(getString("oui"));
158         } else {
159             final Phrase non = new Phrase(getString("non"), severeCellFont);
160             addCell(non);
161         }
162         defaultCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
163         addCell(integerFormat.format(session.getSerializedSize()));
164         defaultCell.setHorizontalAlignment(Element.ALIGN_LEFT);
165         final String remoteAddr = session.getRemoteAddr();
166         if (remoteAddr == null) {
167             addCell("");
168         } else {
169             addCell(remoteAddr);
170         }
171         defaultCell.setHorizontalAlignment(Element.ALIGN_CENTER);
172         writeCountry(session);
173         writeBrowserAndOs(session);
174         if (displayUser) {
175             defaultCell.setHorizontalAlignment(Element.ALIGN_LEFT);
176             final String remoteUser = session.getRemoteUser();
177             if (remoteUser == null) {
178                 addCell("");
179             } else {
180                 addCell(remoteUser);
181             }
182         }
183     }
184
185     private void writeCountry(SessionInformations session) throws IOException, BadElementException {
186         final String country = session.getCountry();
187         if (country == null) {
188             addCell("");
189         } else {
190             final String fileName = "flags/" + country + ".gif";
191             final Image image = getImageByFileName(fileName);
192             if (image == null) {
193                 addCell(country);
194             } else {
195                 addCell(new Phrase(new Chunk(image, 0, 0)));
196             }
197         }
198     }
199
200     private void writeBrowserAndOs(SessionInformations session)
201             throws IOException, BadElementException {
202         final String browser = session.getBrowser();
203         if (browser == null) {
204             addCell("");
205         } else {
206             final String browserIconName = HtmlSessionInformationsReport
207                     .getBrowserIconName(browser);
208             final String fileName = "browsers/" + browserIconName;
209             final Image image = getImageByFileName(fileName);
210             if (image == null) {
211                 addCell(browser);
212             } else {
213                 addCell(new Phrase(new Chunk(image, 0, 0)));
214             }
215         }
216
217         final String os = session.getOs();
218         if (os == null) {
219             addCell("");
220         } else {
221             final String osIconName = HtmlSessionInformationsReport.getOSIconName(os);
222             final String fileName = "servers/" + osIconName;
223             final Image image = getImageByFileName(fileName);
224             if (image == null) {
225                 addCell(os);
226             } else {
227                 addCell(new Phrase(new Chunk(image, 0, 0)));
228             }
229         }
230     }
231
232     private Image getImageByFileName(String fileName) throws BadElementException, IOException {
233         assert fileName != null;
234         Image image = imagesByFileName.get(fileName);
235         if (image == null) {
236             if (getClass().getResource(Parameters.getResourcePath(fileName)) == null) {
237                 return null;
238             }
239             image = PdfDocumentFactory.getImage(fileName);
240             image.scalePercent(40);
241             imagesByFileName.put(fileName, image);
242         }
243         return image;
244     }
245 }
246