Hi everyone,

I am back ;)
I am not going to submit this into bugzilla (where the bug lives..), it
is too much files ;). We all know what it is about by now, if you missed
checkout, you are out of luck ;)

On request I made some working testcases, since I am almost doubling the
testcases for turbine-2, it is a very good effort I must say ;)

First of all : you cannot blindly use the attached patch.diff, since it
has some questionmarks in the beginning (not known to the current CVS
that is, but I left them there, to point out where they actually have to
live)
Here it goes :

- The TurbineDefault.properties is an minimum based property file, which
is enough for tests I am doing in CSV/TSVParser.java
- CSVParserTest.java and TSVParser.java are testcases for the
CVSParserTest.java and the TSVParser.java and are only runnable via
rttest.
- BaseTextCase.java is used by the only testcase currently in rttest
(XMLRPCtest or something, which is btw horribly slow in disconnecting
the socket..). This was not in cvs, so I am attaching it (it doesn't
actually do anything though..)
>From the diff :
- .cvsignore Added two cactus log files that are generated when running
the tests
- TSVParser.java and CSVParser.java : Hardly any code in it anymore, now
just calling super and setting the fieldSeperator. Also added my name :)
- DataStreamParser.java 
Changed a lot of code there. The formerly abstract initTokenizer, it has
changed from an abstract method to a non abstract, since all the
settings are the same for both parsers (or any other fieldseperator you
can think of).
You just have to call the initTokenizer() in super (see CSVParser.java)
and the DataStreamParser.setSeparator(char);, which will handle setting
the ordinarychar correctly.
Since I don't have a use case (at the top of the file this thing is used
from Velocity), it is hard to determine if I can remove the abstract
from the class and just let people call setSeparator where appropiate
and deprecate the CSV/TSVParsers. So feedback on this will be
appreciated, so I can change this behaviour. My intention is this :
I want to be able to use all kinds of seperated files from anywhere,
just by calling DataStreamParser and setting the fieldSeperator. 
I made it almost fool proof, so if you are a monkey, it will still work.
It now supports this :

- Empty fieldnames (say the field header is field1,,field3,,field5

It just makes up a fieldname where the fieldnames are empty.. It will
use the constant EMPTYFIELDNAME+the columnumber. If you actually type a
space there, you are too much a fool for me to handle, so that is not
covered ;)

- Empty field Values

The ValueParser will not show fields that don't have a value. So if you
think it should provide an empty string for whatever reason, let me know
I will put it in.

- Field names and field values

Of course, if you just supply all the values, it will still work.


Back to the diff... 
- cactus.properties  This was referencing the wrong port, so I changed
it to @maven.test.port@
- server.xml also adjusted the test.port to maven.test.port and the
appBase (added maven. in front).

How do I actually test this ?

- Install maven
- vi <your home directory>/build.properties
- add tdk.hom=<the location of catalina home> (the test build process
doesn't change catalina, so don't bother setting up a new catalina for
that).
- from the root type ant -f build-maven maven:uitest
- Wait patiently ;)
- You will see a lot of log4j errors, I couldn't fix that yet though.
- The tests (at least mine) should pass and you get a build successfull
;). 
If you think this is too much work for this commit you will find my test
output below (should be a fairly unique view, since I couldn't get the
rttests running at all from CVS) :

As you can see no errors ;)

Hope this is enough to get it committed...

Mvgr,
Martin van den Bemt


run-iutests:
    [junit] Running org.apache.turbine.services.cache.TurbineCacheTest
[RunServerTests] log4j:ERROR No appenders could be found for category
(org.apache.turbine.services.cache.TurbineCacheTest).
[RunServerTests] log4j:ERROR Please initialize the log4j system
properly.
     [java] log4j:ERROR No appenders could be found for category
(org.apache.turbine.services.cache.TurbineCacheTest).
     [java] log4j:ERROR Please initialize the log4j system properly.
     [java] Closing XML-RPC server socket.
    [junit] Tests run: 7, Failures: 0, Errors: 0, Time elapsed: 215.545
sec
    [junit] Running org.apache.turbine.util.parser.BaseValueParserTest
