1
18 package net.bull.javamelody.internal.web.pdf;
19
20 import java.io.IOException;
21 import java.text.DecimalFormat;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
25
26 import com.lowagie.text.Chunk;
27 import com.lowagie.text.Document;
28 import com.lowagie.text.DocumentException;
29 import com.lowagie.text.Element;
30 import com.lowagie.text.Font;
31 import com.lowagie.text.Image;
32 import com.lowagie.text.Paragraph;
33 import com.lowagie.text.Phrase;
34 import com.lowagie.text.pdf.PdfPCell;
35
36 import net.bull.javamelody.internal.common.I18N;
37 import net.bull.javamelody.internal.model.JavaInformations;
38 import net.bull.javamelody.internal.model.ThreadInformations;
39 import net.bull.javamelody.internal.web.html.HtmlThreadInformationsReport;
40
41
45 class PdfThreadInformationsReport extends PdfAbstractTableReport {
46 private final List<ThreadInformations> threadInformationsList;
47 private final DecimalFormat integerFormat = I18N.createIntegerFormat();
48 private final boolean stackTraceEnabled;
49 private final boolean cpuTimeEnabled;
50 private final Font cellFont = PdfFonts.TABLE_CELL.getFont();
51 private final PdfDocumentFactory pdfDocumentFactory;
52
53 PdfThreadInformationsReport(List<ThreadInformations> threadInformationsList,
54 boolean stackTraceEnabled, PdfDocumentFactory pdfDocumentFactory, Document document) {
55 super(document);
56 assert threadInformationsList != null;
57 assert pdfDocumentFactory != null;
58
59 this.threadInformationsList = threadInformationsList;
60 this.pdfDocumentFactory = pdfDocumentFactory;
61 this.stackTraceEnabled = stackTraceEnabled;
62 this.cpuTimeEnabled = !threadInformationsList.isEmpty()
63 && threadInformationsList.get(0).getCpuTimeMillis() != -1;
64 }
65
66 @Override
67 void toPdf() throws DocumentException, IOException {
68 writeHeader();
69
70 for (final ThreadInformations threadInformations : threadInformationsList) {
71 nextRow();
72 writeThreadInformations(threadInformations);
73 }
74 addTableToDocument();
75
76 final Paragraph tempsThreads = new Paragraph(getString("Temps_threads") + '\n', cellFont);
77 tempsThreads.setAlignment(Element.ALIGN_RIGHT);
78 addToDocument(tempsThreads);
79
80
81
82
83
84
85
86
87
88
89
90
91 }
92
93 void writeIntro(JavaInformations javaInformations) throws DocumentException {
94 final Font boldFont = PdfFonts.BOLD.getFont();
95 final Font normalFont = PdfFonts.NORMAL.getFont();
96 addToDocument(new Phrase(
97 getFormattedString("Threads_sur", javaInformations.getHost()) + ": ", boldFont));
98 addToDocument(new Phrase(getFormattedString("thread_count",
99 javaInformations.getThreadCount(), javaInformations.getPeakThreadCount(),
100 javaInformations.getTotalStartedThreadCount()), normalFont));
101 }
102
103 void writeDeadlocks() throws DocumentException {
104 final List<ThreadInformations> deadlockedThreads = new ArrayList<>();
105 for (final ThreadInformations thread : threadInformationsList) {
106 if (thread.isDeadlocked()) {
107 deadlockedThreads.add(thread);
108 }
109 }
110 if (!deadlockedThreads.isEmpty()) {
111 final StringBuilder sb = new StringBuilder();
112 sb.append('\n');
113 sb.append(getString("Threads_deadlocks"));
114 String separator = " ";
115 for (final ThreadInformations thread : deadlockedThreads) {
116 sb.append(separator);
117 sb.append(thread.getName());
118 separator = ", ";
119 }
120 sb.append('\n');
121 addToDocument(new Phrase(sb.toString(), PdfFonts.SEVERE_CELL.getFont()));
122 }
123 }
124
125 private void writeHeader() throws DocumentException {
126 final List<String> headers = createHeaders();
127 final int[] relativeWidths = new int[headers.size()];
128 Arrays.fill(relativeWidths, 0, headers.size(), 1);
129 relativeWidths[0] = 3;
130 relativeWidths[3] = 2;
131 if (stackTraceEnabled) {
132 relativeWidths[4] = 6;
133 }
134
135 initTable(headers, relativeWidths);
136 }
137
138 private List<String> createHeaders() {
139 final List<String> headers = new ArrayList<>();
140 headers.add(getString("Thread"));
141 headers.add(getString("Demon"));
142 headers.add(getString("Priorite"));
143 headers.add(getString("Etat"));
144 if (stackTraceEnabled) {
145 headers.add(getString("Methode_executee"));
146 }
147 if (cpuTimeEnabled) {
148 headers.add(getString("Temps_cpu"));
149 headers.add(getString("Temps_user"));
150 }
151 return headers;
152 }
153
154 private void writeThreadInformations(ThreadInformations threadInformations)
155 throws DocumentException, IOException {
156 final PdfPCell defaultCell = getDefaultCell();
157 defaultCell.setHorizontalAlignment(Element.ALIGN_LEFT);
158 addCell(threadInformations.getName());
159 defaultCell.setHorizontalAlignment(Element.ALIGN_CENTER);
160 if (threadInformations.isDaemon()) {
161 addCell(getString("oui"));
162 } else {
163 addCell(getString("non"));
164 }
165 defaultCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
166 addCell(integerFormat.format(threadInformations.getPriority()));
167 defaultCell.setHorizontalAlignment(Element.ALIGN_LEFT);
168 final PdfPCell cell = new PdfPCell();
169 final Paragraph paragraph = new Paragraph(
170 getDefaultCell().getLeading() + cellFont.getSize());
171 paragraph.add(new Chunk(
172 getImage(
173 "bullets/" + HtmlThreadInformationsReport.getStateIcon(threadInformations)),
174 0, -1));
175 paragraph.add(new Phrase(String.valueOf(threadInformations.getState()), cellFont));
176 cell.addElement(paragraph);
177 addCell(cell);
178 if (stackTraceEnabled) {
179 addCell(threadInformations.getExecutedMethod());
180 }
181 if (cpuTimeEnabled) {
182 defaultCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
183 addCell(integerFormat.format(threadInformations.getCpuTimeMillis()));
184 addCell(integerFormat.format(threadInformations.getUserTimeMillis()));
185 }
186 }
187
188 private Image getImage(String resourceFileName) throws DocumentException, IOException {
189 return pdfDocumentFactory.getSmallImage(resourceFileName);
190 }
191 }
192