You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by se...@apache.org on 2004/01/23 02:14:11 UTC

cvs commit: jakarta-jmeter/src/functions/org/apache/jmeter/functions FileWrapper.java FileRowColContainer.java

sebb        2004/01/22 17:14:11

  Added:       src/functions/org/apache/jmeter/functions FileWrapper.java
                        FileRowColContainer.java
  Log:
  Support classes for multi-file CSVRead
  
  Revision  Changes    Path
  1.1                  jakarta-jmeter/src/functions/org/apache/jmeter/functions/FileWrapper.java
  
  Index: FileWrapper.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2004 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 JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", 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/>.
   */
  
  package org.apache.jmeter.functions;
  
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.apache.jorphan.logging.LoggingManager;
  import org.apache.log.Logger;
  
  /**
   * This class wraps the FileRowColContainer for use across multiple
   * threads.
   * 
   * It does this by maintaining a list of open files, keyed by file name
   * (or alias, if used).
   * A list of open files is also maintained for each thread, together with
   * the current line number.
   * 
   * @author sebb AT apache DOT org
   * @version $Revision: 1.1 $ $Date: 2004/01/23 01:14:11 $
   */
  public class FileWrapper
  {
  
  	transient private static Logger log = LoggingManager.getLoggerForClass();
  	
  	private FileRowColContainer container;
      private int currentRow;
      private static final int NO_LINE = -1;
      
  	private static Map fileContainers = new HashMap(); // Map file names to containers
      
      /*
       * Only needed locally 
       */
      private FileWrapper(FileRowColContainer fdc)
      {
          super();
          container = fdc;
          currentRow = -1;
      }
  
  	/* The cache of file packs */
  	private static ThreadLocal filePacks = new ThreadLocal(){
  		protected Object initialValue(){
  			return new HashMap();
  		}
  	};
  
      /*
       * called by (file,alias)
       */
      public static void open(String file, String alias)
      {
      	log.info("Opening "+file+ " as " + alias);
      	Map m = (Map) filePacks.get();
      	if (m.get(alias) == null)
      	{
      		FileRowColContainer frcc;
              try
              {
                  frcc = getFile(file, alias);
  				log.info("Stored "+file+" as "+alias);
  				m.put(alias,new FileWrapper(frcc));
              }
              catch (FileNotFoundException e)
              {
              	//Already logged
              }
              catch (IOException e)
              {
  				//Already logged
              }
      	}
      }
      
      private static FileRowColContainer getFile(String file, String alias)
      throws FileNotFoundException, IOException
      {
      	FileRowColContainer frcc;
      	if ((frcc = (FileRowColContainer) fileContainers.get(alias)) == null)
      	{
      		frcc = new FileRowColContainer(file);
  			log.info("Opened "+file+" as "+alias);
      		fileContainers.put(alias,frcc);
      	}
      	return frcc;
      }
      
      /*
       * Called by CSVRead(x,next) - sets the row to nil so the next
       * row will be picked up the next time round
       * 
       */
      public static void endRow(String file)
      {
  		Map my = (Map) filePacks.get();
  		FileWrapper fw = (FileWrapper) (my).get(file);
  		if (fw == null)
  		{
  			log.warn("endRow(): no entry for "+file);
  		}
  		else
  		{
  			fw.endRow();
  		}
      }
      
      private void endRow()
      {
  		if (currentRow == NO_LINE)
  		{
  			log.warn("endRow() called twice in succession");
  		}
  		currentRow = NO_LINE;
      }
  
      public static String getColumn(String file,int col)
      {
      	Map my = (Map) filePacks.get();
  		FileWrapper fw = (FileWrapper) (my).get(file);
  		if (fw == null) // First call
  		{
  			log.info("Attaching "+file);
  			open(file,file);
  			fw = (FileWrapper) my.get(file);
  			//TODO improve the error handling
  			if (fw == null) return "";
  		}
      	return fw.getColumn(col);
      }
      
      private String getColumn(int col)
      {
  		if (currentRow == NO_LINE)
  		{
  			currentRow = container.nextRow();
      		
  		}
  		return container.getColumn(currentRow,col);
      }
  
      /**
       * 
       */
      public static void clearAll()
      {
  		log.debug("clearAll()");
  		Map my = (Map) filePacks.get();
  		for (Iterator i=my.entrySet().iterator();i.hasNext();)
  		{
  			Object fw = i.next();
  			log.info("Removing "+fw.toString());
  			i.remove();
  		}
  		fileContainers.clear();
  	}
  }
  
  
  
  1.1                  jakarta-jmeter/src/functions/org/apache/jmeter/functions/FileRowColContainer.java
  
  Index: FileRowColContainer.java
  ===================================================================
  /*
   * ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001,2004 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 JMeter" must not be used to endorse or promote products
   * derived from this software without prior written permission. For
   * written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   * "Apache JMeter", 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/>.
   */
  package org.apache.jmeter.functions;
  
  import java.io.BufferedReader;
  import java.io.FileNotFoundException;
  import java.io.FileReader;
  import java.io.IOException;
  import java.io.PrintWriter;
  import java.util.ArrayList;
  import java.util.StringTokenizer;
  
  import org.apache.jmeter.junit.JMeterTestCase;
  import org.apache.jorphan.logging.LoggingManager;
  import org.apache.log.Logger;
  
  /**
   * File data container for CSV (and similar delimited) files
   * Data is accessible via row and column number
   *  
   * @author sebb AT apache DOT org (multiple file version)
   * @version $Revision: 1.1 $
   */
  public class FileRowColContainer
  {
      
      transient private static Logger log = LoggingManager.getLoggerForClass();
      
  
      private ArrayList fileData; // Lines in the file, split into columns
  
      private String fileName; // name of the file
      
      public static final String DELIMITER = ","; // Default delimiter
      
      /** Keeping track of which row is next to be read. */
      private int nextRow;
  
      /** Delimiter for this file */
  	private String delimiter;
  
      private FileRowColContainer()// Not intended to be called directly
      {
      }
  
  	public FileRowColContainer(String file,String delim)
  	throws IOException,FileNotFoundException
  	{
  		log.debug("FDC("+file+","+delim+")");
  		fileName = file;
  		delimiter = delim;
  		nextRow = 0;
  		load();
  	}
  
  	public FileRowColContainer(String file)
  	throws IOException,FileNotFoundException
  	{
  		log.debug("FDC("+file+")");
  		fileName = file;
  		delimiter = DELIMITER;
  		nextRow = 0;
  		load();
  	}
  
  
  	private void load() 
  	throws IOException,FileNotFoundException
  	{
  		fileData = new ArrayList();
  
  		BufferedReader myBread=null;
  		try
  		{
  			FileReader fis = new FileReader(fileName);
  			myBread = new BufferedReader(fis);
  			String line = myBread.readLine();
  			while (line != null)
  			{
  				fileData.add(splitLine(line,delimiter));
  				line = myBread.readLine();
  			}
  		} 
  		catch (FileNotFoundException e)
          {
  			fileData = null;
          	log.warn(e.toString());
          	throw e;
          } 
          catch (IOException e)
          {
          	fileData = null;
  			log.warn(e.toString());
  			myBread.close();
              throw e;
          }
  	}
  
      /**
       * Get the string for the column from the current row
       * 
       * @param row row number (from 0)
       * @param col column number (from 0)
       * @return the string (empty if out of bounds)
       * @throws IndexOutOfBoundsException if the column number is out of bounds
       */
      public String getColumn(int row,int col) throws IndexOutOfBoundsException
      {
      	String colData;
  		colData = (String) ((ArrayList) fileData.get(row)).get(col);
      	log.debug(fileName+"("+row+","+col+"): "+colData);
      	return colData;
      }
      
      /**
       * Returns the next row to the caller, and updates it,
       * allowing for wrap round
       * 
       * @return the first free (unread) row
       * 
       */
      public int nextRow()
      {
      	int row = nextRow;
          nextRow++;
          if (nextRow >= fileData.size())// 0-based
          {
              nextRow = 0;
          }
  		log.debug ("Row: "+ row);
  		return row;
      }
  
  
      /**
       * Splits the line according to the specified delimiter
       * 
       * @return an ArrayList of Strings containing one element for each
       *          value in the line
       */
      private static ArrayList splitLine(String theLine,String delim)
      {
          ArrayList result = new ArrayList();
          StringTokenizer tokener = new StringTokenizer(theLine,delim);
          while(tokener.hasMoreTokens())
          {
              String token = tokener.nextToken();
              result.add(token);
          }
          return result;
      }
      public static class Test extends JMeterTestCase
      {
  
  		static{
  //			LoggingManager.setPriority("DEBUG","jmeter");
  //			LoggingManager.setTarget(new PrintWriter(System.out));
  		}
  
  
      	public Test(String a)
      	{
      		super(a);
      	}
      	
      	public void testNull() throws Exception
      	{
      		try
      		{
      			FileRowColContainer f = new FileRowColContainer("testfiles/xyzxyz");
      			fail("Should not find the file");
      		}
      		catch (FileNotFoundException e)
      		{
      		}
      	}
      	
  		public void testrowNum() throws Exception
  		{
  			FileRowColContainer f = new FileRowColContainer("testfiles/test.csv");
  			assertNotNull(f);
  			assertEquals("Expected 4 lines",4,f.fileData.size());
  
  			int myRow=f.nextRow();
  			assertEquals(0,myRow);
  			assertEquals(1,f.nextRow);
  
  			myRow = f.nextRow();
  			assertEquals(1,myRow);
  			assertEquals(2,f.nextRow);
  
  			myRow = f.nextRow();
  			assertEquals(2,myRow);
  			assertEquals(3,f.nextRow);
  
  			myRow = f.nextRow();
  			assertEquals(3,myRow);
  			assertEquals(0,f.nextRow);
  			
  			myRow = f.nextRow();
  			assertEquals(0,myRow);
  			assertEquals(1,f.nextRow);
  
  		}
  		
  		public void testColumns() throws Exception
  		{
  			FileRowColContainer f = new FileRowColContainer("testfiles/test.csv");
  			assertNotNull(f);
  			assertTrue("Not empty",f.fileData.size() > 0);
  
  			int myRow=f.nextRow();
  			assertEquals(0,myRow);
  			assertEquals("a1",f.getColumn(myRow,0));
  			assertEquals("d1",f.getColumn(myRow,3));
  
  			try {
  				f.getColumn(myRow,4);
  				fail("Expected out of bounds");
  			}
  			catch (IndexOutOfBoundsException e)
  			{
  			}
  			myRow=f.nextRow();
  			assertEquals(1,myRow);
  			assertEquals("b2",f.getColumn(myRow,1));
  			assertEquals("c2",f.getColumn(myRow,2));
  		}
      }
      /**
       * @return the file name for this class
       */
      public String getFileName()
      {
          return fileName;
      }
  
  }
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: jmeter-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jmeter-dev-help@jakarta.apache.org