[RunServerTests] log4j:ERROR No appenders could be found for category
(org.apache.turbine.util.parser.BaseValueParserTest).
[RunServerTests] log4j:ERROR Please initialize the log4j system
properly.
    [junit] Tests run: 6, Failures: 0, Errors: 0, Time elapsed: 4.349
sec
    [junit] Running org.apache.turbine.util.CSVParserTest
[RunServerTests] log4j:ERROR No appenders could be found for category
(org.apache.turbine.util.CSVParserTest).
[RunServerTests] log4j:ERROR Please initialize the log4j system
properly.
     [java] testEmptyFieldValues
     [java] testNormalFieldValues
     [java] testEmptyFieldNames
    [junit] Tests run: 3, Failures: 0, Errors: 0, Time elapsed: 2.439
sec
    [junit] Running org.apache.turbine.util.TSVParserTest
[RunServerTests] log4j:ERROR No appenders could be found for category
(org.apache.turbine.util.TSVParserTest).
[RunServerTests] log4j:ERROR Please initialize the log4j system
properly.
     [java] testEmptyFieldValues
     [java] testNormalFieldValues
     [java] testEmptyFieldNames
    [junit] Tests run: 3, Failures: 0, Errors: 0, Time elapsed: 2.785
sec










package org.apache.turbine.test;

/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and 
 *    "Apache Turbine" must not be used to endorse or promote products 
 *    derived from this software without prior written permission. For 
 *    written permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache Turbine", nor may "Apache" appear in their name, without 
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import junit.framework.TestCase;

/**
 * Base functionality to be extended by all Apache Turbine test cases.  Test 
 * case implementations are used to automate testing via JUnit.
 *
 * @author <a href="mailto:[EMAIL PROTECTED]";>Christopher Elkins</a>
 * @version $Id: BaseTestCase.java,v 1.1 2002/02/01 03:20:00 brekke Exp $
 */
public abstract class BaseTestCase extends TestCase
{
    /**
     * Creates a new instance.
     */
    public BaseTestCase(String name)
    {
        super(name);
    }
}
package org.apache.turbine.util;

/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *    "Apache Turbine" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache Turbine", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import java.io.IOException;
import java.io.CharArrayReader;
import java.io.StringBufferInputStream;
import java.util.Iterator;
import java.util.Vector;

import org.apache.turbine.Turbine;

import org.apache.cactus.ServletTestCase;
import junit.framework.Test;
import junit.framework.TestSuite;

/**
 * Test the CSVParser.
 * 
 * NOTE : I am assuming (as is in the code of DataStreamParser.java
 * that the values are reusing the same object for the values.
 * If this shouldn't be, we need to fix that in the code!.
 * 
 * @author <a href="mailto:[EMAIL PROTECTED]";>Martin van den Bemt</a>
 * @version $Id$
 */
