[logback-dev] svn commit: r1781 - in logback/trunk: logback-access/src/main/java/ch/qos/logback/access/html logback-classic/src/main/java/ch/qos/logback/classic/html logback-classic/src/main/java/ch/qos/logback/classic/net logback-classic/src/test/java/ch/qos/logback/classic/html logback-classic/src/test/java/ch/qos/logback/classic/net logback-core/src/main/java/ch/qos/logback/core logback-core/src/main/java/ch/qos/logback/core/html logback-core/src/main/java/ch/qos/logback/core/net
noreply.ceki at qos.ch
noreply.ceki at qos.ch
Wed Aug 27 19:52:19 CEST 2008
Author: ceki
Date: Wed Aug 27 19:52:19 2008
New Revision: 1781
Added:
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/XHTMLEntityResolver.java
Modified:
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/html/DefaultCssBuilder.java
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/html/HTMLLayout.java
logback/trunk/logback-access/src/main/java/ch/qos/logback/access/html/UrlCssBuilder.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultCssBuilder.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultThrowableRenderer.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/UrlCssBuilder.java
logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java
logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/CoreGlobal.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/CssBuilder.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/IThrowableRenderer.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/NOPThrowableRenderer.java
logback/trunk/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
Log:
LBCORE-27 and LBCLASSIC-67
- Fixes both LBCORE-27 and LBCLASSIC-67.
- added test cases (using GreenMail) that verify that the output generated
by SMTPAppender and HTMLLayout conform to xhtml1-strict.dtd
- HTMLLayout* now use StringBuilder instead of StringBuffer. The former is significantly faster.
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/html/DefaultCssBuilder.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/html/DefaultCssBuilder.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/html/DefaultCssBuilder.java Wed Aug 27 19:52:19 2008
@@ -24,8 +24,8 @@
public DefaultCssBuilder() {
}
- public void addCss(StringBuffer sbuf) {
- sbuf.append("<STYLE type=\"text/css\">");
+ public void addCss(StringBuilder sbuf) {
+ sbuf.append("<style type=\"text/css\">");
sbuf.append("table{ ");
sbuf.append("margin-left: 2em; ");
sbuf.append("margin-right: 2em; ");
@@ -76,6 +76,6 @@
sbuf.append(LINE_SEP);
sbuf.append(" }");
sbuf.append("}");
- sbuf.append("</STYLE>");
+ sbuf.append("</style>");
}
}
\ No newline at end of file
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/html/HTMLLayout.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/html/HTMLLayout.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/html/HTMLLayout.java Wed Aug 27 19:52:19 2008
@@ -56,8 +56,8 @@
}
public String doLayout(AccessEvent event) {
- StringBuffer buf = new StringBuffer();
- handleTableClosing(buf);
+ StringBuilder buf = new StringBuilder();
+ startNewTableIfLimitReached(buf);
boolean odd = true;
if (((counter++) & 1) == 0) {
@@ -84,7 +84,7 @@
return buf.toString();
}
- private void appendEventToBuffer(StringBuffer buf, Converter<AccessEvent> c,
+ private void appendEventToBuffer(StringBuilder buf, Converter<AccessEvent> c,
AccessEvent event) {
buf.append("<td class=\"");
buf.append(computeConverterName(c));
Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/html/UrlCssBuilder.java
==============================================================================
--- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/html/UrlCssBuilder.java (original)
+++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/html/UrlCssBuilder.java Wed Aug 27 19:52:19 2008
@@ -34,8 +34,8 @@
this.url = url;
}
- public void addCss(StringBuffer sbuf) {
- sbuf.append("<LINK REL=StyleSheet HREF=\"");
+ public void addCss(StringBuilder sbuf) {
+ sbuf.append("<link REL=StyleSheet HREF=\"");
sbuf.append(url);
sbuf.append("\" TITLE=\"Basic\" />");
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultCssBuilder.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultCssBuilder.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultCssBuilder.java Wed Aug 27 19:52:19 2008
@@ -24,8 +24,8 @@
public DefaultCssBuilder() {
}
- public void addCss(StringBuffer sbuf) {
- sbuf.append("<STYLE type=\"text/css\">");
+ public void addCss(StringBuilder sbuf) {
+ sbuf.append("<style type=\"text/css\">");
sbuf.append(LINE_SEP);
sbuf
.append("table { margin-left: 2em; margin-right: 2em; border-left: 2px solid #AAA; }");
@@ -66,7 +66,7 @@
.append("TD.Exception { background: #A2AEE8; font-family: courier, monospace;}");
sbuf.append(LINE_SEP);
- sbuf.append("</STYLE>");
+ sbuf.append("</style>");
sbuf.append(LINE_SEP);
}
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultThrowableRenderer.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultThrowableRenderer.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/DefaultThrowableRenderer.java Wed Aug 27 19:52:19 2008
@@ -20,7 +20,7 @@
this.throwable = t;
}
- public void render(StringBuffer sbuf, String[] s) {
+ public void render(StringBuilder sbuf, String[] s) {
if (s != null) {
int len = s.length;
if (len == 0) {
@@ -38,7 +38,7 @@
}
}
- public void render(StringBuffer sbuf, Object eventObject) {
+ public void render(StringBuilder sbuf, Object eventObject) {
LoggingEvent event = (LoggingEvent)eventObject;
ThrowableInformation ti = event.getThrowableInformation();
if (ti != null) {
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/HTMLLayout.java Wed Aug 27 19:52:19 2008
@@ -55,8 +55,8 @@
}
public String doLayout(LoggingEvent event) {
- StringBuffer buf = new StringBuffer();
- handleTableClosing(buf);
+ StringBuilder buf = new StringBuilder();
+ startNewTableIfLimitReached(buf);
boolean odd = true;
if (((counter++) & 1) == 0) {
@@ -89,7 +89,7 @@
return buf.toString();
}
- private void appendEventToBuffer(StringBuffer buf, Converter<LoggingEvent> c,
+ private void appendEventToBuffer(StringBuilder buf, Converter<LoggingEvent> c,
LoggingEvent event) {
buf.append("<td class=\"");
buf.append(computeConverterName(c));
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/UrlCssBuilder.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/UrlCssBuilder.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/html/UrlCssBuilder.java Wed Aug 27 19:52:19 2008
@@ -34,8 +34,8 @@
this.url = url;
}
- public void addCss(StringBuffer sbuf) {
- sbuf.append("<LINK REL=StyleSheet HREF=\"");
+ public void addCss(StringBuilder sbuf) {
+ sbuf.append("<link REL=StyleSheet HREF=\"");
sbuf.append(url);
sbuf.append("\" TITLE=\"Basic\" />");
}
Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java
==============================================================================
--- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java (original)
+++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/net/SMTPAppender.java Wed Aug 27 19:52:19 2008
@@ -113,6 +113,10 @@
PatternLayout pl = new PatternLayout();
pl.setContext(getContext());
pl.setPattern(subjectStr);
+ // we don't want a ThrowableInformationConverter appended
+ // to the end of the converter chain
+ // This fixes issue LBCLASSIC-67
+ pl.setPostCompileProcessor(null);
pl.start();
return pl;
}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/HTMLLayoutTest.java Wed Aug 27 19:52:19 2008
@@ -1,35 +1,36 @@
package ch.qos.logback.classic.html;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
-
-import junit.framework.TestCase;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.spi.ThrowableInformation;
+import ch.qos.logback.core.CoreGlobal;
import ch.qos.logback.core.read.ListAppender;
-public class HTMLLayoutTest extends TestCase {
+public class HTMLLayoutTest {
LoggerContext lc;
Logger logger;
HTMLLayout layout;
- @Override
+ @Before
public void setUp() throws Exception {
- super.setUp();
lc = new LoggerContext();
lc.setName("default");
@@ -46,17 +47,17 @@
appender.start();
}
- @Override
+ @After
public void tearDown() throws Exception {
- super.tearDown();
lc = null;
layout = null;
}
@SuppressWarnings("unchecked")
- public void testHeader() {
+ @Test
+ public void testHeader() throws Exception {
String header = layout.getFileHeader();
- //System.out.println(header);
+ // System.out.println(header);
Document doc = parseOutput(header + "</body></html>");
Element rootElement = doc.getRootElement();
@@ -64,11 +65,12 @@
}
@SuppressWarnings("unchecked")
- public void testPresentationHeader() {
+ @Test
+ public void testPresentationHeader() throws Exception {
String header = layout.getFileHeader();
String presentationHeader = layout.getPresentationHeader();
header = header + presentationHeader;
- //System.out.println(header);
+ // System.out.println(header);
Document doc = parseOutput(header + "</table></body></html>");
Element rootElement = doc.getRootElement();
@@ -80,9 +82,10 @@
assertEquals("Thread", elementList.get(1).getText());
assertEquals("Message", elementList.get(2).getText());
}
-
+
+ @Test
public void testAppendThrowable() throws Exception {
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
String[] strArray = { "test1", "test2" };
DefaultThrowableRenderer renderer = (DefaultThrowableRenderer) layout
.getThrowableRenderer();
@@ -93,12 +96,32 @@
assertEquals(DefaultThrowableRenderer.TRACE_PREFIX + "test2", result[1]);
}
+ @Test
public void testDoLayout() throws Exception {
LoggingEvent le = createLoggingEvent();
- String result = layout.doLayout(le);
+
+ String result = layout.getFileHeader();
+ result += layout.getPresentationHeader();
+ result += layout.doLayout(le);
+ result += layout.getPresentationFooter();
+ result += layout.getFileFooter();
+
Document doc = parseOutput(result);
- Element trElement = doc.getRootElement();
- assertEquals(3, trElement.elements().size());
+ Element rootElement = doc.getRootElement();
+ rootElement.toString();
+
+ // the rest of this test is very dependent of the output generated
+ // by HTMLLayout. Given that the XML parser already verifies
+ // that the result conforms to xhtml-strict, we may want to
+ // skip the assertions below. However, the assertions below are another
+ // *independent* way to check the output format.
+
+ // head, body
+ assertEquals(2, rootElement.elements().size());
+ Element bodyElement = (Element) rootElement.elements().get(1);
+ Element tableElement = (Element) bodyElement.elements().get(3);
+ assertEquals("table", tableElement.getName());
+ Element trElement = (Element) tableElement.elements().get(1);
{
Element tdElement = (Element) trElement.elements().get(0);
assertEquals("DEBUG", tdElement.getText());
@@ -111,11 +134,11 @@
Element tdElement = (Element) trElement.elements().get(2);
assertEquals("test message", tdElement.getText());
}
- // System.out.println(result);
}
@SuppressWarnings("unchecked")
- public void testDoLayoutWithException() throws Exception {
+ @Test
+ public void layoutWithException() throws Exception {
layout.setPattern("%level %thread %msg %ex");
LoggingEvent le = createLoggingEvent();
le.setThrowableInformation(new ThrowableInformation(new Exception(
@@ -141,16 +164,23 @@
assertTrue(exceptionElement.getText().contains(
"java.lang.Exception: test Exception"));
}
-
- // public void testLog() {
- // for (int i = 1; i <= 10; i++) {
- // if (i == 5 || i == 8) {
- // logger.debug("test", new Exception("test exception"));
- // } else {
- // logger.debug("test message" + i);
- // }
- // }
- // }
+
+ @Test
+ public void rawLimit() throws Exception {
+ StringBuilder sb = new StringBuilder();
+ String header = layout.getFileHeader();
+ assertTrue(header.startsWith("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">"));
+ sb.append(header);
+ sb.append(layout.getPresentationHeader());
+ for(int i = 0; i < CoreGlobal.TABLE_ROW_LIMIT*3; i++) {
+ sb.append(layout.doLayout( new LoggingEvent(this.getClass().getName(), logger,
+ Level.DEBUG, "test message"+i, null, null)));
+ }
+ sb.append(layout.getPresentationFooter());
+ sb.append(layout.getFileFooter());
+ // check that the output adheres to xhtml-strict.dtd
+ parseOutput(sb.toString());
+ }
private LoggingEvent createLoggingEvent() {
LoggingEvent le = new LoggingEvent(this.getClass().getName(), logger,
@@ -158,65 +188,11 @@
return le;
}
- Document parseOutput(String output) {
-
+ Document parseOutput(String output) throws Exception {
EntityResolver resolver = new XHTMLEntityResolver();
-
SAXReader reader = new SAXReader();
+ reader.setValidation(true);
reader.setEntityResolver(resolver);
- Document doc = null;
-
- try {
- doc = reader.read(new ByteArrayInputStream(output.getBytes()));
- } catch (Exception e) {
- e.printStackTrace();
- }
- return doc;
-
- // try {
- //
- // Document document = DocumentHelper.parseText(output);
- // return document;
- // } catch (Exception e) {
- // System.err.println(e);
- // fail();
- // }
- // return null;
- }
-}
-
-class XHTMLEntityResolver implements EntityResolver {
-
-
- // key: public id, value: relative path to DTD file
- static Map<String, String> entityMap = new HashMap<String, String>();
-
- static {
- entityMap.put("-//W3C//DTD XHTML 1.0 Strict//EN",
- "/dtd/xhtml1-strict.dtd");
- entityMap.put("-//W3C//ENTITIES Latin 1 for XHTML//EN",
- "/dtd/xhtml-lat1.ent");
- entityMap.put("-//W3C//ENTITIES Symbols for XHTML//EN",
- "/dtd/xhtml-symbol.ent");
- entityMap.put("-//W3C//ENTITIES Special for XHTML//EN",
- "/dtd/xhtml-special.ent");
- }
-
- public InputSource resolveEntity(String publicId, String systemId) {
- //System.out.println(publicId);
- final String relativePath = (String)entityMap.get(publicId);
-
- if (relativePath != null) {
- Class clazz = getClass();
- InputStream in =
- clazz.getResourceAsStream(relativePath);
- if (in == null) {
- return null;
- } else {
- return new InputSource(in);
- }
- } else {
- return null;
- }
+ return reader.read(new ByteArrayInputStream(output.getBytes()));
}
}
Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/XHTMLEntityResolver.java
==============================================================================
--- (empty file)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/html/XHTMLEntityResolver.java Wed Aug 27 19:52:19 2008
@@ -0,0 +1,43 @@
+package ch.qos.logback.classic.html;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+
+public class XHTMLEntityResolver implements EntityResolver {
+
+ // key: public id, value: relative path to DTD file
+ static Map<String, String> entityMap = new HashMap<String, String>();
+
+ static {
+ entityMap.put("-//W3C//DTD XHTML 1.0 Strict//EN",
+ "/dtd/xhtml1-strict.dtd");
+ entityMap.put("-//W3C//ENTITIES Latin 1 for XHTML//EN",
+ "/dtd/xhtml-lat1.ent");
+ entityMap.put("-//W3C//ENTITIES Symbols for XHTML//EN",
+ "/dtd/xhtml-symbol.ent");
+ entityMap.put("-//W3C//ENTITIES Special for XHTML//EN",
+ "/dtd/xhtml-special.ent");
+ }
+
+ public InputSource resolveEntity(String publicId, String systemId) {
+ //System.out.println(publicId);
+ final String relativePath = (String)entityMap.get(publicId);
+
+ if (relativePath != null) {
+ Class clazz = getClass();
+ InputStream in =
+ clazz.getResourceAsStream(relativePath);
+ if (in == null) {
+ return null;
+ } else {
+ return new InputSource(in);
+ }
+ } else {
+ return null;
+ }
+ }
+}
Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java
==============================================================================
--- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java (original)
+++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/net/SMTPAppender_GreenTest.java Wed Aug 27 19:52:19 2008
@@ -1,22 +1,33 @@
package ch.qos.logback.classic.net;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import java.io.FileOutputStream;
import java.util.Random;
import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import org.dom4j.io.SAXReader;
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.PatternLayout;
+import ch.qos.logback.classic.html.HTMLLayout;
+import ch.qos.logback.classic.html.XHTMLEntityResolver;
import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.core.CoreGlobal;
import ch.qos.logback.core.Layout;
+import ch.qos.logback.core.html.HTMLLayoutBase;
import com.icegreen.greenmail.util.GreenMail;
+import com.icegreen.greenmail.util.GreenMailUtil;
import com.icegreen.greenmail.util.ServerSetup;
public class SMTPAppender_GreenTest {
@@ -27,8 +38,9 @@
LoggerContext lc = new LoggerContext();
static final String TEST_SUBJECT = "test subject";
-
-
+ static final String HEADER = "HEADER\n";
+ static final String FOOTER = "FOOTER\n";
+
@Before
public void setUp() throws Exception {
ServerSetup serverSetup = new ServerSetup(diff, "localhost",
@@ -43,21 +55,29 @@
smtpAppender.setContext(lc);
smtpAppender.setName("smtp");
smtpAppender.setFrom("user at host.dom");
-
- smtpAppender.setLayout(buildLayout(lc));
smtpAppender.setSMTPHost("localhost");
smtpAppender.setSMTPPort(diff);
smtpAppender.setSubject(TEST_SUBJECT);
smtpAppender.addTo("nospam at qos.ch");
-// smtpAppender.start();
+ // smtpAppender.start();
}
- private Layout<LoggingEvent> buildLayout(LoggerContext lc) {
+ private Layout<LoggingEvent> buildPatternLayout(LoggerContext lc) {
PatternLayout layout = new PatternLayout();
layout.setContext(lc);
- layout.setFileHeader("Some header\n");
+ layout.setFileHeader(HEADER);
layout.setPattern("%-4relative [%thread] %-5level %class - %msg%n");
- layout.setFileFooter("Some footer");
+ layout.setFileFooter(FOOTER);
+ layout.start();
+ return layout;
+ }
+
+ private Layout<LoggingEvent> buildHTMLLayout(LoggerContext lc) {
+ HTMLLayout layout = new HTMLLayout();
+ layout.setContext(lc);
+ // layout.setFileHeader(HEADER);
+ layout.setPattern("%level%class%msg");
+ // layout.setFileFooter(FOOTER);
layout.start();
return layout;
}
@@ -67,7 +87,8 @@
}
@Test
- public void smoke() throws Exception {
+ public void smoke() throws Exception {
+ smtpAppender.setLayout(buildPatternLayout(lc));
smtpAppender.start();
Logger logger = lc.getLogger("test");
logger.addAppender(smtpAppender);
@@ -77,10 +98,69 @@
assertNotNull(mma);
assertEquals(1, mma.length);
MimeMessage mm = mma[0];
-
+ // http://jira.qos.ch/browse/LBCLASSIC-67
assertEquals(TEST_SUBJECT, mm.getSubject());
- //System.out.println(mm.getContent().toString());
-
+
+ MimeMultipart mp = (MimeMultipart) mm.getContent();
+ String body = GreenMailUtil.getBody(mp.getBodyPart(0));
+ assertTrue(body.startsWith(HEADER.trim()));
+ assertTrue(body.endsWith(FOOTER.trim()));
+ }
+
+ @Test
+ public void html() throws Exception {
+ smtpAppender.setLayout(buildHTMLLayout(lc));
+ smtpAppender.start();
+ Logger logger = lc.getLogger("test");
+ logger.addAppender(smtpAppender);
+ logger.debug("hello");
+ logger.error("en error", new Exception("an exception"));
+ MimeMessage[] mma = greenMail.getReceivedMessages();
+ assertNotNull(mma);
+ assertEquals(1, mma.length);
+ MimeMessage mm = mma[0];
+ assertEquals(TEST_SUBJECT, mm.getSubject());
+
+ MimeMultipart mp = (MimeMultipart) mm.getContent();
+
+ // verify strict adherence to xhtml1-strict.dtd
+ SAXReader reader = new SAXReader();
+ reader.setValidation(true);
+ reader.setEntityResolver(new XHTMLEntityResolver());
+ reader.read(mp.getBodyPart(0).getInputStream());
+ // System.out.println(GreenMailUtil.getBody(mp.getBodyPart(0)));
+ }
+
+ @Test
+ /**
+ * Checks that even when many events are processed, the output is still
+ * conforms to xhtml-strict.dtd.
+ *
+ * Note that SMTPAppender only keeps only 500 or so (=buffer size)
+ * events. So the generated output will be rather short.
+ */
+ public void htmlLong() throws Exception {
+ smtpAppender.setLayout(buildHTMLLayout(lc));
+ smtpAppender.start();
+ Logger logger = lc.getLogger("test");
+ logger.addAppender(smtpAppender);
+ for (int i = 0; i < CoreGlobal.TABLE_ROW_LIMIT * 3; i++) {
+ logger.debug("hello " + i);
+ }
+ logger.error("en error", new Exception("an exception"));
+ MimeMessage[] mma = greenMail.getReceivedMessages();
+ assertNotNull(mma);
+ assertEquals(1, mma.length);
+ MimeMessage mm = mma[0];
+ assertEquals(TEST_SUBJECT, mm.getSubject());
+
+ MimeMultipart mp = (MimeMultipart) mm.getContent();
+
+ // verify strict adherence to xhtml1-strict.dtd
+ SAXReader reader = new SAXReader();
+ reader.setValidation(true);
+ reader.setEntityResolver(new XHTMLEntityResolver());
+ reader.read(mp.getBodyPart(0).getInputStream());
}
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/CoreGlobal.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/CoreGlobal.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/CoreGlobal.java Wed Aug 27 19:52:19 2008
@@ -57,4 +57,11 @@
public final static char PERCENT_CHAR = '%';
+
+ /**
+ * Number of rows before in an HTML table before,
+ * we close the table and create a new one
+ */
+ public static final int TABLE_ROW_LIMIT = 10000;
+
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/CssBuilder.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/CssBuilder.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/CssBuilder.java Wed Aug 27 19:52:19 2008
@@ -2,6 +2,6 @@
public interface CssBuilder {
- public void addCss(StringBuffer sbuf);
+ public void addCss(StringBuilder sbuf);
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/HTMLLayoutBase.java Wed Aug 27 19:52:19 2008
@@ -2,6 +2,7 @@
import java.util.Map;
+import ch.qos.logback.core.CoreGlobal;
import ch.qos.logback.core.LayoutBase;
import ch.qos.logback.core.pattern.Converter;
import ch.qos.logback.core.pattern.ConverterUtil;
@@ -22,7 +23,7 @@
protected String title = "Logback Log Messages";
- //It is the responsability of derived classes to set
+ //It is the responsibility of derived classes to set
//this variable in their constructor to a default value.
protected CssBuilder cssBuilder;
@@ -30,8 +31,6 @@
// counter keeping track of the rows output
protected long counter = 0;
- // max number of rows before we close the table and create a new one
- protected static final int ROW_LIMIT = 10000;
/**
* Set the <b>ConversionPattern </b> option. This is the string which controls
@@ -118,15 +117,15 @@
*/
@Override
public String getFileHeader() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"");
+ StringBuilder sbuf = new StringBuilder();
+ sbuf.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"");
sbuf.append(" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
sbuf.append(LINE_SEP);
sbuf.append("<html>");
sbuf.append(LINE_SEP);
- sbuf.append("<head>");
+ sbuf.append(" <head>");
sbuf.append(LINE_SEP);
- sbuf.append("<title>");
+ sbuf.append(" <title>");
sbuf.append(title);
sbuf.append("</title>");
sbuf.append(LINE_SEP);
@@ -138,7 +137,7 @@
// cssBuilder.addExternalCSS(sbuf);
// }
sbuf.append(LINE_SEP);
- sbuf.append("</head>");
+ sbuf.append(" </head>");
sbuf.append(LINE_SEP);
sbuf.append("<body>");
sbuf.append(LINE_SEP);
@@ -147,25 +146,24 @@
}
public String getPresentationHeader() {
- StringBuffer sbuf = new StringBuffer();
- sbuf.append("<hr size=\"1\" noshade=\"true\" width=\"50%\" align=\"left\" />");
+ StringBuilder sbuf = new StringBuilder();
+ sbuf.append("<hr/>");
sbuf.append(LINE_SEP);
- sbuf.append("Log session start time ");
+ sbuf.append("<p>Log session start time ");
sbuf.append(new java.util.Date());
- sbuf.append("<br />");
+ sbuf.append("</p><p></p>");
sbuf.append(LINE_SEP);
- sbuf.append("<br />");
sbuf.append(LINE_SEP);
sbuf.append("<table cellspacing=\"0\">");
sbuf.append(LINE_SEP);
- createTableHeader(sbuf);
+ buildHeaderRowForTable(sbuf);
return sbuf.toString();
}
- private void createTableHeader(StringBuffer sbuf) {
+ private void buildHeaderRowForTable(StringBuilder sbuf) {
Converter c = head;
String name;
sbuf.append("<tr class=\"header\">");
@@ -189,7 +187,7 @@
}
public String getPresentationFooter() {
- StringBuffer sbuf = new StringBuffer();
+ StringBuilder sbuf = new StringBuilder();
sbuf.append("</table>");
return sbuf.toString();
}
@@ -199,21 +197,21 @@
*/
@Override
public String getFileFooter() {
- StringBuffer sbuf = new StringBuffer();
+ StringBuilder sbuf = new StringBuilder();
sbuf.append(LINE_SEP);
sbuf.append("</body></html>");
return sbuf.toString();
}
- protected void handleTableClosing(StringBuffer sbuf) {
- if (this.counter >= ROW_LIMIT) {
+ protected void startNewTableIfLimitReached(StringBuilder sbuf) {
+ if (this.counter >= CoreGlobal.TABLE_ROW_LIMIT) {
counter = 0;
sbuf.append("</table>");
sbuf.append(LINE_SEP);
- sbuf.append("<br />");
+ sbuf.append("<p></p>");
sbuf.append("<table cellspacing=\"0\">");
sbuf.append(LINE_SEP);
- createTableHeader(sbuf);
+ buildHeaderRowForTable(sbuf);
}
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/IThrowableRenderer.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/IThrowableRenderer.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/IThrowableRenderer.java Wed Aug 27 19:52:19 2008
@@ -3,6 +3,6 @@
public interface IThrowableRenderer {
- public void render(StringBuffer sbuf, Object event);
+ public void render(StringBuilder sbuf, Object event);
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/NOPThrowableRenderer.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/NOPThrowableRenderer.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/html/NOPThrowableRenderer.java Wed Aug 27 19:52:19 2008
@@ -5,7 +5,7 @@
public class NOPThrowableRenderer implements IThrowableRenderer {
- public void render(StringBuffer sbuf, Object event) {
+ public void render(StringBuilder sbuf, Object event) {
return;
}
Modified: logback/trunk/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java
==============================================================================
--- logback/trunk/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java (original)
+++ logback/trunk/logback-core/src/main/java/ch/qos/logback/core/net/SMTPAppenderBase.java Wed Aug 27 19:52:19 2008
@@ -213,14 +213,15 @@
sbuf.append(presentationHeader);
}
fillBuffer(sbuf);
- String footer = layout.getFileFooter();
- if (footer != null) {
- sbuf.append(footer);
- }
String presentationFooter = layout.getPresentationFooter();
if (presentationFooter != null) {
sbuf.append(presentationFooter);
}
+ String footer = layout.getFileFooter();
+ if (footer != null) {
+ sbuf.append(footer);
+ }
+
if (subjectLayout != null) {
msg.setSubject(subjectLayout.doLayout(lastEventObject));
More information about the logback-dev
mailing list