Loading ...
Sorry, an error occurred while loading the content.

TextListener improvement

Expand Messages
  • toalexsmail
    Currently TextListener on every event simply writes to standard output (or to PrintWriter). If junits or application aslo writes its logs to standard output
    Message 1 of 6 , Mar 12, 2008
    • 0 Attachment
      Currently TextListener on every event simply writes to standard output
      (or to PrintWriter). If junits or application aslo writes its logs to
      standard output then this output is mixed. For example, failures will
      be written inside the logs of the application and not in the end.
      Moreover, if there is some activity in @AfterClass that also prints to
      the standard output than this will be written down AFTER summary of
      the Junit.

      I have partial solution to this situation. TextListener (or a new
      class, say ConsoleListener) should create new PrintWriter(new
      StringWriter()) and collect the result their. On testRunFinished() it
      should flush the information from StringWriter to the PrintStream that
      received in the constructor (String.out for example).
      This solution doesn't solve situation when there is some writing to
      the standard output in @AfterClass.
    • toalexsmail
      ... See also https://sourceforge.net/tracker/?func=detail&atid=365278&aid=1913115&group_id=15278 (there is a path described below their) Here is my solution:
      Message 2 of 6 , Apr 28 3:08 PM
      • 0 Attachment
        --- In junit@yahoogroups.com, "toalexsmail" <toalexsmail@...> wrote:
        >
        > Currently TextListener on every event simply writes to standard output
        > (or to PrintWriter). If junits or application aslo writes its logs to
        > standard output then this output is mixed. For example, failures will
        > be written inside the logs of the application and not in the end.
        > Moreover, if there is some activity in @AfterClass that also prints to
        > the standard output than this will be written down AFTER summary of
        > the Junit.
        >
        > I have partial solution to this situation. TextListener (or a new
        > class, say ConsoleListener) should create new PrintWriter(new
        > StringWriter()) and collect the result their. On testRunFinished() it
        > should flush the information from StringWriter to the PrintStream that
        > received in the constructor (String.out for example).
        > This solution doesn't solve situation when there is some writing to
        > the standard output in @AfterClass.
        >

        See also
        https://sourceforge.net/tracker/?func=detail&atid=365278&aid=1913115&group_id=15278
        (there is a path described below their)

        Here is my solution:

        public class JUnitTest{

        public static void main(String[] args){
        Request r = Request.aClass(JUnitTest.class);
        JUnitCore runner = new JUnitCore();
        PrintStream out = System.out;
        RunListener runListener = new FlushedPrintStreamListener(out);
        runner.addListener(runListener);
        Result result = runner.run(r);
        int code = -1;
        int failures = result.getFailureCount();
        if(failures>0){
        code = -failures;
        } else {
        code = result.getIgnoreCount();
        }
        System.exit(code);
        }

        }

        public class PrintStreamListener extends RunListener{
        //Definition of delimiters is in Description
        private static final Pattern DISPAY_NAME_PATTERN =
        Pattern.compile("()");
        private TextListener textListener;
        private PrintStream writer;

        public PrintStreamListener() {
        this(System.out);
        }

        public PrintStreamListener(PrintStream writer) {
        super();
        this.textListener = new TextListener(writer);
        this.writer = writer;
        }

        /**
        * For sub-classes use.
        *
        * @return
        */
        protected PrintStream getWriter(){
        return writer;
        }

        private PrintStream getNotNullWriter(){
        PrintStream writer = getWriter();
        if(writer==null){
        throw new IllegalStateException("writer should be not null");
        }
        return writer;
        }


        /**
        * This method can be overriden in sub-classes.
        *
        * @param description
        * @throws IllegalArgumentException if description is null.
        */
        protected void writeMethodName(Description description){
        if(description==null){
        throw new IllegalArgumentException("description should be not null");
        }
        String displayName = description.getDisplayName();
        String[] complexNames = DISPAY_NAME_PATTERN.split(displayName, 3);
        String methodName = (complexNames==null ||
        complexNames.length!=2)?displayName:complexNames[1];
        PrintStream writer = getNotNullWriter();

        writer.print(methodName);
        writer.print(' ');
        }


        /**
        * Called when an atomic test is about to be started.
        * @param description the description of the test that is about to be
        run
        * (generally a class and method name)
        */
        @Override
        public void testStarted(Description description) {
        textListener.testStarted(description);
        }


        /**
        * Called when an atomic test fails.
        * @param failure describes the test that failed and the exception
        that was thrown
        */
        @Override
        public void testFailure(Failure failure) {
        Description description = failure.getDescription();
        PrintStream writer = getNotNullWriter();

        writeMethodName(description);
        textListener.testFailure(failure);
        writer.println();
        }

        /**
        * Called when a test will not be run, generally because a test
        method is annotated
        * with {@link org.junit.Ignore}.
        * @param description describes the test that will not be run
        */
        @Override
        public void testIgnored(Description description) {
        writeMethodName(description);
        PrintStream writer = getNotNullWriter();
        textListener.testIgnored(description);
        writer.println();
        }


        @Override
        public void testRunFinished(Result result) {
        textListener.testRunFinished(result);
        }

        /**
        * Called before any tests have been run.
        * @param description describes the tests to be run
        */
        @Override
        public void testRunStarted(Description description) throws Exception {
        PrintStream writer = getNotNullWriter();
        String displayName = description.getDisplayName();
        String[] complexNames = DISPAY_NAME_PATTERN.split(displayName, 3);
        String className = (complexNames==null ||
        complexNames.length!=2)?displayName:complexNames[0];
        writer.print("started to test "+className);
        writer.println();
        }
        }

        public class FlushedPrintStreamListener extends PrintStreamListener{

        public FlushedPrintStreamListener() {
        super();
        }

        public FlushedPrintStreamListener(PrintStream writer) {
        super(writer);
        }

        /**
        * Called when an atomic test is about to be started.
        * @param description the description of the test that is about to be
        run
        * (generally a class and method name)
        */
        @Override
        public void testStarted(Description description) {
        super.testStarted(description);
        flush();
        }


        /**
        * Called when an atomic test fails.
        * @param failure describes the test that failed and the exception
        that was thrown
        */
        @Override
        public void testFailure(Failure failure) {
        super.testFailure(failure);
        flush();
        }

        /**
        * Called when a test will not be run, generally because a test
        method is annotated
        * with {@link org.junit.Ignore}.
        * @param description describes the test that will not be run
        */
        @Override
        public void testIgnored(Description description) {
        super.testIgnored(description);
        flush();
        }




        @Override
        public void testRunFinished(Result result) {
        super.testRunFinished(result);
        //flush();
        }

        /**
        * Called before any tests have been run.
        * @param description describes the tests to be run
        */
        @Override
        public void testRunStarted(Description description) throws Exception {
        super.testRunStarted(description);
        flushRunStarted();
        }

        /**
        * Can be changed in sub-class.
        */
        protected void flushRunStarted(){
        //don' flush

        }

        /**
        * Can be changed in sub-class.
        *
        */
        protected void flush(){
        PrintStream writer = getWriter();
        if(writer!=null){
        writer.flush();
        }
        }

        }

        /**
        * Redirect an output stream to a logger.
        * This class is useful to redirect standard output or
        * standard error to a Logger. An example use is
        *
        * <pre>
        * final LoggerOutputStream outputStream =
        * new LoggerOutputStream( log );
        * final PrintStream output = new PrintStream( outputStream, true );
        *
        * System.setOut( output );
        * </pre>
        *
        */
        public class LoggerOutputStream
        extends OutputStream
        {
        ///Logger that we log to
        private final Log m_logger;


        ///The buffered output so far
        private final StringBuffer m_output = new StringBuffer(1024);

        ///Flag set to true once stream closed
        private boolean m_closed;

        /**
        * Construct OutputStreamLogger to write to a particular logger at
        a particular priority.
        *
        * @param logger the logger to write to
        * @param priority the priority at which to log
        */
        public LoggerOutputStream( final Log logger)
        {
        m_logger = logger;
        }

        /**
        * Shutdown stream.
        *
        */
        public void close()
        throws IOException
        {
        flush();
        super.close();
        m_closed = true;
        }

        /**
        * Write a single byte of data to output stream.
        *
        * @param data the byte of data
        * @exception IOException if an error occurs
        */
        public void write( final int data )
        throws IOException
        {
        checkValid();

        //Should we properly convert char using locales etc??
        m_output.append( (char)data );


        }

        /**
        * Flush data to underlying logger.
        *
        * @exception IOException if an error occurs
        */
        public synchronized void flush()
        throws IOException
        {
        checkValid();

        m_logger.info(m_output.toString() );
        m_output.setLength( 0 );


        }

        /**
        * Make sure stream is valid.
        *
        * @exception IOException if an error occurs
        */
        private void checkValid()
        throws IOException
        {
        if( true == m_closed )
        {
        throw new EOFException( "OutputStreamLogger closed" );
        }
        }
        }
      • toalexsmail
        PrintStreamListener has a bug. Here is correct version: public class PrintStreamListener extends RunListener{ //Definition of delimiters is in Description
        Message 3 of 6 , Apr 28 4:33 PM
        • 0 Attachment
          PrintStreamListener has a bug. Here is correct version:


          public class PrintStreamListener extends RunListener{
          //Definition of delimiters is in Description
          private static final Pattern DISPAY_NAME_PATTERN =
          Pattern.compile("[()]");
          private TextListener textListener;
          private PrintStream writer;

          public PrintStreamListener() {
          this(System.out);
          }

          public PrintStreamListener(PrintStream writer) {
          super();
          this.textListener = new TextListener(writer);
          this.writer = writer;
          }

          /**
          * For sub-classes use.
          *
          * @return
          */
          protected PrintStream getWriter(){
          return writer;
          }

          private PrintStream getNotNullWriter(){
          PrintStream writer = getWriter();
          if(writer==null){
          throw new IllegalStateException("writer should be not null");
          }
          return writer;
          }


          /**
          * This method can be overriden in sub-classes.
          *
          * @param description
          * @throws IllegalArgumentException if description is null.
          */
          protected void writeMethodName(Description description){
          if(description==null){
          throw new IllegalArgumentException("description should be not null");
          }
          String displayName = description.getDisplayName();
          //third place is empty, workaround to avoid ) at the end of the String
          String[] complexNames = DISPAY_NAME_PATTERN.split(displayName, 3);
          String methodName = (complexNames==null ||
          complexNames.length==0)?null:complexNames[0];
          if(methodName == null || "".equals(methodName)){
          methodName = displayName;
          }
          PrintStream writer = getNotNullWriter();

          writer.print(methodName);
          writer.print(' ');
          }


          /**
          * Called when an atomic test is about to be started.
          * @param description the description of the test that is about to be
          run
          * (generally a class and method name)
          */
          @Override
          public void testStarted(Description description) {
          textListener.testStarted(description);
          }


          /**
          * Called when an atomic test fails.
          * @param failure describes the test that failed and the exception
          that was thrown
          */
          @Override
          public void testFailure(Failure failure) {
          Description description = failure.getDescription();
          PrintStream writer = getNotNullWriter();

          writeMethodName(description);
          textListener.testFailure(failure);
          writer.println();
          }

          /**
          * Called when a test will not be run, generally because a test
          method is annotated
          * with {@link org.junit.Ignore}.
          * @param description describes the test that will not be run
          */
          @Override
          public void testIgnored(Description description) {
          writeMethodName(description);
          PrintStream writer = getNotNullWriter();
          textListener.testIgnored(description);
          writer.println();
          }


          @Override
          public void testRunFinished(Result result) {
          textListener.testRunFinished(result);
          }

          /**
          * Called before any tests have been run.
          * @param description describes the tests to be run
          */
          @Override
          public void testRunStarted(Description description) throws Exception {
          PrintStream writer = getNotNullWriter();
          String displayName = description.getDisplayName();
          //third place is empty, workaround to avoid ) at the end of the String
          String[] complexNames = DISPAY_NAME_PATTERN.split(displayName, 3);
          String className = (complexNames==null ||
          complexNames.length<2)?null:complexNames[1];
          if(className == null || "".equals(className)){
          className = displayName;
          }
          writer.print("started to test "+className);
          writer.println();
          }





          }
        • Kent Beck
          Alex, It would help me if you provided test cases that break with the current code and pass with the changes below. Regards, Kent Beck Three Rivers Institute
          Message 4 of 6 , Apr 28 7:45 PM
          • 0 Attachment
            Alex,

            It would help me if you provided test cases that break with the current code
            and pass with the changes below.

            Regards,

            Kent Beck
            Three Rivers Institute

            _____

            From: junit@yahoogroups.com [mailto:junit@yahoogroups.com] On Behalf Of
            toalexsmail
            Sent: Monday, April 28, 2008 4:33 PM
            To: junit@yahoogroups.com
            Subject: [junit] Re: TextListener improvement



            PrintStreamListener has a bug. Here is correct version:

            public class PrintStreamListener extends RunListener{
            //Definition of delimiters is in Description
            private static final Pattern DISPAY_NAME_PATTERN =
            Pattern.compile("[()]");
            private TextListener textListener;
            private PrintStream writer;

            public PrintStreamListener() {
            this(System.out);
            }

            public PrintStreamListener(PrintStream writer) {
            super();
            this.textListener = new TextListener(writer);
            this.writer = writer;
            }

            /**
            * For sub-classes use.
            *
            * @return
            */
            protected PrintStream getWriter(){
            return writer;
            }

            private PrintStream getNotNullWriter(){
            PrintStream writer = getWriter();
            if(writer==null){
            throw new IllegalStateException("writer should be not null");
            }
            return writer;
            }


            /**
            * This method can be overriden in sub-classes.
            *
            * @param description
            * @throws IllegalArgumentException if description is null.
            */
            protected void writeMethodName(Description description){
            if(description==null){
            throw new IllegalArgumentException("description should be not null");
            }
            String displayName = description.getDisplayName();
            //third place is empty, workaround to avoid ) at the end of the String
            String[] complexNames = DISPAY_NAME_PATTERN.split(displayName, 3);
            String methodName = (complexNames==null ||
            complexNames.length==0)?null:complexNames[0];
            if(methodName == null || "".equals(methodName)){
            methodName = displayName;
            }
            PrintStream writer = getNotNullWriter();

            writer.print(methodName);
            writer.print(' ');
            }


            /**
            * Called when an atomic test is about to be started.
            * @param description the description of the test that is about to be
            run
            * (generally a class and method name)
            */
            @Override
            public void testStarted(Description description) {
            textListener.testStarted(description);
            }

            /**
            * Called when an atomic test fails.
            * @param failure describes the test that failed and the exception
            that was thrown
            */
            @Override
            public void testFailure(Failure failure) {
            Description description = failure.getDescription();
            PrintStream writer = getNotNullWriter();

            writeMethodName(description);
            textListener.testFailure(failure);
            writer.println();
            }

            /**
            * Called when a test will not be run, generally because a test
            method is annotated
            * with {@link org.junit.Ignore}.
            * @param description describes the test that will not be run
            */
            @Override
            public void testIgnored(Description description) {
            writeMethodName(description);
            PrintStream writer = getNotNullWriter();
            textListener.testIgnored(description);
            writer.println();
            }


            @Override
            public void testRunFinished(Result result) {
            textListener.testRunFinished(result);
            }

            /**
            * Called before any tests have been run.
            * @param description describes the tests to be run
            */
            @Override
            public void testRunStarted(Description description) throws Exception {
            PrintStream writer = getNotNullWriter();
            String displayName = description.getDisplayName();
            //third place is empty, workaround to avoid ) at the end of the String
            String[] complexNames = DISPAY_NAME_PATTERN.split(displayName, 3);
            String className = (complexNames==null ||
            complexNames.length<2)?null:complexNames[1];
            if(className == null || "".equals(className)){
            className = displayName;
            }
            writer.print("started to test "+className);
            writer.println();
            }





            }






            [Non-text portions of this message have been removed]
          • toalexsmail
            Kent, I will do it in the future, maybe in this weekend, but I don t promise. ... current code
            Message 5 of 6 , Apr 30 7:20 AM
            • 0 Attachment
              Kent, I will do it in the future, maybe in this weekend, but I don't
              promise.

              --- In junit@yahoogroups.com, "Kent Beck" <kentb@...> wrote:
              >
              > Alex,
              >
              > It would help me if you provided test cases that break with the
              current code
              > and pass with the changes below.
              >
              > Regards,
              >
              > Kent Beck
              > Three Rivers Institute
              >
              > _____
              >
              > From: junit@yahoogroups.com [mailto:junit@yahoogroups.com] On Behalf Of
              > toalexsmail
              > Sent: Monday, April 28, 2008 4:33 PM
              > To: junit@yahoogroups.com
              > Subject: [junit] Re: TextListener improvement
              >
              >
              >
              > PrintStreamListener has a bug. Here is correct version:
              >
              > public class PrintStreamListener extends RunListener{
              > //Definition of delimiters is in Description
              > private static final Pattern DISPAY_NAME_PATTERN =
              > Pattern.compile("[()]");
              > private TextListener textListener;
              > private PrintStream writer;
              >
              > public PrintStreamListener() {
              > this(System.out);
              > }
              >
              > public PrintStreamListener(PrintStream writer) {
              > super();
              > this.textListener = new TextListener(writer);
              > this.writer = writer;
              > }
              >
              > /**
              > * For sub-classes use.
              > *
              > * @return
              > */
              > protected PrintStream getWriter(){
              > return writer;
              > }
              >
              > private PrintStream getNotNullWriter(){
              > PrintStream writer = getWriter();
              > if(writer==null){
              > throw new IllegalStateException("writer should be not null");
              > }
              > return writer;
              > }
              >
              >
              > /**
              > * This method can be overriden in sub-classes.
              > *
              > * @param description
              > * @throws IllegalArgumentException if description is null.
              > */
              > protected void writeMethodName(Description description){
              > if(description==null){
              > throw new IllegalArgumentException("description should be not null");
              > }
              > String displayName = description.getDisplayName();
              > //third place is empty, workaround to avoid ) at the end of the String
              > String[] complexNames = DISPAY_NAME_PATTERN.split(displayName, 3);
              > String methodName = (complexNames==null ||
              > complexNames.length==0)?null:complexNames[0];
              > if(methodName == null || "".equals(methodName)){
              > methodName = displayName;
              > }
              > PrintStream writer = getNotNullWriter();
              >
              > writer.print(methodName);
              > writer.print(' ');
              > }
              >
              >
              > /**
              > * Called when an atomic test is about to be started.
              > * @param description the description of the test that is about to be
              > run
              > * (generally a class and method name)
              > */
              > @Override
              > public void testStarted(Description description) {
              > textListener.testStarted(description);
              > }
              >
              > /**
              > * Called when an atomic test fails.
              > * @param failure describes the test that failed and the exception
              > that was thrown
              > */
              > @Override
              > public void testFailure(Failure failure) {
              > Description description = failure.getDescription();
              > PrintStream writer = getNotNullWriter();
              >
              > writeMethodName(description);
              > textListener.testFailure(failure);
              > writer.println();
              > }
              >
              > /**
              > * Called when a test will not be run, generally because a test
              > method is annotated
              > * with {@link org.junit.Ignore}.
              > * @param description describes the test that will not be run
              > */
              > @Override
              > public void testIgnored(Description description) {
              > writeMethodName(description);
              > PrintStream writer = getNotNullWriter();
              > textListener.testIgnored(description);
              > writer.println();
              > }
              >
              >
              > @Override
              > public void testRunFinished(Result result) {
              > textListener.testRunFinished(result);
              > }
              >
              > /**
              > * Called before any tests have been run.
              > * @param description describes the tests to be run
              > */
              > @Override
              > public void testRunStarted(Description description) throws Exception {
              > PrintStream writer = getNotNullWriter();
              > String displayName = description.getDisplayName();
              > //third place is empty, workaround to avoid ) at the end of the String
              > String[] complexNames = DISPAY_NAME_PATTERN.split(displayName, 3);
              > String className = (complexNames==null ||
              > complexNames.length<2)?null:complexNames[1];
              > if(className == null || "".equals(className)){
              > className = displayName;
              > }
              > writer.print("started to test "+className);
              > writer.println();
              > }
              >
              >
              >
              >
              >
              > }
              >
              >
              >
              >
              >
              >
              > [Non-text portions of this message have been removed]
              >
            • toalexsmail
              I actually did it now. There are many files their, so see https://sourceforge.net/tracker/?func=detail&atid=365278&aid=1913115&group_id=15278 file
              Message 6 of 6 , Apr 30 7:54 PM
              • 0 Attachment
                I actually did it now.
                There are many files their, so see
                https://sourceforge.net/tracker/?func=detail&atid=365278&aid=1913115&group_id=15278

                file RunListenerTest.zip


                --- In junit@yahoogroups.com, "toalexsmail" <toalexsmail@...> wrote:
                >
                > Kent, I will do it in the future, maybe in this weekend, but I don't
                > promise.
                >
                > --- In junit@yahoogroups.com, "Kent Beck" <kentb@> wrote:
                > >
                > > Alex,
                > >
                > > It would help me if you provided test cases that break with the
                > current code
                > > and pass with the changes below.
                > >
                > > Regards,
                > >
                > > Kent Beck
                > > Three Rivers Institute
                > >
                > > _____
                > >
                > > From: junit@yahoogroups.com [mailto:junit@yahoogroups.com] On
                Behalf Of
                > > toalexsmail
                > > Sent: Monday, April 28, 2008 4:33 PM
                > > To: junit@yahoogroups.com
                > > Subject: [junit] Re: TextListener improvement
                > >
                > >
                > >
                > > PrintStreamListener has a bug. Here is correct version:
                > >
                > > public class PrintStreamListener extends RunListener{
                > > //Definition of delimiters is in Description
                > > private static final Pattern DISPAY_NAME_PATTERN =
                > > Pattern.compile("[()]");
                > > private TextListener textListener;
                > > private PrintStream writer;
                > >
                > > public PrintStreamListener() {
                > > this(System.out);
                > > }
                > >
                > > public PrintStreamListener(PrintStream writer) {
                > > super();
                > > this.textListener = new TextListener(writer);
                > > this.writer = writer;
                > > }
                > >
                > > /**
                > > * For sub-classes use.
                > > *
                > > * @return
                > > */
                > > protected PrintStream getWriter(){
                > > return writer;
                > > }
                > >
                > > private PrintStream getNotNullWriter(){
                > > PrintStream writer = getWriter();
                > > if(writer==null){
                > > throw new IllegalStateException("writer should be not null");
                > > }
                > > return writer;
                > > }
                > >
                > >
                > > /**
                > > * This method can be overriden in sub-classes.
                > > *
                > > * @param description
                > > * @throws IllegalArgumentException if description is null.
                > > */
                > > protected void writeMethodName(Description description){
                > > if(description==null){
                > > throw new IllegalArgumentException("description should be not null");
                > > }
                > > String displayName = description.getDisplayName();
                > > //third place is empty, workaround to avoid ) at the end of the String
                > > String[] complexNames = DISPAY_NAME_PATTERN.split(displayName, 3);
                > > String methodName = (complexNames==null ||
                > > complexNames.length==0)?null:complexNames[0];
                > > if(methodName == null || "".equals(methodName)){
                > > methodName = displayName;
                > > }
                > > PrintStream writer = getNotNullWriter();
                > >
                > > writer.print(methodName);
                > > writer.print(' ');
                > > }
                > >
                > >
                > > /**
                > > * Called when an atomic test is about to be started.
                > > * @param description the description of the test that is about to be
                > > run
                > > * (generally a class and method name)
                > > */
                > > @Override
                > > public void testStarted(Description description) {
                > > textListener.testStarted(description);
                > > }
                > >
                > > /**
                > > * Called when an atomic test fails.
                > > * @param failure describes the test that failed and the exception
                > > that was thrown
                > > */
                > > @Override
                > > public void testFailure(Failure failure) {
                > > Description description = failure.getDescription();
                > > PrintStream writer = getNotNullWriter();
                > >
                > > writeMethodName(description);
                > > textListener.testFailure(failure);
                > > writer.println();
                > > }
                > >
                > > /**
                > > * Called when a test will not be run, generally because a test
                > > method is annotated
                > > * with {@link org.junit.Ignore}.
                > > * @param description describes the test that will not be run
                > > */
                > > @Override
                > > public void testIgnored(Description description) {
                > > writeMethodName(description);
                > > PrintStream writer = getNotNullWriter();
                > > textListener.testIgnored(description);
                > > writer.println();
                > > }
                > >
                > >
                > > @Override
                > > public void testRunFinished(Result result) {
                > > textListener.testRunFinished(result);
                > > }
                > >
                > > /**
                > > * Called before any tests have been run.
                > > * @param description describes the tests to be run
                > > */
                > > @Override
                > > public void testRunStarted(Description description) throws Exception {
                > > PrintStream writer = getNotNullWriter();
                > > String displayName = description.getDisplayName();
                > > //third place is empty, workaround to avoid ) at the end of the String
                > > String[] complexNames = DISPAY_NAME_PATTERN.split(displayName, 3);
                > > String className = (complexNames==null ||
                > > complexNames.length<2)?null:complexNames[1];
                > > if(className == null || "".equals(className)){
                > > className = displayName;
                > > }
                > > writer.print("started to test "+className);
                > > writer.println();
                > > }
                > >
                > >
                > >
                > >
                > >
                > > }
                > >
                > >
                > >
                > >
                > >
                > >
                > > [Non-text portions of this message have been removed]
                > >
                >
              Your message has been successfully submitted and would be delivered to recipients shortly.