public class CSVParserTest 
extends ServletTestCase
{
    
    Turbine turbine = null;

	/**
	 * Constructor for CSVParserTest.
	 * @param arg0
	 */
	public CSVParserTest(String name)
    {
		super(name);
	}

    /** 
     * This will setup an instance of turbine to use when testing
     * @exception if an exception occurs.
     */
    
    protected void setUp()
    throws Exception
    {
        super.setUp();
        /* Note: we are using the properties file from the cache test
         *  since we don't really need any specific property at this 
         *  time.  Future tests may require a test case specific 
         *  properties file to be used.:
         */
        config.setInitParameter("properties",
                "/WEB-INF/conf/TurbineDefault.properties");
        turbine = new Turbine();
        turbine.init(config);
    }
    
    /**
     * Shut down our turbine servlet and let our parents clean up also.
     *
     * @exception Exception if an error occurs
     */
    protected void tearDown() 
    throws Exception 
    {
        turbine.destroy();
        super.tearDown();
    }

    /**
     * Return a test suite of all our tests.
     *
     * @return a <code>Test</code> value
     */
    public static Test suite() 
    {
        return new TestSuite(CSVParserTest.class);
    }
    
    /** 
     * Tests if you can leave field values empty
     */
	public void testEmptyFieldValues()
    {
	    System.out.println("testEmptyFieldValues");
		String values = "field1,field2,field3,field4\nvalue11,,value13,\nvalue21,,value23,";
		CharArrayReader reader = new CharArrayReader(values.toCharArray());
		CSVParser parser = new CSVParser(reader);
		StringBuffer sb = new StringBuffer();
		try 
        {
			parser.readColumnNames();
            int currentRecord = 1;
			while (parser.hasNextRow()) 
            {
				ValueParser vp = parser.nextRow();
                int currentField = 1;
                while (currentField <= 4) 
                {
                    if (currentField==2 || currentField == 4) 
                    {
                        assertNull(vp.getString("field"+currentField));
                    }
                    else
                    {
                        assertEquals("value"+currentRecord+currentField, vp.getString("field"+currentField));
                    }
                    currentField+=1;
                }
                currentRecord+=1;
			}
		}
        catch(IOException ioe) 
        {
			fail("Unexpected exception in testcase occured : "+ioe.toString());
		}
	}
    
    /**
     * Tests if normal operation is still working
     */
    public void testNormalFieldValues() 
    {
        System.out.println("testNormalFieldValues");
        String values = "field1,field2,field3,field4\nvalue11,value12,value13,value14\nvalue21,value22,value23,value24";
        CharArrayReader reader = new CharArrayReader(values.toCharArray());
        CSVParser parser = new CSVParser(reader);
        StringBuffer sb = new StringBuffer();
        try 
        {
            parser.readColumnNames();
            int currentRecord = 1;
            while (parser.hasNextRow()) 
            {
                ValueParser vp = parser.nextRow();
                int currentField = 1;
                while (currentField <= 4) 
                {
                    assertEquals("value"+currentRecord+currentField, vp.getString("field"+currentField));
                    currentField+=1;
                }
                currentRecord+=1;
            }
        }
        catch(IOException ioe) 
        {
            fail("Unexpected exception in testcase occured : "+ioe.toString());
        }
    }
    
    /**
     * Tests if some fields are empty, but the values exists..
     */
    public void testEmptyFieldNames() 
    {
        System.out.println("testEmptyFieldNames");
        String values = "field1,,field3,\nvalue11,value12,value13,value14\nvalue21,value22,value23,value24";
        CharArrayReader reader = new CharArrayReader(values.toCharArray());
        CSVParser parser = new CSVParser(reader);
        StringBuffer sb = new StringBuffer();
        try 
        {
            parser.readColumnNames();
            int currentRecord = 1;
            
            while (parser.hasNextRow()) 
            {
                ValueParser vp = parser.nextRow();
                int currentField = 1;
                while (currentField <= 4) 
                {
                    if (currentField==2 || currentField==4) 
                    {
                        assertEquals("value"+currentRecord+currentField, vp.getString(DataStreamParser.EMPTYFIELDNAME+currentField));
                    }
                    else
                    {
                        assertEquals("value"+currentRecord+currentField, vp.getString("field"+currentField));
                    }
                    currentField+=1;
                }
                currentRecord+=1;
            }
        }
        catch(IOException ioe) 
        {
            fail("Unexpected exception in testcase occured : "+ioe.toString());
        }
    }
    
}
package org.apache.turbine.util;

/* ====================================================================
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Apache" and "Apache Software Foundation" and
 *    "Apache Turbine" must not be used to endorse or promote products
 *    derived from this software without prior written permission. For
 *    written permission, please contact [EMAIL PROTECTED]
 *
 * 5. Products derived from this software may not be called "Apache",
 *    "Apache Turbine", nor may "Apache" appear in their name, without
 *    prior written permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import java.io.CharArrayReader;
import java.io.IOException;

import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.cactus.ServletTestCase;
import org.apache.turbine.Turbine;


/**
 * Test the CSVParser.
 * 
 * NOTE : I am assuming (as is in the code of DataStreamParser.java
 * that the values are reusing the same object for the values.
 * If this shouldn't be, we need to fix that in the code!.
 * 
 * @author <a href="mailto:[EMAIL PROTECTED]";>Martin van den Bemt</a>
 * @version $Id$
 */
