// TODO: add column numbers selection
// TODO: use rich gui with preview instead of Bean
package kg.apc.jmeter.config;

import java.io.IOException;
import org.apache.jmeter.config.ConfigTestElement;
import org.apache.jmeter.engine.event.LoopIterationEvent;
import org.apache.jmeter.engine.event.LoopIterationListener;
import org.apache.jmeter.engine.util.NoThreadClone;
import org.apache.jmeter.services.FileServer;
import org.apache.jmeter.testbeans.TestBean;
import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.threads.JMeterVariables;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.jorphan.util.JOrphanUtils;
import org.apache.log.Logger;

/**
 *
 * @author apc
 */
public class VariablesFromCSVFile
      extends ConfigTestElement
      implements TestBean,
                 LoopIterationListener,
                 NoThreadClone
{
   private static final Logger log = LoggingManager.getLoggerForClass();
   private String variablesPrefix;
   private String delimiter;
   private String filename;

   /**
    * 
    * @return
    */
   public String getFilename()
   {
      return filename;
   }

   /**
    *
    * @param filename
    */
   public void setFilename(String filename)
   {
      this.filename = filename;
   }

   /**
    *
    * @return
    */
   public String getVariablesPrefix()
   {
      return variablesPrefix;
   }

   /**
    *
    * @param variableNames
    */
   public void setVariablesPrefix(String variableNames)
   {
      this.variablesPrefix = variableNames;
   }

   /**
    *
    * @return
    */
   public String getDelimiter()
   {
      return delimiter;
   }

   /**
    *
    * @param delimiter
    */
   public void setDelimiter(String delimiter)
   {
      this.delimiter = delimiter;
   }

   public void iterationStart(LoopIterationEvent iterEvent)
   {
      int threanNo = JMeterContextService.getContext().getThreadNum();
      // once only
      if (iterEvent.getIteration() > 1)
      {
         log.debug("Variables already loaded for thread " + Integer.toString(threanNo));
         return;
      }
      
      if (getFilename().length()==0)
      {
         return;
      }

      log.debug("Started loading variables from CSV for thread " + Integer.toString(threanNo));

      JMeterVariables variables = JMeterContextService.getContext().getVariables();
      String alias = this.getClass().getName() + Integer.toString(threanNo);
      FileServer server = FileServer.getFileServer();
      server.reserveFile(getFilename(), "UTF-8", alias);
      // TODO: use all CSV parsing options
      String delim = getResultingDelimiter();

      try
      {
         String line = null;
         while ((line = server.readLine(alias, false)) != null)
         {
            processCSVFileLine(line, delim, variables);
         }

         server.closeFile(alias);
      }
      catch (IOException e)
      {
         log.error(e.toString());
      }

      log.debug("Finished loading variables from CSV for thread " + Integer.toString(threanNo));
   }

   private void processCSVFileLine(String line, String delim, JMeterVariables variables)
   {
      String[] lineValues = JOrphanUtils.split(line, delim, false);
      if (lineValues.length < 2)
      {
         log.warn("Less than 2 columns at line: " + line);
         variables.put(getVariablesPrefix() + lineValues[0], "");
      }
      else
      {
         //log.info("Variable: " + getVariablesPrefix() + lineValues[0] + "=" + lineValues[1] + " was: " + variables.get(getVariablesPrefix() + lineValues[0]));
         variables.put(getVariablesPrefix() + lineValues[0], lineValues[1]);
      }
   }

   private String getResultingDelimiter()
   {
      String delim = delimiter;
      if (delim.equals("\\t"))
      {
         delim = "\t";
      }
      else if (delim.length() == 0)
      {
         log.warn("Empty delimiter converted to ','");
         delim = ",";
      }

      //log.debug("Delimiter: " + delim);
      return delim;
   }
}

@@ -3208,24 +3208,90 @@
 false);%0A
+%0A
       
-if
+ //REV SH - Issue 3: Blank lines cause Java Exception%0A       switch
  (lineVa
@@ -3305,22 +3305,37 @@
 ngth
- %3C 2)
+) %7B
 %0A      
-%7B%0A
+     case 1:%0A      
     
@@ -3390,32 +3390,38 @@
 line);%0A         
+    
+  
 variables.put(ge
@@ -3471,29 +3471,49 @@
     
-%7D%0A
+  
       
-else
+ break;%0A           case 2:
 %0A      
-%7B%0A
     
@@ -3670,32 +3670,38 @@
 %5B0%5D));%0A         
+      
 variables.put(ge
@@ -3752,16 +3752,138 @@
 es%5B1%5D);%0A
+               break;%0A           default:%0A               log.warn(%22Bad format for line: %22 + line);%0A               break;%0A 
       %7D%0A

Fix issue 3 - Variables from CSV Config Item - exception if empty lines Added also drop of bad formatted lines