From: <ca...@us...> - 2007-07-28 00:09:13
|
Revision: 126 http://ant-contrib.svn.sourceforge.net/ant-contrib/?rev=126&view=rev Author: carnold Date: 2007-07-27 17:09:16 -0700 (Fri, 27 Jul 2007) Log Message: ----------- Bug 1760649: Add Maven buildable documentation, break dependency of ant/proposal/xdocs Modified Paths: -------------- cpptasks/trunk/build.xml cpptasks/trunk/pom.xml cpptasks/trunk/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java cpptasks/trunk/src/main/java/net/sf/antcontrib/cpptasks/ProcessorDef.java cpptasks/trunk/src/site/fml/faq.fml cpptasks/trunk/src/site/site.xml Added Paths: ----------- cpptasks/trunk/src/samples/hello/ cpptasks/trunk/src/samples/hello/build.xml cpptasks/trunk/src/samples/hello/src/ cpptasks/trunk/src/samples/hello/src/main/ cpptasks/trunk/src/samples/hello/src/main/c/ cpptasks/trunk/src/samples/hello/src/main/c/hello.c cpptasks/trunk/src/site/apt/index.apt cpptasks/trunk/src/site/xdoc/ cpptasks/trunk/src/site/xdoc/antdocs/ cpptasks/trunk/src/taskdocs/ cpptasks/trunk/src/taskdocs/java/ cpptasks/trunk/src/taskdocs/java/net/ cpptasks/trunk/src/taskdocs/java/net/sf/ cpptasks/trunk/src/taskdocs/java/net/sf/antcontrib/ cpptasks/trunk/src/taskdocs/java/net/sf/antcontrib/taskdocs/ cpptasks/trunk/src/taskdocs/java/net/sf/antcontrib/taskdocs/TaskDoclet.java cpptasks/trunk/src/taskdocs/resources/ cpptasks/trunk/src/taskdocs/resources/net/ cpptasks/trunk/src/taskdocs/resources/net/sf/ cpptasks/trunk/src/taskdocs/resources/net/sf/antcontrib/ cpptasks/trunk/src/taskdocs/resources/net/sf/antcontrib/taskdocs/ cpptasks/trunk/src/taskdocs/resources/net/sf/antcontrib/taskdocs/element.xslt Property Changed: ---------------- cpptasks/trunk/ Property changes on: cpptasks/trunk ___________________________________________________________________ Name: svn:ignore - target ant-contrib-cpptasks* .classpath .settings .project surefire* cobertura* + target ant-contrib-cpptasks* .classpath .settings .project surefire* cobertura* result.xml cpptasks.* Modified: cpptasks/trunk/build.xml =================================================================== --- cpptasks/trunk/build.xml 2007-07-26 23:26:28 UTC (rev 125) +++ cpptasks/trunk/build.xml 2007-07-28 00:09:16 UTC (rev 126) @@ -744,4 +744,12 @@ </target> + <target name="style"> + <mkdir dir="src/site/xdoc"/> + <xslt style="src/taskdocs/resources/net/sf/antcontrib/taskdocs/type.xslt" + baseDir="target/site/antdocs" includes="*.xml" processor="trax" + destDir="src/site/xdoc" extension=".xml" force="true"/> + + </target> + </project> Modified: cpptasks/trunk/pom.xml =================================================================== --- cpptasks/trunk/pom.xml 2007-07-26 23:26:28 UTC (rev 125) +++ cpptasks/trunk/pom.xml 2007-07-28 00:09:16 UTC (rev 126) @@ -48,6 +48,10 @@ <archive>http://sourceforge.net/mailarchive/forum.php?forum_name=ant-contrib-developers</archive> </mailingList> </mailingLists> + <organization> + <name>Ant-Contrib Project</name> + <url>http://ant-contrib.sourceforge.net</url> + </organization> <licenses> <license> <name>The Apache Software License, Version 2.0</name> @@ -97,12 +101,32 @@ <executions> <!-- release builds will put SVN tags into the SCM page, this changes it back to a branch --> <execution> + <phase>pre-site</phase> + <id>pre-site</id> + <configuration> + <tasks> + <mkdir dir="target/taskdocs-classes"/> + <javac srcdir="src/taskdocs/java" destdir="target/taskdocs-classes" debug="true"/> + <mkdir dir="src/site/xdoc/antdocs"/> + <javadoc sourcepath="src/main/java" + doclet="net.sf.antcontrib.taskdocs.TaskDoclet" + docletPath="target/taskdocs-classes" + classpath="${user.home}/.m2/repository/ant/ant/1.6.5/ant-1.6.5.jar"> + <fileset dir="src/main/java" includes="**/*.java"/> + </javadoc> + </tasks> + </configuration> + <goals> + <goal>run</goal> + </goals> + </execution> + <execution> <phase>site</phase> <id>untag-site</id> <configuration> <tasks> <taskdef name="replaceregexp" classname="org.apache.tools.ant.taskdefs.optional.ReplaceRegExp" /> - <replaceregexp file="target/site/source-repository.html" match="/tags/[^ ]*" replace="/branches/v1_2-branch" flags="g" /> + <replaceregexp file="target/site/source-repository.html" match="/tags/[^ ]*" replace="/branches/v1_2-branch" flags="g" /> </tasks> </configuration> <goals> @@ -116,6 +140,16 @@ <artifactId>ant-nodeps</artifactId> <version>1.6.5</version> </dependency> + <dependency> + <groupId>ant</groupId> + <artifactId>ant-trax</artifactId> + <version>1.6.5</version> + </dependency> + <dependency> + <groupId>ant-contrib</groupId> + <artifactId>taskdocs</artifactId> + <version>0.1-SNAPSHOT</version> + </dependency> </dependencies> </plugin> <plugin> @@ -134,7 +168,7 @@ </execution> </executions> </plugin> - <plugin> + <!-- plugin> <artifactId>maven-javadoc-plugin</artifactId> <executions> <execution> @@ -144,7 +178,7 @@ </goals> </execution> </executions> - </plugin> + </plugin --> <plugin> <artifactId>maven-source-plugin</artifactId> <executions> @@ -196,10 +230,6 @@ </reportSets> </plugin> <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>jxr-maven-plugin</artifactId> - </plugin> - <plugin> <artifactId>maven-release-plugin</artifactId> <configuration> <goals>site-deploy</goals> Modified: cpptasks/trunk/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java =================================================================== --- cpptasks/trunk/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java 2007-07-26 23:26:28 UTC (rev 125) +++ cpptasks/trunk/src/main/java/net/sf/antcontrib/cpptasks/CCTask.java 2007-07-28 00:09:16 UTC (rev 126) @@ -79,7 +79,7 @@ * <ul><li>Ant 1.6 or later: add xmlns:cpptasks="antlib:org.sf.net.antcontrib.cpptasks" to <project> element.</li> * <li>Ant 1.5 or later: Add <taskdef resource="cpptasks.tasks"/> and <typedef * resource="cpptasks.types"/> to body of <project> element.</li></ul></li> - * <li>Add <cc/>, <compiler/> and <linker/> elements to + * <li>Add <cc/>, <compiler/> and <linker/> elements to * project.</li> * <li>Set path and environment variables to be able to run compiler from * command line.</li> Modified: cpptasks/trunk/src/main/java/net/sf/antcontrib/cpptasks/ProcessorDef.java =================================================================== --- cpptasks/trunk/src/main/java/net/sf/antcontrib/cpptasks/ProcessorDef.java 2007-07-26 23:26:28 UTC (rev 125) +++ cpptasks/trunk/src/main/java/net/sf/antcontrib/cpptasks/ProcessorDef.java 2007-07-28 00:09:16 UTC (rev 126) @@ -65,7 +65,7 @@ */ private String ifProp; /** - * if true, processor definition inherits values from containing <cc> + * if true, processor definition inherits values from containing cc * element */ private boolean inherit; @@ -175,7 +175,7 @@ * Creates a configuration * * @param baseDef - * reference to def from containing <cc>element, may be null + * reference to def from containing cc element, may be null * @return configuration * */ @@ -192,7 +192,7 @@ return proc.createConfiguration(task, linkType, defaultProviders, this, targetPlatform, versionInfo); } /** - * Prepares list of processor arguments ( <compilerarg>, <linkerarg>) that + * Prepares list of processor arguments ( compilerarg, linkerarg ) that * are active for the current project settings. * * @return active compiler arguments @@ -219,7 +219,7 @@ return array; } /** - * Prepares list of processor arguments ( <compilerarg>, <linkerarg>) that + * Prepares list of processor arguments ( compilerarg, linkerarg) that * are active for the current project settings. * * @return active compiler arguments @@ -315,7 +315,7 @@ } /** * Gets the inherit attribute. If the inherit value is true, this processor - * definition will inherit default values from the containing <cc>element. + * definition will inherit default values from the containing cc element. * * @return if true then properties from the containing <cc>element are * used. @@ -523,7 +523,7 @@ } /** * If inherit has the default value of true, defines, includes and other - * settings from the containing <cc>element will be inherited. + * settings from the containing cc element will be inherited. * * @param inherit * new value Property changes on: cpptasks/trunk/src/samples/hello ___________________________________________________________________ Name: svn:ignore + target Added: cpptasks/trunk/src/samples/hello/build.xml =================================================================== --- cpptasks/trunk/src/samples/hello/build.xml (rev 0) +++ cpptasks/trunk/src/samples/hello/build.xml 2007-07-28 00:09:16 UTC (rev 126) @@ -0,0 +1,26 @@ +<!-- + Licensed to the Ant-Contrib Project under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The Ant-Contrib Project licenses this file to You 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. + +--> +<project name="hello" default="compile"> + <taskdef resource="cpptasks.tasks"/> + <target name="compile"> + <mkdir dir="target/main/obj"/> + <cc outtype="executable" subsystem="console" outfile="target/hello" objdir="target/main/obj"> + <fileset dir="src/main/c" includes="*.c"/> + </cc> + </target> +</project> Added: cpptasks/trunk/src/samples/hello/src/main/c/hello.c =================================================================== --- cpptasks/trunk/src/samples/hello/src/main/c/hello.c (rev 0) +++ cpptasks/trunk/src/samples/hello/src/main/c/hello.c 2007-07-28 00:09:16 UTC (rev 126) @@ -0,0 +1,25 @@ +/* + + Licensed to the Ant-Contrib Project under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The Ant-Contrib Project licenses this file to You 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. + +*/ + +#include <stdio.h> + +int main(int argc, const char** argv) { + puts("Hello, World."); + return 1; +} Added: cpptasks/trunk/src/site/apt/index.apt =================================================================== --- cpptasks/trunk/src/site/apt/index.apt (rev 0) +++ cpptasks/trunk/src/site/apt/index.apt 2007-07-28 00:09:16 UTC (rev 126) @@ -0,0 +1,60 @@ +~~ Licensed to the Ant-Contrib Project under one or more +~~ contributor license agreements. See the NOTICE file distributed with +~~ this work for additional information regarding copyright ownership. +~~ The Ant-Contrib Project licenses this file to You 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. + ------ +cpptasks for Apache Ant + ------ + ------ + ------ + +cpptasks for Apache Ant + + The cc task can compile various source languages and produce executables, + shared libraries (aka DLL's) and static libraries. Compiler adaptors are currently available + for several C/C++ compilers, FORTRAN, MIDL and Windows Resource files. + + The task can be used with Apache Ant 1.5 and later. This software is not a product + of the Apache Software Foundation (ASF) and no endorsement by the ASF is implied. + + + To use: + * Place cpptasks.jar into Ant's classpath by placing in Ant's lib directory, + adding to CLASSPATH environment variable or using the -lib command line option. + + * Add type and task definitions in build file: + Ant 1.6 or later: add xmlns:cpptasks="antlib:sf.net.antcontrib.cpptasks" to <project> element. + Ant 1.5 or later: Add <taskdef resource="cpptasks.tasks"/> and <typedef resource="cpptasks.types"/> to body of <project> element. + + * Add {{{antdocs/CCTask.html}cc}} element to some target in your build file. + + * Set path and environment variables to be able to run compiler from command line. + + * Build project. + + Trivial Sample: + ++-- +<project name="hello" default="compile"> + <taskdef resource="cpptasks.tasks"/> + <target name="compile"> + <mkdir dir="target/main/obj"/> + <cc outtype="executable" subsystem="console" outfile="target/hello" objdir="target/main/obj"> + <fileset dir="src/main/c" includes="*.c"/> + </cc> + </target> +</project> ++-- + + More complex samples appear in src/samples. + Modified: cpptasks/trunk/src/site/fml/faq.fml =================================================================== --- cpptasks/trunk/src/site/fml/faq.fml 2007-07-26 23:26:28 UTC (rev 125) +++ cpptasks/trunk/src/site/fml/faq.fml 2007-07-28 00:09:16 UTC (rev 126) @@ -1,9 +1,9 @@ <?xml version="1.0"?> <!-- - Licensed to the Apache Software Foundation (ASF) under one or more + Licensed to the Ant-Contrib Project under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 + The Ant-Contrib Project licenses this file to You 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 @@ -16,766 +16,12 @@ limitations under the License. --> -<faqs title="Frequently Asked Technical Questions"> +<faqs title="Frequently Asked Questions"> <part id="faq"> - <faq id="1.1"> - <question>What is log4j?</question> - <answer> <p>log4j is a tool to help the programmer output log statements to a - variety of output targets. - </p> - - <p>In case of problems with an application, it is helpful to - enable logging so that the problem can be located. With log4j - it is possible to enable logging at runtime without modifying - the application binary. The log4j package is designed so that - log statements can remain in <i>shipped</i> code without - incurring a high performance cost. It follows that the speed - of logging (or rather not logging) is capital. - </p> - - <p>At the same time, log output can be so voluminous that it quickly - becomes overwhelming. One of the distinctive features of log4j is the - notion of <i>hierarchical loggers</i>. Using loggers it is - possible to selectively control which log statements are output at - arbitrary granularity. - </p> - - <p>log4j is designed with two three goals in mind: - reliability, speed and flexibility. There is a tight balance - between these requirements. We believe that log4j strikes the - right balance. - </p> -</answer> + <faq id="hello"> + <question>A Question?</question> + <answer>An Answer.</answer> </faq> - - - <faq id="1.2"><question>Is log4j a reliable logging system?</question> - <answer><p>No. log4j is not reliable. It is a best-effort - <em>fail-stop</em> logging system. - </p> - - <p>By fail-stop, we mean that log4j will not throw unexpected - exceptions at run-time potentially causing your application to - crash. <b>If for any reason, log4j throws an uncaught exception, - please send an email to the <a href="mailto:log...@lo...">log...@lo...</a> - mailing list</b>. Uncaught exceptions are handled as serious bugs - requiring immediate attention. - </p> - - <p>Moreover, log4j will not revert to System.out or System.err - when its designated output stream is not opened, is not writable or - becomes full. This avoids corrupting an otherwise working program by - flooding the user's terminal because logging fails. However, log4j - will output a single message to System.err indicating that logging can - not be performed. - </p></answer></faq> - - <faq id="1.3"><question>What are the prerequisites for log4j?</question> - <answer> - <p>Log4j versions upto and including 1.2.8 are - compatible with JDK 1.1.x and later. Log4j version 1.3 will - be compatilble with JDK 1.2 and later. - </p> - - <p>The DOMConfigurator is based on the DOM Level 1 - API. The DOMConfigurator.configure(Element) method will work - with any XML parser that will pass it a DOM tree. - </p> - <p>The DOMConfigurator.configure(String filename) method and its - variants require a JAXP compatible XML parser, for example <a href="http://xml.apache.org/">Xerces</a> or Sun's - parser. Compiling the DOMConfigurator requires the presence of a - JAXP parser in the classpath. - </p> - - <p>The <code>org.apache.log4j.net.SMTPAppender</code> - relies on the <a href="http://java.sun.com/products/javamail/">JavaMail - API</a>. It has been tested with JavaMail API version - 1.2. The JavaMail API requires the <a href="http://java.sun.com/beans/glasgow/jaf.html">JavaBeans - Activation Framework</a> package. - </p> - - <p>The <code>org.apache.log4j.net.JMSAppender</code> - requires the presence of the JMS API as well as JNDI. - </p> - - <p>log4j test code relies on the <a href="http://www.junit.org">JUnit</a> testing framework. - </p> - </answer></faq> - - <faq id="1.4"><question>What are the features of log4j?</question> - <answer> - <p>log4j is optimized for speed.</p> - - <p>log4j is based on a named logger hierarchy.</p> - - <p>log4j is fail-stop. However, altough it certainly - strives to ensure delivery, log4j does not guarantee that - each log statement will be delivered to its destination. - </p> - - <p>log4j is thread-safe.</p> - - <p>log4j is not restricted to a predefined set of - facilities.</p> - - <p>Logging behavior can be set at runtime using a - configuration file. Configuration files can be property - files or in XML format. </p> - - <p>log4j is designed to handle Java Exceptions from the - start.</p> - - <p>log4j can direct its output to a file, the console, - an <code>java.io.OutputStream</code>, - <code>java.io.Writer</code>, a remote server using TCP, a - remote Unix Syslog daemon, to a remote listener using JMS, - to the NT EventLog or even send e-mail. </p> - - <p>log4j uses 5 levels, namely DEBUG, INFO, WARN, ERROR and - FATAL. - </p> - - <p>The format of the log output can be easily changed by - extending the <code>Layout</code> - class. </p> - - <p>The target of the log output as well as the writing - strategy can be altered by implementations of the - <code>Appender</code> interface. </p> - - <p>log4j supports multiple output appenders per logger. - </p> - - <p>log4j supports internationalization.</p> - </answer></faq> - - <faq id="1.5"><question>Is there example code for using log4j?</question> - <answer> - <p>See the <code>examples/</code> directory.</p> - </answer> - </faq> - - <faq id="1.6"> - <question>What documentation should I read to learn more about - log4j?</question> - <answer><p>Make sure to read the <a href="manual.html">short - manual</a>. It is also recommended to you read <a href="https://www.qos.ch/shop/products/log4j/log4j-Manual.jsp">The complete - log4j manual</a> which is much more detailed and up to - date. Both documents were written by Ceki Gülcü. - </p></answer> - </faq> - - <faq id="1.7"><question>Is log4j thread-safe?</question> - <answer> - <p>Yes, log4j is thread-safe. Log4j components are designed to - be used in heavily multithreaded systems.</p> - - </answer></faq> - - <faq id="1.8"><question>What does log output look like?</question> - <answer> - <p>The log output can be customized in many ways. Moreover, - one can completely override the output format by implementing - one's own Layout. - </p> - - <p>Here is an example output using <em>PatternLayout</em> with - the conversion pattern <b>"%r [%t] %-5p %c{2} %x - %m%n"</b> - </p> - - <pre class="screen_output"> -176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse order. -225 [main] INFO examples.SortAlgo - Entered the sort method. -262 [main] DEBUG SortAlgo.OUTER i=1 - Outer loop. -276 [main] DEBUG SortAlgo.SWAP i=1 j=0 - Swapping intArray[0] = 1 and intArray[1] = 0 -290 [main] DEBUG SortAlgo.OUTER i=0 - Outer loop. -304 [main] INFO SortAlgo.DUMP - Dump of interger array: -317 [main] INFO SortAlgo.DUMP - Element [0] = 0 -331 [main] INFO SortAlgo.DUMP - Element [1] = 1 -343 [main] INFO examples.Sort - The next log statement should be an error message. -346 [main] ERROR SortAlgo.DUMP - Tried to dump an uninitialized array. - at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58) - at org.log4j.examples.Sort.main(Sort.java:64) -467 [main] INFO examples.Sort - Exiting main method. - </pre> - - <p>The first field is the number of milliseconds elapsed since - the start of the program. The second field is the thread - outputting the log statement. The third field is the level of - the log statement. The fourth field is the rightmost two - components of the logger making the log request. The fifth - field (just before the '-') is the <em>nested diagnostic - context</em> (NDC). Note the nested diagnostic context may be - empty as in the first two statements. The text after the '-' - is the message of the statement. - </p> - </answer></faq> - - <faq id="1.9"><question>Why should I use log4j when JDK 1.4 already ships with a - logging API?</question> - <answer> - - <p> - Although both APIs are conceptually similar, the log4j API is - significantly more flexible and offers many more features, too - numerous to be listed here. You will discover that the - additional features and flexibility turn out to be - indispensable in the context of a mission-critical - application. - </p> - - <p>The open and collaborative way in which log4j is developped - ensures that it continues to preserve and even widen its - competitive edge. At some point, input from bright developers - from all over the world is bound to make a difference. - </p> - </answer> - </faq> - - - <faq id="2.1"><question>What are <em>Loggers</em>?</question> - <answer> - - <p>Lggers lie at the heart of log4j. Loggers define a hierarchy and give - the programmer <em>run-time</em> control on which statements are - printed or not. - </p> - - <p>Loggers are assigned levels. A log statement is printed - depending on its level <em>and</em> its logger. - </p> - - <p>Make sure to read the <a href="manual.html">log4j manual</a> - for more information. - </p> - </answer></faq> - -<faq id="2.2"><question>How can I change log behavior at runtime?</question> - <answer> - <p>Log behavior can be set using configuration files which are parsed - at runtime. Using configuration files the programmer can define - loggers and set their levels. - </p> - - <p>The <code>PropertyConfigurator</code> defines a particular format - of a configuration file. See also the <code>examples/Sort.java</code> - example and associated configuration files. - </p> - - <p>Configuration files can be specified in XML. See - <code>log4j.dtd</code> and - <code>org.log4j.xml.DOMConfigurator</code> for more details. - </p> - - <p>See the various Layout and Appender components for specific - configuration options. - </p> - - <p>In addition to configuration files, the user may disable all - messages belonging to a set of levels. See next item. - </p> - - </answer></faq> - - <faq id="2.3"><question>What is the fastest way of (not) logging?</question> - <answer> - <p> For some logger <code>l</code>, writing, - </p> - - <pre class="source"> - l.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); - </pre> - - <p>incurs the cost of constructing the message parameter, that is - converting both integer <code>i</code> and <code>entry[i]</code> to a - String, and concatenating intermediate strings. This, regardless of - whether the message will be logged or not. - </p> - - <p>If you are worried about speed, then write</p> - <pre class="source"> - if(l.isDebugEnabled()) { - l.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); - } - </pre> - - <p>This way you will not incur the cost of parameter - construction if debugging is disabled for logger - <code>l</code>. On the other hand, if the logger is debug - enabled, you will incur the cost of evaluating whether the - logger is enabled or not, twice: once in - <code>debugEnabled</code> and once in <code>debug</code>. - This is an insignificant overhead since evaluating a logger - takes less than 1% of the time it takes to actually log a - statement. - </p> -</answer></faq> - - <faq id="2.4"><question>Are there any suggested ways for naming loggers?</question> - <answer> - <p>Yes, there are.</p> - - <p>You can name loggers by <strong>locality</strong>. It turns out - that instantiating a logger in each class, with the logger name - equal to the fully-qualified name of the class, is a useful and - straightforward approach of defining loggers. This approach has - many benefits: - </p> - - <ul> - <li>It is very simple to implement.</li> - - <li>It is very simple to explain to new developers.</li> - - <li>It automatically mirrors your application's own modular design. - </li> - <li>It can be further refined at will.</li> - - <li>Printing the logger automatically gives information on the locality - of the log statement. </li> - </ul> - - <p>However, this is not the only way for naming loggers. A - common alternative is to name loggers by <strong>functional - areas</strong>. For example, the "database" logger, "RMI" - logger, "security" logger, or the "XML" logger. - </p> - - <p>You may choose to name loggers by functionality and - subcategorize by locality, as in "DATABASE.com.foo.some.package.someClass" or - "DATABASE.com.foo.some.other.package.someOtherClass". - </p> - - <p><em>You are totally free in choosing the names of your - loggers.</em> The log4j package merely allows you to manage your - names in a hierarchy. However, it is your responsibility to define - this hierarchy. - </p> - - <p>Note by naming loggers by locality one tends to name things by - functionality, since in most cases the locality relates closely to - functionality. - </p> - </answer></faq> - - <faq id="2.5"><question>How do I get the fully-qualified name of a class in a static block?</question> - <answer> - <p>You can easily retrieve the fully-qualified name of a class in a - static block for class X, with the statement - <code>X.class.getName()</code>. Note that <code>X</code> is the class - name and not an instance. The <code>X.class</code> statement does - <i>not</i> create a new instance of class <code>X</code>. - </p> - - <p>Here is the suggested usage template:</p> - - <pre class="source"> -package a.b.c; - -public class Foo { - final static Logger logger = Logger.getLogger(Foo.class); - ... other code - -} - </pre> - </answer></faq> - - <faq id="2.6"><question>Can the log output format be customized? </question> - <answer> - <p>Yes, you can extend the <code>Layout</code> class to create - you own customized log format. Appenders can be parameterized - to use the layout of your choice. - </p> -</answer></faq> - - <faq id="2.7"><question>What are the configurable options for <code>FooBarAppender</code>?</question> - <answer> - <p>Log4j uses JavaBeans style configuration.</p> - - <p>Thus, any setter method in <code>FooBarAppender</code> - corresponds to a configurable option. For example, in <a href="apidocs\org\apache\log4j\RollingFileAppender.html"><code>RollingFileAppender</code></a> - the <a href="apidocs/org/apache/log4j/RollingFileAppender.html#setMaxBackupIndex(int)"><code>setMaxBackupIndex(int - maxBackups)</code></a> method corresponds to the - <code>maxBackupIndex</code> option. The first letter of the - option can be upper case, i.e. <code>MaxBackupIndex</code> - and <code>maxBackupIndex</code> are equivalent but not - <code>MAXBACKUPIndex</code> nor <code>mAXBackupIndex</code>. - </p> - - <p>Layouts options are also defined by their setter methods. The same goes - for most other log4j components. - </p> - </answer></faq> - - <faq id="2.8"><question>What is the recommended way of migrating from - java.util.logging to log4j?</question> - <answer> - - <p>We suggest to just use global file search/replace. You should be able - to replace all the "java.util.Logger" references with - "org.apache.log4j.Logger", and you should be on your way. - </p> - - <p>If you're on a Win32 platform, we recommend <a href="http://www.textpad.com/">Textpad</a>. You can use the - CTRL+SHIFT+O to open all *.java files from a directory including all - its sub-directories, and then use the search/replace function to - replace in all files, and then CTRL+SHIFT+S to save all. Should take - about 60 seconds! :) - </p> - </answer></faq> - - <faq id="2.9"><question>Is it possible to direct log output to - different appenders by level? </question><answer> - <p>Yes it is. Setting the <b>Threshold</b> option of any appender - extending <a href="api/org/apache/log4j/AppenderSkeleton.html">AppenderSkeleton</a>, - (most log4j appenders extend AppenderSkeleton) to filter out all log - events with <em>lower</em> level than the value of the threshold - option. - </p> - - <p>For example, setting the threshold of an appender to DEBUG - also allow INFO, WARN, ERROR and FATAL messages to log along - with DEBUG messages. This is usually acceptable as there is - little use for DEBUG messages without the surrounding INFO, - WARN, ERROR and FATAL messages. Similarly, setting the - threshold of an appender to ERROR will filter out DEBUG, INFO - and WARN messages but not ERROR or FATAL messages. - </p> - - <p>This policy usually best encapsulates what the user - actually wants to do, as opposed to her mind-projected - solution. - </p> - <p>See <i>examples/sort4.lcf</i> for an example threshold - configuration.</p> - - <p>If you must filter events by exact level match, then you can - attach a <a href="apidocs/org/apache/log4j/varia/LevelMatchFilter.html">LevelMatchFilter</a> - to any appender to filter out logging events by exact level match. - </p> - </answer></faq> - - - <faq id="2.10"><question>What does the Windows NT Event Viewer complain about - missing descriptions for my event messages when I use the - <code>NTEventLogAppender</code>?</question> - - <answer> - <p>The NT Event Viewer relies on <i>message resource</i> DLLs - to properly view an event message. The NTEventLogAppender.dll - contains these message resources, but that DLL must be copied - to %SYSTEMROOT%\SYSTEM32 for it to work properly. - </p> - </answer></faq> - - <faq id="2.11"><question>Why can't I map my logger names to the loggers that - appear in the NT Event Log when I use the - NTEventLogAppender?</question> - - <answer> - <p>Unfotunately, the logger names are hardcoded within the - message resource DLL (see previous question about - NTEventLogAppender), so there isn't any easy way to override - those dynamically... in fact, I don't think it's possible to - do it, as you'd have to modify the DLL resources for every - application. Since most native applications don't use the - Logger column anyway... - </p> - </answer></faq> - - <faq id="2.12"><question>Are there suggested approaches for logging in JSP pages?</question> - <answer> - <p> - The suggested approach depends on your design requirements. If you or - your organization has no constraints on the use of Java in JSP pages, - simply use log4j normally in <code><% ... %></code> statements - as indicated in the Short Manual and the rest of the documentation. - </p> - <p> - However, if your design calls for a minimum amount of Java in your JSP - pages, consider using the - <a href="http://jakarta.apache.org/taglibs/doc/log-doc/intro.html">Log Taglib</a> - from the Jakarta Taglibs project. It provides logging JSP tags that invoke - log4j. - </p> - </answer> - </faq> - - <faq id="3.1"><question>Can the outputs of multiple client request go to - different log files?</question> - <answer> - <p>Many developers are confronted with the problem of - distinguishing the log output originating from the same class - but different client requests. They come up with ingenious - mechanisms to fan out the log output to different files. In - most cases, this is not the right approach. - </p> - - <p>It is simpler to use a nested diagnostic context - (NDC). Typically, one would <em>NDC.push()</em> client - specific information, such as the client's hostname, ID or any - other distinguishing information when starting to handle the - client's request. Thereafter, log output will automatically - include the nested diagnostic context so that you can - distinguish logs from different client requests even if they - are output to the same file. - </p> - - <p>See the <code>NDC</code> and the <code>PatternLayout</code> - classes for more information. The <code>NumberCruncher</code> - example shows how the NDC can be used to distinguish the log - output from multiple clients even if they share the same log - file. - </p> - - <p>For select applications, such as virtual hosting - web-servers, the NDC solution is not sufficient. As of version - 0.9.0, log4j supports multiple hierarchy trees. Thus, it is - possible to log to different targets from the same logger - depending on the current context. - </p> - </answer></faq> - - - <faq id="3.2"><question>Logger instances seem to be create only. Why isn't - there a method to remove logger instances?</question> - <answer> - <p>It is quite nontrivial to define the semantics of a - "removed" logger escecially if it is still referenced by the - user. Future releases <em>may</em> include a remove method in - the Logger class.</p></answer></faq> - - <faq id="3.3"><question>How do I get multiple process to log to the same file?</question> - <answer> - <p>You may have each process log to a - <a href="apidocs/org/apache/log4j/net/SocketAppender.html"><code>SocketAppender</code></a>. - The receiving - <a href="apidocs/org/apache/log4j/net/SocketServer.html"><code>SocketServer</code></a> - (or - <a href="apidocs/org/apache/log4j/net/SimpleSocketServer.html"><code>SimpleSocketServer</code></a>) - can receive all the events and send them to a single - log file. - </p> - </answer></faq> - - <faq id="3.4"><question>How about the timesamps of events generated by multiple - processes across multiple hosts (possibly across multiple - timezones)?</question> - <answer> - <p>The timestamp is created when the logging event is created. - That is so say, when the <code>debug</code>, - <code>info</code>, <code>warn</code>, <code>error</code> or - <code>fatal</code> method is invoked. Thus, the timestamp is - unaffected by the time at which event arrive at a remote - socket server. - </p> - - <p>Timestamps are stored in UTC format inside the - event. Consequently, when displayed or written to a log file, - timestamps appear in the same timezone as the host displaying - or creating the logfile. Note that because the clocks of - various machines may not be synchronized, there may be - timestamp inconsistencies between events generated on - different hosts. - </p> - </answer></faq> - - <faq id="3.5"><question>Why can't log4j find my properties file in a J2EE or WAR - application?</question><answer> - <p>The short answer: the log4j classes and the properties file - are not within the scope of the same classloader. - </p> - - <p>The long answer (and what to do about it): J2EE or Servlet - containers utilize Java's class loading system. Sun changed - the way classloading works with the release of Java 2. In - Java 2, classloaders are arranged in a hierarchial - parent-child relationship. When a child classloader needs to - find a class or a resource, it first delegates the request to - the parent. - </p> - - <p>Log4j only uses the default <code>Class.forName()</code> - mechanism for loading classes. Resources are handled - similarly. See the documentation for - <code>java.lang.ClassLoader</code> for more details. - </p> - - <p>So, if you're having problems, try loading the class or - resource yourself. If you can't find it, neither will - log4j. ;) - </p></answer></faq> - - - <faq id="3.6"><question>Is there a way to get log4j to automatically reload a - configuration file if it changes?</question><answer> - - <p>Yes. Both the DOMConfigurator and the PropertyConfigurator support - automatic reloading through the <code>configureAndWatch</code> method. - See the API documentation for more details. - </p> - - - <p>Because the <code>configureAndWatch</code> launches a - separate wathdog thread, and because there is no way to stop - this thread in log4j 1.2, the <code>configureAndWatch</code> - method is unsafe for use in J2EE envrironments where - applications are recycled. - </p></answer></faq> - - - <faq id="4.1"><question>Why should I donate my extensions to log4j back to the - project?</question><answer> - <p>Contrary to the GNU Public License (GPL) the Apache - Software License does not make any claims over your - extensions. By extensions, we mean totally new code that - invokes existing log4j classes. <em>You are free to do - whatever you wish with your proprietary log4j extensions.</em> - In particular, you may choose to never release your extensions - to the wider public. - </p> - - <p>We are very careful not to change the log4j client API so - that newer log4j releases are backward compatible with - previous versions. We are a lot less scrupulous with the - internal log4j API. Thus, if your extension is designed to - work with log4j version <code>n</code>, then when log4j - release version <code>n+1</code> comes out, you will probably - need to adapt your proprietary extensions to the new release. - </p> - - <p>Thus, you will be forced to spend precious resources in - order to keep up with log4j changes. This is commonly referred - to as the "stupid-tax." By donating the code and making it - part of the standard distribution, you save yourself the - unnecessary maintenance work. - </p> - - <p>If your extensions are useful then someone will eventually - write an extension providing the same or very similar - functionality. Your development effort will be wasted. Unless - the proprietary log4j extension is business critical, there is - little reason for not donating your extensions back to the - project. - </p></answer></faq> - - <faq id="4.2"><question>What should I keep in mind when contributing code?</question> - <answer> - <ol> - - <li> - <p>Write a test case for your contribution.</p> - - <p>There is nothing more irritating than finding the bugs - in debugging (i.e. logging) code. Writing a test case - takes some effort but is crucial for a widely used library - such as log4j. Writing a test case will go a long way in - earning you the respect of fellow developers. See the - tests/ directory for exiting test cases. - </p> - </li> - - - <li> - <p>Stick to the existing indentation style even if you hate it.</p> - - <p>Alternating between indentation styles makes it hard to - understand the source code. Make it a little harder on - yourself but easier on others. - </p> - - <p>Log4j has adopted a rather conservative approach by - following the <a href="http://java.sun.com/docs/codeconv/">Code Conventions - for the JavaTM Programming Language</a>. <b>We use 2 (two) - spaces for indentation and no tabs.</b> - </p> - </li> - - <li> - <p>Please do not both modify the code and change the - indentation in a single commit.</p> - - <p>If you change the code and reformat it at the same time - and then commit, the commit notification message will be - hard to read. It will contain many diffs associated with - the reformatting in addition to logical changes. - </p> - - <p>If you must reformat and change the code, then perform - each step separately. For example, reformat the code and - commit. Following that, you can change the logic and - commit. The two steps can be performed in the reverse - order just as well. You can first change the logic and - commit and only later reformat and commit. - </p> - - </li> - <li> - <p>Make every effort to stick to the JDK 1.1 API.</p> - - <p>One of the important advantages of log4j is its - compatibility with JDK 1.1.x. - </p> - </li> - - <li> - <p>Always keep it simple, small and fast when - possible.</p> - - <p>It's all about the application not about logging.</p> - </li> - - <li> - <p>Identify yourself as a contributor at the top of the - relevant file. - </p> - </li> - <li> - <p>Take responsibility for your code.</p> - - <p>Authoring software is very much like running a marathon. It - takes time and endurance. - </p> - </li> - <li> - <p>Did we mention sticking with the indentation style? </p> - </li> - <li><p>Did we mention writing test cases? </p> - </li> - - </ol> - </answer></faq> - - - <faq id="duplicate-messages"> - <question>Why am I getting multiple copies of messages in my log file?</question> - <answer> - <p>There are several reasons this can occur: - <ul> - <li>Repeated configuration of log4j: By default, each call to - PropertyConfigurator.configure or DOMConfigurator.configure is - culmulative. If your configuration file defines a file appender, - calling PropertyConfigurator.configure three times will create - three distinct instances and connect each of them to the specified logger.</li> - <li>Attaching the same appender to multiple loggers: if an appender is - attached to the root logger and child logger, then any message - sent to the child logger will go to the appender twice (unless - additivity is set to false).</li> - </ul></p> - </answer> - </faq> - <faq id="custom-level"> - <question>How do I add a custom level?</question> - <answer> - <p>It is possible, but rarely appropriate. The - request is commonly for a level named something like "audit" - that doesn't obviously fit in the progression "trace", "debug", - "info", "warn", "error" and "fatal". In that case, the request - for a level is really a request for a mechanism to specify - a different audience. The appropriate mechanism is to use a distinct - logger name (or tree) for "audit" related messages.</p> - </answer> - </faq> </part> </faqs> Modified: cpptasks/trunk/src/site/site.xml =================================================================== --- cpptasks/trunk/src/site/site.xml 2007-07-26 23:26:28 UTC (rev 125) +++ cpptasks/trunk/src/site/site.xml 2007-07-28 00:09:16 UTC (rev 126) @@ -16,6 +16,15 @@ --> <project name="cpptasks: Compile tasks for Apache Ant"> + <bannerLeft> + <name>ant-contrib</name> + <href>http://ant-contrib.sourceforge.net/</href> + </bannerLeft> + <bannerRight> + <name>SourceForge.net Logo</name> + <src>http://sflogo.sourceforge.net/sflogo.php?group_id=36177&type=5</src> + <href>http://www.sourceforge.net/</href> + </bannerRight> <body> <breadcrumbs> <item name="ant-contrib" href="http://ant-contrib.sourceforge.net/"/> @@ -31,19 +40,30 @@ <menu name="About cpptasks"> <item name="Usage" href="/index.html"/> <item name="FAQ" href="/faq.html"/> - <item name="Roadmap" href="/roadmap.html"/> </menu> + + <menu name="Elements"> + <item name="cc" href="/antdocs/CCTask.html"/> + <item name="compiler" href="/antdocs/CompilerDef.html"/> + <item name="defineset" href="/antdocs/DefineSet.html"/> + <item name="distributer" href="/antdocs/DistributerDef.html"/> + <item name="libraryset" href="/antdocs/LibrarySet.html"/> + <item name="linker" href="/antdocs/LinkerDef.html"/> + <item name="syslibraryset" href="/antdocs/SystemLibrarySet.html"/> + <item name="targetplatform" href="/antdocs/TargetDef.html"/> + <item name="versioninfo" href="/antdocs/VersionInfo.html"/> + </menu> <menu name="Community"> <item name="Mailing Lists" href="/mail-lists.html"/> <item name="Issue Tracking" href="/issue-tracking.html"/> + <item name="Project Page" href="http://sourceforge.net/projects/ant-contrib/"/> + <item name="News" href="http://sourceforge.net/news/?group_id=36177"/> </menu> <menu name="Development"> <item name="Repository" href="/source-repository.html"/> <item name="JavaDoc" href="/apidocs/index.html"/> - <item name="Cross Reference" href="/jxr.html"/> - <item name="Dependencies" href="/dependencies.html"/> <item name="Continuous Integration" href="/integration.html"/> </menu> </body> Property changes on: cpptasks/trunk/src/site/xdoc/antdocs ___________________________________________________________________ Name: svn:ignore + *.xml Added: cpptasks/trunk/src/taskdocs/java/net/sf/antcontrib/taskdocs/TaskDoclet.java =================================================================== --- cpptasks/trunk/src/taskdocs/java/net/sf/antcontrib/taskdocs/TaskDoclet.java (rev 0) +++ cpptasks/trunk/src/taskdocs/java/net/sf/antcontrib/taskdocs/TaskDoclet.java 2007-07-28 00:09:16 UTC (rev 126) @@ -0,0 +1,414 @@ +/* +Licensed to the Ant-Contrib Project under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The Ant-Contrib Project licenses this file to You 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. + +*/ +package net.sf.antcontrib.taskdocs; + +import com.sun.javadoc.*; +import org.xml.sax.*; +import org.xml.sax.helpers.AttributesImpl; +import org.xml.sax.helpers.DefaultHandler; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Source; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; +import java.io.File; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; + + +/** + * This document writes an XML representation of the + * Ant related Javadoc through an XSLT transform that creates xdoc files. + * + */ +public final class TaskDoclet { + /** + * Process Javadoc content. + * @param root root of javadoc content. + * @return true if successful + * @throws Exception IO exceptions and the like. + */ + public static boolean start(RootDoc root) throws Exception { + SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance(); + Source typeStyle = new StreamSource(new File("src/taskdocs/resources/net/sf/antcontrib/taskdocs/element.xslt")); + // + // replace with tf.newTransformerHandler() if you want to see raw generated XML. + TransformerHandler typeHandler = tf.newTransformerHandler(typeStyle); + + Map referencedTypes = new HashMap(); + Map documentedTypes = new HashMap(); + ClassDoc[] classes = root.classes(); + for (int i = 0; i < classes.length; ++i) { + ClassDoc clazz = classes[i]; + if (clazz.isPublic() && !clazz.isAbstract()) { + if (isTask(clazz) || isType(clazz)) { + writeClass(typeHandler, clazz, referencedTypes); + documentedTypes.put(clazz.qualifiedTypeName(), clazz); + } + } + } + + Map additionalTypes = new HashMap(); + for (Iterator iter = referencedTypes.keySet().iterator(); iter.hasNext();) { + String referencedName = (String) iter.next(); + if (documentedTypes.get(referencedName) == null) { + ClassDoc referencedClass = root.classNamed(referencedName); + if (referencedClass != null) { + if (!referencedClass.qualifiedTypeName().startsWith("org.apache.tools.ant")) { + writeClass(typeHandler, referencedClass, additionalTypes); + documentedTypes.put(referencedClass.qualifiedTypeName(), referencedClass); + } + } + } + } + + + return true; + } + + + /** + * Determine if class is an Ant task. + * @param clazz class to test. + * @return true if class is an Ant task. + */ + private static boolean isTask(final ClassDoc clazz) { + if (clazz == null) return false; + if ("org.apache.tools.ant.Task".equals(clazz.qualifiedTypeName())) { + System.out.print("true"); + return true; + } + return isTask(clazz.superclass()); + + } + + /** + * Determine if class is an Ant type. + * @param clazz class to test. + * @return true if class is an Ant type. + */ + private static boolean isType(final ClassDoc clazz) { + if (clazz == null) return false; + if ("org.apache.tools.ant.types.DataType".equals(clazz.qualifiedTypeName())) { + return true; + } + return isType(clazz.superclass()); + + } + + /** + * Namespace URI for class description elements. + */ + private static final String NS_URI = "http://ant-contrib.sf.net/taskdocs"; + /** + * Namespace URI for XHTML elements. + */ + private static final String XHTML_URI = "http://www.w3.org/1999/xhtml"; + + /** + * Write a Java type. + * @param tf content handler. + * @param type documented type. + * @throws Exception if IO or other exception. + */ + private static void writeType(final TransformerHandler tf, final Type type) throws Exception { + AttributesImpl attributes = new AttributesImpl(); + attributes.addAttribute(null, "name", "name", "CDATA", type.simpleTypeName()); + attributes.addAttribute(null, "qualifiedTypeName", "qualifiedTypeName", "CDATA", type.qualifiedTypeName()); + tf.startElement(NS_URI, "type", "type", attributes); + ClassDoc typeDoc = type.asClassDoc(); + if (typeDoc != null && typeDoc.commentText() != null && typeDoc.commentText().length() > 0) { + writeDescription(tf, typeDoc.commentText()); + } else { + tf.characters(type.typeName().toCharArray(), 0, type.typeName().length()); + } + tf.endElement(NS_URI, "type", "type"); + + } + + /** + * Write an Ant task or type attribute (aka property). + * @param tf content handler. + * @param method set method for property. + * @throws Exception if IO or other exception. + */ + private static void writeAttribute(final TransformerHandler tf, final MethodDoc method) throws Exception { + AttributesImpl attributes = new AttributesImpl(); + attributes.addAttribute(null, "name", "name", "CDATA", method.name().substring(3).toLowerCase(Locale.US)); + tf.startElement(NS_URI, "attribute", "attribute", attributes); + writeType(tf, method.parameters()[0].type()); + attributes.clear(); + tf.startElement(NS_URI, "comment", "comment", attributes); + writeDescription(tf, method.commentText()); + tf.endElement(NS_URI, "comment", "comment"); + tf.endElement(NS_URI, "attribute", "attribute"); + } + + + /** + * Write an Ant nested element. + * @param tf content handler. + * @param method method to add element to task or type. + * @param name name of nested element. + * @param type type of nested element. + * @param referencedTypes map of types referenced in documentation. + * @throws Exception if IO or other exception. + */ + private static void writeChild(final TransformerHandler tf, + final MethodDoc method, + final String name, + final Type type, + final Map referencedTypes) throws Exception { + AttributesImpl attributes = new AttributesImpl(); + attributes.addAttribute(null, "name", "name", "CDATA", name.toLowerCase(Locale.US)); + tf.startElement(NS_URI, "child", "child", attributes); + attributes.clear(); + tf.startElement(NS_URI, "comment", "comment", attributes); + writeDescription(tf, method.commentText()); + tf.endElement(NS_URI, "comment", "comment"); + writeType(tf, type); + tf.endElement(NS_URI, "child", "child"); + referencedTypes.put(type.qualifiedTypeName(), type); + } + + + /** + * Redirects parsed XHTML comment into output stream. + * Drops start and end document and body element. + */ + private static class RedirectHandler extends DefaultHandler { + /** + * output handler. + */ + private final ContentHandler tf; + + /** + * Create new instance. + * @param tf output handler, may not be null. + */ + public RedirectHandler(final TransformerHandler tf) { + if (tf == null) { throw new IllegalArgumentException("tf"); } + this.tf = tf; + } + + /** {@inheritDoc} */ + public void characters(final char[] ch, final int start, final int length) throws SAXException { + tf.characters(ch, start, length); + } + + /** {@inheritDoc} */ + public void endDocument() { + } + + /** {@inheritDoc} */ + public void endElement(final String namespaceURI, + final String localName, + final String qName) throws SAXException { + if (!"body".equals(localName)) { + tf.endElement(namespaceURI, localName, qName); + } + } + + /** {@inheritDoc} */ + public void endPrefixMapping(final String prefix) throws SAXException { + tf.endPrefixMapping(prefix); + } + + /** {@inheritDoc} */ + public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { + tf.ignorableWhitespace(ch, start, length); + } + + /** {@inheritDoc} */ + public void processingInstruction(final String target, final String data) throws SAXException { + tf.processingInstruction(target, data); + } + + /** {@inheritDoc} */ + public void setDocumentLocator(final Locator locator) { + tf.setDocumentLocator(locator); + } + + /** {@inheritDoc} */ + public void skippedEntity(String name) throws SAXException { + tf.skippedEntity(name); + } + + /** {@inheritDoc} */ + public void startDocument() { + } + + /** {@inheritDoc} */ + public void startElement(final String namespaceURI, + final String localName, + final String qName, + final Attributes atts) throws SAXException { + if (!"body".equals(localName)) { + tf.startElement(namespaceURI, localName, qName, atts); + } + } + + /** {@inheritDoc} */ + public void startPrefixMapping(String prefix, String uri) throws SAXException { + tf.startPrefixMapping(prefix, uri); + } + } + + /** + * Writes description. + * @param tf destination. + * @param description description, may contain XHTML elements. + * @throws SAXException if IO or other exception. + */ + private static void writeDescription(final TransformerHandler tf, + final String description) throws SAXException { + if (description.indexOf('<') == -1) { + tf.characters(description.toCharArray(), 0, description.length()); + } else { + // + // attempt to fabricate an XHTML fragment + // + StringBuffer buf = new StringBuffer(description); + buf.insert(0, "<body xmlns='" + XHTML_URI + "'>"); + buf.append("</body>"); + try { + SAXParserFactory sf = SAXParserFactory.newInstance(); + sf.setNamespaceAware(true); + SAXParser parser = sf.newSAXParser(); + parser.parse(new InputSource(new StringReader(buf.toString())), new RedirectHandler(tf)); + } catch (Exception ex) { + tf.characters(ex.toString().toCharArray(), 0, ex.toString().length()); + } + } + } + + /** + * Write all Ant attributes in this class and superclasses. + * @pa... [truncated message content] |