public class TSVParserTest 
extends ServletTestCase 
{
    
    Turbine turbine = null;

    /**
     * Constructor for CSVParserTest.
     * @param arg0
     */
    public TSVParserTest(String name)
    {
        super(name);
    }
    
    /** 
     * This will setup an instance of turbine to use when testing
     * @exception if an exception occurs.
     */
    
    protected void setUp()
    throws Exception
    {
        super.setUp();
        /* Note: we are using the properties file from the cache test
         *  since we don't really need any specific property at this 
         *  time.  Future tests may require a test case specific 
         *  properties file to be used.:
         */
        config.setInitParameter("properties",
                "/WEB-INF/conf/TurbineDefault.properties");
        turbine = new Turbine();
        turbine.init(config);
    }
    
    /**
     * Shut down our turbine servlet and let our parents clean up also.
     *
     * @exception Exception if an error occurs
     */
    protected void tearDown() 
    throws Exception 
    {
        turbine.destroy();
        super.tearDown();
    }

    /**
     * Return a test suite of all our tests.
     *
     * @return a <code>Test</code> value
     */
    public static Test suite() 
    {
        return new TestSuite(TSVParserTest.class);
    }
    
    /** 
     * Tests if you can leave field values empty
     */
    public void testEmptyFieldValues()
    {
        System.out.println("testEmptyFieldValues");
        String values = "field1\tfield2\tfield3\tfield4\nvalue11\t\tvalue13\t\nvalue21\t\tvalue23\t";
        CharArrayReader reader = new CharArrayReader(values.toCharArray());
        TSVParser parser = new TSVParser(reader);
        StringBuffer sb = new StringBuffer();
        try 
        {
            parser.readColumnNames();
            int currentRecord = 1;
            while (parser.hasNextRow()) 
            {
                ValueParser vp = parser.nextRow();
                int currentField = 1;
                while (currentField <= 4) 
                {
                    if (currentField==2 || currentField == 4) 
                    {
                        assertNull(vp.getString("field"+currentField));
                    }
                    else
                    {
                        assertEquals("value"+currentRecord+currentField, vp.getString("field"+currentField));
                    }
                    currentField+=1;
                }
                currentRecord+=1;
            }
        }
        catch(IOException ioe) 
        {
            fail("Unexpected exception in testcase occured : "+ioe.toString());
        }
    }
    
    /**
     * Tests if normal operation is still working
     */
    public void testNormalFieldValues() 
    {
        System.out.println("testNormalFieldValues");
        String values = "field1\tfield2\tfield3\tfield4\nvalue11\tvalue12\tvalue13\tvalue14\nvalue21\tvalue22\tvalue23\tvalue24";
        CharArrayReader reader = new CharArrayReader(values.toCharArray());
        TSVParser parser = new TSVParser(reader);
        StringBuffer sb = new StringBuffer();
        try 
        {
            parser.readColumnNames();
            int currentRecord = 1;
            while (parser.hasNextRow()) 
            {
                ValueParser vp = parser.nextRow();
                int currentField = 1;
                while (currentField <= 4) 
                {
                    assertEquals("value"+currentRecord+currentField, vp.getString("field"+currentField));
                    currentField+=1;
                }
                currentRecord+=1;
            }
        }
        catch(IOException ioe) 
        {
            fail("Unexpected exception in testcase occured : "+ioe.toString());
        }
    }
    
    /**
     * Tests if some fields are empty, but the values exists..
     */
    public void testEmptyFieldNames() 
    {
        System.out.println("testEmptyFieldNames");
        String values = "field1\t\tfield3\t\nvalue11\tvalue12\tvalue13\tvalue14\tvalue21\tvalue22\tvalue23\tvalue24";
        CharArrayReader reader = new CharArrayReader(values.toCharArray());
        TSVParser parser = new TSVParser(reader);
        StringBuffer sb = new StringBuffer();
        try 
        {
            parser.readColumnNames();
            int currentRecord = 1;
            
            while (parser.hasNextRow()) 
            {
                ValueParser vp = parser.nextRow();
                int currentField = 1;
                while (currentField <= 4) 
                {
                    if (currentField==2 || currentField==4) 
                    {
                        assertEquals("value"+currentRecord+currentField, vp.getString(DataStreamParser.EMPTYFIELDNAME+currentField));
                    }
                    else
                    {
                        assertEquals("value"+currentRecord+currentField, vp.getString("field"+currentField));
                    }
                    currentField+=1;
                }
                currentRecord+=1;
            }
        }
        catch(IOException ioe) 
        {
            fail("Unexpected exception in testcase occured : "+ioe.toString());
        }
    }
    
}
# -------------------------------------------------------------------
# $Id$
#
# Note by Martin van den Bemt ([EMAIL PROTECTED]) :
# This is a minimalistic turbine properties file.
# If you want more in this, just add it 
#
# Note that strings containing "," (comma) characters must backslash 
# escape the comma (i.e. '\,')
#
# -------------------------------------------------------------------

