logback-dev
Threads by month
- ----- 2025 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
March 2010
- 11 participants
- 188 discussions

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v0.9.18-65-g108c238
by git-noreply@pixie.qos.ch 05 Mar '10
by git-noreply@pixie.qos.ch 05 Mar '10
05 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 108c2384db2295b33f7b336818954c20765482f9 (commit)
from 8e1cd90c2d99ce58f0cf04c52018f0eb498f08d2 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=108c2384db2295b33f7b3368…
http://github.com/ceki/logback/commit/108c2384db2295b33f7b336818954c2076548…
commit 108c2384db2295b33f7b336818954c20765482f9
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Fri Mar 5 11:11:29 2010 +0100
added link to "What's New in dm Server 2.0" presentation
diff --git a/logback-site/src/site/pages/documentation.html b/logback-site/src/site/pages/documentation.html
index d02275e..9b589d2 100644
--- a/logback-site/src/site/pages/documentation.html
+++ b/logback-site/src/site/pages/documentation.html
@@ -90,6 +90,10 @@
up</a>.
</li>
+ <li><a
+ href="http://www.infoq.com/presentations/New-in-dm-Server-2.0">What's
+ New in dm Server 2.0?</a> by Ben Hale</li>
+
<li><a href="http://it-bubbles.wikidot.com/blog:3">Griffon And
org.slf4j (Logback)</a> by Michal Novak</li>
-----------------------------------------------------------------------
Summary of changes:
logback-site/src/site/pages/documentation.html | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v0.9.18-64-g8e1cd90
by git-noreply@pixie.qos.ch 05 Mar '10
by git-noreply@pixie.qos.ch 05 Mar '10
05 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 8e1cd90c2d99ce58f0cf04c52018f0eb498f08d2 (commit)
from 5be3366d172124a2e1b8245da15b20e87d32b180 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=8e1cd90c2d99ce58f0cf04c5…
http://github.com/ceki/logback/commit/8e1cd90c2d99ce58f0cf04c52018f0eb498f0…
commit 8e1cd90c2d99ce58f0cf04c52018f0eb498f08d2
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Fri Mar 5 10:00:20 2010 +0100
- minor refactoring
diff --git a/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java b/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java
index 88d6d34..c87daf9 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/sift/AppenderFactoryBase.java
@@ -27,11 +27,11 @@ public abstract class AppenderFactoryBase<E> {
protected AppenderFactoryBase(List<SaxEvent> eventList) {
this.eventList = new ArrayList<SaxEvent>(eventList);
- removeHoardElement();
+ removeSiftElement();
}
- void removeHoardElement() {
+ void removeSiftElement() {
eventList.remove(0);
eventList.remove(eventList.size() - 1);
}
-----------------------------------------------------------------------
Summary of changes:
.../qos/logback/core/sift/AppenderFactoryBase.java | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

[JIRA] Created: (LBCLASSIC-192) Document logging separation when both JNDIContextSelector and SiftingAppender are employed
by Ceki Gulcu (JIRA) 05 Mar '10
by Ceki Gulcu (JIRA) 05 Mar '10
05 Mar '10
Document logging separation when both JNDIContextSelector and SiftingAppender are employed
------------------------------------------------------------------------------------------
Key: LBCLASSIC-192
URL: http://jira.qos.ch/browse/LBCLASSIC-192
Project: logback-classic
Issue Type: Task
Reporter: Ceki Gulcu
Assignee: Logback dev list
http://qos.ch/pipermail/logback-user/2010-March/001435.html
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.qos.ch/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
1
0

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v0.9.18-63-g5be3366
by git-noreply@pixie.qos.ch 05 Mar '10
by git-noreply@pixie.qos.ch 05 Mar '10
05 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 5be3366d172124a2e1b8245da15b20e87d32b180 (commit)
from de8338dedace96fe8abb83a9a932a7abed31d0f3 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=5be3366d172124a2e1b8245d…
http://github.com/ceki/logback/commit/5be3366d172124a2e1b8245da15b20e87d32b…
commit 5be3366d172124a2e1b8245da15b20e87d32b180
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Fri Mar 5 08:50:58 2010 +0100
- minor changes
diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/EventObjectInputStream.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/EventObjectInputStream.java
index 0d9726f..5aa56f3 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/encoder/EventObjectInputStream.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/EventObjectInputStream.java
@@ -85,14 +85,14 @@ public class EventObjectInputStream<E> extends InputStream {
int readHeader() throws IOException {
byte[] headerBA = new byte[4 * BYTES_PER_INT];
- System.out.println("available="+ncis.available());
+ //System.out.println("available="+ncis.available());
int bytesRead = ncis.read(headerBA);
if(bytesRead == -1) {
return -1;
}
- System.out.println("**bytesRead="+bytesRead);
+ //System.out.println("**bytesRead="+bytesRead);
- System.out.println(ByteArrayUtil.toHexString(headerBA));
+ //System.out.println(ByteArrayUtil.toHexString(headerBA));
int offset = 0;
int startPebble = ByteArrayUtil.readInt(headerBA, offset);
@@ -118,7 +118,6 @@ public class EventObjectInputStream<E> extends InputStream {
try {
e = (E) ois.readObject();
buffer.add(e);
- System.out.println("Read in event: "+e);
} catch (ClassNotFoundException e1) {
// FIXME Auto-generated catch block
e1.printStackTrace();
diff --git a/logback-site/src/site/pages/css/prettify.css b/logback-site/src/site/pages/css/prettify.css
index 65cfc41..351152b 100644
--- a/logback-site/src/site/pages/css/prettify.css
+++ b/logback-site/src/site/pages/css/prettify.css
@@ -1,28 +1,27 @@
-.str{color:#080}
-.kwd{color:#008}
-.com{color:#800}
-.typ{color:#606}
-.lit{color:#066}
-.pun{color:#660}
-.pln{color:#000}
-.tag{color:#008}
-.atn{color:#606}
-.atv{color:#080}
-.dec{color:#606}
+/* Pretty printing styles. Used with prettify.js. */
-pre.prettyprint{
- padding:2px;
-}
-@media print{.str{color:#060}
+.str { color: #080; }
+.kwd { color: #008; }
+.com { color: #800; }
+.typ { color: #606; }
+.lit { color: #066; }
+.pun { color: #660; }
+.pln { color: #000; }
+.tag { color: #008; }
+.atn { color: #606; }
+.atv { color: #080; }
+.dec { color: #606; }
+pre.prettyprint { padding: 2px; border: 1px solid #888; }
-.kwd{
- color:#006;font-weight:bold}
- .com{color:#600;font-style:italic
+@media print {
+ .str { color: #060; }
+ .kwd { color: #006; font-weight: bold; }
+ .com { color: #600; font-style: italic; }
+ .typ { color: #404; font-weight: bold; }
+ .lit { color: #044; }
+ .pun { color: #440; }
+ .pln { color: #000; }
+ .tag { color: #006; font-weight: bold; }
+ .atn { color: #404; }
+ .atv { color: #060; }
}
-.typ{color:#404;font-weight:bold}
-.lit{color:#044}
-.pun{color:#440}
-.pln{color:#000}
-.tag{color:#006;font-weight:bold}
-.atn{color:#404}
-.atv{color:#060}}
\ No newline at end of file
diff --git a/logback-site/src/site/pages/js/prettify.js b/logback-site/src/site/pages/js/prettify.js
index 8fc4c93..09d6394 100644
--- a/logback-site/src/site/pages/js/prettify.js
+++ b/logback-site/src/site/pages/js/prettify.js
@@ -1,23 +1,1478 @@
-function H(){var x=navigator&&navigator.userAgent&&/\bMSIE 6\./.test(navigator.userAgent);H=function(){return x};return x}(function(){function x(b){b=b.split(/ /g);var a={};for(var c=b.length;--c>=0;){var d=b[c];if(d)a[d]=null}return a}var y="break continue do else for if return while ",U=y+"auto case char const default double enum extern float goto int long register short signed sizeof static struct switch typedef union unsigned void volatile ",D=U+"catch class delete false import new operator private protected public this throw true try ",
-I=D+"alignof align_union asm axiom bool concept concept_map const_cast constexpr decltype dynamic_cast explicit export friend inline late_check mutable namespace nullptr reinterpret_cast static_assert static_cast template typeid typename typeof using virtual wchar_t where ",J=D+"boolean byte extends final finally implements import instanceof null native package strictfp super synchronized throws transient ",V=J+"as base by checked decimal delegate descending event fixed foreach from group implicit in interface internal into is lock object out override orderby params readonly ref sbyte sealed stackalloc string select uint ulong unchecked unsafe ushort var ",
-K=D+"debugger eval export function get null set undefined var with Infinity NaN ",L="caller delete die do dump elsif eval exit foreach for goto if import last local my next no our print package redo require sub undef unless until use wantarray while BEGIN END ",M=y+"and as assert class def del elif except exec finally from global import in is lambda nonlocal not or pass print raise try with yield False True None ",N=y+"alias and begin case class def defined elsif end ensure false in module next nil not or redo rescue retry self super then true undef unless until when yield BEGIN END ",
-O=y+"case done elif esac eval fi function in local set then until ",W=I+V+K+L+M+N+O;function X(b){return b>="a"&&b<="z"||b>="A"&&b<="Z"}function u(b,a,c,d){b.unshift(c,d||0);try{a.splice.apply(a,b)}finally{b.splice(0,2)}}var Y=(function(){var b=["!","!=","!==","#","%","%=","&","&&","&&=","&=","(","*","*=","+=",",","-=","->","/","/=",":","::",";","<","<<","<<=","<=","=","==","===",">",">=",">>",">>=",">>>",">>>=","?","@","[","^","^=","^^","^^=","{","|","|=","||","||=","~","break","case","continue",
-"delete","do","else","finally","instanceof","return","throw","try","typeof"],a="(?:(?:(?:^|[^0-9.])\\.{1,3})|(?:(?:^|[^\\+])\\+)|(?:(?:^|[^\\-])-)";for(var c=0;c<b.length;++c){var d=b[c];a+=X(d.charAt(0))?"|\\b"+d:"|"+d.replace(/([^=<>:&])/g,"\\$1")}a+="|^)\\s*$";return new RegExp(a)})(),P=/&/g,Q=/</g,R=/>/g,Z=/\"/g;function $(b){return b.replace(P,"&").replace(Q,"<").replace(R,">").replace(Z,""")}function E(b){return b.replace(P,"&").replace(Q,"<").replace(R,">")}var aa=
-/</g,ba=/>/g,ca=/'/g,da=/"/g,ea=/&/g,fa=/ /g;function ga(b){var a=b.indexOf("&");if(a<0)return b;for(--a;(a=b.indexOf("&#",a+1))>=0;){var c=b.indexOf(";",a);if(c>=0){var d=b.substring(a+3,c),g=10;if(d&&d.charAt(0)==="x"){d=d.substring(1);g=16}var e=parseInt(d,g);if(!isNaN(e))b=b.substring(0,a)+String.fromCharCode(e)+b.substring(c+1)}}return b.replace(aa,"<").replace(ba,">").replace(ca,"'").replace(da,'"').replace(ea,"&").replace(fa," ")}function S(b){return"XMP"===b.tagName}
-function z(b,a){switch(b.nodeType){case 1:var c=b.tagName.toLowerCase();a.push("<",c);for(var d=0;d<b.attributes.length;++d){var g=b.attributes[d];if(!g.specified)continue;a.push(" ");z(g,a)}a.push(">");for(var e=b.firstChild;e;e=e.nextSibling)z(e,a);if(b.firstChild||!/^(?:br|link|img)$/.test(c))a.push("</",c,">");break;case 2:a.push(b.name.toLowerCase(),'="',$(b.value),'"');break;case 3:case 4:a.push(E(b.nodeValue));break}}var F=null;function ha(b){if(null===F){var a=document.createElement("PRE");
-a.appendChild(document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />'));F=!/</.test(a.innerHTML)}if(F){var c=b.innerHTML;if(S(b))c=E(c);return c}var d=[];for(var g=b.firstChild;g;g=g.nextSibling)z(g,d);return d.join("")}function ia(b){var a=0;return function(c){var d=null,g=0;for(var e=0,h=c.length;e<h;++e){var f=c.charAt(e);switch(f){case "\t":if(!d)d=[];d.push(c.substring(g,e));var i=b-a%b;a+=i;for(;i>=0;i-=" ".length)d.push(" ".substring(0,i));g=e+1;break;
-case "\n":a=0;break;default:++a}}if(!d)return c;d.push(c.substring(g));return d.join("")}}var ja=/(?:[^<]+|<!--[\s\S]*?--\>|<!\[CDATA\[([\s\S]*?)\]\]>|<\/?[a-zA-Z][^>]*>|<)/g,ka=/^<!--/,la=/^<\[CDATA\[/,ma=/^<br\b/i;function na(b){var a=b.match(ja),c=[],d=0,g=[];if(a)for(var e=0,h=a.length;e<h;++e){var f=a[e];if(f.length>1&&f.charAt(0)==="<"){if(ka.test(f))continue;if(la.test(f)){c.push(f.substring(9,f.length-3));d+=f.length-12}else if(ma.test(f)){c.push("\n");++d}else g.push(d,f)}else{var i=ga(f);
-c.push(i);d+=i.length}}return{source:c.join(""),tags:g}}function v(b,a){var c={};(function(){var g=b.concat(a);for(var e=g.length;--e>=0;){var h=g[e],f=h[3];if(f)for(var i=f.length;--i>=0;)c[f.charAt(i)]=h}})();var d=a.length;return function(g,e){e=e||0;var h=[e,"pln"],f="",i=0,j=g;while(j.length){var o,m=null,k,l=c[j.charAt(0)];if(l){k=j.match(l[1]);m=k[0];o=l[0]}else{for(var n=0;n<d;++n){l=a[n];var p=l[2];if(p&&!p.test(f))continue;k=j.match(l[1]);if(k){m=k[0];o=l[0];break}}if(!m){o="pln";m=j.substring(0,
-1)}}h.push(e+i,o);i+=m.length;j=j.substring(m.length);if(o!=="com"&&/\S/.test(m))f=m}return h}}var oa=v([],[["pln",/^[^<]+/,null],["dec",/^<!\w[^>]*(?:>|$)/,null],["com",/^<!--[\s\S]*?(?:--\>|$)/,null],["src",/^<\?[\s\S]*?(?:\?>|$)/,null],["src",/^<%[\s\S]*?(?:%>|$)/,null],["src",/^<(script|style|xmp)\b[^>]*>[\s\S]*?<\/\1\b[^>]*>/i,null],["tag",/^<\/?\w[^<>]*>/,null]]);function pa(b){var a=oa(b);for(var c=0;c<a.length;c+=2)if(a[c+1]==="src"){var d,g;d=a[c];g=c+2<a.length?a[c+2]:b.length;var e=b.substring(d,
-g),h=e.match(/^(<[^>]*>)([\s\S]*)(<\/[^>]*>)$/);if(h)a.splice(c,2,d,"tag",d+h[1].length,"src",d+h[1].length+(h[2]||"").length,"tag")}return a}var qa=v([["atv",/^\'[^\']*(?:\'|$)/,null,"'"],["atv",/^\"[^\"]*(?:\"|$)/,null,'"'],["pun",/^[<>\/=]+/,null,"<>/="]],[["tag",/^[\w:\-]+/,/^</],["atv",/^[\w\-]+/,/^=/],["atn",/^[\w:\-]+/,null],["pln",/^\s+/,null," \t\r\n"]]);function ra(b,a){for(var c=0;c<a.length;c+=2){var d=a[c+1];if(d==="tag"){var g,e;g=a[c];e=c+2<a.length?a[c+2]:b.length;var h=b.substring(g,
-e),f=qa(h,g);u(f,a,c,2);c+=f.length-2}}return a}function r(b){var a=[],c=[];if(b.tripleQuotedStrings)a.push(["str",/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""]);else if(b.multiLineStrings)a.push(["str",/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]);else a.push(["str",/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
-null,"\"'"]);c.push(["pln",/^(?:[^\'\"\`\/\#]+)/,null," \r\n"]);if(b.hashComments)a.push(["com",/^#[^\r\n]*/,null,"#"]);if(b.cStyleComments)c.push(["com",/^\/\/[^\r\n]*/,null]);if(b.regexLiterals)c.push(["str",/^\/(?:[^\\\*\/\[]|\\[\s\S]|\[(?:[^\]\\]|\\.)*(?:\]|$))+(?:\/|$)/,Y]);if(b.cStyleComments)c.push(["com",/^\/\*[\s\S]*?(?:\*\/|$)/,null]);var d=x(b.keywords);b=null;var g=v(a,c),e=v([],[["pln",/^\s+/,null," \r\n"],["pln",/^[a-z_$@][a-z_$@0-9]*/i,null],["lit",/^0x[a-f0-9]+[a-z]/i,null],["lit",
-/^(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?[a-z]*/i,null,"123456789"],["pun",/^[^\s\w\.$@]+/,null]]);function h(f,i){for(var j=0;j<i.length;j+=2){var o=i[j+1];if(o==="pln"){var m,k,l,n;m=i[j];k=j+2<i.length?i[j+2]:f.length;l=f.substring(m,k);n=e(l,m);for(var p=0,t=n.length;p<t;p+=2){var w=n[p+1];if(w==="pln"){var A=n[p],B=p+2<t?n[p+2]:l.length,s=f.substring(A,B);if(s===".")n[p+1]="pun";else if(s in d)n[p+1]="kwd";else if(/^(a)?[A-Z][A-Z$]*[a-z][A-Za-z$]*$/.test(s))n[p+1]=s.charAt(0)==="@"?"lit":
-"typ"}}u(n,i,j,2);j+=n.length-2}}return i}return function(f){var i=g(f);i=h(f,i);return i}}var G=r({keywords:W,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function sa(b,a){for(var c=0;c<a.length;c+=2){var d=a[c+1];if(d==="src"){var g,e;g=a[c];e=c+2<a.length?a[c+2]:b.length;var h=G(b.substring(g,e));for(var f=0,i=h.length;f<i;f+=2)h[f]+=g;u(h,a,c,2);c+=h.length-2}}return a}function ta(b,a){var c=false;for(var d=0;d<a.length;d+=2){var g=a[d+1],e,h;if(g==="atn"){e=
-a[d];h=d+2<a.length?a[d+2]:b.length;c=/^on|^style$/i.test(b.substring(e,h))}else if(g==="atv"){if(c){e=a[d];h=d+2<a.length?a[d+2]:b.length;var f=b.substring(e,h),i=f.length,j=i>=2&&/^[\"\']/.test(f)&&f.charAt(0)===f.charAt(i-1),o,m,k;if(j){m=e+1;k=h-1;o=f}else{m=e+1;k=h-1;o=f.substring(1,f.length-1)}var l=G(o);for(var n=0,p=l.length;n<p;n+=2)l[n]+=m;if(j){l.push(k,"atv");u(l,a,d+2,0)}else u(l,a,d,2)}c=false}}return a}function ua(b){var a=pa(b);a=ra(b,a);a=sa(b,a);a=ta(b,a);return a}function va(b,
-a,c){var d=[],g=0,e=null,h=null,f=0,i=0,j=ia(8);function o(k){if(k>g){if(e&&e!==h){d.push("</span>");e=null}if(!e&&h){e=h;d.push('<span class="',e,'">')}var l=E(j(b.substring(g,k))).replace(/(\r\n?|\n| ) /g,"$1 ").replace(/\r\n?|\n/g,"<br />");d.push(l);g=k}}while(true){var m;m=f<a.length?(i<c.length?a[f]<=c[i]:true):false;if(m){o(a[f]);if(e){d.push("</span>");e=null}d.push(a[f+1]);f+=2}else if(i<c.length){o(c[i]);h=c[i+1];i+=2}else break}o(b.length);if(e)d.push("</span>");return d.join("")}
-var C={};function q(b,a){for(var c=a.length;--c>=0;){var d=a[c];if(!C.hasOwnProperty(d))C[d]=b;else if("console"in window)console.log("cannot override language handler %s",d)}}q(G,["default-code"]);q(ua,["default-markup","html","htm","xhtml","xml","xsl"]);q(r({keywords:I,hashComments:true,cStyleComments:true}),["c","cc","cpp","cs","cxx","cyc"]);q(r({keywords:J,cStyleComments:true}),["java"]);q(r({keywords:O,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);q(r({keywords:M,hashComments:true,
-multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);q(r({keywords:L,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);q(r({keywords:N,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);q(r({keywords:K,cStyleComments:true,regexLiterals:true}),["js"]);function T(b,a){try{var c=na(b),d=c.source,g=c.tags;if(!C.hasOwnProperty(a))a=/^\s*</.test(d)?"default-markup":"default-code";var e=C[a].call({},d);return va(d,g,e)}catch(h){if("console"in window){console.log(h);
-console.trace()}return b}}function wa(b){var a=H(),c=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],d=[];for(var g=0;g<c.length;++g)for(var e=0;e<c[g].length;++e)d.push(c[g][e]);c=null;var h=0;function f(){var i=(new Date).getTime()+250;for(;h<d.length&&(new Date).getTime()<i;h++){var j=d[h];if(j.className&&j.className.indexOf("prettyprint")>=0){var o=j.className.match(/\blang-(\w+)\b/);if(o)o=o[1];var m=false;for(var k=j.parentNode;k;k=
-k.parentNode)if((k.tagName==="pre"||k.tagName==="code"||k.tagName==="xmp")&&k.className&&k.className.indexOf("prettyprint")>=0){m=true;break}if(!m){var l=ha(j);l=l.replace(/(?:\r\n?|\n)$/,"");var n=T(l,o);if(!S(j))j.innerHTML=n;else{var p=document.createElement("PRE");for(var t=0;t<j.attributes.length;++t){var w=j.attributes[t];if(w.specified)p.setAttribute(w.name,w.value)}p.innerHTML=n;j.parentNode.replaceChild(p,j);p=j}if(a&&j.tagName==="PRE"){var A=j.getElementsByTagName("br");for(var B=A.length;--B>=
-0;){var s=A[B];s.parentNode.replaceChild(document.createTextNode("\r\n"),s)}}}}}if(h<d.length)setTimeout(f,250);else if(b)b()}f()}window.PR_normalizedHtml=z;window.prettyPrintOne=T;window.prettyPrint=wa;window.PR={createSimpleLexer:v,registerLangHandler:q,sourceDecorator:r,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
+// Copyright (C) 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+/**
+ * @fileoverview
+ * some functions for browser-side pretty printing of code contained in html.
+ * <p>
+ *
+ * For a fairly comprehensive set of languages see the
+ * <a href="http://google-code-prettify.googlecode.com/svn/trunk/README.html#langs">README</a>
+ * file that came with this source. At a minimum, the lexer should work on a
+ * number of languages including C and friends, Java, Python, Bash, SQL, HTML,
+ * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk
+ * and a subset of Perl, but, because of commenting conventions, doesn't work on
+ * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.
+ * <p>
+ * Usage: <ol>
+ * <li> include this source file in an html page via
+ * {@code <script type="text/javascript" src="/path/to/prettify.js"></script>}
+ * <li> define style rules. See the example page for examples.
+ * <li> mark the {@code <pre>} and {@code <code>} tags in your source with
+ * {@code class=prettyprint.}
+ * You can also use the (html deprecated) {@code <xmp>} tag, but the pretty
+ * printer needs to do more substantial DOM manipulations to support that, so
+ * some css styles may not be preserved.
+ * </ol>
+ * That's it. I wanted to keep the API as simple as possible, so there's no
+ * need to specify which language the code is in, but if you wish, you can add
+ * another class to the {@code <pre>} or {@code <code>} element to specify the
+ * language, as in {@code <pre class="prettyprint lang-java">}. Any class that
+ * starts with "lang-" followed by a file extension, specifies the file type.
+ * See the "lang-*.js" files in this directory for code that implements
+ * per-language file handlers.
+ * <p>
+ * Change log:<br>
+ * cbeust, 2006/08/22
+ * <blockquote>
+ * Java annotations (start with "@") are now captured as literals ("lit")
+ * </blockquote>
+ * @requires console
+ * @overrides window
+ */
+
+// JSLint declarations
+/*global console, document, navigator, setTimeout, window */
+
+/**
+ * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
+ * UI events.
+ * If set to {@code false}, {@code prettyPrint()} is synchronous.
+ */
+window['PR_SHOULD_USE_CONTINUATION'] = true;
+
+/** the number of characters between tab columns */
+window['PR_TAB_WIDTH'] = 8;
+
+/** Walks the DOM returning a properly escaped version of innerHTML.
+ * @param {Node} node
+ * @param {Array.<string>} out output buffer that receives chunks of HTML.
+ */
+window['PR_normalizedHtml']
+
+/** Contains functions for creating and registering new language handlers.
+ * @type {Object}
+ */
+ = window['PR']
+
+/** Pretty print a chunk of code.
+ *
+ * @param {string} sourceCodeHtml code as html
+ * @return {string} code as html, but prettier
+ */
+ = window['prettyPrintOne']
+/** Find all the {@code <pre>} and {@code <code>} tags in the DOM with
+ * {@code class=prettyprint} and prettify them.
+ * @param {Function?} opt_whenDone if specified, called when the last entry
+ * has been finished.
+ */
+ = window['prettyPrint'] = void 0;
+
+/** browser detection. @extern @returns false if not IE, otherwise the major version. */
+window['_pr_isIE6'] = function () {
+ var ieVersion = navigator && navigator.userAgent &&
+ navigator.userAgent.match(/\bMSIE ([678])\./);
+ ieVersion = ieVersion ? +ieVersion[1] : false;
+ window['_pr_isIE6'] = function () { return ieVersion; };
+ return ieVersion;
+};
+
+
+(function () {
+ // Keyword lists for various languages.
+ var FLOW_CONTROL_KEYWORDS =
+ "break continue do else for if return while ";
+ var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " +
+ "double enum extern float goto int long register short signed sizeof " +
+ "static struct switch typedef union unsigned void volatile ";
+ var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " +
+ "new operator private protected public this throw true try typeof ";
+ var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " +
+ "concept concept_map const_cast constexpr decltype " +
+ "dynamic_cast explicit export friend inline late_check " +
+ "mutable namespace nullptr reinterpret_cast static_assert static_cast " +
+ "template typeid typename using virtual wchar_t where ";
+ var JAVA_KEYWORDS = COMMON_KEYWORDS +
+ "abstract boolean byte extends final finally implements import " +
+ "instanceof null native package strictfp super synchronized throws " +
+ "transient ";
+ var CSHARP_KEYWORDS = JAVA_KEYWORDS +
+ "as base by checked decimal delegate descending event " +
+ "fixed foreach from group implicit in interface internal into is lock " +
+ "object out override orderby params partial readonly ref sbyte sealed " +
+ "stackalloc string select uint ulong unchecked unsafe ushort var ";
+ var JSCRIPT_KEYWORDS = COMMON_KEYWORDS +
+ "debugger eval export function get null set undefined var with " +
+ "Infinity NaN ";
+ var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " +
+ "goto if import last local my next no our print package redo require " +
+ "sub undef unless until use wantarray while BEGIN END ";
+ var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " +
+ "elif except exec finally from global import in is lambda " +
+ "nonlocal not or pass print raise try with yield " +
+ "False True None ";
+ var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" +
+ " defined elsif end ensure false in module next nil not or redo rescue " +
+ "retry self super then true undef unless until when yield BEGIN END ";
+ var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " +
+ "function in local set then until ";
+ var ALL_KEYWORDS = (
+ CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS +
+ PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS);
+
+ // token style names. correspond to css classes
+ /** token style for a string literal */
+ var PR_STRING = 'str';
+ /** token style for a keyword */
+ var PR_KEYWORD = 'kwd';
+ /** token style for a comment */
+ var PR_COMMENT = 'com';
+ /** token style for a type */
+ var PR_TYPE = 'typ';
+ /** token style for a literal value. e.g. 1, null, true. */
+ var PR_LITERAL = 'lit';
+ /** token style for a punctuation string. */
+ var PR_PUNCTUATION = 'pun';
+ /** token style for a punctuation string. */
+ var PR_PLAIN = 'pln';
+
+ /** token style for an sgml tag. */
+ var PR_TAG = 'tag';
+ /** token style for a markup declaration such as a DOCTYPE. */
+ var PR_DECLARATION = 'dec';
+ /** token style for embedded source. */
+ var PR_SOURCE = 'src';
+ /** token style for an sgml attribute name. */
+ var PR_ATTRIB_NAME = 'atn';
+ /** token style for an sgml attribute value. */
+ var PR_ATTRIB_VALUE = 'atv';
+
+ /**
+ * A class that indicates a section of markup that is not code, e.g. to allow
+ * embedding of line numbers within code listings.
+ */
+ var PR_NOCODE = 'nocode';
+
+ /** A set of tokens that can precede a regular expression literal in
+ * javascript.
+ * http://www.mozilla.org/js/language/js20/rationale/syntax.html has the full
+ * list, but I've removed ones that might be problematic when seen in
+ * languages that don't support regular expression literals.
+ *
+ * <p>Specifically, I've removed any keywords that can't precede a regexp
+ * literal in a syntactically legal javascript program, and I've removed the
+ * "in" keyword since it's not a keyword in many languages, and might be used
+ * as a count of inches.
+ *
+ * <p>The link a above does not accurately describe EcmaScript rules since
+ * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
+ * very well in practice.
+ *
+ * @private
+ */
+ var REGEXP_PRECEDER_PATTERN = function () {
+ var preceders = [
+ "!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=",
+ "&=", "(", "*", "*=", /* "+", */ "+=", ",", /* "-", */ "-=",
+ "->", /*".", "..", "...", handled below */ "/", "/=", ":", "::", ";",
+ "<", "<<", "<<=", "<=", "=", "==", "===", ">",
+ ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[",
+ "^", "^=", "^^", "^^=", "{", "|", "|=", "||",
+ "||=", "~" /* handles =~ and !~ */,
+ "break", "case", "continue", "delete",
+ "do", "else", "finally", "instanceof",
+ "return", "throw", "try", "typeof"
+ ];
+ var pattern = '(?:^^|[+-]';
+ for (var i = 0; i < preceders.length; ++i) {
+ pattern += '|' + preceders[i].replace(/([^=<>:&a-z])/g, '\\$1');
+ }
+ pattern += ')\\s*'; // matches at end, and matches empty string
+ return pattern;
+ // CAVEAT: this does not properly handle the case where a regular
+ // expression immediately follows another since a regular expression may
+ // have flags for case-sensitivity and the like. Having regexp tokens
+ // adjacent is not valid in any language I'm aware of, so I'm punting.
+ // TODO: maybe style special characters inside a regexp as punctuation.
+ }();
+
+ // Define regexps here so that the interpreter doesn't have to create an
+ // object each time the function containing them is called.
+ // The language spec requires a new object created even if you don't access
+ // the $1 members.
+ var pr_amp = /&/g;
+ var pr_lt = /</g;
+ var pr_gt = />/g;
+ var pr_quot = /\"/g;
+ /** like textToHtml but escapes double quotes to be attribute safe. */
+ function attribToHtml(str) {
+ return str.replace(pr_amp, '&')
+ .replace(pr_lt, '<')
+ .replace(pr_gt, '>')
+ .replace(pr_quot, '"');
+ }
+
+ /** escapest html special characters to html. */
+ function textToHtml(str) {
+ return str.replace(pr_amp, '&')
+ .replace(pr_lt, '<')
+ .replace(pr_gt, '>');
+ }
+
+
+ var pr_ltEnt = /</g;
+ var pr_gtEnt = />/g;
+ var pr_aposEnt = /'/g;
+ var pr_quotEnt = /"/g;
+ var pr_ampEnt = /&/g;
+ var pr_nbspEnt = / /g;
+ /** unescapes html to plain text. */
+ function htmlToText(html) {
+ var pos = html.indexOf('&');
+ if (pos < 0) { return html; }
+ // Handle numeric entities specially. We can't use functional substitution
+ // since that doesn't work in older versions of Safari.
+ // These should be rare since most browsers convert them to normal chars.
+ for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0;) {
+ var end = html.indexOf(';', pos);
+ if (end >= 0) {
+ var num = html.substring(pos + 3, end);
+ var radix = 10;
+ if (num && num.charAt(0) === 'x') {
+ num = num.substring(1);
+ radix = 16;
+ }
+ var codePoint = parseInt(num, radix);
+ if (!isNaN(codePoint)) {
+ html = (html.substring(0, pos) + String.fromCharCode(codePoint) +
+ html.substring(end + 1));
+ }
+ }
+ }
+
+ return html.replace(pr_ltEnt, '<')
+ .replace(pr_gtEnt, '>')
+ .replace(pr_aposEnt, "'")
+ .replace(pr_quotEnt, '"')
+ .replace(pr_nbspEnt, ' ')
+ .replace(pr_ampEnt, '&');
+ }
+
+ /** is the given node's innerHTML normally unescaped? */
+ function isRawContent(node) {
+ return 'XMP' === node.tagName;
+ }
+
+ var newlineRe = /[\r\n]/g;
+ /**
+ * Are newlines and adjacent spaces significant in the given node's innerHTML?
+ */
+ function isPreformatted(node, content) {
+ // PRE means preformatted, and is a very common case, so don't create
+ // unnecessary computed style objects.
+ if ('PRE' === node.tagName) { return true; }
+ if (!newlineRe.test(content)) { return true; } // Don't care
+ var whitespace = '';
+ // For disconnected nodes, IE has no currentStyle.
+ if (node.currentStyle) {
+ whitespace = node.currentStyle.whiteSpace;
+ } else if (window.getComputedStyle) {
+ // Firefox makes a best guess if node is disconnected whereas Safari
+ // returns the empty string.
+ whitespace = window.getComputedStyle(node, null).whiteSpace;
+ }
+ return !whitespace || whitespace === 'pre';
+ }
+
+ function normalizedHtml(node, out) {
+ switch (node.nodeType) {
+ case 1: // an element
+ var name = node.tagName.toLowerCase();
+ out.push('<', name);
+ for (var i = 0; i < node.attributes.length; ++i) {
+ var attr = node.attributes[i];
+ if (!attr.specified) { continue; }
+ out.push(' ');
+ normalizedHtml(attr, out);
+ }
+ out.push('>');
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ normalizedHtml(child, out);
+ }
+ if (node.firstChild || !/^(?:br|link|img)$/.test(name)) {
+ out.push('<\/', name, '>');
+ }
+ break;
+ case 2: // an attribute
+ out.push(node.name.toLowerCase(), '="', attribToHtml(node.value), '"');
+ break;
+ case 3: case 4: // text
+ out.push(textToHtml(node.nodeValue));
+ break;
+ }
+ }
+
+ /**
+ * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
+ * matches the union o the sets o strings matched d by the input RegExp.
+ * Since it matches globally, if the input strings have a start-of-input
+ * anchor (/^.../), it is ignored for the purposes of unioning.
+ * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
+ * @return {RegExp} a global regex.
+ */
+ function combinePrefixPatterns(regexs) {
+ var capturedGroupIndex = 0;
+
+ var needToFoldCase = false;
+ var ignoreCase = false;
+ for (var i = 0, n = regexs.length; i < n; ++i) {
+ var regex = regexs[i];
+ if (regex.ignoreCase) {
+ ignoreCase = true;
+ } else if (/[a-z]/i.test(regex.source.replace(
+ /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
+ needToFoldCase = true;
+ ignoreCase = false;
+ break;
+ }
+ }
+
+ function decodeEscape(charsetPart) {
+ if (charsetPart.charAt(0) !== '\\') { return charsetPart.charCodeAt(0); }
+ switch (charsetPart.charAt(1)) {
+ case 'b': return 8;
+ case 't': return 9;
+ case 'n': return 0xa;
+ case 'v': return 0xb;
+ case 'f': return 0xc;
+ case 'r': return 0xd;
+ case 'u': case 'x':
+ return parseInt(charsetPart.substring(2), 16)
+ || charsetPart.charCodeAt(1);
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7':
+ return parseInt(charsetPart.substring(1), 8);
+ default: return charsetPart.charCodeAt(1);
+ }
+ }
+
+ function encodeEscape(charCode) {
+ if (charCode < 0x20) {
+ return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
+ }
+ var ch = String.fromCharCode(charCode);
+ if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') {
+ ch = '\\' + ch;
+ }
+ return ch;
+ }
+
+ function caseFoldCharset(charSet) {
+ var charsetParts = charSet.substring(1, charSet.length - 1).match(
+ new RegExp(
+ '\\\\u[0-9A-Fa-f]{4}'
+ + '|\\\\x[0-9A-Fa-f]{2}'
+ + '|\\\\[0-3][0-7]{0,2}'
+ + '|\\\\[0-7]{1,2}'
+ + '|\\\\[\\s\\S]'
+ + '|-'
+ + '|[^-\\\\]',
+ 'g'));
+ var groups = [];
+ var ranges = [];
+ var inverse = charsetParts[0] === '^';
+ for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
+ var p = charsetParts[i];
+ switch (p) {
+ case '\\B': case '\\b':
+ case '\\D': case '\\d':
+ case '\\S': case '\\s':
+ case '\\W': case '\\w':
+ groups.push(p);
+ continue;
+ }
+ var start = decodeEscape(p);
+ var end;
+ if (i + 2 < n && '-' === charsetParts[i + 1]) {
+ end = decodeEscape(charsetParts[i + 2]);
+ i += 2;
+ } else {
+ end = start;
+ }
+ ranges.push([start, end]);
+ // If the range might intersect letters, then expand it.
+ if (!(end < 65 || start > 122)) {
+ if (!(end < 65 || start > 90)) {
+ ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
+ }
+ if (!(end < 97 || start > 122)) {
+ ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
+ }
+ }
+ }
+
+ // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
+ // -> [[1, 12], [14, 14], [16, 17]]
+ ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1] - a[1]); });
+ var consolidatedRanges = [];
+ var lastRange = [NaN, NaN];
+ for (var i = 0; i < ranges.length; ++i) {
+ var range = ranges[i];
+ if (range[0] <= lastRange[1] + 1) {
+ lastRange[1] = Math.max(lastRange[1], range[1]);
+ } else {
+ consolidatedRanges.push(lastRange = range);
+ }
+ }
+
+ var out = ['['];
+ if (inverse) { out.push('^'); }
+ out.push.apply(out, groups);
+ for (var i = 0; i < consolidatedRanges.length; ++i) {
+ var range = consolidatedRanges[i];
+ out.push(encodeEscape(range[0]));
+ if (range[1] > range[0]) {
+ if (range[1] + 1 > range[0]) { out.push('-'); }
+ out.push(encodeEscape(range[1]));
+ }
+ }
+ out.push(']');
+ return out.join('');
+ }
+
+ function allowAnywhereFoldCaseAndRenumberGroups(regex) {
+ // Split into character sets, escape sequences, punctuation strings
+ // like ('(', '(?:', ')', '^'), and runs of characters that do not
+ // include any of the above.
+ var parts = regex.source.match(
+ new RegExp(
+ '(?:'
+ + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]' // a character set
+ + '|\\\\u[A-Fa-f0-9]{4}' // a unicode escape
+ + '|\\\\x[A-Fa-f0-9]{2}' // a hex escape
+ + '|\\\\[0-9]+' // a back-reference or octal escape
+ + '|\\\\[^ux0-9]' // other escape sequence
+ + '|\\(\\?[:!=]' // start of a non-capturing group
+ + '|[\\(\\)\\^]' // start/emd of a group, or line start
+ + '|[^\\x5B\\x5C\\(\\)\\^]+' // run of other characters
+ + ')',
+ 'g'));
+ var n = parts.length;
+
+ // Maps captured group numbers to the number they will occupy in
+ // the output or to -1 if that has not been determined, or to
+ // undefined if they need not be capturing in the output.
+ var capturedGroups = [];
+
+ // Walk over and identify back references to build the capturedGroups
+ // mapping.
+ for (var i = 0, groupIndex = 0; i < n; ++i) {
+ var p = parts[i];
+ if (p === '(') {
+ // groups are 1-indexed, so max group index is count of '('
+ ++groupIndex;
+ } else if ('\\' === p.charAt(0)) {
+ var decimalValue = +p.substring(1);
+ if (decimalValue && decimalValue <= groupIndex) {
+ capturedGroups[decimalValue] = -1;
+ }
+ }
+ }
+
+ // Renumber groups and reduce capturing groups to non-capturing groups
+ // where possible.
+ for (var i = 1; i < capturedGroups.length; ++i) {
+ if (-1 === capturedGroups[i]) {
+ capturedGroups[i] = ++capturedGroupIndex;
+ }
+ }
+ for (var i = 0, groupIndex = 0; i < n; ++i) {
+ var p = parts[i];
+ if (p === '(') {
+ ++groupIndex;
+ if (capturedGroups[groupIndex] === undefined) {
+ parts[i] = '(?:';
+ }
+ } else if ('\\' === p.charAt(0)) {
+ var decimalValue = +p.substring(1);
+ if (decimalValue && decimalValue <= groupIndex) {
+ parts[i] = '\\' + capturedGroups[groupIndex];
+ }
+ }
+ }
+
+ // Remove any prefix anchors so that the output will match anywhere.
+ // ^^ really does mean an anchored match though.
+ for (var i = 0, groupIndex = 0; i < n; ++i) {
+ if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
+ }
+
+ // Expand letters to groupts to handle mixing of case-sensitive and
+ // case-insensitive patterns if necessary.
+ if (regex.ignoreCase && needToFoldCase) {
+ for (var i = 0; i < n; ++i) {
+ var p = parts[i];
+ var ch0 = p.charAt(0);
+ if (p.length >= 2 && ch0 === '[') {
+ parts[i] = caseFoldCharset(p);
+ } else if (ch0 !== '\\') {
+ // TODO: handle letters in numeric escapes.
+ parts[i] = p.replace(
+ /[a-zA-Z]/g,
+ function (ch) {
+ var cc = ch.charCodeAt(0);
+ return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
+ });
+ }
+ }
+ }
+
+ return parts.join('');
+ }
+
+ var rewritten = [];
+ for (var i = 0, n = regexs.length; i < n; ++i) {
+ var regex = regexs[i];
+ if (regex.global || regex.multiline) { throw new Error('' + regex); }
+ rewritten.push(
+ '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
+ }
+
+ return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
+ }
+
+ var PR_innerHtmlWorks = null;
+ function getInnerHtml(node) {
+ // inner html is hopelessly broken in Safari 2.0.4 when the content is
+ // an html description of well formed XML and the containing tag is a PRE
+ // tag, so we detect that case and emulate innerHTML.
+ if (null === PR_innerHtmlWorks) {
+ var testNode = document.createElement('PRE');
+ testNode.appendChild(
+ document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />'));
+ PR_innerHtmlWorks = !/</.test(testNode.innerHTML);
+ }
+
+ if (PR_innerHtmlWorks) {
+ var content = node.innerHTML;
+ // XMP tags contain unescaped entities so require special handling.
+ if (isRawContent(node)) {
+ content = textToHtml(content);
+ } else if (!isPreformatted(node, content)) {
+ content = content.replace(/(<br\s*\/?>)[\r\n]+/g, '$1')
+ .replace(/(?:[\r\n]+[ \t]*)+/g, ' ');
+ }
+ return content;
+ }
+
+ var out = [];
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ normalizedHtml(child, out);
+ }
+ return out.join('');
+ }
+
+ /** returns a function that expand tabs to spaces. This function can be fed
+ * successive chunks of text, and will maintain its own internal state to
+ * keep track of how tabs are expanded.
+ * @return {function (string) : string} a function that takes
+ * plain text and return the text with tabs expanded.
+ * @private
+ */
+ function makeTabExpander(tabWidth) {
+ var SPACES = ' ';
+ var charInLine = 0;
+
+ return function (plainText) {
+ // walk over each character looking for tabs and newlines.
+ // On tabs, expand them. On newlines, reset charInLine.
+ // Otherwise increment charInLine
+ var out = null;
+ var pos = 0;
+ for (var i = 0, n = plainText.length; i < n; ++i) {
+ var ch = plainText.charAt(i);
+
+ switch (ch) {
+ case '\t':
+ if (!out) { out = []; }
+ out.push(plainText.substring(pos, i));
+ // calculate how much space we need in front of this part
+ // nSpaces is the amount of padding -- the number of spaces needed
+ // to move us to the next column, where columns occur at factors of
+ // tabWidth.
+ var nSpaces = tabWidth - (charInLine % tabWidth);
+ charInLine += nSpaces;
+ for (; nSpaces >= 0; nSpaces -= SPACES.length) {
+ out.push(SPACES.substring(0, nSpaces));
+ }
+ pos = i + 1;
+ break;
+ case '\n':
+ charInLine = 0;
+ break;
+ default:
+ ++charInLine;
+ }
+ }
+ if (!out) { return plainText; }
+ out.push(plainText.substring(pos));
+ return out.join('');
+ };
+ }
+
+ var pr_chunkPattern = new RegExp(
+ '[^<]+' // A run of characters other than '<'
+ + '|<\!--[\\s\\S]*?--\>' // an HTML comment
+ + '|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>' // a CDATA section
+ // a probable tag that should not be highlighted
+ + '|<\/?[a-zA-Z](?:[^>\"\']|\'[^\']*\'|\"[^\"]*\")*>'
+ + '|<', // A '<' that does not begin a larger chunk
+ 'g');
+ var pr_commentPrefix = /^<\!--/;
+ var pr_cdataPrefix = /^<!\[CDATA\[/;
+ var pr_brPrefix = /^<br\b/i;
+ var pr_tagNameRe = /^<(\/?)([a-zA-Z][a-zA-Z0-9]*)/;
+
+ /** split markup into chunks of html tags (style null) and
+ * plain text (style {@link #PR_PLAIN}), converting tags which are
+ * significant for tokenization (<br>) into their textual equivalent.
+ *
+ * @param {string} s html where whitespace is considered significant.
+ * @return {Object} source code and extracted tags.
+ * @private
+ */
+ function extractTags(s) {
+ // since the pattern has the 'g' modifier and defines no capturing groups,
+ // this will return a list of all chunks which we then classify and wrap as
+ // PR_Tokens
+ var matches = s.match(pr_chunkPattern);
+ var sourceBuf = [];
+ var sourceBufLen = 0;
+ var extractedTags = [];
+ if (matches) {
+ for (var i = 0, n = matches.length; i < n; ++i) {
+ var match = matches[i];
+ if (match.length > 1 && match.charAt(0) === '<') {
+ if (pr_commentPrefix.test(match)) { continue; }
+ if (pr_cdataPrefix.test(match)) {
+ // strip CDATA prefix and suffix. Don't unescape since it's CDATA
+ sourceBuf.push(match.substring(9, match.length - 3));
+ sourceBufLen += match.length - 12;
+ } else if (pr_brPrefix.test(match)) {
+ // <br> tags are lexically significant so convert them to text.
+ // This is undone later.
+ sourceBuf.push('\n');
+ ++sourceBufLen;
+ } else {
+ if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) {
+ // A <span class="nocode"> will start a section that should be
+ // ignored. Continue walking the list until we see a matching end
+ // tag.
+ var name = match.match(pr_tagNameRe)[2];
+ var depth = 1;
+ var j;
+ end_tag_loop:
+ for (j = i + 1; j < n; ++j) {
+ var name2 = matches[j].match(pr_tagNameRe);
+ if (name2 && name2[2] === name) {
+ if (name2[1] === '/') {
+ if (--depth === 0) { break end_tag_loop; }
+ } else {
+ ++depth;
+ }
+ }
+ }
+ if (j < n) {
+ extractedTags.push(
+ sourceBufLen, matches.slice(i, j + 1).join(''));
+ i = j;
+ } else { // Ignore unclosed sections.
+ extractedTags.push(sourceBufLen, match);
+ }
+ } else {
+ extractedTags.push(sourceBufLen, match);
+ }
+ }
+ } else {
+ var literalText = htmlToText(match);
+ sourceBuf.push(literalText);
+ sourceBufLen += literalText.length;
+ }
+ }
+ }
+ return { source: sourceBuf.join(''), tags: extractedTags };
+ }
+
+ /** True if the given tag contains a class attribute with the nocode class. */
+ function isNoCodeTag(tag) {
+ return !!tag
+ // First canonicalize the representation of attributes
+ .replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,
+ ' $1="$2$3$4"')
+ // Then look for the attribute we want.
+ .match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/);
+ }
+
+ /**
+ * Apply the given language handler to sourceCode and add the resulting
+ * decorations to out.
+ * @param {number} basePos the index of sourceCode within the chunk of source
+ * whose decorations are already present on out.
+ */
+ function appendDecorations(basePos, sourceCode, langHandler, out) {
+ if (!sourceCode) { return; }
+ var job = {
+ source: sourceCode,
+ basePos: basePos
+ };
+ langHandler(job);
+ out.push.apply(out, job.decorations);
+ }
+
+ /** Given triples of [style, pattern, context] returns a lexing function,
+ * The lexing function interprets the patterns to find token boundaries and
+ * returns a decoration list of the form
+ * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
+ * where index_n is an index into the sourceCode, and style_n is a style
+ * constant like PR_PLAIN. index_n-1 <= index_n, and style_n-1 applies to
+ * all characters in sourceCode[index_n-1:index_n].
+ *
+ * The stylePatterns is a list whose elements have the form
+ * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
+ *
+ * Style is a style constant like PR_PLAIN, or can be a string of the
+ * form 'lang-FOO', where FOO is a language extension describing the
+ * language of the portion of the token in $1 after pattern executes.
+ * E.g., if style is 'lang-lisp', and group 1 contains the text
+ * '(hello (world))', then that portion of the token will be passed to the
+ * registered lisp handler for formatting.
+ * The text before and after group 1 will be restyled using this decorator
+ * so decorators should take care that this doesn't result in infinite
+ * recursion. For example, the HTML lexer rule for SCRIPT elements looks
+ * something like ['lang-js', /<[s]cript>(.+?)<\/script>/]. This may match
+ * '<script>foo()<\/script>', which would cause the current decorator to
+ * be called with '<script>' which would not match the same rule since
+ * group 1 must not be empty, so it would be instead styled as PR_TAG by
+ * the generic tag rule. The handler registered for the 'js' extension would
+ * then be called with 'foo()', and finally, the current decorator would
+ * be called with '<\/script>' which would not match the original rule and
+ * so the generic tag rule would identify it as a tag.
+ *
+ * Pattern must only match prefixes, and if it matches a prefix, then that
+ * match is considered a token with the same style.
+ *
+ * Context is applied to the last non-whitespace, non-comment token
+ * recognized.
+ *
+ * Shortcut is an optional string of characters, any of which, if the first
+ * character, gurantee that this pattern and only this pattern matches.
+ *
+ * @param {Array} shortcutStylePatterns patterns that always start with
+ * a known character. Must have a shortcut string.
+ * @param {Array} fallthroughStylePatterns patterns that will be tried in
+ * order if the shortcut ones fail. May have shortcuts.
+ *
+ * @return {function (Object)} a
+ * function that takes source code and returns a list of decorations.
+ */
+ function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
+ var shortcuts = {};
+ var tokenizer;
+ (function () {
+ var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
+ var allRegexs = [];
+ var regexKeys = {};
+ for (var i = 0, n = allPatterns.length; i < n; ++i) {
+ var patternParts = allPatterns[i];
+ var shortcutChars = patternParts[3];
+ if (shortcutChars) {
+ for (var c = shortcutChars.length; --c >= 0;) {
+ shortcuts[shortcutChars.charAt(c)] = patternParts;
+ }
+ }
+ var regex = patternParts[1];
+ var k = '' + regex;
+ if (!regexKeys.hasOwnProperty(k)) {
+ allRegexs.push(regex);
+ regexKeys[k] = null;
+ }
+ }
+ allRegexs.push(/[\0-\uffff]/);
+ tokenizer = combinePrefixPatterns(allRegexs);
+ })();
+
+ var nPatterns = fallthroughStylePatterns.length;
+ var notWs = /\S/;
+
+ /**
+ * Lexes job.source and produces an output array job.decorations of style
+ * classes preceded by the position at which they start in job.source in
+ * order.
+ *
+ * @param {Object} job an object like {@code
+ * source: {string} sourceText plain text,
+ * basePos: {int} position of job.source in the larger chunk of
+ * sourceCode.
+ * }
+ */
+ var decorate = function (job) {
+ var sourceCode = job.source, basePos = job.basePos;
+ /** Even entries are positions in source in ascending order. Odd enties
+ * are style markers (e.g., PR_COMMENT) that run from that position until
+ * the end.
+ * @type {Array.<number|string>}
+ */
+ var decorations = [basePos, PR_PLAIN];
+ var pos = 0; // index into sourceCode
+ var tokens = sourceCode.match(tokenizer) || [];
+ var styleCache = {};
+
+ for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
+ var token = tokens[ti];
+ var style = styleCache[token];
+ var match = void 0;
+
+ var isEmbedded;
+ if (typeof style === 'string') {
+ isEmbedded = false;
+ } else {
+ var patternParts = shortcuts[token.charAt(0)];
+ if (patternParts) {
+ match = token.match(patternParts[1]);
+ style = patternParts[0];
+ } else {
+ for (var i = 0; i < nPatterns; ++i) {
+ patternParts = fallthroughStylePatterns[i];
+ match = token.match(patternParts[1]);
+ if (match) {
+ style = patternParts[0];
+ break;
+ }
+ }
+
+ if (!match) { // make sure that we make progress
+ style = PR_PLAIN;
+ }
+ }
+
+ isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
+ if (isEmbedded && !(match && typeof match[1] === 'string')) {
+ isEmbedded = false;
+ style = PR_SOURCE;
+ }
+
+ if (!isEmbedded) { styleCache[token] = style; }
+ }
+
+ var tokenStart = pos;
+ pos += token.length;
+
+ if (!isEmbedded) {
+ decorations.push(basePos + tokenStart, style);
+ } else { // Treat group 1 as an embedded block of source code.
+ var embeddedSource = match[1];
+ var embeddedSourceStart = token.indexOf(embeddedSource);
+ var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
+ if (match[2]) {
+ // If embeddedSource can be blank, then it would match at the
+ // beginning which would cause us to infinitely recurse on the
+ // entire token, so we catch the right context in match[2].
+ embeddedSourceEnd = token.length - match[2].length;
+ embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
+ }
+ var lang = style.substring(5);
+ // Decorate the left of the embedded source
+ appendDecorations(
+ basePos + tokenStart,
+ token.substring(0, embeddedSourceStart),
+ decorate, decorations);
+ // Decorate the embedded source
+ appendDecorations(
+ basePos + tokenStart + embeddedSourceStart,
+ embeddedSource,
+ langHandlerForExtension(lang, embeddedSource),
+ decorations);
+ // Decorate the right of the embedded section
+ appendDecorations(
+ basePos + tokenStart + embeddedSourceEnd,
+ token.substring(embeddedSourceEnd),
+ decorate, decorations);
+ }
+ }
+ job.decorations = decorations;
+ };
+ return decorate;
+ }
+
+ /** returns a function that produces a list of decorations from source text.
+ *
+ * This code treats ", ', and ` as string delimiters, and \ as a string
+ * escape. It does not recognize perl's qq() style strings.
+ * It has no special handling for double delimiter escapes as in basic, or
+ * the tripled delimiters used in python, but should work on those regardless
+ * although in those cases a single string literal may be broken up into
+ * multiple adjacent string literals.
+ *
+ * It recognizes C, C++, and shell style comments.
+ *
+ * @param {Object} options a set of optional parameters.
+ * @return {function (Object)} a function that examines the source code
+ * in the input job and builds the decoration list.
+ */
+ function sourceDecorator(options) {
+ var shortcutStylePatterns = [], fallthroughStylePatterns = [];
+ if (options['tripleQuotedStrings']) {
+ // '''multi-line-string''', 'single-line-string', and double-quoted
+ shortcutStylePatterns.push(
+ [PR_STRING, /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
+ null, '\'"']);
+ } else if (options['multiLineStrings']) {
+ // 'multi-line-string', "multi-line-string"
+ shortcutStylePatterns.push(
+ [PR_STRING, /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
+ null, '\'"`']);
+ } else {
+ // 'single-line-string', "single-line-string"
+ shortcutStylePatterns.push(
+ [PR_STRING,
+ /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
+ null, '"\'']);
+ }
+ if (options['verbatimStrings']) {
+ // verbatim-string-literal production from the C# grammar. See issue 93.
+ fallthroughStylePatterns.push(
+ [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
+ }
+ if (options['hashComments']) {
+ if (options['cStyleComments']) {
+ // Stop C preprocessor declarations at an unclosed open comment
+ shortcutStylePatterns.push(
+ [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,
+ null, '#']);
+ fallthroughStylePatterns.push(
+ [PR_STRING,
+ /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,
+ null]);
+ } else {
+ shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
+ }
+ }
+ if (options['cStyleComments']) {
+ fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
+ fallthroughStylePatterns.push(
+ [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
+ }
+ if (options['regexLiterals']) {
+ var REGEX_LITERAL = (
+ // A regular expression literal starts with a slash that is
+ // not followed by * or / so that it is not confused with
+ // comments.
+ '/(?=[^/*])'
+ // and then contains any number of raw characters,
+ + '(?:[^/\\x5B\\x5C]'
+ // escape sequences (\x5C),
+ + '|\\x5C[\\s\\S]'
+ // or non-nesting character sets (\x5B\x5D);
+ + '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
+ // finally closed by a /.
+ + '/');
+ fallthroughStylePatterns.push(
+ ['lang-regex',
+ new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
+ ]);
+ }
+
+ var keywords = options['keywords'].replace(/^\s+|\s+$/g, '');
+ if (keywords.length) {
+ fallthroughStylePatterns.push(
+ [PR_KEYWORD,
+ new RegExp('^(?:' + keywords.replace(/\s+/g, '|') + ')\\b'), null]);
+ }
+
+ shortcutStylePatterns.push([PR_PLAIN, /^\s+/, null, ' \r\n\t\xA0']);
+ fallthroughStylePatterns.push(
+ // TODO(mikesamuel): recognize non-latin letters and numerals in idents
+ [PR_LITERAL, /^@[a-z_$][a-z_$@0-9]*/i, null],
+ [PR_TYPE, /^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/, null],
+ [PR_PLAIN, /^[a-z_$][a-z_$@0-9]*/i, null],
+ [PR_LITERAL,
+ new RegExp(
+ '^(?:'
+ // A hex number
+ + '0x[a-f0-9]+'
+ // or an octal or decimal number,
+ + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
+ // possibly in scientific notation
+ + '(?:e[+\\-]?\\d+)?'
+ + ')'
+ // with an optional modifier like UL for unsigned long
+ + '[a-z]*', 'i'),
+ null, '0123456789'],
+ [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#]*/, null]);
+
+ return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
+ }
+
+ var decorateSource = sourceDecorator({
+ 'keywords': ALL_KEYWORDS,
+ 'hashComments': true,
+ 'cStyleComments': true,
+ 'multiLineStrings': true,
+ 'regexLiterals': true
+ });
+
+ /** Breaks {@code job.source} around style boundaries in
+ * {@code job.decorations} while re-interleaving {@code job.extractedTags},
+ * and leaves the result in {@code job.prettyPrintedHtml}.
+ * @param {Object} job like {
+ * source: {string} source as plain text,
+ * extractedTags: {Array.<number|string>} extractedTags chunks of raw
+ * html preceded by their position in {@code job.source}
+ * in order
+ * decorations: {Array.<number|string} an array of style classes preceded
+ * by the position at which they start in job.source in order
+ * }
+ * @private
+ */
+ function recombineTagsAndDecorations(job) {
+ var sourceText = job.source;
+ var extractedTags = job.extractedTags;
+ var decorations = job.decorations;
+
+ var html = [];
+ // index past the last char in sourceText written to html
+ var outputIdx = 0;
+
+ var openDecoration = null;
+ var currentDecoration = null;
+ var tagPos = 0; // index into extractedTags
+ var decPos = 0; // index into decorations
+ var tabExpander = makeTabExpander(window['PR_TAB_WIDTH']);
+
+ var adjacentSpaceRe = /([\r\n ]) /g;
+ var startOrSpaceRe = /(^| ) /gm;
+ var newlineRe = /\r\n?|\n/g;
+ var trailingSpaceRe = /[ \r\n]$/;
+ var lastWasSpace = true; // the last text chunk emitted ended with a space.
+
+ // A helper function that is responsible for opening sections of decoration
+ // and outputing properly escaped chunks of source
+ function emitTextUpTo(sourceIdx) {
+ if (sourceIdx > outputIdx) {
+ if (openDecoration && openDecoration !== currentDecoration) {
+ // Close the current decoration
+ html.push('</span>');
+ openDecoration = null;
+ }
+ if (!openDecoration && currentDecoration) {
+ openDecoration = currentDecoration;
+ html.push('<span class="', openDecoration, '">');
+ }
+ // This interacts badly with some wikis which introduces paragraph tags
+ // into pre blocks for some strange reason.
+ // It's necessary for IE though which seems to lose the preformattedness
+ // of <pre> tags when their innerHTML is assigned.
+ // http://stud3.tuwien.ac.at/~e0226430/innerHtmlQuirk.html
+ // and it serves to undo the conversion of <br>s to newlines done in
+ // chunkify.
+ var htmlChunk = textToHtml(
+ tabExpander(sourceText.substring(outputIdx, sourceIdx)))
+ .replace(lastWasSpace
+ ? startOrSpaceRe
+ : adjacentSpaceRe, '$1 ');
+ // Keep track of whether we need to escape space at the beginning of the
+ // next chunk.
+ lastWasSpace = trailingSpaceRe.test(htmlChunk);
+ // IE collapses multiple adjacient <br>s into 1 line break.
+ // Prefix every <br> with ' ' can prevent such IE's behavior.
+ var lineBreakHtml = window['_pr_isIE6']() ? ' <br />' : '<br />';
+ html.push(htmlChunk.replace(newlineRe, lineBreakHtml));
+ outputIdx = sourceIdx;
+ }
+ }
+
+ while (true) {
+ // Determine if we're going to consume a tag this time around. Otherwise
+ // we consume a decoration or exit.
+ var outputTag;
+ if (tagPos < extractedTags.length) {
+ if (decPos < decorations.length) {
+ // Pick one giving preference to extractedTags since we shouldn't open
+ // a new style that we're going to have to immediately close in order
+ // to output a tag.
+ outputTag = extractedTags[tagPos] <= decorations[decPos];
+ } else {
+ outputTag = true;
+ }
+ } else {
+ outputTag = false;
+ }
+ // Consume either a decoration or a tag or exit.
+ if (outputTag) {
+ emitTextUpTo(extractedTags[tagPos]);
+ if (openDecoration) {
+ // Close the current decoration
+ html.push('</span>');
+ openDecoration = null;
+ }
+ html.push(extractedTags[tagPos + 1]);
+ tagPos += 2;
+ } else if (decPos < decorations.length) {
+ emitTextUpTo(decorations[decPos]);
+ currentDecoration = decorations[decPos + 1];
+ decPos += 2;
+ } else {
+ break;
+ }
+ }
+ emitTextUpTo(sourceText.length);
+ if (openDecoration) {
+ html.push('</span>');
+ }
+ job.prettyPrintedHtml = html.join('');
+ }
+
+ /** Maps language-specific file extensions to handlers. */
+ var langHandlerRegistry = {};
+ /** Register a language handler for the given file extensions.
+ * @param {function (Object)} handler a function from source code to a list
+ * of decorations. Takes a single argument job which describes the
+ * state of the computation. The single parameter has the form
+ * {@code {
+ * source: {string} as plain text.
+ * decorations: {Array.<number|string>} an array of style classes
+ * preceded by the position at which they start in
+ * job.source in order.
+ * The language handler should assigned this field.
+ * basePos: {int} the position of source in the larger source chunk.
+ * All positions in the output decorations array are relative
+ * to the larger source chunk.
+ * } }
+ * @param {Array.<string>} fileExtensions
+ */
+ function registerLangHandler(handler, fileExtensions) {
+ for (var i = fileExtensions.length; --i >= 0;) {
+ var ext = fileExtensions[i];
+ if (!langHandlerRegistry.hasOwnProperty(ext)) {
+ langHandlerRegistry[ext] = handler;
+ } else if ('console' in window) {
+ console.warn('cannot override language handler %s', ext);
+ }
+ }
+ }
+ function langHandlerForExtension(extension, source) {
+ if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
+ // Treat it as markup if the first non whitespace character is a < and
+ // the last non-whitespace character is a >.
+ extension = /^\s*</.test(source)
+ ? 'default-markup'
+ : 'default-code';
+ }
+ return langHandlerRegistry[extension];
+ }
+ registerLangHandler(decorateSource, ['default-code']);
+ registerLangHandler(
+ createSimpleLexer(
+ [],
+ [
+ [PR_PLAIN, /^[^<?]+/],
+ [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
+ [PR_COMMENT, /^<\!--[\s\S]*?(?:-\->|$)/],
+ // Unescaped content in an unknown language
+ ['lang-', /^<\?([\s\S]+?)(?:\?>|$)/],
+ ['lang-', /^<%([\s\S]+?)(?:%>|$)/],
+ [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
+ ['lang-', /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
+ // Unescaped content in javascript. (Or possibly vbscript).
+ ['lang-js', /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
+ // Contains unescaped stylesheet content
+ ['lang-css', /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
+ ['lang-in.tag', /^(<\/?[a-z][^<>]*>)/i]
+ ]),
+ ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
+ registerLangHandler(
+ createSimpleLexer(
+ [
+ [PR_PLAIN, /^[\s]+/, null, ' \t\r\n'],
+ [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
+ ],
+ [
+ [PR_TAG, /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
+ [PR_ATTRIB_NAME, /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
+ ['lang-uq.val', /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
+ [PR_PUNCTUATION, /^[=<>\/]+/],
+ ['lang-js', /^on\w+\s*=\s*\"([^\"]+)\"/i],
+ ['lang-js', /^on\w+\s*=\s*\'([^\']+)\'/i],
+ ['lang-js', /^on\w+\s*=\s*([^\"\'>\s]+)/i],
+ ['lang-css', /^style\s*=\s*\"([^\"]+)\"/i],
+ ['lang-css', /^style\s*=\s*\'([^\']+)\'/i],
+ ['lang-css', /^style\s*=\s*([^\"\'>\s]+)/i]
+ ]),
+ ['in.tag']);
+ registerLangHandler(
+ createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': CPP_KEYWORDS,
+ 'hashComments': true,
+ 'cStyleComments': true
+ }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': 'null true false'
+ }), ['json']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': CSHARP_KEYWORDS,
+ 'hashComments': true,
+ 'cStyleComments': true,
+ 'verbatimStrings': true
+ }), ['cs']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': JAVA_KEYWORDS,
+ 'cStyleComments': true
+ }), ['java']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': SH_KEYWORDS,
+ 'hashComments': true,
+ 'multiLineStrings': true
+ }), ['bsh', 'csh', 'sh']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': PYTHON_KEYWORDS,
+ 'hashComments': true,
+ 'multiLineStrings': true,
+ 'tripleQuotedStrings': true
+ }), ['cv', 'py']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': PERL_KEYWORDS,
+ 'hashComments': true,
+ 'multiLineStrings': true,
+ 'regexLiterals': true
+ }), ['perl', 'pl', 'pm']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': RUBY_KEYWORDS,
+ 'hashComments': true,
+ 'multiLineStrings': true,
+ 'regexLiterals': true
+ }), ['rb']);
+ registerLangHandler(sourceDecorator({
+ 'keywords': JSCRIPT_KEYWORDS,
+ 'cStyleComments': true,
+ 'regexLiterals': true
+ }), ['js']);
+ registerLangHandler(
+ createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
+
+ function applyDecorator(job) {
+ var sourceCodeHtml = job.sourceCodeHtml;
+ var opt_langExtension = job.langExtension;
+
+ // Prepopulate output in case processing fails with an exception.
+ job.prettyPrintedHtml = sourceCodeHtml;
+
+ try {
+ // Extract tags, and convert the source code to plain text.
+ var sourceAndExtractedTags = extractTags(sourceCodeHtml);
+ /** Plain text. @type {string} */
+ var source = sourceAndExtractedTags.source;
+ job.source = source;
+ job.basePos = 0;
+
+ /** Even entries are positions in source in ascending order. Odd entries
+ * are tags that were extracted at that position.
+ * @type {Array.<number|string>}
+ */
+ job.extractedTags = sourceAndExtractedTags.tags;
+
+ // Apply the appropriate language handler
+ langHandlerForExtension(opt_langExtension, source)(job);
+ // Integrate the decorations and tags back into the source code to produce
+ // a decorated html string which is left in job.prettyPrintedHtml.
+ recombineTagsAndDecorations(job);
+ } catch (e) {
+ if ('console' in window) {
+ console.log(e);
+ console.trace();
+ }
+ }
+ }
+
+ function prettyPrintOne(sourceCodeHtml, opt_langExtension) {
+ var job = {
+ sourceCodeHtml: sourceCodeHtml,
+ langExtension: opt_langExtension
+ };
+ applyDecorator(job);
+ return job.prettyPrintedHtml;
+ }
+
+ function prettyPrint(opt_whenDone) {
+ var isIE678 = window['_pr_isIE6']();
+ var ieNewline = isIE678 === 6 ? '\r\n' : '\r';
+ // See bug 71 and http://stackoverflow.com/questions/136443/why-doesnt-ie7-
+
+ // fetch a list of nodes to rewrite
+ var codeSegments = [
+ document.getElementsByTagName('pre'),
+ document.getElementsByTagName('code'),
+ document.getElementsByTagName('xmp') ];
+ var elements = [];
+ for (var i = 0; i < codeSegments.length; ++i) {
+ for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
+ elements.push(codeSegments[i][j]);
+ }
+ }
+ codeSegments = null;
+
+ var clock = Date;
+ if (!clock['now']) {
+ clock = { 'now': function () { return (new Date).getTime(); } };
+ }
+
+ // The loop is broken into a series of continuations to make sure that we
+ // don't make the browser unresponsive when rewriting a large page.
+ var k = 0;
+ var prettyPrintingJob;
+
+ function doWork() {
+ var endTime = (window['PR_SHOULD_USE_CONTINUATION'] ?
+ clock.now() + 250 /* ms */ :
+ Infinity);
+ for (; k < elements.length && clock.now() < endTime; k++) {
+ var cs = elements[k];
+ if (cs.className && cs.className.indexOf('prettyprint') >= 0) {
+ // If the classes includes a language extensions, use it.
+ // Language extensions can be specified like
+ // <pre class="prettyprint lang-cpp">
+ // the language extension "cpp" is used to find a language handler as
+ // passed to PR_registerLangHandler.
+ var langExtension = cs.className.match(/\blang-(\w+)\b/);
+ if (langExtension) { langExtension = langExtension[1]; }
+
+ // make sure this is not nested in an already prettified element
+ var nested = false;
+ for (var p = cs.parentNode; p; p = p.parentNode) {
+ if ((p.tagName === 'pre' || p.tagName === 'code' ||
+ p.tagName === 'xmp') &&
+ p.className && p.className.indexOf('prettyprint') >= 0) {
+ nested = true;
+ break;
+ }
+ }
+ if (!nested) {
+ // fetch the content as a snippet of properly escaped HTML.
+ // Firefox adds newlines at the end.
+ var content = getInnerHtml(cs);
+ content = content.replace(/(?:\r\n?|\n)$/, '');
+
+ // do the pretty printing
+ prettyPrintingJob = {
+ sourceCodeHtml: content,
+ langExtension: langExtension,
+ sourceNode: cs
+ };
+ applyDecorator(prettyPrintingJob);
+ replaceWithPrettyPrintedHtml();
+ }
+ }
+ }
+ if (k < elements.length) {
+ // finish up in a continuation
+ setTimeout(doWork, 250);
+ } else if (opt_whenDone) {
+ opt_whenDone();
+ }
+ }
+
+ function replaceWithPrettyPrintedHtml() {
+ var newContent = prettyPrintingJob.prettyPrintedHtml;
+ if (!newContent) { return; }
+ var cs = prettyPrintingJob.sourceNode;
+
+ // push the prettified html back into the tag.
+ if (!isRawContent(cs)) {
+ // just replace the old html with the new
+ cs.innerHTML = newContent;
+ } else {
+ // we need to change the tag to a <pre> since <xmp>s do not allow
+ // embedded tags such as the span tags used to attach styles to
+ // sections of source code.
+ var pre = document.createElement('PRE');
+ for (var i = 0; i < cs.attributes.length; ++i) {
+ var a = cs.attributes[i];
+ if (a.specified) {
+ var aname = a.name.toLowerCase();
+ if (aname === 'class') {
+ pre.className = a.value; // For IE 6
+ } else {
+ pre.setAttribute(a.name, a.value);
+ }
+ }
+ }
+ pre.innerHTML = newContent;
+
+ // remove the old
+ cs.parentNode.replaceChild(pre, cs);
+ cs = pre;
+ }
+
+ // Replace <br>s with line-feeds so that copying and pasting works
+ // on IE 6.
+ // Doing this on other browsers breaks lots of stuff since \r\n is
+ // treated as two newlines on Firefox, and doing this also slows
+ // down rendering.
+ if (isIE678 && cs.tagName === 'PRE') {
+ var lineBreaks = cs.getElementsByTagName('br');
+ for (var j = lineBreaks.length; --j >= 0;) {
+ var lineBreak = lineBreaks[j];
+ lineBreak.parentNode.replaceChild(
+ document.createTextNode(ieNewline), lineBreak);
+ }
+ }
+ }
+
+ doWork();
+ }
+
+ window['PR_normalizedHtml'] = normalizedHtml;
+ window['prettyPrintOne'] = prettyPrintOne;
+ window['prettyPrint'] = prettyPrint;
+ window['PR'] = {
+ 'combinePrefixPatterns': combinePrefixPatterns,
+ 'createSimpleLexer': createSimpleLexer,
+ 'registerLangHandler': registerLangHandler,
+ 'sourceDecorator': sourceDecorator,
+ 'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
+ 'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
+ 'PR_COMMENT': PR_COMMENT,
+ 'PR_DECLARATION': PR_DECLARATION,
+ 'PR_KEYWORD': PR_KEYWORD,
+ 'PR_LITERAL': PR_LITERAL,
+ 'PR_NOCODE': PR_NOCODE,
+ 'PR_PLAIN': PR_PLAIN,
+ 'PR_PUNCTUATION': PR_PUNCTUATION,
+ 'PR_SOURCE': PR_SOURCE,
+ 'PR_STRING': PR_STRING,
+ 'PR_TAG': PR_TAG,
+ 'PR_TYPE': PR_TYPE
+ };
+})();
diff --git a/logback-site/src/site/pages/manual/migrationFromLog4j.html b/logback-site/src/site/pages/manual/migrationFromLog4j.html
index 386dbb4..b9b6e41 100644
--- a/logback-site/src/site/pages/manual/migrationFromLog4j.html
+++ b/logback-site/src/site/pages/manual/migrationFromLog4j.html
@@ -10,7 +10,7 @@
<link rel="stylesheet" type="text/css" href="../css/_print.css" media="print" />
<link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen" />
</head>
- <body onload="prettyPrint()">
+ <body onload="prettyPrint();">
<script type="text/javascript">prefix='../'</script>
<script type="text/javascript" src="../js/prettify.js"></script>
<script src="../templates/header.js" type="text/javascript"></script>
@@ -23,7 +23,7 @@
</div>
<div id="content">
- <h2>Migration from log4j</h2>
+ <h2>Migration from log4j</h2>
<div class="quote">
<p><em>The more things change, the more they remain the
diff --git a/pom.xml b/pom.xml
index c2ff239..380b1f3 100755
--- a/pom.xml
+++ b/pom.xml
@@ -198,7 +198,12 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
+ <configuration>
+ <excludeModules>fml</excludeModules>
+ <excludeModules>apt</excludeModules>
+ </configuration>
</plugin>
+
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
@@ -214,18 +219,16 @@
maven-project-info-reports-plugin
</artifactId>
<reportSets>
- <reportSet>
- <reports>
- </reports>
- </reportSet>
+ <reportSet><reports></reports></reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-javadoc-plugin</artifactId>
+ <artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<aggregate>true</aggregate>
+ <!--<linksource>true</linksource>-->
<links>
<link>
http://java.sun.com/j2se/1.5.0/docs/api
@@ -253,7 +256,7 @@
<packages>chapter*:joran*</packages>
</group>
</groups>
- </configuration>
+ </configuration>
</plugin>
</plugins>
@@ -265,21 +268,7 @@
<developerConnection>scm:svn:https://svn.qos.ch/repos/logback/trunk/</developerConnection>
<url>http://svn.qos.ch/repos/logback/trunk/</url>
</scm>
-
- <!-- disable sending message to logback-dev mailing list
- <ciManagement>
- <system>continuum</system>
- <notifiers>
- <notifier>
- <type>mail</type>
- <configuration>
- <address>logback-dev(a)qos.ch</address>
- </configuration>
- </notifier>
- </notifiers>
- </ciManagement>
- -->
-
+
<distributionManagement>
<site>
<id>pixie</id>
@@ -344,6 +333,27 @@
</pluginRepository>
</pluginRepositories>
</profile>
+
+ <profile>
+ <id>javadocjar</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
</profiles>
</project>
\ No newline at end of file
diff --git a/release.sh b/release.sh
new file mode 100644
index 0000000..041719c
--- /dev/null
+++ b/release.sh
@@ -0,0 +1,7 @@
+
+# memeory aid
+mvn clean
+mvn -P javadocjar install
+mvn site:site
+mvn javadoc:jar
+mvn assembly:assembly
\ No newline at end of file
-----------------------------------------------------------------------
Summary of changes:
.../core/encoder/EventObjectInputStream.java | 7 +-
logback-site/src/site/pages/css/prettify.css | 49 +-
logback-site/src/site/pages/js/prettify.js | 1501 +++++++++++++++++++-
.../src/site/pages/manual/migrationFromLog4j.html | 4 +-
pom.xml | 52 +-
release.sh | 7 +
6 files changed, 1545 insertions(+), 75 deletions(-)
create mode 100644 release.sh
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v0.9.18-62-gde8338d
by git-noreply@pixie.qos.ch 04 Mar '10
by git-noreply@pixie.qos.ch 04 Mar '10
04 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via de8338dedace96fe8abb83a9a932a7abed31d0f3 (commit)
from 3d5ba2cfc7f4c381ba2fc10cd0a5342c6330757c (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=de8338dedace96fe8abb83a9…
http://github.com/ceki/logback/commit/de8338dedace96fe8abb83a9a932a7abed31d…
commit de8338dedace96fe8abb83a9a932a7abed31d0f3
Author: Ceki Gulcu <ceki(a)qos.ch>
Date: Thu Mar 4 16:18:55 2010 +0100
- chapter renumbering in the manual
diff --git a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientFileOutputStream.java b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientFileOutputStream.java
index 95ad0d2..cbe3b90 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientFileOutputStream.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientFileOutputStream.java
@@ -56,7 +56,7 @@ public class ResilientFileOutputStream extends OutputStream {
return file;
}
- boolean isPresumedInError() {
+ final private boolean isPresumedInError() {
// existence of recoveryCoordinator indicates failed state
return (recoveryCoordinator != null && !presumedClean);
}
@@ -93,7 +93,7 @@ public class ResilientFileOutputStream extends OutputStream {
}
}
- private void postSuccessfulWrite() {
+ final private void postSuccessfulWrite() {
if (recoveryCoordinator != null) {
recoveryCoordinator = null;
statusCount = 0;
diff --git a/logback-examples/src/main/java/chapters/appenders/mail/mail3.xml b/logback-examples/src/main/java/chapters/appenders/mail/mail3.xml
index bda5873..342de5d 100644
--- a/logback-examples/src/main/java/chapters/appenders/mail/mail3.xml
+++ b/logback-examples/src/main/java/chapters/appenders/mail/mail3.xml
@@ -7,7 +7,7 @@
<configuration>
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
- <Evaluator class="chapter4.mail.CounterBasedEvaluator" />
+ <Evaluator class="chapters.appenders.mail.CounterBasedEvaluator" />
<BufferSize>1050</BufferSize>
<SMTPHost>${smtpHost}</SMTPHost>
<To>${to}</To>
diff --git a/logback-examples/src/main/java/chapters/architecture/sample-config-3.xml b/logback-examples/src/main/java/chapters/architecture/sample-config-3.xml
index ae279c9..e486c21 100644
--- a/logback-examples/src/main/java/chapters/architecture/sample-config-3.xml
+++ b/logback-examples/src/main/java/chapters/architecture/sample-config-3.xml
@@ -17,7 +17,7 @@
<File>sample-log.txt</File>
</appender>
- <logger name="chapter2" level="info" />
+ <logger name="chapters.architecture" level="info" />
<root level="debug">
<appender-ref ref="STDOUT" />
diff --git a/logback-examples/src/main/java/chapters/configuration/containingConfig.xml b/logback-examples/src/main/java/chapters/configuration/containingConfig.xml
index a6bc77b..b9693e5 100644
--- a/logback-examples/src/main/java/chapters/configuration/containingConfig.xml
+++ b/logback-examples/src/main/java/chapters/configuration/containingConfig.xml
@@ -2,7 +2,7 @@
<configuration>
- <include file="src/main/java/chapter3/includedConfig.xml" />
+ <include file="src/main/java/chapters/configuration/includedConfig.xml" />
<root level="DEBUG">
<appender-ref ref="includedConsole" />
diff --git a/logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml b/logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml
index 10d9643..3a5e0a4 100644
--- a/logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml
+++ b/logback-examples/src/main/java/chapters/configuration/variableSubstitution3.xml
@@ -1,6 +1,6 @@
<configuration>
- <property file="src/main/java/chapter3/variables1.properties" />
+ <property file="src/main/java/chapters/configuration/variables1.properties" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${USER_HOME}/myApp.log</file>
diff --git a/logback-examples/src/main/java/chapters/configuration/variableSubstitution4.xml b/logback-examples/src/main/java/chapters/configuration/variableSubstitution4.xml
index 361eb57..a35ada7 100644
--- a/logback-examples/src/main/java/chapters/configuration/variableSubstitution4.xml
+++ b/logback-examples/src/main/java/chapters/configuration/variableSubstitution4.xml
@@ -1,6 +1,6 @@
<configuration>
- <property file="src/main/java/chapter3/variables2.properties" />
+ <property file="src/main/java/chapters/configuration/variables2.properties" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${destination}/myApp.log</file>
diff --git a/logback-examples/src/main/java/chapters/filters/sampleFilterConfig.xml b/logback-examples/src/main/java/chapters/filters/sampleFilterConfig.xml
index 1e8a10e..203b247 100644
--- a/logback-examples/src/main/java/chapters/filters/sampleFilterConfig.xml
+++ b/logback-examples/src/main/java/chapters/filters/sampleFilterConfig.xml
@@ -2,7 +2,7 @@
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
- <Filter class="chapter6.SampleFilter" />
+ <Filter class="chapters.filters.SampleFilter" />
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>
diff --git a/logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml b/logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml
index 6421d5f..cb9dbe3 100644
--- a/logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml
+++ b/logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml
@@ -1,6 +1,6 @@
<configuration>
- <turboFilter class="chapter6.SampleTurboFilter">
+ <turboFilter class="chapters.filters.SampleTurboFilter">
<Marker>sample</Marker>
</turboFilter>
diff --git a/logback-examples/src/main/java/chapters/layouts/callerEvaluatorConfig.xml b/logback-examples/src/main/java/chapters/layouts/callerEvaluatorConfig.xml
index 1d84e19..ffbcb38 100644
--- a/logback-examples/src/main/java/chapters/layouts/callerEvaluatorConfig.xml
+++ b/logback-examples/src/main/java/chapters/layouts/callerEvaluatorConfig.xml
@@ -2,7 +2,7 @@
<evaluator name="DISPLAY_CALLER_EVAL">
<Expression>
- logger.getName().contains("chapter5") && message.contains("who calls thee")
+ logger.getName().contains("chapters.layouts") && message.contains("who calls thee")
</Expression>
</evaluator>
diff --git a/logback-examples/src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml b/logback-examples/src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml
index f9b8502..1f51577 100644
--- a/logback-examples/src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml
+++ b/logback-examples/src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml
@@ -1,7 +1,7 @@
<configuration>
<evaluator name="DISPLAY_EX_EVAL">
- <Expression>throwable != null && throwable instanceof chapter5.TestException</Expression>
+ <Expression>throwable != null && throwable instanceof chapters.layouts.TestException</Expression>
</evaluator>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
diff --git a/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml b/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml
index c526c1b..048eb24 100644
--- a/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml
+++ b/logback-examples/src/main/java/chapters/layouts/mySampleConverterConfig.xml
@@ -1,6 +1,6 @@
<configuration>
- <conversionRule conversionWord="sample" converterClass="chapter5.MySampleConverter" />
+ <conversionRule conversionWord="sample" converterClass="chapters.layouts.MySampleConverter" />
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
diff --git a/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml b/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml
index 4ec1933..9cff3bb 100644
--- a/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml
+++ b/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml
@@ -2,7 +2,7 @@
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
- <layout class="chapter5.MySampleLayout" />
+ <layout class="chapters.layouts.MySampleLayout" />
</appender>
<root level="debug">
diff --git a/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig2.xml b/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig2.xml
index 24ed95d..5c302fb 100644
--- a/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig2.xml
+++ b/logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig2.xml
@@ -2,7 +2,7 @@
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
- <layout class="chapter5.MySampleLayout2">
+ <layout class="chapters.layouts.MySampleLayout2">
<prefix>MyPrefix</prefix>
<printThreadName>false</printThreadName>
</layout>
diff --git a/logback-examples/src/main/java/chapters/mdc/NumberCruncherClient.java b/logback-examples/src/main/java/chapters/mdc/NumberCruncherClient.java
index 5c58943..142964d 100644
--- a/logback-examples/src/main/java/chapters/mdc/NumberCruncherClient.java
+++ b/logback-examples/src/main/java/chapters/mdc/NumberCruncherClient.java
@@ -42,7 +42,7 @@ public class NumberCruncherClient {
static void usage(String msg) {
System.err.println(msg);
- System.err.println("Usage: java chapter7.NumberCruncherClient HOST\n" +
+ System.err.println("Usage: java chapters.mdc.NumberCruncherClient HOST\n" +
" where HOST is the machine where the NumberCruncherServer is running.");
System.exit(1);
}
diff --git a/logback-examples/src/main/java/chapters/mdc/NumberCruncherServer.java b/logback-examples/src/main/java/chapters/mdc/NumberCruncherServer.java
index 47fa237..cadb377 100644
--- a/logback-examples/src/main/java/chapters/mdc/NumberCruncherServer.java
+++ b/logback-examples/src/main/java/chapters/mdc/NumberCruncherServer.java
@@ -113,7 +113,7 @@ public class NumberCruncherServer extends UnicastRemoteObject
static void usage(String msg) {
System.err.println(msg);
- System.err.println("Usage: java chapter7.NumberCruncherServer configFile\n" +
+ System.err.println("Usage: java chapters.mdc.NumberCruncherServer configFile\n" +
" where configFile is a logback configuration file.");
System.exit(1);
}
diff --git a/logback-examples/src/main/java/chapters/mdc/SimpleMDC.java b/logback-examples/src/main/java/chapters/mdc/SimpleMDC.java
index a2fa7ae..927de27 100644
--- a/logback-examples/src/main/java/chapters/mdc/SimpleMDC.java
+++ b/logback-examples/src/main/java/chapters/mdc/SimpleMDC.java
@@ -34,7 +34,7 @@ public class SimpleMDC {
// we put the first name
MDC.put("first", "Dorothy");
- // configure via the configuration file "chapter7/simpleMDC.xml"
+ // configure via the configuration file "chapters/mdc/simpleMDC.xml"
// which ships with the examples
configureViaXML_File();
@@ -84,7 +84,7 @@ public class SimpleMDC {
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
lc.stop();
- URL url = Loader.getResourceBySelfClassLoader("chapter7/simpleMDC.xml");
+ URL url = Loader.getResourceBySelfClassLoader("chapters/mdc/simpleMDC.xml");
configurator.doConfigure(url);
} catch (JoranException je) {
StatusPrinter.print(lc);
diff --git a/logback-examples/src/main/java/chapters/mdc/UserServletFilter.java b/logback-examples/src/main/java/chapters/mdc/UserServletFilter.java
index 5feed3f..cc9db4c 100644
--- a/logback-examples/src/main/java/chapters/mdc/UserServletFilter.java
+++ b/logback-examples/src/main/java/chapters/mdc/UserServletFilter.java
@@ -40,7 +40,7 @@ import org.slf4j.MDC;
* <filter>
* <filter-name>User Servlet Filter</filter-name>
* <filter-class>
- * chapter7.UserServletFilter
+ * chapters.mdc.UserServletFilter
* </filter-class>
* </filter>
* <filter-mapping>
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/Log4jMain.java b/logback-examples/src/main/java/chapters/migrationFromLog4j/Log4jMain.java
index 281fd6e..f61f54a 100644
--- a/logback-examples/src/main/java/chapters/migrationFromLog4j/Log4jMain.java
+++ b/logback-examples/src/main/java/chapters/migrationFromLog4j/Log4jMain.java
@@ -27,7 +27,7 @@ public class Log4jMain {
static Logger logger = Logger.getLogger(Log4jMain.class);
public static void main(String[] args) {
- PropertyConfigurator.configure("src/main/java/chapter11/log4jTrivial.properties");
+ PropertyConfigurator.configure("src/main/java/chapters/migrationFromLog4j/log4jTrivial.properties");
logger.debug("Hello world");
}
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/LogbackMain.java b/logback-examples/src/main/java/chapters/migrationFromLog4j/LogbackMain.java
index feb8532..76fff92 100644
--- a/logback-examples/src/main/java/chapters/migrationFromLog4j/LogbackMain.java
+++ b/logback-examples/src/main/java/chapters/migrationFromLog4j/LogbackMain.java
@@ -38,7 +38,7 @@ public class LogbackMain {
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
lc.reset();
- configurator.doConfigure("src/main/java/chapter11/logback-trivial.xml");
+ configurator.doConfigure("src/main/java/chapters/migrationFromLog4j/logback-trivial.xml");
StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/log4jTrivial.properties b/logback-examples/src/main/java/chapters/migrationFromLog4j/log4jTrivial.properties
index db27c8b..74017ed 100644
--- a/logback-examples/src/main/java/chapters/migrationFromLog4j/log4jTrivial.properties
+++ b/logback-examples/src/main/java/chapters/migrationFromLog4j/log4jTrivial.properties
@@ -1,3 +1,3 @@
log4j.rootLogger=DEBUG, TRIVIAL
-log4j.appender.TRIVIAL=chapter11.TrivialLog4jAppender
-log4j.appender.TRIVIAL.layout=chapter11.TrivialLog4jLayout
\ No newline at end of file
+log4j.appender.TRIVIAL=chapters.migrationFromLog4j.TrivialLog4jAppender
+log4j.appender.TRIVIAL.layout=chapters.migrationFromLog4j.TrivialLog4jLayout
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/logback-trivial.xml b/logback-examples/src/main/java/chapters/migrationFromLog4j/logback-trivial.xml
index 1423887..9c23d9a 100644
--- a/logback-examples/src/main/java/chapters/migrationFromLog4j/logback-trivial.xml
+++ b/logback-examples/src/main/java/chapters/migrationFromLog4j/logback-trivial.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
- <appender name="TRIVIAL" class="chapter11.TrivialLogbackAppender">
- <layout class="chapter11.TrivialLogbackLayout"/>
+ <appender name="TRIVIAL" class="chapters.migrationFromLog4j.TrivialLogbackAppender">
+ <layout class="chapters.migrationFromLog4j.TrivialLogbackLayout"/>
</appender>
<root level="DEBUG">
<appender-ref ref="TRIVIAL"/>
diff --git a/logback-examples/src/main/java/chapters/onJoran/SimpleConfigurator.java b/logback-examples/src/main/java/chapters/onJoran/SimpleConfigurator.java
new file mode 100644
index 0000000..27e434d
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/SimpleConfigurator.java
@@ -0,0 +1,64 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran;
+
+import java.util.List;
+import java.util.Map;
+
+import ch.qos.logback.core.joran.GenericConfigurator;
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.action.ImplicitAction;
+import ch.qos.logback.core.joran.spi.Interpreter;
+import ch.qos.logback.core.joran.spi.Pattern;
+import ch.qos.logback.core.joran.spi.RuleStore;
+
+/**
+ * A minimal configurator extending GenericConfigurator.
+ *
+ * @author Ceki Gücü
+ *
+ */
+public class SimpleConfigurator extends GenericConfigurator {
+
+ final Map<Pattern, Action> ruleMap;
+ final List<ImplicitAction> iaList;
+
+ public SimpleConfigurator(Map<Pattern, Action> ruleMap) {
+ this(ruleMap, null);
+ }
+
+ public SimpleConfigurator(Map<Pattern, Action> ruleMap, List<ImplicitAction> iaList) {
+ this.ruleMap = ruleMap;
+ this.iaList = iaList;
+ }
+
+ @Override
+ protected void addInstanceRules(RuleStore rs) {
+ for (Pattern pattern : ruleMap.keySet()) {
+ Action action = ruleMap.get(pattern);
+ rs.addRule(pattern, action);
+ }
+ }
+
+ @Override
+ protected void addImplicitRules(Interpreter interpreter) {
+ if(iaList == null) {
+ return;
+ }
+ for (ImplicitAction ia : iaList) {
+ interpreter.addImplicitAction(ia);
+ }
+ }
+
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/AddAction.java b/logback-examples/src/main/java/chapters/onJoran/calculator/AddAction.java
new file mode 100644
index 0000000..c58f6f5
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/AddAction.java
@@ -0,0 +1,69 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran.calculator;
+
+import java.util.EmptyStackException;
+
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+
+
+/**
+ * This action adds the two integers at the top of the stack (they are removed)
+ * and pushes the result to the top the stack.
+ *
+ * @author Ceki Gülcü
+ */
+public class AddAction extends Action {
+
+ public void begin(InterpretationContext ic, String name, Attributes attributes) {
+ int first = fetchInteger(ic);
+ int second = fetchInteger(ic);
+ // Push the result of the addition for the following actions.
+ ic.pushObject(new Integer(first + second));
+ }
+
+ /**
+ * Pop the Integer object at the top of the stack.
+ * This code also illustrates usage of Joran's error handling paradigm.
+ */
+ int fetchInteger(InterpretationContext ic) {
+ int result = 0;
+
+ try {
+ // Pop the object at the top of the interpretation context's stack.
+ Object o1 = ic.popObject();
+
+ if (o1 instanceof Integer) {
+ result = ((Integer) o1).intValue();
+ } else {
+ String errMsg =
+ "Object [" + o1
+ + "] currently at the top of the stack is not an integer.";
+ ic.addError(errMsg);
+ throw new IllegalArgumentException(errMsg);
+ }
+ } catch (EmptyStackException ese) {
+ ic.addError(("Expecting an integer on the execution stack."));
+ throw ese;
+ }
+ return result;
+ }
+
+ public void end(InterpretationContext ic, String name) {
+ // Nothing to do here.
+ }
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator1.java b/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator1.java
new file mode 100644
index 0000000..e3444cf
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator1.java
@@ -0,0 +1,55 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran.calculator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.ContextBase;
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.spi.Pattern;
+import ch.qos.logback.core.util.StatusPrinter;
+import chapters.onJoran.SimpleConfigurator;
+
+/**
+ * This examples illustrates collaboration between multiple actions through the
+ * common execution context stack.
+ *
+ * @author Ceki Güulcü
+ */
+public class Calculator1 {
+
+ public static void main(String[] args) throws Exception {
+ Context context = new ContextBase();
+
+ Map<Pattern, Action> ruleMap = new HashMap<Pattern, Action>();
+
+ // Associate "/computation" pattern with ComputationAction1
+ ruleMap.put(new Pattern("/computation"), new ComputationAction1());
+
+ // Other associations
+ ruleMap.put(new Pattern("/computation/literal"), new LiteralAction());
+ ruleMap.put(new Pattern("/computation/add"), new AddAction());
+ ruleMap.put(new Pattern("/computation/multiply"), new MultiplyAction());
+
+ SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap);
+ // link the configurator with its context
+ simpleConfigurator.setContext(context);
+
+ simpleConfigurator.doConfigure(args[0]);
+ // Print any errors that might have occured.
+ StatusPrinter.print(context);
+ }
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator2.java b/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator2.java
new file mode 100644
index 0000000..1a637ce
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/Calculator2.java
@@ -0,0 +1,64 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran.calculator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.ContextBase;
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.spi.JoranException;
+import ch.qos.logback.core.joran.spi.Pattern;
+import ch.qos.logback.core.util.StatusPrinter;
+import chapters.onJoran.SimpleConfigurator;
+
+
+/**
+ * This examples illustrates collaboration between multiple actions through the
+ * common execution context stack.
+ *
+ * It differs from Calculator1 in that it supports arbitrary nesting of
+ * computation elements.
+ *
+ * You can test this application with the sample XML file <em>calculator3.xml</em>.
+ *
+ * @author Ceki Güulcü
+ */
+public class Calculator2 {
+ public static void main(String[] args) throws Exception {
+ Map<Pattern, Action> ruleMap = new HashMap<Pattern, Action>();
+
+
+ // Note the wild card character '*', in the paterns, signifying any level
+ // of nesting.
+ ruleMap.put(new Pattern("*/computation"), new ComputationAction2());
+
+ ruleMap.put(new Pattern("*/computation/literal"), new LiteralAction());
+ ruleMap.put(new Pattern("*/computation/add"), new AddAction());
+ ruleMap.put(new Pattern("*/computation/multiply"), new MultiplyAction());
+
+ Context context = new ContextBase();
+ SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap);
+ // link the configurator with its context
+ simpleConfigurator.setContext(context);
+
+ try {
+ simpleConfigurator.doConfigure(args[0]);
+ } catch (JoranException e) {
+ // Print any errors that might have occured.
+ StatusPrinter.print(context);
+ }
+ }
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction1.java b/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction1.java
new file mode 100644
index 0000000..a71c652
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction1.java
@@ -0,0 +1,61 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran.calculator;
+
+
+
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+import ch.qos.logback.core.util.OptionHelper;
+
+
+/**
+ * ComputationAction1 will print the result of the compuration made by
+ * children elements but only if the compuration itself is named, that is if the
+ * name attribute of the associated computation element is not null. In other
+ * words, anonymous computations will not print their result.
+ *
+ * @author Ceki Gülcü
+ */
+public class ComputationAction1 extends Action {
+ public static String NAME_ATR = "name";
+
+ String nameStr;
+
+ /**
+ * Store the value of the name attribute for future use.
+ */
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ nameStr = attributes.getValue(NAME_ATR);
+ }
+
+ /**
+ * Children elements have been processed. The sesults should be an integer
+ * placed at the top of the execution stack.
+ *
+ * This value will be printed on the console but only if the action is
+ * named. Anonymous computation will not print their result.
+ */
+ public void end(InterpretationContext ec, String name) {
+ if (OptionHelper.isEmpty(nameStr)) {
+ // nothing to do
+ } else {
+ Integer i = (Integer) ec.peekObject();
+ System.out.println(
+ "The computation named [" + nameStr + "] resulted in the value " + i);
+ }
+ }
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction2.java b/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction2.java
new file mode 100644
index 0000000..ed32c45
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/ComputationAction2.java
@@ -0,0 +1,86 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran.calculator;
+
+import java.util.Stack;
+
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+import ch.qos.logback.core.util.OptionHelper;
+
+
+/**
+ * ComputationAction2 will print the result of the compuration made by
+ * children elements but only if the computation itself is named, that is if the
+ * name attribute of the associated computation element is not null. In other
+ * words, anonymous computations will not print their result.
+ *
+ * ComputationAction2 differs from ComputationAction1 in its handling of
+ * instance variables. ComputationAction1 has a simple <Code>nameStr</code>
+ * instance variable. This variable is set when the begin() method is called
+ * and then later used within the end() method.
+ *
+ * This simple approach works properly if the begin() and end()
+ * method of a given action are expected to be called in sequence. However,
+ * there are situations where the begin() method of the same action instance is
+ * invoked multiple times before the matching end() method is invoked.
+ *
+ * When this happens, the second call to begin() overwrites values set by
+ * the first invocation to begin(). The solution is to save parameter values
+ * into a separate stack. The well-formedness of XML will guarantee that a value
+ * saved by one begin() will be consumed only by the matching end() method.
+ *
+ * Note that in the vast majority of cases there is no need to resort to a
+ * separate stack for each variable. The situation of successive begin()
+ * invocations can only occur if:
+ *
+ * 1) the associated pattern contains a wildcard, i.e. the * character
+ *
+ * and
+ *
+ * 2) the associated element tag can contain itself as a child
+ *
+ * For example, "*/computation" pattern means that computations can contain
+ * other computation elements as children.
+ *
+ * @author Ceki Gülcü
+ */
+public class ComputationAction2 extends Action {
+ public static String NAME_ATR = "name";
+
+ Stack<String> nameStrStack = new Stack<String>();
+
+
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ String nameStr = attributes.getValue(NAME_ATR);
+ // save nameStr value in a special stack. Note that the value is saved
+ // even if it is empty or null.
+ nameStrStack.push(nameStr);
+ }
+
+ public void end(InterpretationContext ec, String name) {
+ // pop nameStr value from the special stack
+ String nameStr = (String) nameStrStack.pop();
+
+ if (OptionHelper.isEmpty(nameStr)) {
+ // nothing to do
+ } else {
+ Integer i = (Integer) ec.peekObject();
+ System.out.println(
+ "The computation named [" + nameStr + "] resulted in the value " + i);
+ }
+ }
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/LiteralAction.java b/logback-examples/src/main/java/chapters/onJoran/calculator/LiteralAction.java
new file mode 100644
index 0000000..d56c3a4
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/LiteralAction.java
@@ -0,0 +1,58 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran.calculator;
+
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+import ch.qos.logback.core.util.OptionHelper;
+
+/**
+ * This action converts the value attribute of the associated element to an
+ * integer and pushes the resulting Integer object on top of the execution
+ * context stack.
+ *
+ * <p>It also illustrates usage of Joran's error reporting/handling paradigm.
+ *
+ * @author Ceki Gülcü
+ */
+public class LiteralAction extends Action {
+ public static String VALUE_ATR = "value";
+
+ public void begin(InterpretationContext ic, String name, Attributes attributes) {
+ String valueStr = attributes.getValue(VALUE_ATR);
+
+ if (OptionHelper.isEmpty(valueStr)) {
+ ic.addError("The literal action requires a value attribute");
+ return;
+ }
+
+ try {
+ Integer i = Integer.valueOf(valueStr);
+ ic.pushObject(i);
+ } catch (NumberFormatException nfe) {
+ ic.addError("The value [" + valueStr
+ + "] could not be converted to an Integer", nfe);
+ throw nfe;
+ }
+ }
+
+ public void end(InterpretationContext ic, String name) {
+ // Nothing to do here.
+ // In general, the end() method of actions associated with elements
+ // having no children do not need to perform any processing in their
+ // end() method.
+ }
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/MultiplyAction.java b/logback-examples/src/main/java/chapters/onJoran/calculator/MultiplyAction.java
new file mode 100644
index 0000000..2b2ae95
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/MultiplyAction.java
@@ -0,0 +1,66 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran.calculator;
+
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+
+import java.util.EmptyStackException;
+
+/**
+ *
+ * This action multiplies the two integers at the top of the stack (they are
+ * removed) and pushes the result on top the stack.
+ *
+ * @author Ceki Gülcü
+ */
+public class MultiplyAction extends Action {
+
+ public void begin(InterpretationContext ic, String name, Attributes attributes) {
+ int first = fetchInteger(ic);
+ int second = fetchInteger(ic);
+ ic.pushObject(new Integer(first * second));
+ }
+
+ /**
+ * Pop the Integer object at the top of the stack. This code illustrates usage
+ * of Joran's error handling paradigm.
+ */
+ int fetchInteger(InterpretationContext ic) {
+ int result = 0;
+
+ try {
+ Object o1 = ic.popObject();
+
+ if (o1 instanceof Integer) {
+ result = ((Integer) o1).intValue();
+ } else {
+ String errMsg = "Object [" + o1
+ + "] currently at the top of the stack is not an integer.";
+ ic.addError(errMsg);
+ throw new IllegalArgumentException(errMsg);
+ }
+ } catch (EmptyStackException ese) {
+ ic.addError("Expecting an integer on the execution stack.");
+ throw ese;
+ }
+ return result;
+ }
+
+ public void end(InterpretationContext ic, String name) {
+ // Nothing to do here.
+ }
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/calculator1.xml b/logback-examples/src/main/java/chapters/onJoran/calculator/calculator1.xml
new file mode 100644
index 0000000..111db47
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/calculator1.xml
@@ -0,0 +1,3 @@
+<computation name="total">
+ <literal value="3"/>
+</computation>
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/calculator2.xml b/logback-examples/src/main/java/chapters/onJoran/calculator/calculator2.xml
new file mode 100644
index 0000000..4a96c62
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/calculator2.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE computation>
+
+<computation name="toto">
+ <literal value="7"/>
+ <literal value="3"/>
+ <add/>
+ <literal value="3"/>
+ <multiply/>
+</computation>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/calculator3.xml b/logback-examples/src/main/java/chapters/onJoran/calculator/calculator3.xml
new file mode 100644
index 0000000..837c513
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/calculator3.xml
@@ -0,0 +1,15 @@
+<!-- This file is intended to be executed by Caculator2.
+ It is not suited for Calculator1 due to nested computation
+ elements.
+ -->
+
+<computation name="toto">
+ <computation>
+ <literal value="7"/>
+ <literal value="3"/>
+ <add/>
+ </computation>
+
+ <literal value="3"/>
+ <multiply/>
+</computation>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/onJoran/calculator/readme.txt b/logback-examples/src/main/java/chapters/onJoran/calculator/readme.txt
new file mode 100644
index 0000000..a0d9621
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/calculator/readme.txt
@@ -0,0 +1,7 @@
+This directory contains the the calculator example. It shows how Actions can
+collaborate in order to accomplish a simple computation.
+
+For further information, please refer to
+
+ http://logback.qos.ch/manual/onJoran.html#calculator
+
diff --git a/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorld.java b/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorld.java
new file mode 100644
index 0000000..6b9f3e5
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorld.java
@@ -0,0 +1,48 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran.helloWorld;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.ContextBase;
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.spi.Pattern;
+import ch.qos.logback.core.util.StatusPrinter;
+import chapters.onJoran.SimpleConfigurator;
+
+/**
+ *
+ * A hello world example using Joran.
+ *
+ * @author Ceki Gulcu
+ */
+public class HelloWorld {
+ public static void main(String[] args) throws Exception {
+ Map<Pattern, Action> ruleMap = new HashMap<Pattern, Action>();
+
+ // Associate "hello-world" pattern with HelloWorldAction
+ ruleMap.put(new Pattern("hello-world"), new HelloWorldAction());
+
+ // Joran needs to work within a context.
+ Context context = new ContextBase();
+ SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap);
+ // link the configurator with its context
+ simpleConfigurator.setContext(context);
+
+ simpleConfigurator.doConfigure(args[0]);
+ StatusPrinter.print(context);
+ }
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorldAction.java b/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorldAction.java
new file mode 100644
index 0000000..aecc201
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/helloWorld/HelloWorldAction.java
@@ -0,0 +1,35 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran.helloWorld;
+
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+
+/**
+ * A trivial action that writes "Hello world" on the console.
+ *
+ * See the {@link HelloWorld} class for integration with Joran.
+ *
+ * @author Ceki Gülcü
+ */
+public class HelloWorldAction extends Action {
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ System.out.println("Hello World");
+ }
+
+ public void end(InterpretationContext ec, String name) {
+ }
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/helloWorld/hello.xml b/logback-examples/src/main/java/chapters/onJoran/helloWorld/hello.xml
new file mode 100644
index 0000000..7d764cd
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/helloWorld/hello.xml
@@ -0,0 +1,2 @@
+<hello-world>
+</hello-world>
diff --git a/logback-examples/src/main/java/chapters/onJoran/helloWorld/readme.txt b/logback-examples/src/main/java/chapters/onJoran/helloWorld/readme.txt
new file mode 100644
index 0000000..c96bb14
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/helloWorld/readme.txt
@@ -0,0 +1,6 @@
+The example illustrates the minimal plumbing required for using Joran.
+
+For further explanations, please refer to
+
+ http://logback.qos.ch/manual/onJoran.html#helloWorld
+
diff --git a/logback-examples/src/main/java/chapters/migrationFromLog4j/Log4jMain.java b/logback-examples/src/main/java/chapters/onJoran/implicit/NOPAction.java
similarity index 54%
copy from logback-examples/src/main/java/chapters/migrationFromLog4j/Log4jMain.java
copy to logback-examples/src/main/java/chapters/onJoran/implicit/NOPAction.java
index 281fd6e..ce8c0db 100644
--- a/logback-examples/src/main/java/chapters/migrationFromLog4j/Log4jMain.java
+++ b/logback-examples/src/main/java/chapters/onJoran/implicit/NOPAction.java
@@ -11,24 +11,24 @@
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
-package chapters.migrationFromLog4j;
+package chapters.onJoran.implicit;
+
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
-import org.apache.log4j.Logger;
-import org.apache.log4j.PropertyConfigurator;
/**
- * A minimal application making use of log4j and TrivialLog4jAppender.
- *
+ * No operation (NOP) action that does strictly nothing.
+ *
* @author Ceki Gülcü
- *
*/
-public class Log4jMain {
-
- static Logger logger = Logger.getLogger(Log4jMain.class);
-
- public static void main(String[] args) {
- PropertyConfigurator.configure("src/main/java/chapter11/log4jTrivial.properties");
- logger.debug("Hello world");
+public class NOPAction extends Action {
+
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
}
+ public void end(InterpretationContext ec, String name) {
+ }
}
diff --git a/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMe.java b/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMe.java
new file mode 100644
index 0000000..3e007a8
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMe.java
@@ -0,0 +1,61 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran.implicit;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.ContextBase;
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.action.ImplicitAction;
+import ch.qos.logback.core.joran.spi.Pattern;
+import ch.qos.logback.core.util.StatusPrinter;
+import chapters.onJoran.SimpleConfigurator;
+
+/**
+ * This example illustrates the usage of implicit actions.
+ *
+ * <p>Keep in mind that implicit actions are not associated with any specific
+ * pattern. Moreover, they are added directly to a Joran Interpreter instead of
+ * a rule store.
+ *
+ * @author Ceki Güulcü
+ */
+public class PrintMe {
+
+ public static void main(String[] args) throws Exception {
+ Context context = new ContextBase();
+
+ Map<Pattern, Action> ruleMap = new HashMap<Pattern, Action>();
+
+ // we start with the rule for the top-most (root) element
+ ruleMap.put(new Pattern("*/foo"), new NOPAction());
+
+ // Add an implicit action.
+ List<ImplicitAction> iaList = new ArrayList<ImplicitAction>();
+ iaList.add(new PrintMeImplicitAction());
+ SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap,
+ iaList);
+
+ // link the configurator with its context
+ simpleConfigurator.setContext(context);
+
+ simpleConfigurator.doConfigure(args[0]);
+ StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+
+ }
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMeImplicitAction.java b/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMeImplicitAction.java
new file mode 100644
index 0000000..e708619
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/implicit/PrintMeImplicitAction.java
@@ -0,0 +1,44 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran.implicit;
+
+import org.xml.sax.Attributes;
+
+import ch.qos.logback.core.joran.action.ImplicitAction;
+import ch.qos.logback.core.joran.spi.InterpretationContext;
+import ch.qos.logback.core.joran.spi.Pattern;
+
+/**
+ *
+ * A rather trivial implicit action which is applicable if an element has a
+ * printme attribute set to true.
+ *
+ * @author Ceki Gülcü
+ */
+public class PrintMeImplicitAction extends ImplicitAction {
+
+ public boolean isApplicable(Pattern pattern, Attributes attributes,
+ InterpretationContext ec) {
+ String printmeStr = attributes.getValue("printme");
+
+ return Boolean.valueOf(printmeStr).booleanValue();
+ }
+
+ public void begin(InterpretationContext ec, String name, Attributes attributes) {
+ System.out.println("Element [" + name + "] asked to be printed.");
+ }
+
+ public void end(InterpretationContext ec, String name) {
+ }
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/implicit/implicit1.xml b/logback-examples/src/main/java/chapters/onJoran/implicit/implicit1.xml
new file mode 100644
index 0000000..54fe4d9
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/implicit/implicit1.xml
@@ -0,0 +1,21 @@
+<foo>
+
+ <!-- These elements will print due to the implicit rule -->
+ <xyz printme="true">
+ <abc printme="true"/>
+ </xyz>
+
+ <!-- This element has no associated rule and no implicit rule
+ applies for it because the printme attribute is not set. -->
+ <xyz/>
+
+
+
+ <!-- This element will not be printed even if its printme
+ attribute is set because implicit rules are invoked only
+ if no explicit rule matches the element. The */foo rule
+ matches the following element.
+ -->
+ <foo printme="true"/>
+
+</foo>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/onJoran/implicit/readme.txt b/logback-examples/src/main/java/chapters/onJoran/implicit/readme.txt
new file mode 100644
index 0000000..ad5fc94
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/implicit/readme.txt
@@ -0,0 +1,7 @@
+
+This directory contains an example illustrating implicit actions.
+
+For further information, please refer to
+
+ http://logback.qos.ch/manual/onJoran.html#implicit
+
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/onJoran/newRule/NewRuleCalculator.java b/logback-examples/src/main/java/chapters/onJoran/newRule/NewRuleCalculator.java
new file mode 100644
index 0000000..7585155
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/newRule/NewRuleCalculator.java
@@ -0,0 +1,63 @@
+/**
+ * Logback: the reliable, generic, fast and flexible logging framework.
+ * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
+ *
+ * This program and the accompanying materials are dual-licensed under
+ * either the terms of the Eclipse Public License v1.0 as published by
+ * the Eclipse Foundation
+ *
+ * or (per the licensee's choosing)
+ *
+ * under the terms of the GNU Lesser General Public License version 2.1
+ * as published by the Free Software Foundation.
+ */
+package chapters.onJoran.newRule;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import ch.qos.logback.core.Context;
+import ch.qos.logback.core.ContextBase;
+import ch.qos.logback.core.joran.action.Action;
+import ch.qos.logback.core.joran.action.NewRuleAction;
+import ch.qos.logback.core.joran.spi.Pattern;
+import ch.qos.logback.core.util.StatusPrinter;
+import chapters.onJoran.SimpleConfigurator;
+import chapters.onJoran.calculator.ComputationAction1;
+
+/**
+ * This example illustrates the usage of NewRuleAction which allows the Joran
+ * interpreter to learn new rules on the fly.
+ *
+ * <p>This example relies heavily on the code from the joran.calculator
+ * package.
+ *
+ * @author Ceki Güulcü
+ */
+public class NewRuleCalculator {
+ public static void main(String[] args) throws Exception {
+
+ Context context = new ContextBase();
+
+ Map<Pattern, Action> ruleMap = new HashMap<Pattern, Action>();
+
+ // we start with the rule for the top-most (root) element
+ ruleMap.put(new Pattern("*/computation"), new ComputationAction1());
+
+ // Associate "/new-rule" pattern with NewRuleAction from the
+ // org.apache.joran.action package.
+ //
+ // We will let the XML file to teach the Joran interpreter about new rules
+ ruleMap.put(new Pattern("/computation/new-rule"), new NewRuleAction());
+
+ SimpleConfigurator simpleConfigurator = new SimpleConfigurator(ruleMap);
+ // link the configurator with its context
+ simpleConfigurator.setContext(context);
+
+ simpleConfigurator.doConfigure(args[0]);
+
+ // Print any errors that might have occured.
+ StatusPrinter.printInCaseOfErrorsOrWarnings(context);
+ }
+
+}
diff --git a/logback-examples/src/main/java/chapters/onJoran/newRule/new-rule.xml b/logback-examples/src/main/java/chapters/onJoran/newRule/new-rule.xml
new file mode 100644
index 0000000..8416bc4
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/newRule/new-rule.xml
@@ -0,0 +1,23 @@
+<!--
+ This file is intended to be executed by NewRuleCalculator.
+ Note that the rules for adding and multiplying are learned on
+ the fly, while parsingthis file.
+-->
+
+<computation name="toto">
+ <new-rule pattern="*/computation/literal"
+ actionClass="chapters.onJoran.calculator.LiteralAction"/>
+ <new-rule pattern="*/computation/add"
+ actionClass="chapters.onJoran.calculator.AddAction"/>
+ <new-rule pattern="*/computation/multiply"
+ actionClass="chapters.onJoran.calculator.MultiplyAction"/>
+
+ <computation>
+ <literal value="7"/>
+ <literal value="3"/>
+ <add/>
+ </computation>
+
+ <literal value="3"/>
+ <multiply/>
+</computation>
\ No newline at end of file
diff --git a/logback-examples/src/main/java/chapters/onJoran/newRule/readme.txt b/logback-examples/src/main/java/chapters/onJoran/newRule/readme.txt
new file mode 100644
index 0000000..fb7a5ca
--- /dev/null
+++ b/logback-examples/src/main/java/chapters/onJoran/newRule/readme.txt
@@ -0,0 +1,8 @@
+
+This directory contains an example showing how Joran can
+learn new parsing rules on the fly.
+
+For further documentation please see
+
+ http://logback.qos.ch/manual/onJoran.html#newRule
+
diff --git a/logback-site/src/site/pages/faq.html b/logback-site/src/site/pages/faq.html
index de18525..d5ab5b9 100644
--- a/logback-site/src/site/pages/faq.html
+++ b/logback-site/src/site/pages/faq.html
@@ -322,7 +322,7 @@
place the file <em>logback.xml</em> under the
<em>$JETTY_HOME/resources</em> directory. You can find
sample configuration files in the
- <em>logback-examples/src/main/java/chapter4/conf/</em>
+ <em>logback-examples/src/main/java/chapters/appenders/conf/</em>
folder shipping within the logback distribution.
</p>
diff --git a/logback-site/src/site/pages/index.html b/logback-site/src/site/pages/index.html
index 495c196..f9942ce 100644
--- a/logback-site/src/site/pages/index.html
+++ b/logback-site/src/site/pages/index.html
@@ -62,6 +62,8 @@
<li><a href="http://www.jfrog.org/products.php">Artifactory</a></li>
+ <li><a href="http://www.geomajas.org/">Geomajas</a></li>
+
<li><a href="http://code.google.com/p/openmeetings/">OpenMeetings</a></li>
<li><a href="http://liftweb.net/">Lift</a></li>
@@ -72,8 +74,8 @@
<li><a
href="http://static.springsource.org/s2-dmserver/2.0.x/user-guide/htmlsingle/user…">SpringSource
dm Server</a></li>
-
+ </ul>
<script src="templates/footer.js" type="text/javascript"></script>
</div>
diff --git a/logback-site/src/site/pages/manual/appenders.html b/logback-site/src/site/pages/manual/appenders.html
index f36f1d3..2469859 100644
--- a/logback-site/src/site/pages/manual/appenders.html
+++ b/logback-site/src/site/pages/manual/appenders.html
@@ -3363,7 +3363,7 @@ logger.debug("Alice says hello"); </p>
<em>Example 4.<span class="autoExec"/>:
<code>CountingConsoleAppender</code>
(logback-examples/src/main/java/chapters/appenders/CountingConsoleAppender.java)</em>
- <pre class="prettyprint source">package chapter4;
+ <pre class="prettyprint source">package chapters.appenders;
import ch.qos.logback.core.AppenderBase;
import ch.qos.logback.core.Layout;
diff --git a/logback-site/src/site/pages/manual/filters.html b/logback-site/src/site/pages/manual/filters.html
index 46a2f68..716c3f2 100644
--- a/logback-site/src/site/pages/manual/filters.html
+++ b/logback-site/src/site/pages/manual/filters.html
@@ -105,8 +105,8 @@
events, the value NEUTRAL is returned.
</p>
-<em>Example 6.<span class="autoEx"/>: Basic custom filter (<a href="../xref/chapter6/SampleFilter.html">logback-examples/src/main/java/chapter6/SampleFilter.java</a>)</em>
-<pre class="prettyprint source">package chapter6;
+<em>Example 6.<span class="autoEx"/>: Basic custom filter (<a href="../xref/chapters/filters/SampleFilter.html">logback-examples/src/main/java/chapters/filters/SampleFilter.java</a>)</em>
+<pre class="prettyprint source">package chapters.filters;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
@@ -128,11 +128,11 @@ public class SampleFilter extends Filter>ILoggingEvent> {
<code>SampleFilter</code> to a <code>ConsoleAppener</code>.
</p>
-<em>Example 6.<span class="autoEx"/>: SampleFilter configuration (logback-examples/src/main/java/chapter6/SampleFilterConfig.xml)</em>
+<em>Example 6.<span class="autoEx"/>: SampleFilter configuration (logback-examples/src/main/java/chapters/filters/SampleFilterConfig.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <b><Filter class="chapter6.SampleFilter" /></b>
+ <b><Filter class="chapters.filters.SampleFilter" /></b>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>
@@ -183,7 +183,7 @@ public class SampleFilter extends Filter>ILoggingEvent> {
configuration file.
</p>
-<em>Example 6.<span class="autoEx"/>: Sample LevelFilter configuration (logback-examples/src/main/java/chapter6/levelFilterConfig.xml)</em>
+<em>Example 6.<span class="autoEx"/>: Sample LevelFilter configuration (logback-examples/src/main/java/chapters/filters/levelFilterConfig.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="CONSOLE"
class="ch.qos.logback.core.ConsoleAppender">
@@ -215,7 +215,7 @@ public class SampleFilter extends Filter>ILoggingEvent> {
configuration file.
</p>
-<em>Example 6.<span class="autoEx"/>: Sample ThresholdFilter configuration (logback-examples/src/main/java/chapter6/thresholdFilterConfig.xml)</em>
+<em>Example 6.<span class="autoEx"/>: Sample ThresholdFilter configuration (logback-examples/src/main/java/chapters/filters/thresholdFilterConfig.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="CONSOLE"
class="ch.qos.logback.core.ConsoleAppender">
@@ -393,7 +393,7 @@ public class SampleFilter extends Filter>ILoggingEvent> {
<p>Here is a concrete example.</p>
-<em>Example 6.<span class="autoEx"/>: Basic event evaluator usage (logback-examples/src/main/java/chapter6/basicEventEvaluator.xml)</em>
+<em>Example 6.<span class="autoEx"/>: Basic event evaluator usage (logback-examples/src/main/java/chapters/filters/basicEventEvaluator.xml)</em>
<pre class="prettyprint source longline"><configuration>
@@ -444,27 +444,27 @@ public class SampleFilter extends Filter>ILoggingEvent> {
</p>
<p>The <a
- href="../xref/chapter6/FilterEvents.html"><code>FilterEvents</code></a>
+ href="../xref/chapters/filters/FilterEvents.html"><code>FilterEvents</code></a>
application issues ten logging requests, numbered 0 to 9. Let us
first run <code>FilterEvents</code> class without any filters:
</p>
<div class="source"><pre>
-java chapter6.FilterEvents src/main/java/chapter6/basicConfiguration.xml
+java chapters.filters.FilterEvents src/main/java/chapters/filters/basicConfiguration.xml
</pre></div>
<p>All requests will be displayed, as shown below:</p>
-<div class="source"><pre>0 [main] INFO chapter6.FilterEvents - logging statement 0
-0 [main] INFO chapter6.FilterEvents - logging statement 1
-0 [main] INFO chapter6.FilterEvents - logging statement 2
-0 [main] DEBUG chapter6.FilterEvents - logging statement 3
-0 [main] INFO chapter6.FilterEvents - logging statement 4
-0 [main] INFO chapter6.FilterEvents - logging statement 5
-0 [main] ERROR chapter6.FilterEvents - <b>billing statement 6</b>
-0 [main] INFO chapter6.FilterEvents - logging statement 7
-0 [main] INFO chapter6.FilterEvents - logging statement 8
-0 [main] INFO chapter6.FilterEvents - logging statement 9</pre></div>
+<div class="source"><pre>0 [main] INFO chapters.filters.FilterEvents - logging statement 0
+0 [main] INFO chapters.filters.FilterEvents - logging statement 1
+0 [main] INFO chapters.filters.FilterEvents - logging statement 2
+0 [main] DEBUG chapters.filters.FilterEvents - logging statement 3
+0 [main] INFO chapters.filters.FilterEvents - logging statement 4
+0 [main] INFO chapters.filters.FilterEvents - logging statement 5
+0 [main] ERROR chapters.filters.FilterEvents - <b>billing statement 6</b>
+0 [main] INFO chapters.filters.FilterEvents - logging statement 7
+0 [main] INFO chapters.filters.FilterEvents - logging statement 8
+0 [main] INFO chapters.filters.FilterEvents - logging statement 9</pre></div>
@@ -474,19 +474,19 @@ java chapter6.FilterEvents src/main/java/chapter6/basicConfiguration.xml
precisely the desired outcome.</p>
<p>Running with <em>basicEventEvaluator.xml</em>:</p>
- <p class="source">java chapter6.FilterEvents src/main/java/chapter6/basicEventEvaluator.xml</p>
+ <p class="source">java chapters.filters.FilterEvents src/main/java/chapters/filters/basicEventEvaluator.xml</p>
<p>we obtain:
</p>
- <p class="source">0 [main] INFO chapter6.FilterEvents - logging statement 0
-0 [main] INFO chapter6.FilterEvents - logging statement 1
-0 [main] INFO chapter6.FilterEvents - logging statement 2
-0 [main] DEBUG chapter6.FilterEvents - logging statement 3
-0 [main] INFO chapter6.FilterEvents - logging statement 4
-0 [main] INFO chapter6.FilterEvents - logging statement 5
-0 [main] INFO chapter6.FilterEvents - logging statement 7
-0 [main] INFO chapter6.FilterEvents - logging statement 8
-0 [main] INFO chapter6.FilterEvents - logging statement 9</p>
+ <p class="source">0 [main] INFO chapters.filters.FilterEvents - logging statement 0
+0 [main] INFO chapters.filters.FilterEvents - logging statement 1
+0 [main] INFO chapters.filters.FilterEvents - logging statement 2
+0 [main] DEBUG chapters.filters.FilterEvents - logging statement 3
+0 [main] INFO chapters.filters.FilterEvents - logging statement 4
+0 [main] INFO chapters.filters.FilterEvents - logging statement 5
+0 [main] INFO chapters.filters.FilterEvents - logging statement 7
+0 [main] INFO chapters.filters.FilterEvents - logging statement 8
+0 [main] INFO chapters.filters.FilterEvents - logging statement 9</p>
<h2><a name="matcher" href="#matcher">Matchers</a></h2>
@@ -502,7 +502,7 @@ java chapter6.FilterEvents src/main/java/chapter6/basicConfiguration.xml
<p>An example should clarify the point:</p>
-<em>Example 6.<span class="autoEx"/>: Defining matchers in an event evaluator (logback-examples/src/main/java/chapter6/evaluatorWithMatcher.xml)</em>
+<em>Example 6.<span class="autoEx"/>: Defining matchers in an event evaluator (logback-examples/src/main/java/chapters/filters/evaluatorWithMatcher.xml)</em>
<pre class="prettyprint source"><configuration debug="true">
@@ -531,15 +531,15 @@ java chapter6.FilterEvents src/main/java/chapter6/basicConfiguration.xml
</configuration></pre>
<p>Running with <em>evaluatorWithMatcher.xml</em>:</p>
- <p class="source">java chapter6.FilterEvents src/main/java/chapter6/evaluatorWithMatcher.xml</p>
+ <p class="source">java chapters.filters.FilterEvents src/main/java/chapters/filters/evaluatorWithMatcher.xml</p>
<p>we obtain:
</p>
- <p class="source">260 [main] INFO chapter6.FilterEvents - logging statement 0
-264 [main] INFO chapter6.FilterEvents - logging statement 2
-264 [main] INFO chapter6.FilterEvents - logging statement 4
-266 [main] ERROR chapter6.FilterEvents - billing statement 6
-266 [main] INFO chapter6.FilterEvents - logging statement 8</p>
+ <p class="source">260 [main] INFO chapters.filters.FilterEvents - logging statement 0
+264 [main] INFO chapters.filters.FilterEvents - logging statement 2
+264 [main] INFO chapters.filters.FilterEvents - logging statement 4
+266 [main] ERROR chapters.filters.FilterEvents - billing statement 6
+266 [main] INFO chapters.filters.FilterEvents - logging statement 8</p>
<p>In case you need to define additional matchers, you can do so by
adding further <code><matcher></code> elements.</p>
@@ -587,8 +587,8 @@ java chapter6.FilterEvents src/main/java/chapter6/basicConfiguration.xml
slightly more complex filter:
</p>
-<em>Example 6.<span class="autoEx"/>: Basic custom <code>TurboFilter</code> (<a href="../xref/chapter6/SampleTurboFilter.html">logback-examples/src/main/java/chapter6/SampleTurboFilter.java</a>)</em>
-<pre class="prettyprint source">package chapter6;
+<em>Example 6.<span class="autoEx"/>: Basic custom <code>TurboFilter</code> (<a href="../xref/chapters/filters/SampleTurboFilter.html">logback-examples/src/main/java/chapters/filters/SampleTurboFilter.java</a>)</em>
+<pre class="prettyprint source">package chapters.filters;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
@@ -652,9 +652,9 @@ public class SampleTurboFilter extends TurboFilter {
created <code>TurboFilter</code>.
</p>
-<em>Example 6.<span class="autoEx"/>: Basic custom <code>TurboFilter</code> configuration (logback-examples/src/main/java/chapter6/sampleTurboFilterConfig.xml)</em>
+<em>Example 6.<span class="autoEx"/>: Basic custom <code>TurboFilter</code> configuration (logback-examples/src/main/java/chapters/filters/sampleTurboFilterConfig.xml)</em>
<pre class="prettyprint source"><configuration>
- <b><turboFilter class="chapter6.SampleTurboFilter">
+ <b><turboFilter class="chapters.filters.SampleTurboFilter">
<Marker>sample</Marker>
</turboFilter></b>
@@ -689,7 +689,7 @@ public class SampleTurboFilter extends TurboFilter {
</p>
<em>Example 6.<span class="autoEx"/>: <code>MDCFilter</code> and <code>MarkerFilter</code>
-configuration (logback-examples/src/main/java/chapter6/turboFilters.xml)</em>
+configuration (logback-examples/src/main/java/chapters/filters/turboFilters.xml)</em>
<pre class="prettyprint source"><configuration>
<turboFilter class="ch.qos.logback.classic.turbo.MDCFilter">
@@ -718,10 +718,10 @@ configuration (logback-examples/src/main/java/chapter6/turboFilters.xml)</em>
following command:
</p>
- <p class="source">java chapter6.FilterEvents src/main/java/chapter6/turboFilters.xml</p>
+ <p class="source">java chapters.filters.FilterEvents src/main/java/chapters/filters/turboFilters.xml</p>
<p>As we've seen previously, the <a
- href="../xref/chapter6/FilterEvents.html"><code>FilterEvents</code></a>
+ href="../xref/chapters/filters/FilterEvents.html"><code>FilterEvents</code></a>
application issues 10 logging requests, numbered 0 to 9. Except
for requests 3 and 6, all of the requests are of level
<em>INFO</em>, the same level as the one assigned to the root
@@ -739,15 +739,15 @@ configuration (logback-examples/src/main/java/chapter6/turboFilters.xml)</em>
configured with <em>turboFilters.xml</em> file shown above is:
</p>
- <p class="source">2006-12-04 15:17:22,859 [main] INFO chapter6.FilterEvents - logging statement 0
-2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 1
-2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 2
-2006-12-04 15:17:22,875 [main] DEBUG chapter6.FilterEvents - logging statement 3
-2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 4
-2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 5
-2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 7
-2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 8
-2006-12-04 15:17:22,875 [main] INFO chapter6.FilterEvents - logging statement 9</p>
+ <p class="source">2006-12-04 15:17:22,859 [main] INFO chapters.filters.FilterEvents - logging statement 0
+2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 1
+2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 2
+2006-12-04 15:17:22,875 [main] DEBUG chapters.filters.FilterEvents - logging statement 3
+2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 4
+2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 5
+2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 7
+2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 8
+2006-12-04 15:17:22,875 [main] INFO chapters.filters.FilterEvents - logging statement 9</p>
<p>One can see that the 3rd request, which should not be displayed
@@ -816,7 +816,7 @@ logger.debug("Hello {}.", name1);</pre>
<em>Example 6.<span class="autoEx"/>: <code>DuplicateMessageFilter</code>
-configuration (logback-examples/src/main/java/chapter6/duplicateMessage.xml)</em>
+configuration (logback-examples/src/main/java/chapters/filters/duplicateMessage.xml)</em>
<pre class="prettyprint source"><configuration>
<b><turboFilter class="ch.qos.logback.classic.turbo.DuplicateMessageFilter"/></b>
@@ -836,12 +836,12 @@ configuration (logback-examples/src/main/java/chapter6/duplicateMessage.xml)</em
configured with <em>duplicateMessage.xml</em> is:
</p>
- <p class="source">2008-12-19 15:04:26,156 [main] INFO chapter6.FilterEvents - logging statement 0
-2008-12-19 15:04:26,156 [main] INFO chapter6.FilterEvents - logging statement 1
-2008-12-19 15:04:26,156 [main] INFO chapter6.FilterEvents - logging statement 2
-2008-12-19 15:04:26,156 [main] INFO chapter6.FilterEvents - logging statement 4
-2008-12-19 15:04:26,156 [main] INFO chapter6.FilterEvents - logging statement 5
-2008-12-19 15:04:26,171 [main] ERROR chapter6.FilterEvents - billing statement 6</p>
+ <p class="source">2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 0
+2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 1
+2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 2
+2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 4
+2008-12-19 15:04:26,156 [main] INFO chapters.filters.FilterEvents - logging statement 5
+2008-12-19 15:04:26,171 [main] ERROR chapters.filters.FilterEvents - billing statement 6</p>
<p>"logging statement 0" is the first <em>occurrence</em> of the
message "logging statement {}". "logging statement 1" is the first
@@ -890,7 +890,7 @@ configuration (logback-examples/src/main/java/chapter6/duplicateMessage.xml)</em
error will be logged:
</p>
-<em>Example 6.<span class="autoEx"/>: Access Evaluator (logback-examples/src/main/java/chapter6/accessEventEvaluator.xml)</em>
+<em>Example 6.<span class="autoEx"/>: Access Evaluator (logback-examples/src/main/java/chapters/filters/accessEventEvaluator.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="STDOUT"
@@ -917,7 +917,7 @@ configuration (logback-examples/src/main/java/chapter6/duplicateMessage.xml)</em
CSS resources. Here is what such a configuration would look like:
</p>
- <em>Example 6.10: Access Evaluator (logback-examples/src/main/java/chapter6/accessEventEvaluator2.xml)</em>
+ <em>Example 6.10: Access Evaluator (logback-examples/src/main/java/chapters/filters/accessEventEvaluator2.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="STDOUT"
diff --git a/logback-site/src/site/pages/manual/jmxConfig.html b/logback-site/src/site/pages/manual/jmxConfig.html
index e7eb933..96eeb39 100644
--- a/logback-site/src/site/pages/manual/jmxConfig.html
+++ b/logback-site/src/site/pages/manual/jmxConfig.html
@@ -70,7 +70,7 @@
<p><a name="jmxConfigurator" href="#jmxConfigurator">Screen-shot
of <code>JMXConfigurator</code> viewed in
<code>jconsole</code></a></p>
- <img src="images/chapter9/jmxConfigurator.gif" alt="jmxConfigurator"/>
+ <img src="images/chapters/jmxConfigurator/jmxConfigurator.gif" alt="jmxConfigurator"/>
<p>Thus, you can</p>
@@ -95,7 +95,7 @@
<p>The status list can help you diagnose logbacks internal
state.</p>
- <img src="images/chapter9/statusList.gif" alt="statusList.gif"/>
+ <img src="images/chapters/jmxConfigurator/statusList.gif" alt="statusList.gif"/>
<h3><a name="leak" href="#leak">Avoiding memory leaks</a></h3>
@@ -176,7 +176,7 @@ public class MyContextListener implements ServletContextListener {
<p>In jconsole's MBeans panel, you would two distinct
<code>JMXConfigurator</code> instances:</p>
- <img src="images/chapter9/multiple.gif" alt="multiple.gif"/>
+ <img src="images/chapters/jmxConfigurator/multiple.gif" alt="multiple.gif"/>
<p>You may fully control the name under which JMXConfigurator is
registered with MBeans server with the help of the "objectName"
@@ -251,7 +251,7 @@ mvn jetty:run</p>
logback's <code>JMXConfigurator</code> via
<code>jconsole</code>.</p>
- <img src="images/chapter9/jconsole15_jetty.gif" alt="jconsole15_jetty.gif"/>
+ <img src="images/chapters/jmxConfigurator/jconsole15_jetty.gif" alt="jconsole15_jetty.gif"/>
<p>After you are connected, you should be able to access
<code>JMXXConfigurator</code> as shown in the <a
@@ -315,7 +315,7 @@ mvn jetty:run</p>
<p>Below is a screen shot view of the MX4J interface.</p>
- <img src="images/chapter9/mx4j_jetty.gif" alt="mx4j_jetty.gif"/>
+ <img src="images/chapters/jmxConfigurator/mx4j_jetty.gif" alt="mx4j_jetty.gif"/>
<!-- ================ Tomcat ================== -->
@@ -338,7 +338,7 @@ mvn jetty:run</p>
<p class="source">jconsole</p>
- <img src="images/chapter9/jconsole15_tomcat.gif" alt="jconsole15_tomcat.gif"/>
+ <img src="images/chapters/jmxConfigurator/jconsole15_tomcat.gif" alt="jconsole15_tomcat.gif"/>
<p>After you are connected, you should be able to access
<code>JMXXConfigurator</code> as shown in the <a
@@ -386,7 +386,7 @@ CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/mx4j-tools.jar</p>
<p>Below is a screen shot view of the MX4J interface.</p>
- <img src="images/chapter9/mx4j_tomcat.gif" alt="mx4j_tomcat.gif"/>
+ <img src="images/chapters/jmxConfigurator/mx4j_tomcat.gif" alt="mx4j_tomcat.gif"/>
diff --git a/logback-site/src/site/pages/manual/layouts.html b/logback-site/src/site/pages/manual/layouts.html
index adacb6b..35e165a 100644
--- a/logback-site/src/site/pages/manual/layouts.html
+++ b/logback-site/src/site/pages/manual/layouts.html
@@ -86,10 +86,10 @@
<p>Here is a possible implementation, authored by the Texan developer:</p>
<em>Example 5.0: Sample implementation of a Layout
- <a href="../xref/chapter5/MySampleLayout.html">
- (logback-examples/src/main/java/chapter5/MySampleLayout.java)</a></em>
+ <a href="../xref/chapters/layouts/MySampleLayout.html">
+ (logback-examples/src/main/java/chapters/layouts/MySampleLayout.java)</a></em>
- <pre class="prettyprint source">package chapter5;
+ <pre class="prettyprint source">package chapters.layouts;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.LayoutBase;
@@ -150,12 +150,12 @@ public class MySampleLayout extends LayoutBase<ILoggingEvent> {
example:</p>
<em>Example 5.0: Configuration of MySampleLayout
- (logback-examples/src/main/java/chapter5/sampleLayoutConfig.xml)</em>
+ (logback-examples/src/main/java/chapters/layouts/sampleLayoutConfig.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
- <b><layout class="chapter5.MySampleLayout" /></b>
+ <b><layout class="chapters.layouts.MySampleLayout" /></b>
</appender>
<root level="debug">
@@ -164,8 +164,8 @@ public class MySampleLayout extends LayoutBase<ILoggingEvent> {
</configuration></pre>
<p>The sample application <a
- href="../xref/chapter5/SampleLogging.html">
- <code>chapter5.SampleLogging</code></a> configures logback with
+ href="../xref/chapters/layouts/SampleLogging.html">
+ <code>chapters.layouts.SampleLogging</code></a> configures logback with
the configuration script supplied as a parameter and then logs a
debug message, followed by an error message. </p>
@@ -174,12 +174,12 @@ public class MySampleLayout extends LayoutBase<ILoggingEvent> {
<em>logback-examples</em> directory.
</p>
- <p class="command">java chapter5.SampleLogging src/main/java/chapter5/sampleLayoutConfig.xml</p>
+ <p class="command">java chapters.layouts.SampleLogging src/main/java/chapters/layouts/sampleLayoutConfig.xml</p>
<p> This will produce:</p>
-<div class="source"><pre>0 DEBUG [main] chapter5.SampleLogging - Everything's going well
-0 ERROR [main] chapter5.SampleLogging - maybe not quite...</pre></div>
+<div class="source"><pre>0 DEBUG [main] chapters.layouts.SampleLogging - Everything's going well
+0 ERROR [main] chapters.layouts.SampleLogging - maybe not quite...</pre></div>
<p>That was simple enough. The skeptic Pyrrho of Elea, who
insists that nothing is certain except perhaps uncertainty itself,
@@ -192,7 +192,7 @@ public class MySampleLayout extends LayoutBase<ILoggingEvent> {
<p>
The
- <a href="../xref/chapter5/MySampleLayout2.html"><code>MySampleLayout2</code>
+ <a href="../xref/chapters/layouts/MySampleLayout2.html"><code>MySampleLayout2</code>
</a>
class contains two attributes. The first one is a prefix that
can be added to the output. The second attribute is used to
@@ -201,7 +201,7 @@ public class MySampleLayout extends LayoutBase<ILoggingEvent> {
</p>
<p>Here is the implementation of this class:</p>
- <pre class="prettyprint source">package chapter5;
+ <pre class="prettyprint source">package chapters.layouts;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.LayoutBase;
@@ -257,7 +257,7 @@ public class MySampleLayout2 extends LayoutBase<ILoggingEvent> {
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
- <layout class="chapter5.MySampleLayout2">
+ <layout class="chapters.layouts.MySampleLayout2">
<b><prefix>MyPrefix</prefix></b>
<b><printThreadName>false</printThreadName></b>
</layout>
@@ -299,10 +299,10 @@ public class MySampleLayout2 extends LayoutBase<ILoggingEvent> {
</p>
<em>
Example 5.1: Sample usage of a PatternLayout
- <a href="../xref/chapter5/PatternSample.html">
- (logback-examples/src/main/java/chapter5/PatternSample.java)</a>
+ <a href="../xref/chapters/layouts/PatternSample.html">
+ (logback-examples/src/main/java/chapters/layouts/PatternSample.java)</a>
</em>
- <pre class="prettyprint source">package chapter5;
+ <pre class="prettyprint source">package chapters.layouts;
import org.slf4j.LoggerFactory;
@@ -1196,11 +1196,11 @@ Caller+2 at mainPackage.ConfigTester.main(ConfigTester.java:38)</pre>
<em>
Example 5.2: Sample usage of EventEvaluators
- (logback-examples/src/main/java/chapter5/callerEvaluatorConfig.xml)
+ (logback-examples/src/main/java/chapters/layouts/callerEvaluatorConfig.xml)
</em>
<pre class="prettyprint source"><configuration>
<b><evaluator name="DISP_CALLER_EVAL">
- <Expression>logger.getName().contains("chapter5") &amp;&amp; \
+ <Expression>logger.getName().contains("chapters.layouts") &amp;&amp; \
message.contains("who calls thee")</Expression>
</evaluator></b>
@@ -1224,11 +1224,11 @@ Caller+2 at mainPackage.ConfigTester.main(ConfigTester.java:38)</pre>
<p><em>
Example 5.2: Sample usage of EventEvaluators
- <a href="../xref/chapter5/CallerEvaluatorExample.html">
- (logback-examples/src/main/java/chapter5/CallerEvaluatorExample.java)</a>
+ <a href="../xref/chapters/layouts/CallerEvaluatorExample.html">
+ (logback-examples/src/main/java/chapters/layouts/CallerEvaluatorExample.java)</a>
</em>
</p>
- <pre class="prettyprint source">package chapter5;
+ <pre class="prettyprint source">package chapters.layouts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -1283,7 +1283,7 @@ public class CallerEvaluatorExample {
0 [main] DEBUG - I know me 1
0 [main] DEBUG - I know me 2
0 [main] DEBUG - who calls thee?
-Caller+0 at chapter5.CallerEvaluatorExample.main(CallerEvaluatorExample.java:28)
+Caller+0 at chapters.layouts.CallerEvaluatorExample.main(CallerEvaluatorExample.java:28)
0 [main] DEBUG - I know me 4</pre></div>
<p>One can change the expression to correspond a real world
@@ -1310,11 +1310,11 @@ Caller+0 at chapter5.CallerEvaluatorExample.main(CallerEvaluatorExample.java:2
<p><em>
Example 5.2: Sample usage of EventEvaluators
- <a href="../xref/chapter5/ExceptionEvaluatorExample.html">
- (logback-examples/src/main/java/chapter5/ExceptionEvaluatorExample.java)</a>
+ <a href="../xref/chapters/layouts/ExceptionEvaluatorExample.html">
+ (logback-examples/src/main/java/chapters/layouts/ExceptionEvaluatorExample.java)</a>
</em>
</p>
-<pre class="prettyprint source">package chapter5;
+<pre class="prettyprint source">package chapters.layouts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -1352,13 +1352,13 @@ public class ExceptionEvaluatorExample {
third logging request.</p>
<em>
Example 5.3: Sample usage of EventEvaluators
- (logback-examples/src/main/java/chapter5/exceptionEvaluatorConfig.xml)
+ (logback-examples/src/main/java/chapters/layouts/exceptionEvaluatorConfig.xml)
</em>
<pre class="prettyprint source"><configuration>
<b><evaluator name="DISPLAY_EX_EVAL">
<Expression>throwable != null &amp;&amp; throwable instanceof \
- chapter5.TestException</Expression>
+ chapters.layouts.TestException</Expression>
</evaluator></b>
<appender name="STDOUT"
@@ -1375,7 +1375,7 @@ public class ExceptionEvaluatorExample {
</configuration></pre>
<p>With this configuration, each time an instance of the
- <em>chapter5.TestException</em> is included within a logging
+ <em>chapters.layouts.TestException</em> is included within a logging
request, the stack trace will be suppressed.
</p>
@@ -1412,9 +1412,9 @@ public class ExceptionEvaluatorExample {
conventions. Here is a possible implementation:</p>
<em> Example 5.4: Sample Converter Example
-<a href="../xref/chapter5/MySampleConverter.html">
-(src/main/java/chapter5/MySampleConverter.java)</a></em>
-<pre class="prettyprint source">package chapter5;
+<a href="../xref/chapters/layouts/MySampleConverter.html">
+(src/main/java/chapters/layouts/MySampleConverter.java)</a></em>
+<pre class="prettyprint source">package chapters.layouts;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.pattern.ClassicConverter;
@@ -1464,10 +1464,10 @@ public class MySampleConverter extends ClassicConverter {
<code>Converter</code>. For this purpose, we need to declare the
new conversion word in the configuration file, as shown below:</p>
-<em> Example 5.4: Sample Converter Example (src/main/java/chapter5/mySampleConverterConfig.xml)</em>
+<em> Example 5.4: Sample Converter Example (src/main/java/chapters/layouts/mySampleConverterConfig.xml)</em>
<pre class="prettyprint source"><configuration>
- <b><conversionRule conversionWord="sample" converterClass="chapter5.MySampleConverter" /></b>
+ <b><conversionRule conversionWord="sample" converterClass="chapters.layouts.MySampleConverter" /></b>
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
@@ -1490,7 +1490,7 @@ public class MySampleConverter extends ClassicConverter {
view the results on non-Windows platforms such as Linux or
Mac. The following command:</p>
- <div class="source">java chapter5.SampleLogging src/main/java/chapter5/mySampleConverterConfig.xml </div>
+ <div class="source">java chapters.layouts.SampleLogging src/main/java/chapters/layouts/mySampleConverterConfig.xml </div>
<p>should yield:</p>
diff --git a/logback-site/src/site/pages/manual/mdc.html b/logback-site/src/site/pages/manual/mdc.html
index a31ebfd..6529648 100644
--- a/logback-site/src/site/pages/manual/mdc.html
+++ b/logback-site/src/site/pages/manual/mdc.html
@@ -96,12 +96,12 @@ public class MDC {
<p>
The next application named
- <code><a href="../xref/chapter7/SimpleMDC.html">SimpleMDC</a></code>
+ <code><a href="../xref/chapters/mdc/SimpleMDC.html">SimpleMDC</a></code>
demonstrates this basic principle.
</p>
-<em>Example 7.1: Basic MDC usage (<a href="../xref/chapter7/SimpleMDC.html">
-logback-examples/src/main/java/chapter7/SimpleMDC.java)</a></em>
-<pre class="prettyprint source">package chapter7;
+<em>Example 7.1: Basic MDC usage (<a href="../xref/chapters/mdc/SimpleMDC.html">
+logback-examples/src/main/java/chapters/mdc/SimpleMDC.java)</a></em>
+<pre class="prettyprint source">package chapters.mdc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -213,9 +213,9 @@ Richard Nixon - Attributed to the former US president. 17 Nov 1973.</pre></div>
retrieve the distinct factors of an integer.
</p>
-<em>Example 7.2: The service interface (<a href="../xref/chapter7/NumberCruncher.html">
-logback-examples/src/main/java/chapter7/NumberCruncher.java)</a></em>
-<pre class="prettyprint source">package chapter7;
+<em>Example 7.2: The service interface (<a href="../xref/chapters/mdc/NumberCruncher.html">
+logback-examples/src/main/java/chapters/mdc/NumberCruncher.java)</a></em>
+<pre class="prettyprint source">package chapters.mdc;
import java.rmi.Remote;
import java.rmi.RemoteException;
@@ -237,9 +237,9 @@ public interface NumberCruncher extends Remote {
an RMI Registry on the local host that accepts requests on a well-known port.
</p>
-<em>Example 7.3: The server side (<a href="../xref/chapter7/NumberCruncherServer.html">
-logback-examples/src/main/java/chapter7/NumberCruncherServer.java)</a></em>
-<pre class="prettyprint source">package chapter7;
+<em>Example 7.3: The server side (<a href="../xref/chapters/mdc/NumberCruncherServer.html">
+logback-examples/src/main/java/chapters/mdc/NumberCruncherServer.java)</a></em>
+<pre class="prettyprint source">package chapters.mdc;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
@@ -341,7 +341,7 @@ public class NumberCruncherServer extends UnicastRemoteObject
static void usage(String msg) {
System.err.println(msg);
- System.err.println("Usage: java chapter7.NumberCruncherServer configFile\n" +
+ System.err.println("Usage: java chapters.mdc.NumberCruncherServer configFile\n" +
" where configFile is a logback configuration file.");
System.exit(1);
}
@@ -412,12 +412,12 @@ public class NumberCruncherServer extends UnicastRemoteObject
cruncher example. Start the server with the following command:
</p>
-<div class="source"><pre>java chapter7.NumberCruncherServer src/main/java/chapter7/mdc1.xml</pre></div>
+<div class="source"><pre>java chapters.mdc.NumberCruncherServer src/main/java/chapters/mdc/mdc1.xml</pre></div>
<p>
The <em>mdc1.xml</em> configuration file is listed below:
</p>
-<em>Example 7.4: Configuration file (logback-examples/src/main/java/chapter7/mdc1.xml)</em>
+<em>Example 7.4: Configuration file (logback-examples/src/main/java/chapters/mdc/mdc1.xml)</em>
<pre class="prettyprint source"><configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout>
@@ -440,7 +440,7 @@ public class NumberCruncherServer extends UnicastRemoteObject
application:
</p>
-<div class="source"><pre>java chapter7.NumberCruncherClient <em>hostname</em></pre></div>
+<div class="source"><pre>java chapters.mdc.NumberCruncherClient <em>hostname</em></pre></div>
<p>
where <em>hostname</em> is the host where the
@@ -530,9 +530,9 @@ public class NumberCruncherServer extends UnicastRemoteObject
<p>Here is an implementation of such a filter:</p>
-<em>Example 7.5: User servlet filter (<a href="../xref/chapter7/UserServletFilter.html">
-logback-examples/src/main/java/chapter7/UserServletFilter.java)</a></em>
-<pre class="prettyprint source">package chapter7;
+<em>Example 7.5: User servlet filter (<a href="../xref/chapters/mdc/UserServletFilter.html">
+logback-examples/src/main/java/chapters/mdc/UserServletFilter.java)</a></em>
+<pre class="prettyprint source">package chapters.mdc;
import java.io.IOException;
import java.security.Principal;
diff --git a/logback-site/src/site/pages/manual/migrationFromLog4j.html b/logback-site/src/site/pages/manual/migrationFromLog4j.html
index ed7cd04..386dbb4 100644
--- a/logback-site/src/site/pages/manual/migrationFromLog4j.html
+++ b/logback-site/src/site/pages/manual/migrationFromLog4j.html
@@ -69,13 +69,13 @@
<p>Let us begin by migrating a hypothetcical and trivially simple
log4j layout named <a
- href="../xref/chapter11/TrivialLog4jLayout.html">TrivialLog4jLayout</a>
+ href="../xref/chapters/migrationFromLog4j/TrivialLog4jLayout.html">TrivialLog4jLayout</a>
which returns the message contained in a logging events as the
formatted message. Here is the code.
</p>
- <pre class="prettyprint source">package chapter11;
+ <pre class="prettyprint source">package chapters.migrationFromLog4j;
import org.apache.log4j.Layout;
import org.apache.log4j.spi.LoggingEvent;
@@ -96,10 +96,10 @@ public class TrivialLog4jLayout extends Layout {
}</pre>
<p>The logback-classic equivalent named <a
- href="../xref/chapter11/TrivialLogbackLayout.html">TrivialLogbackLayout</a>
+ href="../xref/chapters/migrationFromLog4j/TrivialLogbackLayout.html">TrivialLogbackLayout</a>
would be </p>
- <pre class="prettyprint source">package chapter11;
+ <pre class="prettyprint source">package chapters.migrationFromLog4j;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.LayoutBase;
@@ -140,10 +140,10 @@ public class TrivialLogbackLayout extends <b>LayoutBase<ILoggingEvent></b> {
<p>Migrating an appender is quite similar to migrating layout. Here
is a trivially simple appender called <a
- href="../xref/chapter11/TrivialLog4jLayout.html">TrivialLog4jLayout</a>
+ href="../xref/chapters/migrationFromLog4j/TrivialLog4jLayout.html">TrivialLog4jLayout</a>
which writes on the console the string returned by its layout.</p>
- <pre class="prettyprint source">package chapter11;
+ <pre class="prettyprint source">package chapters.migrationFromLog4j;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
@@ -166,11 +166,11 @@ public class TrivialLog4jAppender extends AppenderSkeleton {
}</pre>
<p>The logback-classic equivalent named <a
- href="../xref/chapter11/TrivialLogbackAppender.html">TrivialLogbackAppender</a>
+ href="../xref/chapters/migrationFromLog4j/TrivialLogbackAppender.html">TrivialLogbackAppender</a>
would be written as</p>
- <pre class="prettyprint source">package chapter11;
+ <pre class="prettyprint source">package chapters.migrationFromLog4j;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;
diff --git a/logback-site/src/site/pages/manual/onJoran.html b/logback-site/src/site/pages/manual/onJoran.html
index eab4c87..b44a270 100644
--- a/logback-site/src/site/pages/manual/onJoran.html
+++ b/logback-site/src/site/pages/manual/onJoran.html
@@ -47,7 +47,7 @@
</p>
<p>The examples presented in this chapter can be found under
- <em>LOGBACK_HOME/logback-examples/src/main/java/chapter10</em>
+ <em>LOGBACK_HOME/logback-examples/src/main/java/chapters/onJoran/</em>
folder.
</p>
@@ -248,15 +248,15 @@ public abstract class Action {
<p>The first example in this chapter illustrates the minimal
plumbing required for using Joran. The example consists of a
trivial action called <a
- href="../xref/chapter10/helloWorld/HelloWorldAction.html">
+ href="../xref/chapters/onJoran/helloWorld/HelloWorldAction.html">
<code>HelloWorldAction</code></a> which prints "Hello World" on the
console when it's <code>begin()</code> method is invoked. The
parsing of XML files is done by a configurator. For the purposes of
this chapter, we have developped a very simple configurator called
<a
- href="../xref/chapter10/SimpleConfigurator.html"><code>SimpleConfigurator</code></a>.
+ href="../xref/chapters/onJoran/SimpleConfigurator.html"><code>SimpleConfigurator</code></a>.
The <a
- href="../xref/chapter10/helloWorld/HelloWorld.html"><code>HelloWorld</code></a>
+ href="../xref/chapters/onJoran/helloWorld/HelloWorld.html"><code>HelloWorld</code></a>
application brings all pieces together.
</p>
@@ -276,14 +276,14 @@ public abstract class Action {
<p>The <em>hello.xml</em> file contains one <hello-world>
element, without any other nested elements. See the
- <em>logback-examples/src/main/java/chapter10/helloWorld/</em>
+ <em>logback-examples/src/main/java/chapters/onJoran/helloWorld/</em>
folder for exact contents.
</p>
<p>Running the HelloWorld application with <em>hello.xml</em> file
will print "Hello World" on the console.</p>
- <p class="command">java chapter10.helloWorld.HelloWorld src/main/java/chapter10/helloWorld/hello.xml</p>
+ <p class="command">java chapters.onJoran.helloWorld.HelloWorld src/main/java/chapters/onJoran/helloWorld/hello.xml</p>
<p>You are highly encourared to poke about this example, by adding
new rules on the rule store, modifying the XML document
@@ -307,14 +307,14 @@ public abstract class Action {
</p>
<em>Example 10.<span class="autoEx"/>: First calculator example
- (logback-examples/src/main/java/chapter10/calculator/calculator1.xml)</em>
+ (logback-examples/src/main/java/chapters/onJoran/calculator/calculator1.xml)</em>
<em> </em>
<pre class="prettyprint source"><computation name="total">
<literal value="3"/>
</computation></pre>
- <p>In the <a href="../xref/chapter10/calculator/Calculator1.html">
+ <p>In the <a href="../xref/chapters/onJoran/calculator/Calculator1.html">
<code>Calculator1</code></a> application, we declare various
parsing rules (patterns and actions) collaborating together to
compute a result based on the contents of an XML document.
@@ -323,7 +323,7 @@ public abstract class Action {
<p> Running <code>Calculator1</code> application with
<em>calculator1.xml</em></p>
- <p class="command">java chapter10.calculator.Calculator1 src/main/java/chapter10/calculator/calculator1.xml</p>
+ <p class="command">java chapters.onJoran.calculator.Calculator1 src/main/java/chapters/onJoran/calculator/calculator1.xml</p>
<p>will print:</p>
@@ -338,11 +338,11 @@ public abstract class Action {
<li>The start event corresponding to the <computation>
element translates into the current pattern
"/computation". Since in the <a
- href="../xref/chapter10/calculator/Calculator1.html">
+ href="../xref/chapters/onJoran/calculator/Calculator1.html">
<code>Calculator1</code></a> application we associated the
pattern "/computation" with a
<a
- href="../xref/chapter10/calculator/ComputationAction1.html">
+ href="../xref/chapters/onJoran/calculator/ComputationAction1.html">
<code>ComputationAction1</code></a> instance, the
<code>begin()</code> method of that
<code>ComputationAction1</code> instance is invoked.
@@ -353,7 +353,7 @@ public abstract class Action {
"/computation/literal". Given the association of the
"/computation/literal" pattern with a
<a
- href="../xref/chapter10/calculator/LiteralAction.html">
+ href="../xref/chapters/onJoran/calculator/LiteralAction.html">
<code>LiteralAction</code></a> instance, the
<code>begin()</code> method of that <code>LiteralAction</code>
instance is called.</p>
@@ -390,7 +390,7 @@ public abstract class Action {
<em>Example 10.<span class="autoEx"/>: Calculator configuration
file
- (logback-examples/src/main/java/chapter10/calculator/calculator2.xml)</em>
+ (logback-examples/src/main/java/chapters/onJoran/calculator/calculator2.xml)</em>
<pre class="prettyprint source"><computation name="toto">
<literal value="7"/>
<literal value="3"/>
@@ -402,19 +402,19 @@ public abstract class Action {
<p>As in the previous example, in response to the <literal>
element,the appropriate <a
- href="../xref/chapter10/calculator/LiteralAction.html">
+ href="../xref/chapters/onJoran/calculator/LiteralAction.html">
<code>LiteralAction</code></a> instance will push an integer,
corresponding to the value attribute, at the top of the
interpretation context's object stack. In this example, that is
<em>calculator2.xml</em>, the values are 7 and 3. In response to the
<add> element, the appropriate <a
- href="../xref/chapter10/calculator/AddAction.html"><code>AddAction</code></a>
+ href="../xref/chapters/onJoran/calculator/AddAction.html"><code>AddAction</code></a>
will pop two previously pushed integers, compute their sum and push
the result, i.e. 10 (=7+3), at the top of the interpretation
context's stack. The next literal element will cause LiteralAction
to push an integer with value 3 at the top of the stack. In response
to the <multiply> element, the appropriate <a
- href="../xref/chapter10/calculator/MultiplyAction.html"><code>MultiplyAction</code></a>
+ href="../xref/chapters/onJoran/calculator/MultiplyAction.html"><code>MultiplyAction</code></a>
will pop two previously pushed integers, i.e. 10 and 3, and compute
their product. It will push the result, i.e. 30, at the top of the
stack. At the very end, in reponse to the end event corresponding to
@@ -422,7 +422,7 @@ public abstract class Action {
object at the top of the stack. Thus, running:
</p>
- <p class="command">java chapter10.calculator.Calculator1 src/main/java/chapter10/calculator/calculator2.xml </p>
+ <p class="command">java chapters.onJoran.calculator.Calculator1 src/main/java/chapters/onJoran/calculator/calculator2.xml </p>
<p>will yield</p>
@@ -437,7 +437,7 @@ public abstract class Action {
same element. Here's the content of <em>calculator3.xml</em>:</p>
<em>Example 10.<span class="autoEx"/>: Calculator configuration file
- (logback-examples/src/main/java/chapter10/calculator/calculator3.xml)</em>
+ (logback-examples/src/main/java/chapters/onJoran/calculator/calculator3.xml)</em>
<pre class="prettyprint source"><computation name="toto">
<computation>
@@ -453,7 +453,7 @@ public abstract class Action {
<p>Much like the use of parentheses in an algebrical equation, the
presence of a <code>computation</code> element nested in another is
managed by the <a
- href="../xref/chapter10/calculator/ComputationAction2.html">
+ href="../xref/chapters/onJoran/calculator/ComputationAction2.html">
<code>ComputationAction2</code></a> class using an internal
stack. The well-formedness of XML will guarantee that a value saved
by one <code>begin()</code> will be consumed only by the matching
@@ -496,19 +496,19 @@ public abstract class Action {
<p>You can create and register a custom implicit action as
illustrated in the next example contained within the
- <em>logback-examples/src/main/java/chapter10/implicit</em> folder.
+ <em>logback-examples/src/main/java/chapters/onJoran/implicit</em> folder.
</p>
<p>The <a
- href="../xref/chapter10/implicit/PrintMe.html"><code>PrintMe</code></a>
+ href="../xref/chapters/onJoran/implicit/PrintMe.html"><code>PrintMe</code></a>
application associates an <a
- href="../xref/chapter10/implicit/NOPAction.html">
+ href="../xref/chapters/onJoran/implicit/NOPAction.html">
<code>NOPAction</code></a> instance with the pattern "*/foo", that
is any element named as "foo". As its name indicates, the
<code>begin</code>() and <code>end</code>() methods of
<code>NOPAction</code> are empty. The <code>PrintMe</code>
application also registers an instance of <a
- href="../xref/chapter10/implicit/PrintMeImplicitAction.html">PrintMeImplicitAction</a>
+ href="../xref/chapters/onJoran/implicit/PrintMeImplicitAction.html">PrintMeImplicitAction</a>
in its list of implicit actions. The
<code>PrintMeImplicitAction</code> is applicable for any element
which has a <span class="attr">printme</span> attribute set to
@@ -522,7 +522,7 @@ public abstract class Action {
how implicit actions come into play.</p>
<em>Example 10.<span class="autoEx"/>: Usage of implicit rules
- (logback-examples/src/main/java/chapter10/implicit/implicit1.xml)</em>
+ (logback-examples/src/main/java/chapters/onJoran/implicit/implicit1.xml)</em>
<pre class="prettyprint source"><foo>
<xyz printme="true">
<abc printme="true"/>
@@ -536,7 +536,7 @@ public abstract class Action {
<p>Running</p>
- <p class="command">java chapter10.implicit.PrintMe src/main/java/chapter10/implicit/implicit1.xml</p>
+ <p class="command">java chapters.onJoran.implicit.PrintMe src/main/java/chapters/onJoran/implicit/implicit1.xml</p>
<p>yields:</p>
<p class="console">Element [xyz] asked to be printed.
@@ -693,9 +693,9 @@ Element [abc] asked to be printed.
<p>Joran includes an action which allows the Joran interpreter to
learn new rules on the fly, that is while interpreting an XML
document. See the
- <em>logback-examples/src/main/java/chapter10/newRule/</em> directory
+ <em>logback-examples/src/main/java/chapters/onJoran/newRule/</em> directory
for sample code. In this package, the <a
- href="../xref/chapter10/newRule/NewRuleCalculator.html">
+ href="../xref/chapters/onJoran/newRule/NewRuleCalculator.html">
<code>NewRuleCalculator</code></a> application sets up just two
rules, one rule to process the top-most element, and a second rule
to learn new rules. Here is the relevant code from
@@ -719,7 +719,7 @@ Element [abc] asked to be printed.
<p>Here is how new rules can be declared in an xml file:</p>
<pre class="prettyprint source"><new-rule pattern="*/computation/literal"
- actionClass="chapter10.calculator.LiteralAction"/></pre>
+ actionClass="chapters.onJoran.calculator.LiteralAction"/></pre>
<p>Using such new-rule declarations, we can transform
<code>NewRuleCalculator</code> to behave like the
@@ -728,15 +728,15 @@ Element [abc] asked to be printed.
<em>Example 10..<span class="autoEx"/>: Configuration file using new
rules on the fly
- (logback-examples/src/main/java/chapter10/newrule/new-rule.xml)</em>
+ (logback-examples/src/main/java/chapters/onJoran/newrule/new-rule.xml)</em>
<pre class="prettyprint source"><computation name="toto">
<new-rule pattern="*/computation/literal"
- actionClass="chapter10.calculator.LiteralAction"/>
+ actionClass="chapters.onJoran.calculator.LiteralAction"/>
<new-rule pattern="*/computation/add"
- actionClass="chapter10.calculator.AddAction"/>
+ actionClass="chapters.onJoran.calculator.AddAction"/>
<new-rule pattern="*/computation/multiply"
- actionClass="chapter10.calculator.MultiplyAction"/>
+ actionClass="chapters.onJoran.calculator.MultiplyAction"/>
<computation>
<literal value="7"/>
@@ -749,7 +749,7 @@ Element [abc] asked to be printed.
</computation></pre>
- <p class="command">java java chapter10.newRule.NewRuleCalculator src/main/java/chapter10/newRule/new-rule.xml</p>
+ <p class="command">java java chapters.onJoran.newRule.NewRuleCalculator src/main/java/chapters/onJoran/newRule/new-rule.xml</p>
<p>yields</p>
diff --git a/logback-site/src/site/pages/news.html b/logback-site/src/site/pages/news.html
index 2b2c803..fa1ef89 100644
--- a/logback-site/src/site/pages/news.html
+++ b/logback-site/src/site/pages/news.html
@@ -59,13 +59,13 @@
</div>
<p><code>FileAppender</code> and derived classes can now
- gracefully deal with IO failreus and recover quickly after the
+ gracefully deal with IO failures and recover quickly after the
original cause of the IO failure is corrected. For example, if the
log file is located on a <a
href="http://en.wikipedia.org/wiki/Network-attached_storage">network-attached
storage (NAS)</a>, and the connection to the NAS server is lost,
<code>FileAppender</code> and derived classes will recover quickly
- after the connection to the server is re-established.
+ after the connection to the server is re-established.
</p>
<p>Added <a
diff --git a/logback-site/src/site/pages/setup.html b/logback-site/src/site/pages/setup.html
index 4f5d924..71093ef 100644
--- a/logback-site/src/site/pages/setup.html
+++ b/logback-site/src/site/pages/setup.html
@@ -44,12 +44,12 @@
<em>$LOGBACK_HOME/logback-examples</em>, where
<em>$LOGBACK_HOME</em> stands for the directory where you
installed logback, you can launch the first sample application,
- <em>chapter1.HelloWord1</em> with the following command:
+ <em>chapters.introduction.HelloWord1</em> with the following command:
</p>
<p class="source">java -cp lib/slf4j-api-${slf4j.version}.jar;../logback-core-${version}.jar;\
../logback-classic-${version}.jar;logback-examples-${version}.jar\
- chapter1.HelloWorld1</p>
+ chapters.introduction.HelloWorld1</p>
<p>It is more convenient to set the CLASSPATH environment variable
once and for all before running the examples.
diff --git a/logback-site/src/site/resources/manual/images/chapters/configuration/sample.xml b/logback-site/src/site/resources/manual/images/chapters/configuration/sample.xml
deleted file mode 100644
index aa8e4b8..0000000
--- a/logback-site/src/site/resources/manual/images/chapters/configuration/sample.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration>
- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <file>myApp.log</file>
- <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <FileNamePattern> myApp-%d{yyyy-MM-dd-HH-mm-ss}.log</FileNamePattern>
- </rollingPolicy>
- <layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>%date %level [%thread] %logger{10} [%file : %line] %msg%n</Pattern>
- </layout>
- </appender>
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <filter class="ch.qos.logback.classic.filter.LevelFilter">
- <level>INFO</level>
- <onMatch>ACCEPT</onMatch>
- <onMismatch>DENY</onMismatch>
- </filter>
- <layout class="ch.qos.logback.classic.PatternLayout">
- <Pattern>%msg%n</Pattern>
- </layout>
- </appender>
- <logger name="chapter3">
- <appender-ref ref="FILE"/>
- </logger>
- <logger name="chapter4">
- <appender-ref ref="FILE"/>
- </logger>
- <root>
- <level value="debug"/>
- <appender-ref ref="STDOUT"/>
- </root>
-</configuration>
-----------------------------------------------------------------------
Summary of changes:
.../core/recovery/ResilientFileOutputStream.java | 4 +-
.../main/java/chapters/appenders/mail/mail3.xml | 2 +-
.../java/chapters/architecture/sample-config-3.xml | 2 +-
.../chapters/configuration/containingConfig.xml | 2 +-
.../configuration/variableSubstitution3.xml | 2 +-
.../configuration/variableSubstitution4.xml | 2 +-
.../java/chapters/filters/sampleFilterConfig.xml | 2 +-
.../chapters/filters/sampleTurboFilterConfig.xml | 2 +-
.../chapters/layouts/callerEvaluatorConfig.xml | 2 +-
.../chapters/layouts/exceptionEvaluatorConfig.xml | 2 +-
.../chapters/layouts/mySampleConverterConfig.xml | 2 +-
.../java/chapters/layouts/sampleLayoutConfig.xml | 2 +-
.../java/chapters/layouts/sampleLayoutConfig2.xml | 2 +-
.../java/chapters/mdc/NumberCruncherClient.java | 2 +-
.../java/chapters/mdc/NumberCruncherServer.java | 2 +-
.../src/main/java/chapters/mdc/SimpleMDC.java | 4 +-
.../main/java/chapters/mdc/UserServletFilter.java | 2 +-
.../chapters/migrationFromLog4j/Log4jMain.java | 2 +-
.../chapters/migrationFromLog4j/LogbackMain.java | 2 +-
.../migrationFromLog4j/log4jTrivial.properties | 4 +-
.../migrationFromLog4j/logback-trivial.xml | 4 +-
.../onJoran/SimpleConfigurator.java | 2 +-
.../onJoran/calculator/AddAction.java | 2 +-
.../onJoran/calculator/Calculator1.java | 4 +-
.../onJoran/calculator/Calculator2.java | 4 +-
.../onJoran/calculator/ComputationAction1.java | 2 +-
.../onJoran/calculator/ComputationAction2.java | 2 +-
.../onJoran/calculator/LiteralAction.java | 2 +-
.../onJoran/calculator/MultiplyAction.java | 2 +-
.../onJoran/calculator/calculator1.xml | 0
.../onJoran/calculator/calculator2.xml | 0
.../onJoran/calculator/calculator3.xml | 1 -
.../{appenders => }/onJoran/calculator/readme.txt | 0
.../onJoran/helloWorld/HelloWorld.java | 4 +-
.../onJoran/helloWorld/HelloWorldAction.java | 2 +-
.../{appenders => }/onJoran/helloWorld/hello.xml | 0
.../{appenders => }/onJoran/helloWorld/readme.txt | 0
.../onJoran/implicit/NOPAction.java | 2 +-
.../{appenders => }/onJoran/implicit/PrintMe.java | 4 +-
.../onJoran/implicit/PrintMeImplicitAction.java | 2 +-
.../{appenders => }/onJoran/implicit/implicit1.xml | 0
.../{appenders => }/onJoran/implicit/readme.txt | 0
.../onJoran/newRule/NewRuleCalculator.java | 6 +-
.../{appenders => }/onJoran/newRule/new-rule.xml | 6 +-
.../{appenders => }/onJoran/newRule/readme.txt | 0
logback-site/src/site/pages/faq.html | 2 +-
logback-site/src/site/pages/index.html | 4 +-
logback-site/src/site/pages/manual/appenders.html | 2 +-
logback-site/src/site/pages/manual/filters.html | 122 ++++++++++----------
logback-site/src/site/pages/manual/jmxConfig.html | 14 +-
logback-site/src/site/pages/manual/layouts.html | 68 ++++++------
logback-site/src/site/pages/manual/mdc.html | 34 +++---
.../src/site/pages/manual/migrationFromLog4j.html | 16 ++--
logback-site/src/site/pages/manual/onJoran.html | 66 ++++++------
logback-site/src/site/pages/news.html | 4 +-
logback-site/src/site/pages/setup.html | 4 +-
.../images/chapters/configuration/sample.xml | 32 -----
57 files changed, 217 insertions(+), 248 deletions(-)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/SimpleConfigurator.java (97%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/calculator/AddAction.java (97%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/calculator/Calculator1.java (94%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/calculator/Calculator2.java (95%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/calculator/ComputationAction1.java (97%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/calculator/ComputationAction2.java (98%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/calculator/LiteralAction.java (97%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/calculator/MultiplyAction.java (97%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/calculator/calculator1.xml (100%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/calculator/calculator2.xml (100%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/calculator/calculator3.xml (95%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/calculator/readme.txt (100%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/helloWorld/HelloWorld.java (93%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/helloWorld/HelloWorldAction.java (95%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/helloWorld/hello.xml (100%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/helloWorld/readme.txt (100%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/implicit/NOPAction.java (95%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/implicit/PrintMe.java (95%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/implicit/PrintMeImplicitAction.java (96%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/implicit/implicit1.xml (100%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/implicit/readme.txt (100%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/newRule/NewRuleCalculator.java (92%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/newRule/new-rule.xml (67%)
copy logback-examples/src/main/java/chapters/{appenders => }/onJoran/newRule/readme.txt (100%)
delete mode 100644 logback-site/src/site/resources/manual/images/chapters/configuration/sample.xml
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0
Document context properties
---------------------------
Key: LBSITE-37
URL: http://jira.qos.ch/browse/LBSITE-37
Project: logback-site
Issue Type: Task
Components: Documentation
Reporter: Ceki Gulcu
Assignee: Logback dev list
See http://qos.ch/pipermail/logback-user/2010-March/001443.html
and http://qos.ch/pipermail/logback-user/2010-March/001444.html
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.qos.ch/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
1
0

[JIRA] Created: (LBCORE-113) SMTPAppender should have support for avoiding flooding
by Ceki Gulcu (JIRA) 03 Mar '10
by Ceki Gulcu (JIRA) 03 Mar '10
03 Mar '10
SMTPAppender should have support for avoiding flooding
------------------------------------------------------
Key: LBCORE-113
URL: http://jira.qos.ch/browse/LBCORE-113
Project: logback-core
Issue Type: New Feature
Reporter: Ceki Gulcu
Assignee: Logback dev list
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.qos.ch/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
1
1

03 Mar '10
Writing subsequent to an IO failure
-----------------------------------
Key: LBCORE-133
URL: http://jira.qos.ch/browse/LBCORE-133
Project: logback-core
Issue Type: Sub-task
Components: Appender
Affects Versions: 0.9.18
Reporter: Ceki Gulcu
Assignee: Logback dev list
See http://www.qos.ch/pipermail/logback-user/2009-December/001382.html
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.qos.ch/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
1
1

[GIT] Logback: the generic, reliable, fast and flexible logging framework. branch, master, updated. v0.9.18-61-g3d5ba2c
by git-noreply@pixie.qos.ch 03 Mar '10
by git-noreply@pixie.qos.ch 03 Mar '10
03 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, master has been updated
via 3d5ba2cfc7f4c381ba2fc10cd0a5342c6330757c (commit)
from d87d66c281909ad2e24013286821874416a2c87e (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=3d5ba2cfc7f4c381ba2fc10c…
http://github.com/ceki/logback/commit/3d5ba2cfc7f4c381ba2fc10cd0a5342c63307…
commit 3d5ba2cfc7f4c381ba2fc10cd0a5342c6330757c
Author: Ceki Gulcu <ceki(a)gimmel.(none)>
Date: Wed Mar 3 23:59:51 2010 +0100
attempt to improve test passing rate
diff --git a/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java b/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java
index 2b55163..99a6698 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilienceTest.java
@@ -63,8 +63,9 @@ public class FileAppenderResilienceTest {
Thread t = new Thread(runner);
t.start();
+ double delayCoeff = 2.0;
for (int i = 0; i < 5; i++) {
- Thread.sleep((int) (RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN * 2));
+ Thread.sleep((int)(RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN * delayCoeff));
ResilientFileOutputStream resilientFOS = (ResilientFileOutputStream) fa
.getOutputStream();
FileChannel fileChannel = resilientFOS.getChannel();
@@ -73,8 +74,9 @@ public class FileAppenderResilienceTest {
runner.setDone(true);
t.join();
+ double bestCase = 1/delayCoeff;
ResilienceUtil
- .verify(logfileStr, "^hello (\\d{1,5})$", runner.getCounter());
+ .verify(logfileStr, "^hello (\\d{1,5})$", runner.getCounter(), bestCase);
}
}
@@ -89,7 +91,7 @@ class Runner extends RunnableWithCounterAndDone {
while (!isDone()) {
counter++;
fa.doAppend("hello " + counter);
- if (counter % 512 == 0) {
+ if (counter % 1024 == 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
diff --git a/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilience_AS_ROOT_Test.java b/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilience_AS_ROOT_Test.java
index 0ed804b..a5a7691 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilience_AS_ROOT_Test.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/FileAppenderResilience_AS_ROOT_Test.java
@@ -35,7 +35,6 @@ public class FileAppenderResilience_AS_ROOT_Test {
static String PATH_LOOPFS_SCRIPT = "/home/ceki/java/logback/logback-core/src/test/loopfs.sh";
-
enum LoopFSCommand {
setup, shake, teardown;
}
@@ -44,16 +43,16 @@ public class FileAppenderResilience_AS_ROOT_Test {
int diff = RandomUtil.getPositiveInt();
String outputDirStr = MOUNT_POINT + "resilience-" + diff + "/";
String logfileStr = outputDirStr + "output.log";
-
+
FileAppender<Object> fa = new FileAppender<Object>();
static boolean isConformingHost() {
- return Env.isLocalHostNameInList(new String[] {"gimmel"});
+ return Env.isLocalHostNameInList(new String[] { "gimmel" });
}
-
+
@Before
public void setUp() throws IOException, InterruptedException {
- if(!isConformingHost()) {
+ if (!isConformingHost()) {
return;
}
Process p = runLoopFSScript(LoopFSCommand.setup);
@@ -89,10 +88,9 @@ public class FileAppenderResilience_AS_ROOT_Test {
}
}
-
@After
public void tearDown() throws IOException, InterruptedException {
- if(!isConformingHost()) {
+ if (!isConformingHost()) {
return;
}
StatusPrinter.print(context);
@@ -108,7 +106,7 @@ public class FileAppenderResilience_AS_ROOT_Test {
@Test
public void go() throws IOException, InterruptedException {
- if(!isConformingHost()) {
+ if (!isConformingHost()) {
return;
}
Process p = runLoopFSScript(LoopFSCommand.shake);
@@ -117,7 +115,9 @@ public class FileAppenderResilience_AS_ROOT_Test {
Thread.sleep(DELAY);
}
p.waitFor();
- ResilienceUtil.verify(logfileStr, "^(\\d{1,3}) x*$", NUM_STEPS);
+ // the extrernal script has the file system ready for IO 50% of the time
+ double bestCase = 0.5;
+ ResilienceUtil.verify(logfileStr, "^(\\d{1,3}) x*$", NUM_STEPS, bestCase);
System.out.println("Done go");
}
@@ -127,7 +127,7 @@ public class FileAppenderResilience_AS_ROOT_Test {
InterruptedException {
// causing a NullPointerException is better than locking the whole
// machine which the next operation can and will do.
- if(!isConformingHost()) {
+ if (!isConformingHost()) {
return null;
}
ProcessBuilder pb = new ProcessBuilder();
diff --git a/logback-core/src/test/java/ch/qos/logback/core/util/ResilienceUtil.java b/logback-core/src/test/java/ch/qos/logback/core/util/ResilienceUtil.java
index 2233fbc..9a8d2e5 100644
--- a/logback-core/src/test/java/ch/qos/logback/core/util/ResilienceUtil.java
+++ b/logback-core/src/test/java/ch/qos/logback/core/util/ResilienceUtil.java
@@ -11,7 +11,7 @@ import java.util.regex.Pattern;
public class ResilienceUtil {
- static public void verify(String logfile, String regexp, long totalSteps) throws NumberFormatException, IOException {
+ static public void verify(String logfile, String regexp, long totalSteps, double bestCase) throws NumberFormatException, IOException {
FileReader fr = new FileReader(logfile);
BufferedReader br = new BufferedReader(fr);
Pattern p = Pattern.compile(regexp);
@@ -35,8 +35,9 @@ public class ResilienceUtil {
fr.close();
br.close();
+ double expectedSuccessRate = bestCase * 0.7;
// at least 40% of the logs should have been written
- int lowerLimit = (int) (totalSteps*0.4);
+ int lowerLimit = (int) (totalSteps*expectedSuccessRate);
assertTrue("totalLines="+totalLines+" less than "+lowerLimit, totalLines > lowerLimit);
// we want some gaps which indicate recuperation
-----------------------------------------------------------------------
Summary of changes:
.../logback/core/FileAppenderResilienceTest.java | 8 +++++---
.../core/FileAppenderResilience_AS_ROOT_Test.java | 20 ++++++++++----------
.../ch/qos/logback/core/util/ResilienceUtil.java | 5 +++--
3 files changed, 18 insertions(+), 15 deletions(-)
hooks/post-receive
--
Logback: the generic, reliable, fast and flexible logging framework.
1
0
Hi all
What I can see there is no way to roll the file on a specific time. E.g.
every day at 17:00
As we require this I had a closer look on how logback decides to roll. I
found the ch.qos.logback.core.rolling.helper.RollingCalendar is
responsible to define when the next roll should happen. I extended it so
that one can define the time rather then 0:00 if you roll daily.
Now my problem is that there is no way to set my extended
RollingCalander on the TimeBasedFileNameAndTriggeringPolicyBase as it is
created inside the start method. Overriding the start of
TimeBasedFileNameAndTriggeringPolicyBase and do the same without calling
the super method works only if me override is in the same package which
is not a nice thing. The problem would be easy solved if you would add a
setter for the RollingCalander to the
TimeBasedFileNameAndTriggeringPolicyBase and then change the line
rc = new RollingCalendar();
to
if(rc==null){
rc = new RollingCalendar();
}
Clearly I could just go ahead and change that by myself but I thought
maybe someone else want's this as well and it would be nice not to keep
a separate code base.
Let me know what you think and if you want an example of my specific
time rolling calendar.
Cheers Andy
2
2