1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package ca.uhn.hl7v2.testpanel.ui;
27
28 import java.awt.Color;
29 import java.awt.Component;
30 import java.awt.EventQueue;
31 import java.awt.Font;
32
33 import javax.swing.JScrollBar;
34 import javax.swing.JTable;
35
36 import org.apache.commons.lang.StringUtils;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 import ca.uhn.hl7v2.HL7Exception;
41 import ca.uhn.hl7v2.testpanel.model.ActivityBytesBase;
42 import ca.uhn.hl7v2.testpanel.model.ActivityInfo;
43 import ca.uhn.hl7v2.testpanel.model.ActivityInfoError;
44 import ca.uhn.hl7v2.testpanel.model.ActivityMessage;
45 import ca.uhn.hl7v2.testpanel.model.ActivityValidationOutcome;
46 import ca.uhn.hl7v2.testpanel.util.FormatUtil;
47 import ca.uhn.hl7v2.testpanel.xsd.Hl7V2EncodingTypeEnum;
48
49 public class ActivityDetailsCellRenderer extends ActivityCellRendererBase {
50
51 private static final Logger ourLog = LoggerFactory.getLogger(ActivityDetailsCellRenderer.class);
52
53 private Font myFixedWidthFont;
54 private Font myVarWidthFont;
55
56 private boolean myScrollToBottom;
57
58 public ActivityDetailsCellRenderer(ActivityTable theTablePanel) {
59 super(theTablePanel);
60
61 myFixedWidthFont = new Font("Lucida Console", Font.PLAIN, 12);
62 myVarWidthFont = new Font("Lucida", Font.PLAIN, 12);
63 }
64
65 @Override
66 public Component getTableCellRendererComponent(final JTable theTable, Object theValue, boolean theIsSelected, boolean theHasFocus, final int theRow, int theColumn) {
67 super.getTableCellRendererComponent(theTable, theValue, theIsSelected, theHasFocus, theRow, theColumn);
68
69 if (theValue instanceof ActivityInfo) {
70
71 renderInfo(theTable, theValue, theRow);
72
73 } else if (theValue instanceof ActivityMessage) {
74
75 renderMessage(theTable, theValue, theRow, theIsSelected);
76
77 } else if (theValue instanceof ActivityBytesBase) {
78
79 renderBytes(theTable, theValue, theRow);
80
81 } else if (theValue instanceof ActivityValidationOutcome) {
82
83 renderValidation(theTable, (ActivityValidationOutcome) theValue, theRow);
84
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 if (myScrollToBottom) {
116 EventQueue.invokeLater(new Runnable() {
117 public void run() {
118 JScrollBar vsb = getTablePanel().getScrollPane().getVerticalScrollBar();
119 int newValue = vsb.getMaximum();
120 int existingValue = vsb.getValue();
121 if (newValue != existingValue) {
122 vsb.setValue(newValue);
123 ourLog.debug("Setting scrollbar to bottom, from {} to {}", existingValue, newValue);
124 }
125
126 if (theRow == getTablePanel().getTableModel().getRowCount() - 1) {
127 myScrollToBottom = false;
128 }
129 }
130 });
131
132 }
133
134 return this;
135 }
136
137 private void renderValidation(JTable theTable, ActivityValidationOutcome theValue, int theRow) {
138 if (theValue.isValidated()) {
139
140 setText("No Errors");
141
142 } else {
143
144 StringBuilder b = new StringBuilder("<html>");
145
146 b.append("<font color=\"#800000\">");
147 b.append("<ul>");
148
149 for (HL7Exception next : theValue.getIssues()) {
150 b.append("<li>");
151 if (StringUtils.isNotBlank(next.getLocation().getSegmentName())) {
152 b.append("<b>");
153 b.append(next.getLocation().getSegmentName());
154 if (next.getLocation().getSegmentRepetition() > 1) {
155 b.append("(").append(next.getLocation().getSegmentRepetition()).append(")");
156 }
157 if (next.getLocation().getField() > 0) {
158 b.append("-");
159 b.append(next.getLocation().getField());
160 }
161 b.append("</b>: ");
162 }
163 b.append("<nobr>").append(next.getMessage()).append("</nobr>");
164 b.append("</li>");
165 }
166
167 b.append("</ul>");
168 b.append("</font>");
169 b.append("</html>");
170 setText(b.toString());
171
172 }
173
174 updatePreferredHeight(theTable, theRow);
175
176 }
177
178 private void renderBytes(final JTable theTable, Object theValue, final int theRow) {
179 ActivityBytesBase msg = (ActivityBytesBase) theValue;
180
181 StringBuilder b = new StringBuilder();
182 b.append("<html>");
183 b.append("<table>");
184
185 StringBuilder charsB = new StringBuilder();
186 StringBuilder bytesB = new StringBuilder();
187
188 byte[] bytes = msg.getBytes();
189 for (int i = 0; i < bytes.length; i++) {
190
191 if (i == 0) {
192 b.append("<tr>");
193 } else if (i % 20 == 0) {
194 b.append("<td><nobr>");
195 b.append(charsB.toString());
196 for (int j = charsB.toString().length(); j < 20; j++) {
197 b.append(" ");
198 }
199 b.append("</nobr></td><td><nobr>");
200 b.append(bytesB.toString());
201 b.append("</nobr></td></tr><tr>");
202 charsB.setLength(0);
203 bytesB.setLength(0);
204 }
205
206 byte nextByte = bytes[i];
207 if (nextByte < 32) {
208 charsB.append(" ");
209 } else if ((char)nextByte == '<') {
210 charsB.append("<");
211 } else {
212 charsB.append(new String(new byte[] { nextByte }));
213 }
214
215 String byteToString = Integer.toString(nextByte);
216 if (nextByte < 32) {
217 byteToString = "<font color=\"#FF0000\">" + byteToString + "</font>";
218 }
219
220 if (nextByte < 100) {
221 bytesB.append(" ");
222 }
223 bytesB.append(byteToString).append(" ");
224
225 }
226
227 b.append("<td><nobr>");
228 b.append(charsB.toString());
229 for (int j = charsB.toString().length(); j < 20; j++) {
230 b.append(" ");
231 }
232 b.append("</nobr></td><td><nobr>");
233 b.append(bytesB.toString());
234 b.append("</nobr></td></tr><tr>");
235 b.append("</tr>");
236 b.append("</table>");
237 b.append("</html>");
238
239 String rawMessage = b.toString();
240 setText(rawMessage);
241 setFont(myFixedWidthFont);
242 setForeground(Color.black);
243
244 updatePreferredHeight(theTable, theRow);
245
246 }
247
248 private void renderInfo(final JTable theTable, Object theValue, final int theRow) {
249 if (theValue instanceof ActivityInfoError) {
250 setForeground(Color.red);
251 } else {
252 setForeground(Color.black);
253 }
254
255 String message = ((ActivityInfo) theValue).getMessage();
256 setText(message);
257
258
259 setFont(myVarWidthFont);
260
261 if (theTable.getRowHeight(theRow) != theTable.getRowHeight()) {
262 EventQueue.invokeLater(new Runnable() {
263 public void run() {
264 theTable.setRowHeight(theRow, theTable.getRowHeight());
265 }
266 });
267 }
268 }
269
270 private void renderMessage(final JTable theTable, Object theValue, final int theRow, boolean theSelected) {
271 ActivityMessage msg = (ActivityMessage) theValue;
272
273 if (theSelected) {
274
275 String rawMessage;
276 if (msg.getEncoding() == Hl7V2EncodingTypeEnum.XML) {
277 StringBuilder b = new StringBuilder();
278 b.append("<html>");
279
280 String raw = msg.getRawMessage();
281 for (int c = 0; c < raw.length(); c++) {
282 char nextChar = raw.charAt(c);
283 boolean isSpecial = nextChar == msg.getEncodingCharacters().getComponentSeparator();
284 isSpecial |= nextChar == msg.getEncodingCharacters().getFieldSeparator();
285 isSpecial |= nextChar == msg.getEncodingCharacters().getEscapeCharacter();
286 isSpecial |= nextChar == msg.getEncodingCharacters().getRepetitionSeparator();
287 isSpecial |= nextChar == msg.getEncodingCharacters().getSubcomponentSeparator();
288
289 if (isSpecial) {
290 b.append("<font color=\"#48A0A0\">");
291 }
292
293 switch (nextChar) {
294 case '\r':
295 case '\n':
296 b.append("<br>");
297 break;
298 case ' ':
299 b.append(" ");
300 break;
301 case '&':
302 b.append("&");
303 break;
304 case '<':
305 b.append("<");
306 break;
307 case '>':
308 b.append(">");
309 break;
310 default:
311 b.append(nextChar);
312 }
313
314 if (isSpecial) {
315 b.append("</font>");
316 }
317
318 }
319
320 b.append("</html>");
321
322 rawMessage = b.toString();
323
324 } else {
325
326 rawMessage = FormatUtil.formatEr7(msg.getRawMessage(), false).replace("\r", "<br>");
327
328 }
329
330 setText(rawMessage);
331
332 } else {
333
334 setText("<html>" + msg.getRawMessage().replace("\r", "<br>") + "</html>");
335 }
336
337
338 setForeground(Color.black);
339 setFont(myFixedWidthFont);
340
341 updatePreferredHeight(theTable, theRow);
342
343 }
344
345 private void updatePreferredHeight(final JTable theTable, final int theRow) {
346 final int newHeight = (int) getPreferredSize().getHeight();
347 if (theTable.getRowHeight(theRow) != newHeight) {
348 EventQueue.invokeLater(new Runnable() {
349 public void run() {
350 theTable.setRowHeight(theRow, newHeight);
351
352 }
353 });
354 }
355 }
356
357 public void markScrollToBottom() {
358 myScrollToBottom = true;
359 }
360 }