# -------------------------------------------------------------------
# 
#  M O D U L E  P A C K A G E S
#
# -------------------------------------------------------------------
# This is the "classpath" for Turbine.  In order to locate your own
# modules, you should add them to this path.  For example, if you have
# com.company.actions, com.company.screens, com.company.navigations,
# then this setting would be "com.company,org.apache.turbine.modules".
# This path is searched in order.  For example, Turbine comes with a
# screen module named "Login".  If you wanted to have your own screen
# module named "Login", then you would specify the path to your
# modules before the others.
#
# Default: org.apache.turbine.modules
# -------------------------------------------------------------------

module.packages=org.apache.turbine.modules

# -------------------------------------------------------------------
# 
#  S E R V I C E S
#
# -------------------------------------------------------------------
# Classes for Turbine Services should be defined here.
# Format: services.[name].classname=[implementing class]
#
# To specify properties of a service use the following syntax:
# service.[name].[property]=[value]
#
# The order that these services is listed is important! The
# order that is stated here is the order in which the services
# will be initialized. Keep this is mind if you have services
# that depend on other services during initialization.
# -------------------------------------------------------------------
services.ResourceService.classname=org.apache.turbine.services.resources.TurbineResourceService

# -------------------------------------------------------------------
#
#  R U N   D A T A   S E R V I C E
#
# -------------------------------------------------------------------
# Default implementations of base interfaces for request processing.
# Additional configurations can be defined by using other keys
# in the place of the <default> key.  
# -------------------------------------------------------------------

services.RunDataService.default.run.data=org.apache.turbine.services.rundata.DefaultTurbineRunData
services.RunDataService.default.parameter.parser=org.apache.turbine.util.parser.DefaultParameterParser
services.RunDataService.default.cookie.parser=org.apache.turbine.util.parser.DefaultCookieParser

#--------------------------------------------------------------------
#
# P A R A M E T E R  P A R S E R
#
#--------------------------------------------------------------------
#
# This variable controls the case folding applied to URL variable
# names.
#
# Allowed values: none, lower, upper
# Default: lower
#

url.case.folding=lower

? src/rttest/org/apache/turbine/test
? src/rttest/org/apache/turbine/util/CSVParserTest.java
? src/rttest/org/apache/turbine/util/TSVParserTest.java
? src/rttest/testapp/WEB-INF/conf/TurbineDefault.properties
Index: .cvsignore
===================================================================
RCS file: /home/cvspublic/jakarta-turbine-2/.cvsignore,v
retrieving revision 1.2
diff -u -r1.2 .cvsignore
--- .cvsignore  29 Apr 2002 22:17:22 -0000      1.2
+++ .cvsignore  24 May 2002 21:14:23 -0000
@@ -1,2 +1,4 @@
 target
+cactus_client.log
+cactus_server.log
 *~
Index: src/java/org/apache/turbine/util/CSVParser.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-turbine-2/src/java/org/apache/turbine/util/CSVParser.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 CSVParser.java
--- src/java/org/apache/turbine/util/CSVParser.java     16 Aug 2001 05:09:38 -0000     
 1.1.1.1
