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

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@host.dom"); - - smtpAppender.setLayout(buildLayout(lc)); smtpAppender.setSMTPHost("localhost"); smtpAppender.setSMTPPort(diff); smtpAppender.setSubject(TEST_SUBJECT); smtpAppender.addTo("nospam@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));
participants (1)
-
noreply.ceki@qos.ch