Clover Coverage Report - Atlassian Mail
Coverage timestamp: Mon Sep 29 2008 21:26:36 CDT
70   210   71   8.75
48   183   1.01   4
8     8.88  
2    
 
 
  HtmlToTextConverter       Line # 16 6 2 100% 1.0
  HtmlToTextConverter.HTMLCallbackHandler       Line # 20 64 69 44.9% 0.44915253
 
  (6)
 
1    package com.atlassian.mail;
2   
3    import org.apache.log4j.Category;
4   
5    import javax.swing.text.html.HTML;
6    import javax.swing.text.html.HTMLEditorKit;
7    import javax.swing.text.html.parser.ParserDelegator;
8    import java.io.*;
9    import java.util.ArrayList;
10   
11    /**
12    * Helper class to convert arbitrary HTML documents into text. Conversion is very basic, intended
13    * to be used to strip markup from HTML-only emails for inclusion within JIRA issue reports or
14    * comments.
15    */
 
16    public class HtmlToTextConverter
17    {
18    private static final Category log = Category.getInstance(HtmlToTextConverter.class);
19   
 
20    private class HTMLCallbackHandler extends HTMLEditorKit.ParserCallback {
21   
22    Writer out;
23    boolean started = false;
24    boolean inBody = false;
25    boolean inList = false;
26    boolean firstTD = true;
27    int listCount = -1;
28    ArrayList links = new ArrayList();
29   
30    private static final String NEWLINE = "\n";
31    private static final String TAB = "\t";
32    private static final String STAR = "*";
33    private static final String SPACE = " ";
34    private static final String PERIOD = ".";
35    private static final String OPEN_BRACKET = "[";
36    private static final String CLOSE_BRACKET = "]";
37    private static final String DASH_LINE = "----------------------------------------------------------------------------------------";
38   
39    // Note: the "position" parameter for all the methods below denotes our
40    // character position in the source document. Thus, we ignore it a lot.
 
41  6 toggle public HTMLCallbackHandler(Writer writer) {
42  6 out = writer;
43    }
44   
 
45  23 toggle public void handleStartTag(HTML.Tag tag, javax.swing.text.MutableAttributeSet set, int position) {
46  23 try
47    {
48  23 if (inBody && started && tag.equals(HTML.Tag.P))
49    {
50  1 out.write(NEWLINE + NEWLINE);
51    }
52  22 else if (inBody && started && tag.equals(HTML.Tag.OL) || tag.equals(HTML.Tag.UL))
53    {
54  0 inList = true;
55  0 out.write(NEWLINE + NEWLINE);
56  0 if(tag.equals(HTML.Tag.OL))
57  0 listCount = 1;
58    }
59  22 else if (inBody && started && inList && tag.equals(HTML.Tag.LI))
60    {
61  0 out.write(NEWLINE);
62  0 if(listCount != -1)
63    {
64  0 out.write(listCount + PERIOD + SPACE);
65  0 listCount++;
66    }
67    else
68  0 out.write(STAR);
69    }
70  22 else if (inBody && started && tag.equals(HTML.Tag.TABLE))
71    {
72  0 out.write(NEWLINE);
73    }
74  22 else if (inBody && started && tag.equals(HTML.Tag.TR))
75    {
76  0 out.write(NEWLINE);
77  0 firstTD = true;
78    }
79  22 else if (inBody && started && tag.equals(HTML.Tag.TD) || tag.equals(HTML.Tag.TH))
80    {
81  0 if(!firstTD)
82    {
83  0 out.write(TAB);
84    }
85    else
86    {
87  0 firstTD = false;
88    }
89    }
90  22 else if (inBody && started && tag.equals(HTML.Tag.PRE))
91    {
92  0 out.write(NEWLINE);
93    }
94  22 else if (inBody && started && tag.equals(HTML.Tag.IMG))
95    {
96    // Check if the img has a src attribute
97  0 handleLink((String)set.getAttribute(HTML.Attribute.SRC));
98    }
99  22 else if (inBody && started && tag.equals(HTML.Tag.A))
100    {
101    // Check if the img has a src attribute
102  0 handleLink((String)set.getAttribute(HTML.Attribute.HREF));
103    }
104  22 else if (inBody && started && tag.equals(HTML.Tag.HR))
105    {
106  0 out.write(NEWLINE + DASH_LINE);
107    }
108  22 else if (inBody && started && tag.equals(HTML.Tag.H1) || tag.equals(HTML.Tag.H2) || tag.equals(HTML.Tag.H3) || tag.equals(HTML.Tag.H4) || tag.equals(HTML.Tag.H5) || tag.equals(HTML.Tag.H6))
109    {
110  0 out.write(NEWLINE);
111    }
112  22 else if (tag.equals(HTML.Tag.BODY))
113    {
114  6 inBody = true;
115    }
116    }
117    catch (IOException e)
118    {
119  0 log.warn("IO error converting HTML to text", e);
120    }
121   
122    }
123   
 
124  0 toggle private void handleLink(String src) throws IOException
125    {
126  0 if(src != null)
127    {
128  0 links.add(src);
129  0 out.write(OPEN_BRACKET + links.size() + CLOSE_BRACKET);
130    }
131    }
132   
 
133  23 toggle public void handleEndTag(HTML.Tag tag, int position) {
134  23 if (inBody && started && tag.equals(HTML.Tag.OL) || tag.equals(HTML.Tag.UL))
135    {
136  0 inList = false;
137  0 if(tag.equals(HTML.Tag.OL))
138  0 listCount = -1;
139    }
140  23 else if (tag.equals(HTML.Tag.BODY))
141    {
142  6 if(links.size() != 0)
143    {
144    // write out the links
145  0 try
146    {
147  0 out.write(NEWLINE + DASH_LINE + NEWLINE);
148  0 for (int i = 0; i < links.size(); i++)
149    {
150  0 String src = (String)links.get(i);
151  0 out.write(OPEN_BRACKET + (i + 1) + CLOSE_BRACKET + SPACE + src);
152  0 if((i + 1) < links.size())
153    {
154  0 out.write(NEWLINE);
155    }
156    }
157    }
158    catch (IOException e)
159    {
160  0 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
161    }
162    }
163  6 inBody = false;
164    }
165    }
166   
 
167  14 toggle public void handleText(char[] aChar, int position) {
168  14 try
169    {
170  14 if (inBody)
171    {
172  13 out.write(aChar);
173  13 started = true;
174    }
175    }
176    catch (IOException e)
177    {
178  0 log.warn("IO error converting HTML to text", e);
179    }
180    }
181   
 
182  6 toggle public void handleSimpleTag(HTML.Tag tag, javax.swing.text.MutableAttributeSet a, int pos) {
183  6 try
184    {
185  6 if (inBody && started && tag.equals(HTML.Tag.BR))
186  6 out.write(NEWLINE);
187    }
188    catch (IOException e)
189    {
190  0 log.warn("IO error converting HTML to text", e);
191    }
192   
193    }
194    }
195   
196   
 
197  6 toggle public String convert(String html) throws IOException
198    {
199  6 StringWriter out = new StringWriter();
200  6 convert(new StringReader(html), out);
201  6 out.close();
202  6 return out.toString();
203    }
204   
 
205  6 toggle private void convert(Reader reader, Writer writer) throws IOException
206    {
207  6 HTMLCallbackHandler handler = new HTMLCallbackHandler(writer);
208  6 new ParserDelegator().parse(reader, handler, true);
209    }
210    }