+++ src/java/org/apache/turbine/util/CSVParser.java     24 May 2002 21:14:25 -0000
@@ -79,6 +79,7 @@
  * </pre>
  *
  * @author <a href="mailto:[EMAIL PROTECTED]";>Sean Legassick</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]";>Martin van den Bemt</a>
  * @version $Id: CSVParser.java,v 1.1.1.1 2001/08/16 05:09:38 jvanzyl Exp $
  */
 public class CSVParser extends DataStreamParser
@@ -125,25 +126,14 @@
     /**
      * Initialize the StreamTokenizer instance used to read the lines
      * from the input reader. 
+     * It is now only needed to set the fieldSeparator
      */
     protected void initTokenizer(StreamTokenizer tokenizer)
     {
-        // set all numeric characters as ordinary characters
-        // (switches off number parsing)
-        tokenizer.ordinaryChars('0', '9');
-        tokenizer.ordinaryChars('-', '-');
-        tokenizer.ordinaryChars('.', '.');
-        
-        // set all printable characters to be treated as word chars
-        tokenizer.wordChars(' ', Integer.MAX_VALUE);
+        // everything is default so let's call super
+        super.initTokenizer(tokenizer);
+        // set the field separator to comma
+        super.setFieldSeparator(',');
 
-        // now set comma as the whitespace character
-        tokenizer.whitespaceChars(',', ',');
-
-        // and  set the quote mark as the quoting character
-        tokenizer.quoteChar('"');
-
-        // and finally say that end of line is significant
-        tokenizer.eolIsSignificant(true);
     }
 }
Index: src/java/org/apache/turbine/util/DataStreamParser.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-turbine-2/src/java/org/apache/turbine/util/DataStreamParser.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 DataStreamParser.java
--- src/java/org/apache/turbine/util/DataStreamParser.java      16 Aug 2001 05:09:38 
-0000      1.1.1.1
+++ src/java/org/apache/turbine/util/DataStreamParser.java      24 May 2002 21:14:25 
+-0000
@@ -86,6 +86,7 @@
  * </pre>
  *
  * @author <a href="mailto:[EMAIL PROTECTED]";>Sean Legassick</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]";>Martin van den Bemt</a>
  * @version $Id: DataStreamParser.java,v 1.1.1.1 2001/08/16 05:09:38 jvanzyl Exp $
  */
 public abstract class DataStreamParser implements Iterator
@@ -94,6 +95,11 @@
      * Conditional compilation flag.
      */
     private static final boolean DEBUG = false;
+    
+    /**
+     * The constant for empty fields
+     */
+    protected static final String EMPTYFIELDNAME="UNKNOWNFIELD";
 
     /**
      * The list of column names.
@@ -119,6 +125,11 @@
      * The character encoding of the input
      */
     private String          characterEncoding;
+    
+    /**
+     * The fieldseperator, which can be almost any char
+     */
+    private char            fieldSeparator;
 
     /**
      * Create a new DataStreamParser instance. Requires a Reader to read the
@@ -155,9 +166,40 @@
     /**
      * Initialize the StreamTokenizer instance used to read the lines
      * from the input reader. This must be implemented in subclasses to
-     * set up the tokenizing properties.
+     * set up other tokenizing properties.
+     * 
+     * @param tokenizer the tokenizer to adjust
+     */
+    protected void initTokenizer(StreamTokenizer tokenizer) 
+    {
+        // set all numeric characters as ordinary characters
+        // (switches off number parsing)
+        tokenizer.ordinaryChars('0', '9');
+        tokenizer.ordinaryChars('-', '-');
+        tokenizer.ordinaryChars('.', '.');
+        
+        // leave out the comma sign (,), we need it for empty fields
+
+        tokenizer.wordChars(' ', Integer.MAX_VALUE);
+
+        // and  set the quote mark as the quoting character
+        tokenizer.quoteChar('"');
+
+        // and finally say that end of line is significant
+        tokenizer.eolIsSignificant(true);
+    }
+    
+    /**
+     * This method must be called to setup the field seperator
+     * @param fieldSeparator the char which separates the fields
      */
-    protected abstract void initTokenizer(StreamTokenizer tokenizer);
+    public void setFieldSeparator(char fieldSeparator) 
+    {
+        this.fieldSeparator = fieldSeparator;
+        // make this field also an ordinary char by default.
+        tokenizer.ordinaryChar(fieldSeparator);
+    }
+        
 
     /**
      * Set the list of column names explicitly.
@@ -171,7 +213,8 @@
 
     /**
      * Read the list of column names from the input reader using the
-     * tokenizer.
+     * tokenizer. If fieldNames are empty, we use the current fieldNumber 
+     * + the EMPTYFIELDNAME to make one up.
      *
      * @exception IOException an IOException occurred.
      */
@@ -179,13 +222,35 @@
         throws IOException
     {
         columnNames = new ArrayList();
+        int lastTtype = 0;
+        int fieldCounter = 1;
 
         neverRead = false;
         tokenizer.nextToken();
-        while (tokenizer.ttype == StreamTokenizer.TT_WORD
-               || tokenizer.ttype == '"')
+        while (tokenizer.ttype == tokenizer.TT_WORD || tokenizer.ttype == 
+tokenizer.TT_EOL
+               || tokenizer.ttype == '"' || tokenizer.ttype == fieldSeparator)
         {
-            columnNames.add(tokenizer.sval);
+            if (tokenizer.ttype !=  fieldSeparator && tokenizer.ttype != 
+tokenizer.TT_EOL) 
+            {
+                columnNames.add(tokenizer.sval);
+                fieldCounter++;
+            }
+            else if (tokenizer.ttype == fieldSeparator && lastTtype == 
+fieldSeparator) 
+            {
+                // we have an empty field name
+                columnNames.add(EMPTYFIELDNAME+fieldCounter);
+                fieldCounter++;
+            }
+            else if (lastTtype == fieldSeparator && tokenizer.ttype == 
+tokenizer.TT_EOL) 
+            {
+                columnNames.add(EMPTYFIELDNAME+fieldCounter);
+                break;
+            }
+            else if(tokenizer.ttype == tokenizer.TT_EOL)
+            {
+                break;
+            }
+            lastTtype = tokenizer.ttype;
             tokenizer.nextToken();
         }
     }
@@ -237,20 +302,37 @@
         Iterator it = columnNames.iterator();
         tokenizer.nextToken();
         while (tokenizer.ttype == StreamTokenizer.TT_WORD
-               || tokenizer.ttype == '"')
+               || tokenizer.ttype == '"' || tokenizer.ttype == fieldSeparator)
         {
+            int lastTtype = 0;
             // note this means that if there are more values than
             // column names, the extra values are discarded.
             if (it.hasNext())
             {
                 String colname = it.next().toString();
                 String colval  = tokenizer.sval;
-                if (DEBUG)
+                if (tokenizer.ttype != fieldSeparator && lastTtype != fieldSeparator)
                 {
-                       Log.debug("DataStreamParser.nextRow(): " +
-                                 colname + "=" + colval);
-                               }
-                lineValues.add(colname, colval);
+                    if (DEBUG)
+                    {
+                        Log.debug("DataStreamParser.nextRow(): " +
+                            colname + "=" + colval);
+                    }
+                    lineValues.add(colname, colval);
+                 }
+                 else if (tokenizer.ttype == fieldSeparator && lastTtype != 
+fieldSeparator) 
+                 {
+                    lastTtype = tokenizer.ttype;
+                    tokenizer.nextToken();
+                    if (tokenizer.ttype != fieldSeparator && tokenizer.sval!=null)
+                    {
+                        lineValues.add(colname, tokenizer.sval);
+                    }
+                    else if (tokenizer.ttype == tokenizer.TT_EOL)
+                    {
+                        tokenizer.pushBack();
+                    }
+                }
             }
             tokenizer.nextToken();
         }
Index: src/java/org/apache/turbine/util/TSVParser.java
===================================================================
RCS file: 
/home/cvspublic/jakarta-turbine-2/src/java/org/apache/turbine/util/TSVParser.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 TSVParser.java
--- src/java/org/apache/turbine/util/TSVParser.java     16 Aug 2001 05:09:42 -0000     
 1.1.1.1
+++ src/java/org/apache/turbine/util/TSVParser.java     24 May 2002 21:14:26 -0000
@@ -79,6 +79,7 @@
  * </pre>
  *
  * @author <a href="mailto:[EMAIL PROTECTED]";>Sean Legassick</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]";>Martin van den Bemt</a>
  * @version $Id: TSVParser.java,v 1.1.1.1 2001/08/16 05:09:42 jvanzyl Exp $
  */
 public class TSVParser extends DataStreamParser
@@ -125,19 +126,12 @@
     /**
      * Initialize the StreamTokenizer instance used to read the lines
      * from the input reader. 
+     * It is now only needed to set the fieldSeparator
      */
     protected void initTokenizer(StreamTokenizer tokenizer)
     {
-        // set all numeric characters as ordinary characters
-        // (switches off number parsing)
-        tokenizer.ordinaryChars('0', '9');
-        tokenizer.ordinaryChars('-', '-');
-        tokenizer.ordinaryChars('.', '.');
-        
-        // set all printable characters to be treated as word chars
-        tokenizer.wordChars(' ', Integer.MAX_VALUE);
-
-        // and finally say that end of line is significant
-        tokenizer.eolIsSignificant(true);
+        super.initTokenizer(tokenizer);
+        // set the field separator to tabs.
+        super.setFieldSeparator('\t');
     }
 }
Index: src/rttest/cactus/cactus.properties
===================================================================
RCS file: /home/cvspublic/jakarta-turbine-2/src/rttest/cactus/cactus.properties,v
retrieving revision 1.1
diff -u -r1.1 cactus.properties
--- src/rttest/cactus/cactus.properties 1 Feb 2002 03:19:59 -0000       1.1
+++ src/rttest/cactus/cactus.properties 24 May 2002 21:14:26 -0000
@@ -9,10 +9,10 @@
 # application. In the example below, the context is "test".
 
 # Servlet Redirector. Used by ServletTestCase test cases.
-cactus.servletRedirectorURL = http://localhost:@test.port@/test/ServletRedirector/
+cactus.servletRedirectorURL = 
+http://localhost:@maven.test.port@/test/ServletRedirector/
 
 # JSP Redirector. Used by JspTestCase test cases.
-cactus.jspRedirectorURL = http://localhost:@test.port@/test/JspRedirector/
+cactus.jspRedirectorURL = http://localhost:@maven.test.port@/test/JspRedirector/
 
 # Filter Redirector. Used by FilterTestCase test cases.
 
@@ -21,6 +21,6 @@
 # with just any mapping.
 #
 # For example, the following would work with Tomcat :
-# cactus.filterRedirectorURL = http://localhost:@test.port@/test/FilterRedirector
+# cactus.filterRedirectorURL = 
+http://localhost:@maven.test.port@/test/FilterRedirector
 
-cactus.filterRedirectorURL = 
http://localhost:@test.port@/test/test/filterRedirector.jsp
+cactus.filterRedirectorURL = 
+http://localhost:@maven.test.port@/test/test/filterRedirector.jsp
Index: src/rttest/cactus/tomcat40/server.xml
===================================================================
RCS file: /home/cvspublic/jakarta-turbine-2/src/rttest/cactus/tomcat40/server.xml,v
retrieving revision 1.1
diff -u -r1.1 server.xml
--- src/rttest/cactus/tomcat40/server.xml       1 Feb 2002 03:19:59 -0000       1.1
+++ src/rttest/cactus/tomcat40/server.xml       24 May 2002 21:14:26 -0000
@@ -3,14 +3,14 @@
   <Service name="Tomcat-Standalone">
 
     <Connector className="org.apache.catalina.connector.http.HttpConnector"
-               port="@test.port@" minProcessors="5" maxProcessors="75"
+               port="@maven.test.port@" minProcessors="5" maxProcessors="75"
                acceptCount="10" debug="0"/>
 
     <Engine name="Standalone" defaultHost="localhost" debug="0">
 
       <Realm className="org.apache.catalina.realm.MemoryRealm" />
 
-      <Host name="localhost" debug="0" appBase="@out.tomcat40.full.dir@/webapps">
+      <Host name="localhost" debug="0" 
+appBase="@maven.out.tomcat40.full.dir@/webapps">
       </Host>
 
     </Engine>

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to